Eino v0.8 Breaking Changes
This document records all breaking changes in the
v0.8.0.Betabranch compared to themainbranch.
1. API Breaking Changes
1.1 filesystem Shell Interface Renamed
Location: adk/filesystem/backend.go Change Description: Shell-related interfaces have been renamed and no longer embed the Backend interface. Before (main):
type ShellBackend interface {
Backend
Execute(ctx context.Context, input *ExecuteRequest) (result *ExecuteResponse, err error)
}
type StreamingShellBackend interface {
Backend
ExecuteStreaming(ctx context.Context, input *ExecuteRequest) (result *schema.StreamReader[*ExecuteResponse], err error)
}
After (v0.8.0.Beta):
type Shell interface {
Execute(ctx context.Context, input *ExecuteRequest) (result *ExecuteResponse, err error)
}
type StreamingShell interface {
ExecuteStreaming(ctx context.Context, input *ExecuteRequest) (result *schema.StreamReader[*ExecuteResponse], err error)
}
Impact:
ShellBackendrenamed toShellStreamingShellBackendrenamed toStreamingShell- Interfaces no longer embed
Backend. If your implementation depends on the composite interface, you need to implement them separately Migration Guide:
// Before
type MyBackend struct {}
func (b *MyBackend) Execute(...) {...}
// MyBackend implementing ShellBackend needed to implement all Backend methods
// After
type MyShell struct {}
func (s *MyShell) Execute(...) {...}
// MyShell only needs to implement Shell interface methods
// If you also need Backend functionality, implement both interfaces separately
2. Behavioral Breaking Changes
2.1 AgentEvent Sending Mechanism Change
Location: adk/chatmodel.go Change Description: ChatModelAgent’s AgentEvent sending mechanism changed from eino callback mechanism to Middleware mechanism. Before (main):
AgentEventwas sent through eino’s callback mechanism- If users customized ChatModel or Tool Decorator/Wrapper, and the original ChatModel/Tool had embedded Callback points,
AgentEventwould be sent inside the Decorator/Wrapper - This applied to all ChatModels implemented in eino-ext, but may not apply to most user-implemented Tools and Tools provided by eino After (v0.8.0.Beta):
AgentEventis sent through Middleware mechanismAgentEventis sent outside user-customized Decorator/Wrapper Impact:- Under normal circumstances, users won’t notice this change
- If users previously implemented their own ChatModel or Tool Decorator/Wrapper, the relative position of event sending will change
- Position change may cause
AgentEventcontent to change: previous events didn’t include Decorator/Wrapper modifications, current events will include them Reason for Change: - In normal business scenarios, we want emitted events to include Decorator/Wrapper modifications Migration Guide: If you previously wrapped ChatModel or Tool through Decorator/Wrapper, you need to implement the
ChatModelAgentMiddlewareinterface instead:
// Before: Wrapping ChatModel through Decorator/Wrapper
type MyModelWrapper struct {
inner model.BaseChatModel
}
func (w *MyModelWrapper) Generate(ctx context.Context, input []*schema.Message, opts ...model.Option) (*schema.Message, error) {
// Custom logic
return w.inner.Generate(ctx, input, opts...)
}
// After: Implement WrapModel method of ChatModelAgentMiddleware
type MyMiddleware struct{}
func (m *MyMiddleware) WrapModel(ctx context.Context, chatModel model.BaseChatModel, mc *ModelContext) (model.BaseChatModel, error) {
return &myWrappedModel{inner: chatModel}, nil
}
// For Tool Wrappers, implement WrapInvokableToolCall / WrapStreamableToolCall methods instead
2.2 filesystem.ReadRequest.Offset Semantic Change
Location: adk/filesystem/backend.go Change Description: Offset field changed from 0-based to 1-based. Before (main):
type ReadRequest struct {
FilePath string
// Offset is the 0-based line number to start reading from.
Offset int
Limit int
}
After (v0.8.0.Beta):
type ReadRequest struct {
FilePath string
// Offset specifies the starting line number (1-based) for reading.
// Line 1 is the first line of the file.
// Values < 1 will be treated as 1.
Offset int
Limit int
}
Migration Guide:
// Before: Read from line 0 (i.e., first line)
req := &ReadRequest{Offset: 0, Limit: 100}
// After: Read from line 1 (i.e., first line)
req := &ReadRequest{Offset: 1, Limit: 100}
// If you previously used Offset: 10 to mean starting from line 11
// Now you need to use Offset: 11
2.3 filesystem.FileInfo.Path Semantic Change
Location: adk/filesystem/backend.go Change Description: FileInfo.Path field is no longer guaranteed to be an absolute path. Before (main):
type FileInfo struct {
// Path is the absolute path of the file or directory.
Path string
}
After (v0.8.0.Beta):
type FileInfo struct {
// Path is the path of the file or directory, which can be a filename,
// relative path, or absolute path.
Path string
// ...
}
Impact:
- Code that depends on
Pathbeing an absolute path may have issues - Need to check and handle relative path cases
2.4 filesystem.WriteRequest Behavior Change
Location: adk/filesystem/backend.go Change Description: WriteRequest write behavior changed from “error if file exists” to “overwrite if file exists”. Before (main):
// WriteRequest comment:
// The file will be created if it does not exist, or error if file exists.
After (v0.8.0.Beta):
// WriteRequest comment:
// Creates the file if it does not exist, overwrites if it exists.
Impact:
- Code that previously relied on “error if file exists” behavior will no longer error, but directly overwrite
- May cause unexpected data loss Migration Guide:
- If you need to preserve the original behavior, check if the file exists before writing
2.5 GrepRequest.Pattern Semantic Change
Location: adk/filesystem/backend.go Change Description: GrepRequest.Pattern changed from literal matching to regular expression matching. Before (main):
// Pattern is the literal string to search for. This is not a regular expression.
// The search performs an exact substring match within the file's content.
After (v0.8.0.Beta):
// Pattern is the search pattern, supports full regular expression syntax.
// Uses ripgrep syntax (not grep).
Impact:
- Search patterns containing regex special characters will behave differently
- For example, searching for
interface{}now needs to be escaped asinterface\{\}Migration Guide:
// Before: Literal search
req := &GrepRequest{Pattern: "interface{}"}
// After: Regex search, need to escape special characters
req := &GrepRequest{Pattern: "interface\\{\\}"}
// Or if searching for literals containing . * + ?, also need to escape
// Before
req := &GrepRequest{Pattern: "config.json"}
// After
req := &GrepRequest{Pattern: "config\\.json"}
Migration Recommendations
- Handle compile errors first: Type changes (like Shell interface renaming) will cause compilation failures, need to fix first
- Pay attention to semantic changes:
ReadRequest.Offsetchanged from 0-based to 1-based,Patternchanged from literal to regex - these won’t cause compile errors but will change runtime behavior - Check file operations:
WriteRequestoverwrite behavior change may cause data loss, requires additional checks - Migrate Decorator/Wrapper: If you have custom ChatModel/Tool Decorator/Wrapper, change to implement
ChatModelAgentMiddleware - Upgrade backend implementations as needed: If using local/ark agentkit backend provided by eino-ext, upgrade to corresponding alpha versions: local backend v0.2.0-alpha, ark agentkit backend v0.2.0-alpha
- Test verification: After migration, perform comprehensive testing, especially for code involving file operations and search functionality