DoublewordDoubleword
Get started

Agno

Agno (formerly Phidata) provides an OpenAILike model class designed for custom OpenAI-compatible endpoints.

Install

pip install agno openai

Configure

from agno.agent import Agent
from agno.models.openai import OpenAILike

agent = Agent(
    model=OpenAILike(
        id="{{selectedModel.id}}",
        base_url="https://api.doubleword.ai/v1",
        api_key="{{apiKey}}",
    )
)

agent.print_response("Say hello.")

Prompt caching

Pass the system prompt as a Message whose content block carries cache_control:

from agno.agent import Agent
from agno.models.message import Message
from agno.models.openai import OpenAILike

agent = Agent(
    model=OpenAILike(
        id="{{selectedModel.id}}",
        base_url="https://api.doubleword.ai/v1",
        api_key="{{apiKey}}",
    ),
    system_message=Message(
        role="system",
        content=[{
            "type": "text",
            "text": "…large, stable instructions (~1024-token floor)…",
            "cache_control": {"type": "ephemeral", "ttl": "1h"},
        }],
    ),
)

response = agent.run("What is 2 + 2?")
print(response.metrics.cache_read_tokens)

Agno forwards the block unchanged. It reports cache reads but not writes, so compare cache_read_tokens across two runs. See the prompt caching guide.

Async pricing with Autobatcher

For background tasks where latency is not critical, use Autobatcher to run requests on Doubleword's cheaper async (flex) tier:

pip install agno openai autobatcher
from autobatcher import BatchOpenAI
from agno.agent import Agent
from agno.models.openai import OpenAILike
import asyncio

client = BatchOpenAI(
    api_key="{{apiKey}}",
    base_url="https://api.doubleword.ai/v1",
)

agent = Agent(
    model=OpenAILike(
        id="{{selectedModel.id}}",
        async_client=client,
    )
)

async def main():
    response = await agent.arun("Say hello.")
    print(response.content)
    await client.close()

asyncio.run(main())

BatchOpenAI is a drop-in AsyncOpenAI subclass. By default it sends each call as an async (flex) request and polls for the result. For the deepest discount, pass completion_window="24h" and it collects calls into 24h batch jobs instead.