Changelog
New Features:
- Conversation Compaction:
Agent(compaction=True)keeps long sessions inside the context window by folding older turns into a summary. Stored messages are never rewritten: aCompactionRecordin the newagno_compactionstable drives a derived model payload, so removing the record restores the full conversation. Tune withCompaction(model=..., compact_at_tokens=..., uncompacted_runs=...), fold on demand withagent.compact()/acompact(), and inspectrun.compaction. Withsearchable=Truethe agent gets asearch_compacted_historytool, a regex grep over the archived transcript. See cookbook. (#9873) - Codex External Agent: Added
CodexAgent, an adapter for OpenAI Codex built on theopenai-codexSDK, alongside the Claude Agent SDK, LangGraph, DSPy and Antigravity adapters. Codex runs its own agent loop; the adapter translates its notifications into Agno run and tool-call events, maps each Agno session to one Codex thread (persisted when adbis set), and exposessandbox,approval_mode,reasoning_effort,output_schemaand MCP config. Works standalone and through AgentOS. See cookbook. (#10901) - HyDE Query Transform: Added
QueryTransformeras a new retrieval hook andHyDEas its first implementation:Knowledge(vector_db=..., query_transformer=HyDE())searches with a hypothetical answer instead of the raw question, while rerankers still score against the original query.HyDEuses its ownmodel, then the calling agent or team's model, then the framework default. See cookbook. (#10527) - Browser Origin Policy: Added
AgentOS(cors=CORSConfig(origins=..., origin_regex=..., merge_base_app=...))and opt-inPublicSurface(enforce_browser_origins=True). One origin policy is now shared by CORS preflights, public run and cancel admission, auth error headers, workflow WebSockets and MCP aliases, and CORS is the outermost middleware so error responses carry consistent headers.cors_allowed_originskeeps its existing behaviour. See cookbook. (#10869) - Configurable Follow-ups:
followups: bool | FollowupConfigon Agent and Team.FollowupConfigsets a count range (num_followupsormin_followups/max_followups), a separate model and custom instructions that go only to the follow-up call. The default prompt now stays within the answer's boundaries and no longer re-offers a request the answer declined. Existingnum_followupscallers keep getting exactly N suggestions. See cookbook. (#10087) - Heabsy: Added
Heabsyas an OpenAI-compatible model provider, also resolvable as"heabsy:<model>". See cookbook. (#10828) - FlexAI: Added
FlexAIas an OpenAI-compatible model provider for open-weight models, also resolvable as"flexai:<model>". See cookbook. (#10871) - SixtyDBTools: New toolkit for the 60db hosted speech API: discover workspace voices and generate speech as WAV audio artifacts. See cookbook. (#10786)
Improvements:
- Page Sync Logs: Page synchronization now logs lock waits, discovery, progress every 25 pages and final counts, so long syncs show progress without a custom callback. Added an AgentOS cookbook that syncs documentation into PostgreSQL-backed knowledge pages and exposes them through the agent's filesystem. See cookbook. (#10868)
- OpenAIResponses & OpenRouterResponses: Recognise GPT-6 (OpenAI) and GPT-5/6 (OpenRouter) as reasoning models, so reasoning-state chaining and encrypted reasoning replay apply and tool-call follow-ups no longer fail with missing reasoning-item errors. (#10830)
- PerplexitySearch: Requests now send an
X-Pplx-Integration: agnoheader so Perplexity can attribute traffic from the integration. (#10827)
Bug Fixes:
- Approvals: Each
@approvaltool call in a run now gets its own approval record, for agents and teams. Previously a second pause in the same run created no record and the next continue ran the new call against the approval resolved for the first one. (#10812) - Model Response Cache: Pydantic
output_schemaclasses are keyed by their JSON schema instead of their class name, so two schemas with the same name but different fields no longer share a cached response. (#10621) - Usage Metrics:
MessageMetrics.cache_write_tokensis now populated from OpenAI Chat Completions and Responses usage (#10313) and from LiteLLM'sprompt_tokens_details(#10476). Previously it was always zero. - JsonDb: Tables are serialized to a staging file and published with
os.replace, so a failed write leaves the last successfully saved table readable instead of a truncated file. (#10794) - MongoDb & MongoVectorDb:
session_name,search_contentand keyword-search filters are regex-escaped, so a value like(draftno longer returns HTTP 500 fromGET /sessionsandGET /memories, andv1.2no longer matchesv1x2. (#10709) - Tool Schemas:
Annotated[T, ...]hints are unwrapped toTbefore JSON schema generation instead of falling through to an empty object schema. (#10858) - SQLTools: Connection URLs are built with
URL.create, so a password likep@sswordis no longer split into passwordpand hostssword@.... (#10800) - FileTools:
replace_file_chunkrejects negative, reversed and out-of-bounds line ranges with an error and leaves the file untouched; a valid replacement preserves the trailing newline. (#10798) - GoogleCalendarTools:
find_available_slotscompares the full slot end against closing time on its start date, so a 45 minute slot is no longer offered at 16:30 for a 17:00 close and slots cannot cross midnight. (#10878) - BaiduSearchTools, Searxng & SpiderTools: An explicit
max_results=0/fixed_max_results=0now means no results instead of falling back to the default. (#10877) - Readers:
TextReader,MarkdownReader(#10779) andJSONReader(#10634) accept streams whosenameis an integer orNone, such as descriptor-backed temporary files, instead of returning nothing or raising. - Cookbooks: Fixed the
DynamoDbimport path in the DynamoDB storage README. (#10788)
What's Changed
- [fix] Handle non-string stream names in JSONReader by @Jim-jimu in #10634
- [cookbook] Fix DynamoDb import path in the DynamoDB cookbook README by @Xx-173 in #10788
- [fix] Read text and Markdown streams with non-string names by @pei711 in #10779
- fix: create a separate approval record for each approval-required tool call in a run by @kausmeows in #10812
- [fix] Reject invalid file replacement line ranges by @LeonSGP43 in #10798
- [feat] Add Perplexity integration attribution by @qirh in #10827
- [fix] Preserve reserved characters in SQLTools credentials by @wToTw123 in #10800
- [fix] Preserve saved JsonDb tables when writes fail by @rudycelekli in #10794
- fix: recognize GPT reasoning models in OpenAI and OpenRouter Responses by @Ayush0054 in #10830
- [feat] Add 60db workspace voice tools by @uditgoenka in #10786
- fix: match Mongo text filters as literal text by @devYRPauli in #10709
- cookbook: add knowledge filesystem example and sync progress logs by @Ayush0054 in #10868
- [fix] Include response schema in model cache keys by @charan-rathore in #10621
- fix: keep configurable follow-ups within response boundaries by @ashpreetbedi in #10087
- [feat] Add FlexAI as an OpenAI-compatible model provider by @sundar-flex in #10871
- [fix] Preserve OpenAI cache-write usage metrics by @basnijholt in #10313
- [fix] Preserve cache-write tokens in the LiteLLM usage parser by @HardMax71 in #10476
- chore: auto-close external PRs that skip triage or the PR template by @kausmeows in #10866
- [fix] Unwrap Annotated types in tool JSON schema generation by @michaelkillgta in #10858
- fix: honor zero max_results in BaiduSearch, Searxng and Spider toolkits by @Madin-H23 in #10877
- [feat] Add Heabsy as an OpenAI-compatible model provider by @kafomichev in #10828
- feat: unify browser origin policy across AgentOS surfaces by @ysolanky in #10869
- [fix] Keep Google Calendar slots within working hours by @lux-liang in #10878
- feat: add HyDE query transform by @sannya-singal in #10527
- feat: add support for codex harness external agent by @kausmeows in #10901
- feat: auto compaction with a searchable archive by @kausmeows in #9873
- chore: Release v3.1.2 by @kausmeows in #10892
New Contributors
- @Jim-jimu made their first contribution in #10634
- @Xx-173 made their first contribution in #10788
- @pei711 made their first contribution in #10779
- @LeonSGP43 made their first contribution in #10798
- @qirh made their first contribution in #10827
- @wToTw123 made their first contribution in #10800
- @rudycelekli made their first contribution in #10794
- @uditgoenka made their first contribution in #10786
- @charan-rathore made their first contribution in #10621
- @sundar-flex made their first contribution in #10871
- @HardMax71 made their first contribution in #10476
- @michaelkillgta made their first contribution in #10858
- @Madin-H23 made their first contribution in #10877
- @kafomichev made their first contribution in #10828
- @lux-liang made their first contribution in #10878
Full Changelog: v3.1.1...v3.1.2