Eino V0.9 Migration Notes

This document lists the API and semantic changes that existing users need to be aware of when upgrading from V0.8.x to V0.9 agentic-runtime. New capabilities not listed here generally do not affect the existing *schema.Message path.

Explicit API Changes

V0.9 marks the multi-Agent collaboration model based on Agent Transfer (full context sharing) as NOT RECOMMENDED. Affected public APIs include:

Agent Transfer related:

  • SetSubAgents
  • AgentWithOptions / WithDisallowTransferToParent / WithHistoryRewriter
  • ChatModelAgentConfig.Exit / ChatModelAgentConfig.OutputKey
  • AgentWithDeterministicTransferTo
  • OnSetSubAgents / OnSetAsSubAgent / OnDisallowTransferToParent

Workflow Agent:

  • NewSequentialAgent / SequentialAgentConfig
  • NewParallelAgent / ParallelAgentConfig
  • NewLoopAgent / LoopAgentConfig

Supervisor:

  • supervisor.New / supervisor.Config

💡 These APIs can still be used and will not cause compilation failures, but they are not recommended for new projects. Experience has shown that the transfer model where Agents share full conversation context does not perform better than the tool-calling model in practice.

Recommended migration directions:

  • Use ChatModelAgent + AgentTool (wrap sub-Agents as tools, call on demand).
  • Use DeepAgent (structured sub-task delegation).
  • Both approaches provide better controllability, observability, and prompt cache efficiency.

ChatModelAgentMiddleware Adds AfterAgent

ChatModelAgentMiddleware adds the AfterAgent method. Types that manually implement this interface need to add this method, otherwise compilation will fail.

Recommended approach:

  • If the middleware doesn’t need special cleanup logic, embed *adk.BaseChatModelAgentMiddleware.
  • If the middleware needs to clean up state, record events, or add statistics after the Agent completes successfully, implement AfterAgent(ctx, state).

Impact:

  • Only affects user code that explicitly implements ChatModelAgentMiddleware.
  • Code that extends via BaseChatModelAgentMiddleware composition remains compatible.

AgentMiddleware Struct Deprecated

The AgentMiddleware struct and the ChatModelAgentConfig.Middlewares field have been marked as Deprecated and will be removed in a future version.

💡 Both AgentMiddleware and the Middlewares field are deprecated. Please migrate to the interface-based Handlers (ChatModelAgentMiddleware) approach.

Migration steps:

  • Migrate the logic from Middlewares []AgentMiddleware to Handlers []ChatModelAgentMiddleware.
  • AgentMiddleware.BeforeChatModel → implement ChatModelAgentMiddleware.BeforeModelRewriteState.
  • AgentMiddleware.AfterChatModel → implement ChatModelAgentMiddleware.AfterModelRewriteState.
  • AgentMiddleware.WrapToolCall → implement ChatModelAgentMiddleware.WrapToolCall.
  • AgentMiddleware.AdditionalInstruction → modify state.Instruction in BeforeModelRewriteState.
  • AgentMiddleware.AdditionalTools → modify state.ToolInfos in BeforeModelRewriteState.
  • If the middleware doesn’t need special logic, embed *adk.BaseChatModelAgentMiddleware for a default no-op implementation.

Impact:

  • All code using AgentMiddleware in ChatModelAgentConfig.Middlewares needs to be migrated.
  • In the current version, both approaches can coexist (Handlers execute after Middlewares), but early migration is recommended to avoid compilation failures when removed in future versions.

summarization.SummarizeMessages Removed

summarization.SummarizeMessages and summarization.SummarizeOutput are no longer exported.

Migration steps:

  • Continue using summarization.New or summarization.NewTyped when constructing the summarization middleware.
  • When needing to trigger synchronous summarization manually, use TypedMiddleware.Summarize.

This change converges summarization’s configuration, state reading, and execution logic into the middleware, avoiding semantic divergence between standalone functions and runtime state.

Semantic Changes to Be Aware Of

Summarization Finalize Post-Processing Semantic Change

In V0.8.x, the summarization middleware would first execute default summary post-processing, then call the user-configured Finalize. Therefore, the custom Finalize received a summary that already included PreserveUserMessages replacement, TranscriptFilePath injection, and summary preamble.

In V0.9, if Config.Finalize is set, the middleware passes the raw summary generated by the model directly to Finalize, no longer automatically executing default post-processing. Affected configurations include:

  • PreserveUserMessages
  • TranscriptFilePath

Migration steps:

  • If you want to retain default post-processing, don’t set Finalize—let the middleware use the default finalization path.
  • If you must customize Finalize but still want to retain default post-processing, first construct a default finalizer via DefaultFinalizer, then explicitly compose it in your custom logic.
  • DefaultFinalizer does not automatically read the outer Config.PreserveUserMessages and Config.TranscriptFilePath; they need to be explicitly passed via DefaultFinalizerConfig.
  • Code using NewFinalizer().PreserveSkills(...).Build() needs special attention: this finalizer only handles preserve skills and does not automatically add PreserveUserMessages and TranscriptFilePath.

Tool List Modification Path Adjustment

ModelContext.Tools is no longer the recommended entry point for tool list modification.

Upgrade recommendations:

  • Modify state.ToolInfos in BeforeModelRewriteState.
  • For model-native deferred tool search, modify state.DeferredToolInfos.
  • Modifying the tool list in WrapModel is not recommended; such modifications only affect the current model call—subsequent middlewares, subsequent turns, or checkpoint/resume will not inherit this modification.

ToolSearch / AgentsMD Middleware Internal Implementation Migration

The internal implementations of ToolSearch and AgentsMD middlewares have been migrated from WrapModel (v0.8.x) to BeforeModelRewriteState (v0.9).

💡 For users who only use toolsearch.New() / agentsmd.New(), the public API (Config struct, constructor) has not changed—no code modifications needed.

Semantic changes:

  • v0.8.x: Middleware temporarily injected tool lists via model.Option through WrapModel during model calls—changes were not persisted and did not enter agent state.
  • v0.9: Middleware directly modifies state.ToolInfos / state.DeferredToolInfos and state.Messages (injecting reminder messages) in BeforeModelRewriteState—changes persist with state.

Impact:

  • Checkpoint/Resume: Reminder messages and dynamic tool search results injected by ToolSearch now persist with checkpoints and are correctly reconstructed on restoration; in v0.8.x this information was lost after restoration.
  • Visibility to Other Middlewares: Subsequent middlewares’ BeforeModelRewriteState / AfterModelRewriteState can now see the state.ToolInfos modified by ToolSearch; in v0.8.x these modifications were invisible to other middlewares.
  • Prompt Cache: Since tool list changes are now reflected in state (rather than temporarily injected during each model call), the model’s KV-cache behavior may differ.

Note:

  • If you have custom middlewares that rely on ModelContext.Tools in WrapModel to read/modify the tool list, they should be migrated to reading state.ToolInfos in BeforeModelRewriteState.

Model Retry Decision Semantic Enhancement

ModelRetryConfig adds ShouldRetry. When ShouldRetry is non-nil, IsRetryAble is ignored.

Note:

  • The old IsRetryAble can still be used for simple error-dimension retries.
  • When using ShouldRetry, explicitly handle scenarios where output is successful but not accepted by the business.
  • Interrupt and ErrStreamCanceled are not treated as normal retry errors.

Cancel Error Semantics

After V0.9 introduces active cancellation semantics, applications need to distinguish between active cancellation, normal errors, and business interrupts.

Upgrade recommendations:

  • The upper layer should distinguish between CancelError, normal error, and business interrupt.
  • If the application actively integrates WithCancel, do not treat CancelError as a normal business failure.

AgenticMessage Migration Requires Understanding the New Message Structure

TypedChatModelAgent[*schema.AgenticMessage] is the new path targeting model-native Agentic protocols. Migrating to this path isn’t just changing the generic parameter from *schema.Message to *schema.AgenticMessage—it also requires processing message content according to AgenticMessage’s content block structure.

Note:

  • The AgenticMessage path uses AgenticModel and AgenticToolsNode to handle tool calls.
  • Tool calls and tool results are expressed through AgenticMessage content blocks; correct handling of tool call / tool result content blocks is particularly important.
  • Agent transfer capability does not apply to the AgenticMessage path.
  • Existing applications that don’t need model-native Agentic protocols should continue using the default *schema.Message path; only migrate when explicitly needing to integrate AgenticModel protocols.

Model Adapters Need to Recognize New Options

After V0.9 introduces AgenticModel, model adapters need to handle call-time options more strictly. AgenticModel is an alias for BaseModel[*schema.AgenticMessage] and no longer provides enhanced interfaces like ToolCallingChatModel.WithTools; tool binding is uniformly passed as a model.Option via model.WithTools.

Note:

  • All model adapters supporting AgenticMessage should read Options.Tools and map them to the provider’s tool calling protocol.
  • AgenticModel should not require users to first call some WithTools method to get a “model instance with tools”; ADK passes the current tool list via model.WithTools on each model call.
  • If the adapter only reads tools from its own config while ignoring model.WithTools, in the ChatModelAgent / AgenticToolsNode path the model won’t see tools or the tool list won’t change with runtime state.

V0.9 also adds the following to model.Options:

  • DeferredTools
  • ToolSearchTool
  • AgenticToolChoice

Existing model adapters ignoring these options generally won’t cause compilation failures, but will result in deferred tool search, model-native tool search, or agentic tool choice not taking effect. Adapter maintainers should add conversion logic according to the target provider’s protocol.

ToolInfo Serialization Format Change

ToolInfo adds explicit JSON/Gob encoding/decoding to preserve ParamsOneOf.

Impact:

  • ToolInfo is now part of ChatModelAgentState.ToolInfos / DeferredToolInfos, and may therefore enter checkpoints along with Agent state.
  • Explicit JSON/Gob encoding/decoding ensures that ParamsOneOf is not lost during checkpoint, deep copy, and restoration.
  • If external systems directly depend on the old ToolInfo JSON format, serialization compatibility needs to be re-verified.