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
Agent Transfer / Workflow Agent / Supervisor Marked as NOT RECOMMENDED
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:
SetSubAgentsAgentWithOptions/WithDisallowTransferToParent/WithHistoryRewriterChatModelAgentConfig.Exit/ChatModelAgentConfig.OutputKeyAgentWithDeterministicTransferToOnSetSubAgents/OnSetAsSubAgent/OnDisallowTransferToParent
Workflow Agent:
NewSequentialAgent/SequentialAgentConfigNewParallelAgent/ParallelAgentConfigNewLoopAgent/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
BaseChatModelAgentMiddlewarecomposition 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 []AgentMiddlewaretoHandlers []ChatModelAgentMiddleware. AgentMiddleware.BeforeChatModel→ implementChatModelAgentMiddleware.BeforeModelRewriteState.AgentMiddleware.AfterChatModel→ implementChatModelAgentMiddleware.AfterModelRewriteState.AgentMiddleware.WrapToolCall→ implementChatModelAgentMiddleware.WrapToolCall.AgentMiddleware.AdditionalInstruction→ modifystate.InstructioninBeforeModelRewriteState.AgentMiddleware.AdditionalTools→ modifystate.ToolInfosinBeforeModelRewriteState.- If the middleware doesn’t need special logic, embed
*adk.BaseChatModelAgentMiddlewarefor a default no-op implementation.
Impact:
- All code using
AgentMiddlewareinChatModelAgentConfig.Middlewaresneeds 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.Neworsummarization.NewTypedwhen 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:
PreserveUserMessagesTranscriptFilePath
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
Finalizebut still want to retain default post-processing, first construct a default finalizer viaDefaultFinalizer, then explicitly compose it in your custom logic. DefaultFinalizerdoes not automatically read the outerConfig.PreserveUserMessagesandConfig.TranscriptFilePath; they need to be explicitly passed viaDefaultFinalizerConfig.- Code using
NewFinalizer().PreserveSkills(...).Build()needs special attention: this finalizer only handles preserve skills and does not automatically addPreserveUserMessagesandTranscriptFilePath.
Tool List Modification Path Adjustment
ModelContext.Tools is no longer the recommended entry point for tool list modification.
Upgrade recommendations:
- Modify
state.ToolInfosinBeforeModelRewriteState. - For model-native deferred tool search, modify
state.DeferredToolInfos. - Modifying the tool list in
WrapModelis 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.OptionthroughWrapModelduring model calls—changes were not persisted and did not enter agent state. - v0.9: Middleware directly modifies
state.ToolInfos/state.DeferredToolInfosandstate.Messages(injecting reminder messages) inBeforeModelRewriteState—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/AfterModelRewriteStatecan now see thestate.ToolInfosmodified 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.ToolsinWrapModelto read/modify the tool list, they should be migrated to readingstate.ToolInfosinBeforeModelRewriteState.
Model Retry Decision Semantic Enhancement
ModelRetryConfig adds ShouldRetry. When ShouldRetry is non-nil, IsRetryAble is ignored.
Note:
- The old
IsRetryAblecan 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
ErrStreamCanceledare 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 treatCancelErroras 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
AgenticModelandAgenticToolsNodeto handle tool calls. - Tool calls and tool results are expressed through
AgenticMessagecontent 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.Messagepath; only migrate when explicitly needing to integrateAgenticModelprotocols.
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.Toolsand map them to the provider’s tool calling protocol. AgenticModelshould not require users to first call someWithToolsmethod to get a “model instance with tools”; ADK passes the current tool list viamodel.WithToolson 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:
DeferredToolsToolSearchToolAgenticToolChoice
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:
ToolInfois now part ofChatModelAgentState.ToolInfos/DeferredToolInfos, and may therefore enter checkpoints along with Agent state.- Explicit JSON/Gob encoding/decoding ensures that
ParamsOneOfis not lost during checkpoint, deep copy, and restoration. - If external systems directly depend on the old
ToolInfoJSON format, serialization compatibility needs to be re-verified.