Models
- Recommended:
gpt-4o(latest, best quality) - Fast/Cheap:
gpt-4o-mini(fast, cost-effective) - Reasoning:
o1,o1-mini(advanced reasoning) - Latest:
gpt-4.1,gpt-4.5-preview(newest releases)
Python
With Tools
Multi-Agent
Transparent Responses API routing
For OpenAI models that support the Responses API (gpt-4o, gpt-4.1, gpt-4.5, gpt-5, o1, o3, o4, chatgpt-4o, and their azure/ / openai/ prefixes), PraisonAI uses the Responses endpoint automatically on the native client path โ no code change, no flag. Chat Completions is only used when a custom base_url is set or the installed openai SDK does not expose responses.
agent.chat / agent.start) use the same transparent routing โ the client rebinds its async transport across asyncio.run loops, so a sync turn and the next sync turn stay on the Responses endpoint rather than silently swapping to Chat Completions.
Supplying history with tool calls
If you pass conversation history that includes an assistant turn withtool_calls, the content field may be any of:
- a plain string:
"Checking" - a list of text parts:
[{"type": "text", "text": "Checking"}](the Chat Completions multimodal shape) - empty โ
"",None,[], or whitespace โ in which case only the tool call is emitted
content was fixed in PraisonAI PR #5695 (merged 2026-10-08). On earlier versions the same history raised AttributeError and silently fell back to Chat Completions.
Fallback is quieter now
Two spuriousResponses API failed, falling back to Chat Completions: โฆ WARNING lines were fixed in PraisonAI PR #5682 (merged 2026-10-08):
- Orphan tool outputs no longer 400. If your history contains a
role="tool"message whosetool_call_idhas no matching assistantfunction_callin the same payload โ e.g. history trimming dropped the assistant turn, or a user turn follows a tool round from an earlier session โ the client now drops thatfunction_call_outputbefore sending. Before #5682 the Responses API rejected the payload withNo tool call found for function call output with call_id โฆand the client logged a fallback WARNING for every such turn. - Sync callers no longer see โEvent loop is closedโ. The cached
AsyncOpenAIinstance is rebuilt whenever the running loop differs from the one it was bound to (the common case for syncagent.chat()/agent.start()which bridge into the async path via a freshasyncio.runper call). Before #5682 the stale httpx transport raisedEvent loop is closedon reuse and the client logged a fallback WARNING for every turn.
The fallback mechanism is unchanged โ on a real Responses failure the client still falls back to Chat Completions, so answers are not lost. #5682 only stops the two spurious triggers above from firing.
Follow-up in PR #5859 (merged 2026-10-16). After #5682 rebinds the client on each sync turn, the previous loopโs
AsyncOpenAI is eventually garbage-collected. Before #5859 that GC fired httpx.AsyncClient.aclose() on whichever loop was running โ raising RuntimeError: Event loop is closed and logging Task exception was never retrieved at ERROR level. The cached client is now built with openai.DefaultAsyncHttpxClient() (same timeouts, limits, redirects) so no cross-loop aclose task is scheduled from __del__.Sync OpenAIClient.close() also changed: it used to call AsyncOpenAI.close() without awaiting it (closing nothing). It now closes the sync client and drops the async client reference. Use await client.aclose() or await agent.aclose() for async teardown.function_call_output items are dropped while the Responses input is built โ the client scans assistant tool_calls first, then keeps only the tool outputs whose call_id matches one it emitted.
The cached AsyncOpenAI is rebound whenever the running loop changes, so each sync turn gets a client bound to its own asyncio.run loop.
Reasoning model parameter normalization. Whenever a request goes through Chat Completions (custom
base_url, the installed openai SDK has no responses, or a Responses call falls back), PraisonAI omits unset temperature/max_tokens instead of sending null, and for reasoning models (o1, o3, o4, gpt-5.x) maps an explicit max_tokens to max_completion_tokens (PR #5910). See Reasoning Models for the full behaviour table.
