Changelog¶
User-facing changes to symfonic-core. The format is based on Keep a Changelog and the project follows Semantic Versioning.
This is the curated public changelog — it covers changes relevant to users of the published package. Fine-grained internal release notes are maintained separately by the maintainers.
[Unreleased]¶
[9.9.0] - 2026-07-19¶
Added¶
- Kimi OAuth auto-refresh.
KimiOAuthProvider.from_kimi_cli()reads thekimi-clicredential file and auto-refreshes the short-lived (~15 min) token on every request — local dev sessions no longer 401 mid-run or need a manualkimirefresh. The rotated refresh token is written back safely (file lock + atomic write) so yourkimi-clilogin stays valid; tokens are never logged. ExplicitKIMI_OAUTH_ACCESS_TOKENopts out (unchanged).
Changed¶
- Clear, actionable auth-failure messages for all OAuth providers. An
expired/revoked subscription token now names the exact remediation
(
kimi-cli login/codex login/claude login) via a clear error or a log-only WARNING on401/403, instead of an opaque SDK error.
[9.8.0] - 2026-07-19¶
Subscription OAuth providers for local dev/test. Three providers now let a single developer drive the full pipeline against a real LLM using the OAuth token their CLI already stored — no metered API key. They are not a production path: none bill per tenant or refresh tokens, each replays a personal subscription token (which may be throttled/disallowed under the vendor's ToS), and each refuses to construct in a production-like environment. See the Subscription OAuth providers guide.
Added¶
KimiOAuthProvider(symfonic.core.kimi_oauth_provider) — dev/test-only provider that calls the Kimi/Moonshot OpenAI-compatible backend with a kimi.com subscription token instead of a meteredMOONSHOT_API_KEY. Env-vars-only (KIMI_OAUTH_ACCESS_TOKEN,KIMI_OAUTH_BASE_URL,KIMI_OAUTH_PLATFORM); production guard identical toCodexOAuthProvider. Defaults to the kimi.com subscription/coding endpoint (https://api.kimi.com/coding/v1, modelkimi-for-coding) — the only endpoint a subscription token authenticates against — so subscription tokens work without an override.- Live (
live_llm) tests for all three OAuth providers — each sends a realSystemMessage+HumanMessageround-trip and is deselected by default.
Changed¶
AnthropicOAuthProvideris no longer deprecated. It is now a supported dev/test-only provider (same posture asCodexOAuthProvider): construction no longer emits aDeprecationWarning— instead it logs a one-time ToS caveat. It still auto-loads the Claude Code token from the Keychain /~/.claude/.credentials.jsonand is never for production.
Fixed¶
CodexOAuthProvidernow works through the normal agent path. The Codex Responses backend rejectsrole: "system"(400 System messages are not allowed), which crashed everySymfonicAgentrun on the first call. The provider now rewrites outgoing system messages to thedeveloperrole on the Responses-API path. (Verified live against the Codex backend.)symfonic init --llm-provider openrouternow points adopters atOPENROUTER_API_KEYinstead of a genericLLM_API_KEYhint.KimiProviderobservability — Kimi spans now reportgen_ai.system="openai"(was"unknown"), consistent with its DeepSeek sibling.
[9.3.0] - 2026-07-13¶
Lazy-tooling skill-resolution contract (issue #36). No API changes.
Changed¶
lazy_toolingvalidates procedural skills against your registered tools. A skill's tool identifier is itsaction_toolmetadata (elsecontent) and must be the exact name of a registered tool. A name that matches nothing is now dropped with aLazySkillResolutionWarninginstead of leaking into the system prompt as a phantom tool. Correctly-named skills are unaffected; put descriptive text insteps/context, not in the identifier field.
[9.2.1] - 2026-07-13¶
Correctness patch from an external review of the 9.1/9.2 work. No API changes.
Fixed¶
- Agent shutdown no longer blocks on unrelated agents. Background
consolidation is now tracked and flushed per agent, so exiting one agent's
async withnever waits on another agent's pending work. - Provider-family extraction respects routing. The family-tuned extraction template is now selected from the resolved model config, so a router serving a different vendor than its default gets the right template.
- Config facades validate overrides.
FrameworkConfig.child(...)andAgentBuildernow re-validate the assembled config, enforcing field constraints and warning on unknown fields instead of silently keeping them. - Declarative sub-agent descriptions preserved. A
SubAgentSpecwith onlydescriptionset now gives the child a matching domain description (was empty).
[9.2.0] - 2026-07-12¶
Facade minor: a fluent builder over the 9.1 construction surface and provider-family-aware memory extraction. Fully additive — no breaking changes.
Added¶
AgentBuilder— a fluent way to assemble an agent. Chain.provider().model().domain().tools().enable_hms().memory().sub_agent().build()instead of hand-wiringFrameworkConfig+SymfonicAgent. It's a thin facade over the same primitives (FrameworkConfig,SubAgentSpec,HMSFactory) — no new behaviour — and.memory(embeddings=…)builds an in-memory HMS for you.
Changed¶
- HMS memory extraction adapts to the provider family. OpenAI-family and
Google agents now render a more explicit extraction directive (a strict
<GRAPH_OPERATIONS>JSON protocol) instead of the Anthropic-delimiter default, reducing silent memory loss on instruction-following models. Anthropic and unrecognised/custom providers are unchanged (wire-neutral). An explicitextraction_template_pathstill overrides the family default.
[9.1.0] - 2026-07-12¶
Construction-DX minor for sub-agent ergonomics and non-Claude memory reliability. Fully additive — no breaking changes.
Added¶
- Declarative sub-agents —
SubAgentSpec. Describe a child agent and let the parent build it:SymfonicAgent(sub_agents=[SubAgentSpec(name="researcher", description="deep research", tools=[...], temperature=0.2)]). The parent constructs the isolated child at wiring time, inheriting the parent'sModelProviderand every behaviour flag, but with its own fresh domain so its tool manifest auto-derives from its own tools. The pre-builtSubAgent(agent=...)form remains as the escape hatch; mix both freely. FrameworkConfig.child(parent, name=, description=, model_name=, temperature=, max_tokens=, **overrides)— derive a sub-agent config that inherits every parent flag and overrides only what you name. Stops per-child config drift.- Provider inheritance. A
SubAgentSpecinherits the parent's provider by default (providers are stateless, so one instance is safe to share); passprovider=to override per child. AgentResponse.delegated_tois now populated. The field (added empty in 9.0.1) is wired: a parent run records the sub-agent(s) it delegated to viarun_agentand stamps them, in order, onto its final response.FrameworkConfig.extraction_template_path— point HMS memory extraction at a custom directive template. The bundled template is Anthropic-delimiter oriented; non-Claude adopters (Qwen/DeepSeek/vLLM) can supply a JSON-only directive to stop silent memory loss when the model ignores the delimiter.
Changed¶
async with SymfonicAgent(...)now flushes background memory work.__aexit__awaitsflush_background_tasks()before releasing resources, so the idiomatic context-manager exit no longer silently drops fire-and-forget consolidation.aclose()stays a pure resource-release for the hot-reload path. A best-effortatexitguard emits aRuntimeWarningif a process exits with consolidation still pending — turning silent memory loss into a visible signal.
[9.0.1] - 2026-07-12¶
Agent-experience patch from autonomous-adopter feedback. No breaking changes.
Added¶
symfonic guideand a wheel-residentAGENTS.md— an offline quick reference (decision tree, canonical imports, a real quickstart, footguns) discoverable from an installed wheel, no repo needed. Plusllms.txtfor online agents.AgentResponse.delegated_to— the sub-agent(s) a parent delegated to (tuple[str, ...], empty = answered directly).
Changed¶
tool_manifestauto-derives silently from your registered tools (was aUserWarning); this closes the "tool registered but the LLM can't see it" footgun. Tools marked@symfonic_tool(visibility="hidden")are excluded; an explicit manifest still wins.symfonic.corenow points tosymfonic.agentin its docstring, and theLazyToolingWarningcarries an actionableFix:line.- Sharing one
ModelProvideracross a parent and its sub-agents is safe and documented (providers hold no per-call state).
Fixed¶
- Non-Claude memory-label corruption — labels are whitespace-collapsed and length-capped so a model that ignores the extraction format can't persist its whole response as a node label.
[9.0.0] - 2026-07-10¶
Changed (breaking)¶
- Migrated to the langgraph 1.x / langchain-core 1.x line. Core now requires
langgraph>=1.0,<2.0andlangchain-core>=1.0,<2.0; the 0.x line is no longer supported. Provider extras admit the langchain- 1.x releases (anthropic, openai, aws, google, ollama, chroma). A plainpip install -U symfonic-corepulls the aligned 1.x set. Step-by-step upgrade instructions:* Migrate 8.x to 9.x.
Fixed¶
- The durable Mongo checkpointer is now installable. It shipped in 8.12.0
but
pip install "symfonic-core[mongodb]"could not resolve — the Mongo adapter requireslanggraph-checkpoint>=3(i.e.langgraph>=1.0), which the oldlanggraph<1.0core pin forbade. On the 1.x line the whole checkpoint cluster (postgres/sqlite/mongo) resolves consistently. - Tool errors no longer crash a run on langgraph 1.x. langgraph 1.x changed the tool-node default to re-raise non-validation tool exceptions; symfonic now restores the prior behavior where a raised tool error is fed back to the model as a recoverable message instead of aborting the graph.
- Anthropic
http_clienttransport injection works across the langchain-anthropic 1.x line (the seam's version gate now spans the 1.x releases, still guarded by its structural probe).
[8.12.0] - 2026-07-09¶
Added¶
- Durable checkpointer for MongoDB. A Mongo graph backend now wires a
durable
MongoDBSaver(needspip install "symfonic-core[mongodb]") instead of silently falling through to the ephemeral in-processMemorySaver— so resumable interactive sessions and durable transcripts survive a restart on Mongo deployments. ask_user pause tokens are made durable on Mongo too via aMongoPauseTokenStore. Selected automatically from the graph backend, exactly like the Postgres path; no config change required. Seedocs/concepts/conversation-persistence.md. - Conversation managers. Named, swappable strategies for keeping history in
the context window —
SummarizingConversationManager(default: summarize overflow),SlidingWindowConversationManager(window_size=N)(keep the last N messages, no LLM summary), andNullConversationManager(unbounded). Pass one asSymfonicAgent(conversation_manager=…). Thin wrappers over the existing compaction + windowing engine — orthogonal to HMS memory. Seedocs/concepts/conversation-managers.md. symfonic examplesCLI. Copy a curated, runnable example straight into your project without cloning the repo —symfonic examples listshows what's available andsymfonic examples add <name>copies it into./<name>/and prints how to run it. The curated set (minimal_agent,basic_agent,tool_agent,skill_agent,sub_agents,memory_agent,e2e_basic_agent) is bundled in the wheel as data and runs onMockModelProvider— no API key, no extra dependencies. Requires the[cli]extra. Also includesreal_agent, which runs against a real Anthropic model ([anthropic]extra + an API key);examples list/addstate each example's requirements.- Full-code example walkthroughs. Each of the nine core learning-path examples now has a documentation page with the complete source and a step-by-step explanation, so the code is readable without a checkout.
Fixed¶
- Durable checkpointer was never selected (Postgres or Mongo). The engine's
graph-backend selectors read a non-existent
.backendattribute (the store exposes_backend), so every deployment silently fell through to the ephemeral in-processMemorySaverregardless of a durable Postgres/Mongo graph backend — transcripts and resumable state did not survive a restart. Now reads the real backend. Surfaced by end-to-end testing the Mongo path. - Mongo checkpoints lost their channel values.
MongoDBSaverserializes the whole checkpoint in one call; the safe serializer degraded the entire checkpoint toNonewhen it contained a non-serializable runtime channel (deps), soget_transcript/ restart-resume returned empty on Mongo. The serializer now sanitizes channel values per entry, keepingmessages. - Examples install guidance. Corrected the docs claim that an editable/dev
install "exposes" the examples tree — it's running from the repo root (which
puts
examplesonsys.path) that makespython -m examples.<name>work; the extras are only needed for examples that import them.
[8.10.0] - 2026-07-08¶
Added¶
- AWS Bedrock provider. Run any Bedrock model (Claude, Llama, Nova,
Mistral, …) through the Converse API via
AWSBedrockProvider(pip install symfonic-core[aws]). The wire family is auto-detected per model — Claude gets extended thinking, other vendors are treated wire-neutral. Region and credentials resolve through the standard boto3 chain;LLM_MODELis a Bedrock model / inference-profile id.symfonic init --llm-provider awsscaffolds it end-to-end. - OpenRouter provider. Reach many vendors through one OpenAI-compatible
gateway via
OpenRouterProvider(pip install symfonic-core[openrouter]).LLM_MODELis a fully-qualified id (anthropic/claude-sonnet-4.5); auth viaOPENROUTER_API_KEY.symfonic init --llm-provider openrouterscaffolds it.
Fixed¶
- Bedrock cost telemetry. Claude-on-Bedrock calls now report correct token
cost (Anthropic list rates) instead of
$0. Non-Anthropic Bedrock models need a pricing override.
[8.9.1] - 2026-07-08¶
Added¶
- Sub-agent delegation. A parent agent can hand a self-contained task to a
named child agent through the built-in
run_agent/list_agentstools. Declare children withSymfonicAgent(sub_agents=[SubAgent(...)]); each child runs isolated, inherits the parent's tenant scope, and is bounded by a delegation-depth guard. See the Sub-agents guide. - Sampling controls on
ModelConfig. Newtop_p(all providers) andtop_k(Anthropic, Google, Ollama) knobs, alongside the existingtemperature/max_tokens. See Model Tuning. - Scaffolded projects (
symfonic init) now ship a workingresearchersub-agent, a visible "delegating…" indicator in the chat UI, and tighter default reply lengths.
Fixed¶
- The built-in mock chat model now streams incrementally, so streamed UIs and end-to-end tests observe real token deltas instead of an empty response.
[8.8.0] - 2026-07-07¶
Added¶
- Pluggable metrics persistence. A storage-agnostic
MetricsStorelets per-LLM-call usage and cost survive worker restarts, with Postgres and MongoDB reference backends. Fully additive — behaviour is unchanged when no store is configured.
[8.7.1] - 2026-07-03¶
Fixed¶
- Consolidated hotfix across the agent engine, memory backends, prompt cache, pricing/observability, and metrics endpoints. Hardens state-key propagation, conversation isolation in the messages cache, precondition gating, and metrics-router authentication.
Packaging¶
- The published source distribution is now curated: it contains the package, tests, license, README, and a hand-picked set of user-facing guides and examples. Internal tooling, local artifacts, and internal-only notes are no longer included.
- Installation now defaults to public PyPI (
pip install symfonic-core); no extra package index configuration is required. - Added an explicit MIT
LICENSEfile to the distribution.
[8.7.0] - 2026-07-01¶
Added¶
- Opt-in rolling messages-region cache ladder (
messages_cache_policy="rolling"). For long agentic tool-loops it converts the previously ~quadratic uncached token tail into a roughly linear one by holding prior cache markers as reads and adding one new marker per iteration. No default behavior change — the request wire is byte-identical under the default policy.
[8.6.0 – 8.6.9] - 2026-06¶
Changed¶
- A series of reliability and correctness improvements across memory backends, prompt caching, usage/cost accounting, and the diagnostics CLI.
[8.0.0] - 2026-06-13¶
Added¶
- Major release of the 8.x line: the agent orchestration layer, 5-layer Hierarchical Memory System (HMS), capability-based dependency injection, streaming event taxonomy, and the FastAPI bridge.
For upgrade guidance between major lines, see Migrate 8.x to 9.x and Migrate 6.x to 7.x.