Cross-model comparison
Every adapter implements the same Model protocol, so you can save independent artifacts for one task.
compare.py
1import asyncio
2from opentine import Agent
3from opentine.models.anthropic import Anthropic
4from opentine.models.google import Google
5from opentine.models.ollama import Ollama
6from opentine.models.openai import OpenAI
7
8models = {
9 "anthropic": Anthropic("claude-sonnet-5"),
10 "openai": OpenAI("gpt-5.6"),
11 "google": Google("gemini-3.5-flash"),
12 "ollama": Ollama("qwen3"),
13}
14
15async def evaluate(name, model):
16 run = await Agent(model=model).run("Explain artifact provenance in 120 words.")
17 run.save(f"comparison-{name}.tine")
18 return name, run
19
20async def main():
21 results = await asyncio.gather(*(evaluate(n, m) for n, m in models.items()))
22 for name, run in results:
23 print(name, run.status, len(run.steps), run.total_cost, run.total_duration)
24
25asyncio.run(main())
Interpret costs carefully
Every adapter returns normalized usage and a billing state. total_cost is the known subtotal: compare it together with complete, partial, unknown, or unmetered billing metadata. Local Ollama calls default to unmetered, which does not mean the underlying hardware is free.
Diff
Terminal
tine diff comparison-anthropic.tine comparison-openai.tineIndependent runs may have no common ancestor. Field alignment is most useful when graph positions and kinds correspond.