Skip to content

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 the kimi-cli credential file and auto-refreshes the short-lived (~15 min) token on every request — local dev sessions no longer 401 mid-run or need a manual kimi refresh. The rotated refresh token is written back safely (file lock + atomic write) so your kimi-cli login stays valid; tokens are never logged. Explicit KIMI_OAUTH_ACCESS_TOKEN opts 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 on 401/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 metered MOONSHOT_API_KEY. Env-vars-only (KIMI_OAUTH_ACCESS_TOKEN, KIMI_OAUTH_BASE_URL, KIMI_OAUTH_PLATFORM); production guard identical to CodexOAuthProvider. Defaults to the kimi.com subscription/coding endpoint (https://api.kimi.com/coding/v1, model kimi-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 real SystemMessage + HumanMessage round-trip and is deselected by default.

Changed

  • AnthropicOAuthProvider is no longer deprecated. It is now a supported dev/test-only provider (same posture as CodexOAuthProvider): construction no longer emits a DeprecationWarning — instead it logs a one-time ToS caveat. It still auto-loads the Claude Code token from the Keychain / ~/.claude/.credentials.json and is never for production.

Fixed

  • CodexOAuthProvider now works through the normal agent path. The Codex Responses backend rejects role: "system" (400 System messages are not allowed), which crashed every SymfonicAgent run on the first call. The provider now rewrites outgoing system messages to the developer role on the Responses-API path. (Verified live against the Codex backend.)
  • symfonic init --llm-provider openrouter now points adopters at OPENROUTER_API_KEY instead of a generic LLM_API_KEY hint.
  • KimiProvider observability — Kimi spans now report gen_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_tooling validates procedural skills against your registered tools. A skill's tool identifier is its action_tool metadata (else content) and must be the exact name of a registered tool. A name that matches nothing is now dropped with a LazySkillResolutionWarning instead of leaking into the system prompt as a phantom tool. Correctly-named skills are unaffected; put descriptive text in steps / 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 with never 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(...) and AgentBuilder now re-validate the assembled config, enforcing field constraints and warning on unknown fields instead of silently keeping them.
  • Declarative sub-agent descriptions preserved. A SubAgentSpec with only description set 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-wiring FrameworkConfig + 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 explicit extraction_template_path still 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's ModelProvider and every behaviour flag, but with its own fresh domain so its tool manifest auto-derives from its own tools. The pre-built SubAgent(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 SubAgentSpec inherits the parent's provider by default (providers are stateless, so one instance is safe to share); pass provider= to override per child.
  • AgentResponse.delegated_to is now populated. The field (added empty in 9.0.1) is wired: a parent run records the sub-agent(s) it delegated to via run_agent and 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__ awaits flush_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-effort atexit guard emits a RuntimeWarning if 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 guide and a wheel-resident AGENTS.md — an offline quick reference (decision tree, canonical imports, a real quickstart, footguns) discoverable from an installed wheel, no repo needed. Plus llms.txt for online agents.
  • AgentResponse.delegated_to — the sub-agent(s) a parent delegated to (tuple[str, ...], empty = answered directly).

Changed

  • tool_manifest auto-derives silently from your registered tools (was a UserWarning); 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.core now points to symfonic.agent in its docstring, and the LazyToolingWarning carries an actionable Fix: line.
  • Sharing one ModelProvider across 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.0 and langchain-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 plain pip install -U symfonic-core pulls 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 requires langgraph-checkpoint>=3 (i.e. langgraph>=1.0), which the old langgraph<1.0 core 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_client transport 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 (needs pip install "symfonic-core[mongodb]") instead of silently falling through to the ephemeral in-process MemorySaver — so resumable interactive sessions and durable transcripts survive a restart on Mongo deployments. ask_user pause tokens are made durable on Mongo too via a MongoPauseTokenStore. Selected automatically from the graph backend, exactly like the Postgres path; no config change required. See docs/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), and NullConversationManager (unbounded). Pass one as SymfonicAgent(conversation_manager=…). Thin wrappers over the existing compaction + windowing engine — orthogonal to HMS memory. See docs/concepts/conversation-managers.md.
  • symfonic examples CLI. Copy a curated, runnable example straight into your project without cloning the repo — symfonic examples list shows what's available and symfonic 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 on MockModelProvider — no API key, no extra dependencies. Requires the [cli] extra. Also includes real_agent, which runs against a real Anthropic model ([anthropic] extra + an API key); examples list / add state 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 .backend attribute (the store exposes _backend), so every deployment silently fell through to the ephemeral in-process MemorySaver regardless 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. MongoDBSaver serializes the whole checkpoint in one call; the safe serializer degraded the entire checkpoint to None when it contained a non-serializable runtime channel (deps), so get_transcript / restart-resume returned empty on Mongo. The serializer now sanitizes channel values per entry, keeping messages.
  • 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 examples on sys.path) that makes python -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_MODEL is a Bedrock model / inference-profile id. symfonic init --llm-provider aws scaffolds it end-to-end.
  • OpenRouter provider. Reach many vendors through one OpenAI-compatible gateway via OpenRouterProvider (pip install symfonic-core[openrouter]). LLM_MODEL is a fully-qualified id (anthropic/claude-sonnet-4.5); auth via OPENROUTER_API_KEY. symfonic init --llm-provider openrouter scaffolds 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_agents tools. Declare children with SymfonicAgent(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. New top_p (all providers) and top_k (Anthropic, Google, Ollama) knobs, alongside the existing temperature / max_tokens. See Model Tuning.
  • Scaffolded projects (symfonic init) now ship a working researcher sub-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 MetricsStore lets 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 LICENSE file 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.