Documentation
¶
Overview ¶
Package flyto 是 Flyto Agent 引擎的公共契约包.
这个包只包含接口和类型定义,零实现,零外部依赖. 消费者(TUI,HTTP Server,第三方 SDK)只需 import 这一个包, 不需要了解引擎内部实现细节.
核心原则:
- 最大公约数:接口只包含所有实现者都必须支持的方法
- 可选能力:provider 特有功能通过 type assertion 的可选接口暴露
- 零依赖:只用 Go 标准库,可嵌入任何环境
- 向后兼容:此包的任何 breaking change 都需要版本升级
包结构:
events.go - 引擎→消费者的事件流(Event 接口 + 所有具体事件) observer.go - 消费者实现的可观测性接口(EventObserver 等) message.go - 消息模型(Message,Block,Role) tool.go - 工具定义(Tool) provider.go - 模型提供商接口(ModelProvider + 可选能力接口) engine.go - 引擎接口(Engine,消费者编程的目标) errors.go - 结构化错误类型(ErrorCode,EngineError)
API consumption shapes:
Flyto exposes three distinct API shapes to consumers; pick by mechanism, not by domain. See docs/api-reference.md section "API 消费形态 / API Consumption Patterns" for full taxonomy and when to use which.
- Push (subscribe) — form 1: consumers open a stream or register a callback; the engine notifies asynchronously. Interfaces: Event (via `<-chan flyto.Event`) and EventObserver.
- Pull — form 2: consumers call a method to read a current snapshot. Example consumers of this package's types: `Session.Stats() SessionStats` and `DenialTracker.Stats() DenialStats` in engine/permission packages.
- Synchronous callback — form 3: engine blocks for a consumer decision. Interfaces in sibling packages: permission.Handler, engine.ApprovalPolicy, engine.ElicitationHandler, security.AuditSink, hooks.HookHandler.
API 消费形态:
Flyto 对消费者暴露三种独立 API 形态, 按机制选而非按领域选. 完整分类和选型 指引见 docs/api-reference.md "API 消费形态 / API Consumption Patterns" 章节.
- 订阅 (push) —— 形态一:消费者开流或注册回调, 引擎异步通知. 本包接口: Event (经 `<-chan flyto.Event`) 和 EventObserver.
- 调取 (pull) —— 形态二:消费者调方法读当前快照. 本包类型在引擎/权限包 的消费例: `Session.Stats() SessionStats`, `DenialTracker.Stats() DenialStats`.
- 同步回调 (callback) —— 形态三:引擎阻塞等消费者决策. 兄弟包接口: permission.Handler, engine.ApprovalPolicy, engine.ElicitationHandler, security.AuditSink, hooks.HookHandler.
Index ¶
- Constants
- func Float(v float64) *float64
- func FormatErrorForDisplay(err error, verbose bool) string
- func IsRetryable(err error) bool
- type Block
- func ImageBlockBase64(mediaType, data string) Block
- func ImageBlockURL(url string) Block
- func TextBlock(text string) Block
- func ThinkingBlock(text string, providerMeta map[string]string) Block
- func ToolResultBlock(toolUseID, result string, isError bool) Block
- func ToolResultBlocks(toolUseID string, blocks []Block, isError bool) Block
- func ToolUseBlock(id, name string, input map[string]any) Block
- type BlockType
- type CheckpointEvent
- type CheckpointSuggestedEvent
- type CompactEvent
- type DoneEvent
- type Engine
- type EngineError
- type ErrorCode
- type ErrorEvent
- type Event
- type EventObserver
- type ImageSource
- type InboxMessageEvent
- type Message
- type MetricObserver
- type ModelInfo
- type ModelProvider
- type PermissionLearnEvent
- type PermissionLearnRule
- type PermissionRequestEvent
- type Request
- type ResponseFormat
- type Role
- type RunOption
- type SessionInfoEvent
- type SlashCommandEvent
- type SystemBlock
- type TeammateMessageReceivedEvent
- type TextDeltaEvent
- type TextEvent
- type ThinkingDeltaEvent
- type ThinkingEvent
- type Tool
- type ToolProgressEvent
- type ToolResultEvent
- type ToolSummaryEvent
- type ToolUseEvent
- type TraceObserver
- type TurnEndEvent
- type TurnStartEvent
- type UsageEvent
- type WarningEvent
Constants ¶
const ( WarnTokenUsageHigh = "token_usage_high" WarnBudgetNearLimit = "budget_near_limit" WarnSessionExpiring = "session_expiring" )
Variables ¶
This section is empty.
Functions ¶
func Float ¶
Float returns a pointer to v. Sugar for setting *float64 fields like Request.Temperature / Request.TopP without a temporary local variable.
Float 返回指向 v 的指针. 给 Request.Temperature / Request.TopP 这类 *float64 字段赋值时省去临时局部变量.
func FormatErrorForDisplay ¶
FormatErrorForDisplay 格式化错误供用户阅读.
Types ¶
type Block ¶
type Block struct {
Type BlockType
// --- TextBlock 字段 ---
Text string
// --- ToolUseBlock 字段(模型请求调用工具)---
ToolUseID string
ToolName string
ToolInput map[string]any
// --- ToolResultBlock 字段(工具执行结果回传)---
// ToolUseID 复用上方同名字段(关联请求)
ResultText string
IsError bool
// ResultBlocks carries tool_result content as an array of blocks when
// the result includes non-text payloads (e.g. image). Populated by the
// engine when a tool returns *tools/builtin.ImageResult via Result.Data.
// Nil when ResultText is sufficient (plain text result). Provider
// layer emits "content":[...] when non-nil; otherwise falls back to
// "content":"string" using ResultText.
//
// Anthropic API spec (verified 2026-04-21, docs.anthropic.com): a
// tool_result content field accepts either string or array. Array form
// supports text + image mixed blocks so the model can ground its
// response in the returned image.
//
// ResultBlocks 以 block 数组形式承载 tool_result 内容, 当结果含非文本
// 载荷 (如图片) 时填入. 引擎在工具经 Result.Data 返回
// *tools/builtin.ImageResult 时填. 纯文本结果 ResultText 够用时为 nil.
// Provider 层据此决定 wire 形态: 非 nil 发 "content":[...] array,
// 否则用 "content":"string" 字符串 (fallback 到 ResultText).
//
// Anthropic spec (2026-04-21 verify): tool_result content 支持 string
// 或 array. Array 形式允许 text + image 混排, 让模型基于返回图片应答.
ResultBlocks []Block
// --- ThinkingBlock 字段(模型扩展思考内容)---
ThinkingText string // 思考内容文本
// --- ImageBlock 字段 (BlockImage 类型消息内容) ---
// ImageSource carries image data in either base64-inline or URL form.
// Nil for non-image blocks. Populated by engine when the user inlines
// an image path or a tool returns image data via tools.Result.Data.
//
// ImageSource 携带图片数据, base64 内联或 URL 两种形式. 非图片块为 nil.
// 用户粘贴图片路径或工具经 tools.Result.Data 返图时由引擎填入.
ImageSource *ImageSource
// ProviderMetadata 存储 Provider 特有的不透明数据(如签名,ID 等).
// 引擎不解读此字段,原样回传给 Provider.
ProviderMetadata map[string]string
}
Block 是消息内容块.
精妙之处(CLEVER): 用单一结构体 + BlockType 判断,而非 interface + 多个子类型-- 避免了消费者写 type switch + 类型断言的样板代码, 同时保持零 interface 分配开销(结构体值语义).
func ImageBlockBase64 ¶
ImageBlockBase64 constructs an image block carrying base64-encoded data. mediaType is required (e.g. "image/png"). data must NOT include the "data:image/...;base64," prefix -- pass raw base64 bytes only.
ImageBlockBase64 构造含 base64 编码数据的图片块. mediaType 必填 (如 "image/png"). data 必须是纯 base64 字节, 不带 "data:image/...;base64," 前缀.
func ImageBlockURL ¶
ImageBlockURL constructs an image block referencing an HTTPS image URL. Provider layer may fetch or pass through; check provider docs.
ImageBlockURL 构造引用 HTTPS 图片链接的图片块. Provider 层可能抓取或透传, 详见 provider 文档.
func ThinkingBlock ¶
ThinkingBlock 创建扩展思考内容块. providerMeta 是 provider 返回的不透明元数据(如签名),回传时必须原样携带. 传 nil 表示无额外元数据.
func ToolResultBlock ¶
ToolResultBlock 创建工具结果块.
func ToolResultBlocks ¶
ToolResultBlocks constructs a tool_result block whose content is an array of nested blocks (typically text + image mixed). Use when the tool returns an image (via Result.Data) that should be surfaced to the model; for plain text results prefer ToolResultBlock.
ToolResultBlocks 构造 content 为 block 数组形式的 tool_result 块 (典型是 text + image 混排). 工具经 Result.Data 返图且要让模型看见时使用; 纯文本 结果优先 ToolResultBlock.
type BlockType ¶
type BlockType string
BlockType 标识内容块类型.
const ( // BlockText 是普通文本内容. BlockText BlockType = "text" // BlockToolUse 表示模型请求调用一个工具. BlockToolUse BlockType = "tool_use" // BlockToolResult 表示工具执行结果(回传给模型). BlockToolResult BlockType = "tool_result" // BlockThinking 表示模型的扩展思考内容(extended thinking). BlockThinking BlockType = "thinking" // BlockImage carries image data (base64 or URL) for multimodal models. // Provider compatibility varies -- Anthropic and compatible endpoints // consume this; other providers (openai, gemini, minimax native) // currently return an error when encountering BlockImage. Callers // routing images must select a vision-capable provider. // // BlockImage 携带图片数据 (base64 或 URL) 给多模态模型. Provider 兼容性 // 有差异 -- Anthropic 及兼容端点已支持, 其他 (openai / gemini / minimax // native) 目前遇 BlockImage 返 error. 需要传图的调用方应选用有 vision // 能力的 provider. BlockImage BlockType = "image" )
type CheckpointEvent ¶
type CheckpointEvent struct {
ToolCallID string
ToolName string
Input map[string]any
Message string
}
CheckpointEvent 表示引擎在执行不可逆操作前暂停,等待外部确认.
func (*CheckpointEvent) EventType ¶
func (e *CheckpointEvent) EventType() string
type CheckpointSuggestedEvent ¶
type CheckpointSuggestedEvent struct {
ToolCallID string // 触发建议的工具调用 ID
ToolName string // 工具名("Bash" / "FileEdit" / "FileWrite" 等)
Input map[string]any // 工具输入(用于消费层展示)
RiskReason string // 高风险原因(英文,方便日志分析)
RiskPattern string // 匹配到的风险模式(如 "rm -rf" / "drop table" / "overwrite")
}
CheckpointSuggestedEvent 是引擎的主动建议--检测到高风险操作模式时推送, 但不阻塞执行(与 CheckpointEvent 不同:CheckpointEvent 是工具声明的强制拦截, CheckpointSuggestedEvent 是引擎的静态分析建议,最终决定权仍在消费层).
升华改进(ELEVATED): 早期设计 "Human checkpoint" 仅靠提示词引导模型自主提示用户, 依赖模型遵从,无法覆盖所有 Provider. 我们在引擎层做静态模式匹配:无论底层是哪个模型,只要检测到高风险命令就主动通知消费层. 消费层(TUI/SDK)可选择展示警告,弹出确认框,或忽略(如果用户已在 FLYTO.md 中授权).
替代方案:<在权限系统中拦截> - 否决:权限系统面向"是否允许执行该类工具"(二元决策), 这里是"建议消费层展示额外确认"(建议而非强制),语义不同,不应混入权限系统.
func (*CheckpointSuggestedEvent) EventType ¶
func (e *CheckpointSuggestedEvent) EventType() string
type CompactEvent ¶
CompactEvent 表示上下文被压缩.
func (*CompactEvent) EventType ¶
func (e *CompactEvent) EventType() string
type DoneEvent ¶
type DoneEvent struct {
TotalInputTokens int
TotalOutputTokens int
TotalCostUSD float64
TurnCount int
// Reason 非空表示受控终止(如 "pre_sampling_blocked"),空字符串表示正常结束.
Reason string
}
DoneEvent 表示 Agent 运行结束.
type Engine ¶
type Engine interface {
// Run 在指定会话中执行一轮对话,返回事件流.
//
// messages 是本轮输入(用户消息 + 工具结果等).
// 事件流关闭表示本轮结束,最后一个 *DoneEvent 或 *ErrorEvent 说明结束原因.
//
// 精妙之处(CLEVER): 返回 <-chan Event 而非 error--
// 错误通过 *ErrorEvent 在流中传递,消费者用统一的 for-range 处理所有情况,
// 不需要双返回值(err + channel)的尴尬.
Run(ctx context.Context, sessionID string, messages []Message, opts ...RunOption) <-chan Event
// Close 停止引擎,释放所有资源(goroutine,连接,文件句柄).
// 幂等:多次调用安全.
Close() error
}
Engine 是 Flyto Agent 引擎的公共接口.
Shape: push (stream entry). Engine.Run returns `<-chan Event` that consumers range + type-switch on. Close is a pull-side lifecycle call.
形态: 订阅 (流入口). Engine.Run 返回 `<-chan Event`, 消费者 range + type-switch 处理. Close 是 pull 侧生命周期调用.
type EngineError ¶
type EngineError struct {
Code ErrorCode
Message string
Detail string
Suggestion string
Cause error
Retryable bool
}
EngineError 是引擎统一错误类型.
func NewEngineError ¶
func NewEngineError(code ErrorCode, message string, cause error) *EngineError
NewEngineError 创建引擎错误(使用默认 Suggestion 和 Retryable).
func WrapError ¶
func WrapError(cause error, code ErrorCode, message string) *EngineError
WrapError 将普通错误包装为 EngineError.
func (*EngineError) Error ¶
func (e *EngineError) Error() string
func (*EngineError) Unwrap ¶
func (e *EngineError) Unwrap() error
type ErrorCode ¶
type ErrorCode string
ErrorCode 是引擎错误码枚举.
const ( ErrAPIAuth ErrorCode = "api_auth_error" ErrAPIRateLimit ErrorCode = "api_rate_limit" ErrAPIOverloaded ErrorCode = "api_overloaded" ErrAPIBadRequest ErrorCode = "api_bad_request" ErrToolNotFound ErrorCode = "tool_not_found" ErrToolExecution ErrorCode = "tool_execution_error" ErrPermissionDenied ErrorCode = "permission_denied" ErrContextOverflow ErrorCode = "context_overflow" ErrBudgetExceeded ErrorCode = "budget_exceeded" ErrMaxTurns ErrorCode = "max_turns_reached" ErrSessionNotFound ErrorCode = "session_not_found" ErrSessionClosed ErrorCode = "session_closed" ErrMCPConnection ErrorCode = "mcp_connection_error" ErrPluginLoad ErrorCode = "plugin_load_error" ErrInternal ErrorCode = "internal_error" ErrStreamTruncated ErrorCode = "stream_truncated" )
type ErrorEvent ¶
ErrorEvent 表示运行出错.
func (*ErrorEvent) Error ¶
func (e *ErrorEvent) Error() string
func (*ErrorEvent) EventType ¶
func (e *ErrorEvent) EventType() string
type Event ¶
type Event interface {
EventType() string
}
Event is the interface all engine output events implement. Consumed via the `<-chan flyto.Event` channel returned by Engine.Run / Session.Send; consumers type-switch on concrete types (*TextDeltaEvent / *DoneEvent / *CheckpointSuggestedEvent / *InboxMessageEvent / *TeammateMessageReceivedEvent etc.) to dispatch.
Shape: push (stream). The channel delivers events asynchronously; the consumer ranges and does not reply.
Event 是所有引擎输出事件的接口. 消费端从 Engine.Run / Session.Send 返回的 `<-chan flyto.Event` channel 取事件, type-switch 到具体类型 (*TextDeltaEvent / *DoneEvent / *CheckpointSuggestedEvent / *InboxMessageEvent / *TeammateMessageReceivedEvent 等) 分发处理.
形态: 订阅 (stream). channel 异步推事件, 消费者 range 即可, 不回应.
type EventObserver ¶
type EventObserver interface {
// Event 记录离散事件.
// name 例如 "tool_result_pairing_repaired",data 是结构化上下文.
Event(name string, data map[string]any)
// Error 记录错误(含上下文,用于告警).
Error(err error, context map[string]any)
}
EventObserver 核心事件接口(消费者必须实现以接收引擎内部事件).
注意:这里的"事件"是引擎内部运行事件(tool_result_pairing_repaired 等), 与 Event 接口(引擎输出事件流)是两个不同的概念.
Shape: push (subscribe). Consumers register an implementation via engine.Config.Observer; the engine calls back asynchronously on state changes, no consumer response expected.
形态: 订阅 (push). 消费者经 engine.Config.Observer 注入实现, 引擎在状态 变更时异步回调, 不等消费者回应.
type ImageSource ¶
type ImageSource struct {
// SourceType is "base64" or "url".
// SourceType 为 "base64" 或 "url".
SourceType string
// MediaType is the IANA media type (e.g. "image/png", "image/jpeg").
// Required when SourceType is "base64".
//
// MediaType 是 IANA 媒体类型 (如 "image/png" / "image/jpeg"). SourceType
// 为 "base64" 时必填.
MediaType string
// Data is the base64-encoded image bytes (no data-URL prefix). Required
// when SourceType is "base64".
//
// Data 是图片 bytes 的 base64 编码 (不带 data-URL 前缀). SourceType 为
// "base64" 时必填.
Data string
// URL points to an image served over HTTPS. Required when SourceType is
// "url".
//
// URL 是 HTTPS 图片链接. SourceType 为 "url" 时必填.
URL string
}
ImageSource carries a single image as either base64-inline data or a URL. Mirrors Anthropic's image source shape (provider layer reshapes per API).
ImageSource 携带单张图片, base64 内联数据或 URL 二选一. shape 对齐 Anthropic image source, provider 层按具体 API 适配.
type InboxMessageEvent ¶
type InboxMessageEvent struct {
Type string // "progress" / "log" / "result"
ToolUseID string
Data string
Meta string // JSON 格式的额外元数据
}
InboxMessageEvent 表示工具子进程通过 UDS 发来的消息.
func (*InboxMessageEvent) EventType ¶
func (e *InboxMessageEvent) EventType() string
type MetricObserver ¶
type MetricObserver interface {
// Metric 记录数值指标.
// 例如:name="api_latency_ms", value=123.4, tags={"model":"claude-sonnet-4-6"}
Metric(name string, value float64, tags map[string]string)
}
MetricObserver 数值指标接口(可选,通过 type assertion 检测).
Shape: push (subscribe). Engine emits numeric metric samples; consumer forwards to Prometheus / StatsD / OpenTelemetry etc.
形态: 订阅 (push). 引擎发数值指标样本, 消费者转给 Prometheus / StatsD / OpenTelemetry 等.
type ModelInfo ¶
type ModelInfo struct {
ID string // API 使用的模型 ID,如 "claude-sonnet-4-6"
DisplayName string // 展示名称,如 "Claude Sonnet 4.6"
Provider string // provider 标识
ContextWindow int // 上下文窗口(tokens)
MaxOutputTokens int // 最大输出(tokens)
// 定价(USD / 1M tokens,0 = 免费或未知)
InputPricePer1M float64
OutputPricePer1M float64
CacheReadPricePer1M float64 // 缓存读取价格(美元/百万 token)
CacheWritePricePer1M float64 // 缓存写入价格(美元/百万 token)
// 能力标志(provider 填写).
// 升华改进(ELEVATED): 早期仅作展示元数据,新版同时驱动引擎自动决策--
// SupportsCaching=true + CachingMinTokens > 0 → 引擎自动检查 system 长度并注入 cache_control(已实现,2026-04)
// SupportsThinking=true → 消费者可用 Request.NeedsThinking 触发自动 budget 注入(已实现,2026-04)
// 替代方案:<把所有能力逻辑放在消费者侧> - 否决:每个消费者都得手动处理阈值/header/格式差异.
//
// SupportsCaching 已知支持(2026-04):
// anthropic claude-opus-4-6 / claude-sonnet-4-6 : 1024t(官方文档)
// anthropic claude-haiku-4-5 : 4096t(官方文档)
// minimax MiniMax-M2.7/M2.5/M2.1/M2 : 1024t(probe 实测)
// openrouter → anthropic 路径 : ✗(probe 确认 cr=0@7200t)
SupportsCaching bool
SupportsBatch bool
SupportsThinking bool
SupportsVision bool
// CachingMinTokens 是触发 prompt caching 的最低系统提示 token 数.
// 数据来源:官方文档 + 实测探测(2026-04).
// 0 = 不支持或未知.
//
// 已知阈值(2026-04):
// anthropic claude-opus-4-6 / claude-sonnet-4-6 : 1024t(官方文档)
// anthropic claude-haiku-4-5 : 4096t(官方文档;probe 确认需要 ~7200t 才触发,文档值 4096 在范围内)
// minimax MiniMax-M2.x : 1024t(probe 实测 cr=1110 @~1000t 系统提示)
//
// 历史包袱(LEGACY): OpenRouter 路径 cache_control 不被转发给上游后端
// (probe 确认 cr=0@7200t),OpenRouter 路由的模型应设 SupportsCaching=false.
CachingMinTokens int
// MaxTools 是单次请求允许的最大工具数(0 = 未知/无限制).
//
// 已知值(2026-04):
// OpenAI Chat API : 128(OpenAPI spec 明确记录)
// Anthropic strict : 20(官方文档;普通模式无明确文档上限,此处填 0)
// MiniMax : 0(probe 实测 @256 未发现上限,待后续验证)
// OpenRouter : 0(透传底层模型,自身无额外限制)
//
// 精妙之处(CLEVER): 用 0 表示"未知/不限制"而非 MaxInt--
// 0 是 Go 零值,静态表不填此字段即表示"不限制",无需显式声明;
// MaxInt 在各层传递时容易溢出或被误用为"极大数"参与比较运算.
MaxTools int
// MaxToolsExhaustive 表示 MaxTools 是否是穷尽测试得到的真上限.
//
// 升华改进(ELEVATED): 与 cmd/capability-probe 输出的 max_tools.exhaustive
// schema 对应.区分两种语义:
// true = MaxTools 是确认上限,provider 可硬执行(len(tools) > MaxTools 即报错)
// false = MaxTools 是已知下界(probe 测到这个数没出错,但没找到真上限),
// provider 应软处理(继续发请求让 API 自己拒),不应客户端硬拒
//
// 默认零值 false 是保守选择:静态表不显式填写时按"已知下界"对待,避免误伤.
// 替代方案:<*bool 三态> - 否决:MaxTools=0 已是哨兵语义(无上限),
// Exhaustive 仅在 MaxTools > 0 时有意义,bool 零值刚好对应"保守软处理".
MaxToolsExhaustive bool
}
ModelInfo 描述一个模型的规格和能力.
用途:token 进度条(ContextWindow),费用估算(Price), 模型选择 UI(DisplayName),能力过滤(Supports*).
type ModelProvider ¶
type ModelProvider interface {
// Name 返回 provider 标识,如 "openai","ollama".
Name() string
// Stream 向模型发送请求,返回事件流.
//
// 精妙之处(CLEVER): channel 而非回调--
// channel 天然背压(consumer 慢则 provider 等待),
// 与 Go 的 for-range 习惯完美契合,支持 context 取消.
//
// provider 负责将 API 响应转换为 flyto.Event 事件序列.
// channel 关闭表示流结束,最后一个事件为 *ErrorEvent 表示出错.
Stream(ctx context.Context, req *Request) (<-chan Event, error)
// Models 返回此 provider 可用的模型列表.
// 用于模型选择 UI,合法性验证,定价展示,token 进度条等.
Models(ctx context.Context) ([]ModelInfo, error)
}
ModelProvider 是模型提供商的核心接口(最大公约数).
已有实现:
- pkg/providers/anthropic - Anthropic 原生
- pkg/providers/openai - OpenAI 原生
- pkg/providers/openrouter - OpenRouter 聚合(OpenAI 兼容)
- pkg/providers/minimax - MiniMax 原生
- pkg/providers/gemini - Google Gemini 原生(AI Studio + Vertex AI 双模式)[待 probe 验证]
- pkg/providers/ollama - Ollama 本地部署(OpenAI 兼容)
- pkg/providers/lmstudio - LM Studio 本地部署(OpenAI 兼容)
Shape: push (stream) from engine's perspective. Engine calls Stream(ctx, req) and ranges the returned channel; the provider fans out upstream API chunks as flyto.Event sequence. Consumers wanting to plug a new model backend implement this interface.
形态: 引擎视角 push (流). 引擎调 Stream(ctx, req), range 返回的 channel; provider 将上游 API chunks 分发为 flyto.Event 序列. 要接新模型后端的 消费者实现此接口.
type PermissionLearnEvent ¶
type PermissionLearnEvent struct {
Rules []PermissionLearnRule
}
PermissionLearnEvent 建议添加永久权限规则(用户反复批准同类操作时触发).
func (*PermissionLearnEvent) EventType ¶
func (e *PermissionLearnEvent) EventType() string
type PermissionLearnRule ¶
PermissionLearnRule 是一条建议的权限规则.
type PermissionRequestEvent ¶
type PermissionRequestEvent struct {
ID string
ToolName string
Input map[string]any
Message string
}
PermissionRequestEvent 表示工具需要用户批准. 消费层收到此事件后展示权限 UI,通过 Session.ResolvePermission() 回复.
func (*PermissionRequestEvent) EventType ¶
func (e *PermissionRequestEvent) EventType() string
type Request ¶
type Request struct {
Model string // 模型 ID,如 "claude-sonnet-4-6"
Messages []Message // 对话历史(含工具调用/结果)
System string // 系统提示(空 = 不使用)
MaxTokens int // 最大输出 token 数
Tools []Tool // 可用工具列表(空 = 不使用工具)
// ResponseFormat 约束输出格式(nil = 文本,不限制).
// 仅 "json_object" 类型在所有主流 provider 中通用.
// Provider 特有的 json_schema + 额外 header 通过 provider Config 配置.
ResponseFormat *ResponseFormat
// NeedsThinking: 消费者声明需要扩展思考(thinking 是有感知的,消费者主动声明).
// 引擎无法判断业务复杂度,因此 thinking 必须由消费者显式开启,而非自动决策.
// Provider 自动注入 ThinkingBudget 或 reasoning 参数.
// 若模型不支持 thinking,silently skip(不报错).
// 对比 Config 级别的 ThinkingBudget:Config 是全局开关,NeedsThinking 是 per-request 开关.
NeedsThinking bool
// FastMode 启用快速模式(影响 max_tokens 默认值 + provider 专有 beta header).
// 仅部分 provider 支持,不支持的 provider 应忽略此字段.
FastMode bool
// Effort 努力级别("low"/"medium"/"high"),空字符串表示不设置.
// 仅部分 provider 支持,不支持的 provider 应忽略此字段.
Effort string
// Temperature controls per-request sampling temperature. Nil = use the
// provider/model default (do not transmit a temperature field on the
// wire). Non-nil = use this value; each provider passes it through to
// its native API and lets the upstream service validate (Anthropic
// 0-1, OpenAI/Gemini/Ollama 0-2, MiniMax (0,1], OpenRouter per-model,
// LMStudio backend-defined). Out-of-range values surface as the
// provider's natural 4xx ErrorEvent rather than client-side clamp --
// this matches industry consensus (Vercel AI SDK / LangChain /
// instructor passthrough; only litellm tries drop_params and is
// empirically buggy). One in-Request deterministic conflict gets
// pre-handled: Anthropic + NeedsThinking + Temperature != 1.0 →
// silent override to 1.0 + WarningEvent (server otherwise 400s).
//
// Temperature 控制本次请求的采样温度. nil = 用 provider/模型默认
// (wire 上不传 temperature 字段); 非 nil = 用该值, 每个 provider 直接
// 透传到原生 API 由上游服务校验 (Anthropic 0-1, OpenAI/Gemini/Ollama
// 0-2, MiniMax (0,1], OpenRouter 按 model 各异, LMStudio 由 backend
// 决定). 越界一律不在 flyto 层 clamp, 由上游 4xx 自然冒泡为
// ErrorEvent -- 与业界共识一致 (Vercel AI SDK / LangChain /
// instructor 全 passthrough; 只有 litellm 尝试 drop_params 且 bug
// 频发). 仅一个 wire 时已知冲突预拦: Anthropic + NeedsThinking +
// Temperature != 1.0 → silent override 1.0 + WarningEvent (否则
// 服务端 400).
//
// CLEVER: nullable *float64 而非 float64 + sentinel -- Go 零值 0
// 在采样语义里是合法的 deterministic, 不能复用作 "未设". helper
// flyto.Float() 简化指针字段构造.
Temperature *float64
// TopP controls nucleus sampling cutoff (1.0 = disabled). Nil = use
// the provider/model default. Non-nil = use this value; same
// passthrough policy as Temperature -- upstream validates, out-of-range
// surfaces as 4xx ErrorEvent. One pre-handled conflict: Anthropic +
// NeedsThinking restricts top_p to [0.95, 1.0]; values below 0.95
// silent-override to 1.0 + WarningEvent.
//
// TopP 控制 nucleus 采样阈值 (1.0 = 不启用). nil = 用 provider/
// 模型默认; 非 nil = 用该值. 与 Temperature 同 passthrough 策略,
// 上游校验, 越界 4xx 自然冒泡. 仅一个预拦特例: Anthropic +
// NeedsThinking 限制 top_p 在 [0.95, 1.0], 低于 0.95 silent override
// 1.0 + WarningEvent.
TopP *float64
// SystemBlocks 分段系统提示词(支持 per-block 缓存策略).
// 如果非 nil 且非空,Provider 应优先使用此字段而非 System string.
// 每个 block 有 Text 和 CacheScope 字段.
SystemBlocks []SystemBlock
// Capabilities 是本次请求关联的模型能力快照(由 engine 在调用 provider 之前注入).
//
// 升华改进(ELEVATED): data-driven-capabilities RFC 的核心机制--
// engine 每次调用 provider.Stream 之前从 ModelRegistry 取出当前模型的 ModelInfo,
// 塞进这个字段.Provider 优先读取这里的字段(registry 数据驱动),
// 缺失时降级到 provider 包内的硬编码常量(向后兼容兜底).
//
// 设计要点:
// - nil = engine 未注入(单元测试 / mock 场景 / model 不在 registry 中),
// provider 必须降级到包内常量,行为完全等同于现状(零回归)
// - 非 nil = engine 已注入快照,provider 优先使用此字段
// - 这是只读快照--provider 不应修改它的字段,registry 后续修改也不影响
// 进行中的请求(值的指针,但 ModelInfo 字段都是值类型)
//
// 替代方案:<provider 持有 ModelRegistry 引用> - 否决:
// 会让 provider 包 import config 包,引入依赖循环风险;
// 而 Request 字段注入让 provider 完全无感知 registry 的存在.
// 替代方案:<让 engine 全部预先解析完成后只传 maxTools/supportsThinking 等扁平字段> - 否决:
// flyto.Request 字段会膨胀,且每加一个能力都要改 Request schema.
Capabilities *ModelInfo
}
Request 是发给 ModelProvider 的请求(最大公约数字段).
升华改进(ELEVATED): 只包含所有 provider 通用的字段. provider 特有参数(Thinking budget,cache breakpoints,beta flags 等) 在 provider 工厂的 Config 里配置,不污染公共 Request 类型.
Auto-caching 行为:当 system prompt 超过模型阈值时,引擎自动注入 cache_control, 消费者无需声明.阈值来自 ModelInfo.CachingMinTokens(官方文档 + probe 实测).
type ResponseFormat ¶
type ResponseFormat struct {
// Type 是格式类型:
// "json_object" - 约束输出为合法 JSON 对象(所有主流 provider 支持)
// "json_schema" - 按指定 schema 约束(OpenAI/OpenRouter/MiniMax 原生支持;
// 不支持的 provider 降级为 fence strip,不传 schema)
Type string
// JSONSchema 是 json_schema 类型的 schema 定义(json_schema 时必填,其他类型忽略)
JSONSchema json.RawMessage `json:"json_schema,omitempty"`
}
ResponseFormat 控制模型的输出格式约束(跨 provider 最大公约数).
精妙之处(CLEVER): 只放真正跨 provider 通用的格式-- "json_object" 几乎所有现代 provider 都原生支持(OpenAI/OpenRouter/MiniMax/Gemini). 部分 provider 的结构化输出需要特殊 header + json_schema,属于 provider 特有能力, 通过 provider Config 配置,不出现在此通用类型中. 替代方案:<把 json_schema + 特殊 flag 都塞进来> - 否决: 绑定了特定 provider 实现细节,其他 provider 无法使用这些字段, 造成"通用"接口实际上只有一个 provider 能完整支持.
type RunOption ¶
type RunOption interface {
// contains filtered or unexported methods
}
RunOption 是单次 Run 调用的选项(不透明类型).
精妙之处(CLEVER): interface 而非 func(*runConfig)-- 外部包无法实现此接口(unexported method),只能使用引擎提供的 WithXxx 工厂函数. 这样引擎能在不破坏 API 的前提下修改内部 runConfig 结构.
type SessionInfoEvent ¶
type SessionInfoEvent struct {
SessionID string
Title string
TurnCount int
InputTokens int
OutputTokens int
CostUSD float64
}
SessionInfoEvent 通知消费层更新会话统计(token 用量,花费等).
func (*SessionInfoEvent) EventType ¶
func (e *SessionInfoEvent) EventType() string
type SlashCommandEvent ¶
SlashCommandEvent 表示检测到斜杠命令(引擎不处理,通知消费层).
func (*SlashCommandEvent) EventType ¶
func (e *SlashCommandEvent) EventType() string
type SystemBlock ¶
type SystemBlock struct {
Text string // 文本内容
CacheScope string // "", "session", "global" - 非空表示需要缓存
}
SystemBlock 是分段系统提示词的一块.
type TeammateMessageReceivedEvent ¶
type TeammateMessageReceivedEvent struct {
From string // 发送方 agent 名称
To string // 接收方 agent 名称 (自己)
Type string // Message.Type (task_assignment / idle_notification 等)
MessageID string // Message.ID
PayloadSize int // payload 字节数
}
TeammateMessageReceivedEvent 表示 Agent Teams 通讯中收到来自同伴的消息.
升华改进(ELEVATED): 复用 flyto.EventObserver 统一事件总线, 不再新建 hook 系统. 对标 Anthropic Claude Code Agent Teams v2.1.32 的 TeammateIdle/TaskCreated/TaskCompleted 三个独立 shell hook -- 我们用单一事件总线 (类型字段区分) 覆盖其超集:
- 可编程性: Observer 实现任意 Go 逻辑 (调 DB / 发 Slack / 更新 UI), 不限于 shell
- 跨进程: SaaS 场景订阅 Event 的不必是本机, shell hook 做不到
- 结构化: Data 字段是 struct, 解析无歧义; shell 拿到字符串参数
替代方案: <仿 Anthropic 三个独立 shell hook> - 否决: L1326 刚把 hooks/context/evolve 三包 Observer 收敛到 flyto.EventObserver, 再拆回去是架构回退.
func (*TeammateMessageReceivedEvent) EventType ¶
func (e *TeammateMessageReceivedEvent) EventType() string
type TextDeltaEvent ¶
type TextDeltaEvent struct {
Text string
}
TextDeltaEvent 是流式文本增量(最频繁的事件).
func (*TextDeltaEvent) EventType ¶
func (e *TextDeltaEvent) EventType() string
type ThinkingDeltaEvent ¶
type ThinkingDeltaEvent struct {
Text string
}
ThinkingDeltaEvent 是流式思考增量.
func (*ThinkingDeltaEvent) EventType ¶
func (e *ThinkingDeltaEvent) EventType() string
type ThinkingEvent ¶
type ThinkingEvent struct {
Text string
}
ThinkingEvent 是完整的思考块.
func (*ThinkingEvent) EventType ¶
func (e *ThinkingEvent) EventType() string
type Tool ¶
type Tool struct {
Name string // 工具名称,如 "Bash"
Description string // 工具描述(给模型看的自然语言说明)
InputSchema json.RawMessage // 输入参数的 JSON Schema(object 类型)
}
Tool 是工具定义(JSON Schema 格式的输入规格).
type ToolProgressEvent ¶
type ToolProgressEvent struct {
ID string
ToolName string
Progress float64 // 0.0-1.0
Detail string
}
ToolProgressEvent 表示工具执行中的进度更新(长时间运行的工具).
func (*ToolProgressEvent) EventType ¶
func (e *ToolProgressEvent) EventType() string
type ToolResultEvent ¶
type ToolResultEvent struct {
ID string // 对应 ToolUseEvent.ID
ToolName string
Output string
IsError bool
// Truncated marks that Output is a short summary and the full tool
// result has been persisted to StoredPath. Consumer UIs use this to
// render "result truncated -- click to open full content".
//
// Truncated 标记 Output 是短摘要, 完整结果已经落盘到 StoredPath. 消费层
// UI 据此渲染 "结果已截断 -- 点击打开完整内容".
Truncated bool
// StoredPath is where the full tool result was persisted (by the
// orchestrator's pluggable ResultProcessor). Empty when Truncated is
// false. Path shape is consumer-layer defined (local filesystem path,
// sandbox-internal path, object-storage key, ...); callers parse per
// the ResultProcessor they installed.
//
// SECURITY: the path may carry sandbox-internal structure or caller-
// specific details. Downstream observers / SSE bridges MUST treat it
// as untrusted data (e.g. avoid logging to shared destinations without
// review).
//
// StoredPath 是完整工具结果的持久化位置 (由 orchestrator 的可插拔
// ResultProcessor 决定). Truncated=false 时为空串. Path shape 由消费层
// 定义 (本地文件路径 / sandbox 内部路径 / 对象存储 key / ...); 调用方按
// 自己装的 ResultProcessor 解析.
//
// 安全: path 可能携带 sandbox 内部结构或调用方特定细节. 下游 observer /
// SSE bridge 必须把它当作不可信数据 (例如未审查前不写入共享目的地).
StoredPath string
}
ToolResultEvent 表示工具执行完成.
Truncated / StoredPath surface the orchestrator's large-result handling to consumers: when a tool emits an oversized output, the orchestrator replaces Output with a short summary and persists the full content via the consumer-installed ResultProcessor. Without these fields on the event, UIs / SSE bridges see only the summary and cannot render a "click to open full content" affordance or audit the full result.
Truncated / StoredPath 把 orchestrator 的大结果处理透传给消费层: 工具产 生超大输出时, orchestrator 用短摘要替换 Output 并经消费层装的 ResultProcessor 把完整内容落盘. 事件不带这两个字段时, UI / SSE bridge 只看得到摘要, 无法渲染 "点击打开完整内容" 入口, 也无法审计完整结果.
func (*ToolResultEvent) EventType ¶
func (e *ToolResultEvent) EventType() string
type ToolSummaryEvent ¶
ToolSummaryEvent 表示工具执行摘要已异步生成(用于 UI 展示).
func (*ToolSummaryEvent) EventType ¶
func (e *ToolSummaryEvent) EventType() string
type ToolUseEvent ¶
type ToolUseEvent struct {
ID string // 工具调用 ID
ToolName string // 工具名称
Input map[string]any // 工具输入参数
}
ToolUseEvent 表示模型请求调用工具.
func (*ToolUseEvent) EventType ¶
func (e *ToolUseEvent) EventType() string
type TraceObserver ¶
type TraceObserver interface {
SpanStart(name string, tags map[string]string) string // 返回 span ID
SpanEnd(spanID string, err error)
}
TraceObserver 调用链接口(可选,通过 type assertion 检测).
Shape: push (subscribe). Engine emits span-start / span-end events for distributed tracing consumers (Jaeger / Zipkin / Tempo).
形态: 订阅 (push). 引擎发 span-start / span-end 事件给分布式追踪消费者 (Jaeger / Zipkin / Tempo).
type TurnEndEvent ¶
type TurnEndEvent struct {
TurnNumber int
InputTokens int
OutputTokens int
CostUSD float64
MaxTokens int
}
TurnEndEvent 表示对话轮次结束(含本轮 token 用量).
func (*TurnEndEvent) EventType ¶
func (e *TurnEndEvent) EventType() string
type TurnStartEvent ¶
type TurnStartEvent struct {
TurnNumber int
Model string
ContextWindowTokens int // 由 provider.Models() 提供,消费层无需硬编码
}
TurnStartEvent 表示新对话轮次开始.
func (*TurnStartEvent) EventType ¶
func (e *TurnStartEvent) EventType() string
type UsageEvent ¶
type UsageEvent struct {
InputTokens int
OutputTokens int
CacheReadTokens int // prompt caching 命中的 token 数(仅支持缓存的 provider)
CacheCreationTokens int // prompt caching 写入的 token 数(仅支持缓存的 provider)
StopReason string // "end_turn"/"max_tokens"/"tool_use"/"stop_sequence"/"length"
}
UsageEvent 由 ModelProvider 推送,携带本轮原始 token 用量.
精妙之处(CLEVER): provider 只汇报原始数字,不计算费用-- 费用计算需要模型定价表,而定价表属于引擎层(通过 Models() 获取). 分层清晰:provider 知道 token 数,引擎知道单价,两者在引擎层合并. 如果 provider 自己计费,定价表就得维护两份,数据来源单一原则被破坏.
消费者不应依赖此事件--引擎会将其转换为 TurnEndEvent. 直接使用 provider(不经过引擎)时才需要读取此事件.
func (*UsageEvent) EventType ¶
func (e *UsageEvent) EventType() string
type WarningEvent ¶
WarningEvent 表示非致命警告(token 接近上限,花费接近预算等).
func (*WarningEvent) EventType ¶
func (e *WarningEvent) EventType() string