Documentation
¶
Index ¶
- Constants
- func BuildProvider(p *ai_provider_entity.AIProvider, apiKey string) (cagoProvider.Provider, error)
- func BuildSystem(ctx context.Context, cfg SystemConfig) (*coding.System, error)
- func ToAgentMessages(messages []Message) []agent.Message
- type AIContext
- type EventTranslator
- type Message
- type ModelDefaults
- type ModelInfo
- type PermissionResponse
- type PromptBuilder
- type Role
- type StreamEvent
- type SystemConfig
- type TabInfo
- type ToolCall
- type ToolFunction
- type Usage
Constants ¶
const ( // FallbackMaxOutputTokens 未知模型的默认最大输出 token FallbackMaxOutputTokens = 16384 // FallbackContextWindow 未知模型的默认上下文窗口 FallbackContextWindow = 128000 )
Variables ¶
This section is empty.
Functions ¶
func BuildProvider ¶
func BuildProvider(p *ai_provider_entity.AIProvider, apiKey string) (cagoProvider.Provider, error)
BuildProvider 根据 AIProvider entity + 已解密 API Key 构造 cago provider.Provider。 后续对话全部走 cago provider;model / max_tokens / reasoning 在 request 阶段注入, 这里只负责"传输层"。
func BuildSystem ¶
BuildSystem 拼装 coding.System:
- 关掉 ~/.claude 自动加载 / skills / slash commands;
- 用 OpsKat 自定义 system 模板;
- 注册 auditMiddleware(around 模式:跑前挂 *aictx.CheckResult slot,跑后落审计);
- 非空 SystemPrompt 走 coding.AppendSystem 注入;
- 非空 Model 走 coding.WithModel;
- ProviderEntity 开启 reasoning 时走 coding.WithThinking;
- 非空 Tools 走 coding.WithExtraTools;
- aitool.LocalToolGate 非 nil 时为 local_bash/local_write/local_edit 加审批 middleware (local_read/local_grep/local_find/local_ls 只读,不审批)。注册顺序: audit 在前(外层),gate 在后(内层)—— 这样 gate AbortWithDeny 后 audit 的 c.Next() 返回时 c.Output 已是 deny block,照样落审计。
- cago 的 subagent dispatch 工具不会把父 middleware 透传给 child agent。 Explore/Plan 工具集只读,无 local_bash/local_write/local_edit 路径; GeneralPurpose 含全套 coding 工具,因此显式替换默认 GP,把 audit + aitool.LocalToolGate 中间件挂上。
func ToAgentMessages ¶
ToAgentMessages 把 OpsKat 的 []Message 转换为 cago agent.Message 切片。
转换规则:
- user → agent.Message{Role: RoleUser, Content: [TextBlock]}
- assistant → Content 依次包含 ThinkingBlock?(若 Thinking 非空)+ TextBlock?(若 Content 非空)
- 每个 ToolCall 转 ToolUseBlock(State=ToolUseReady,Input 来自 Arguments JSON)
- tool → Content = [ToolResultBlock{ToolUseID, Content:[TextBlock]}]
块必须使用值类型(agent.TextBlock{}),cago 的 BuildRequest 与 Conversation 内部 一律用值类型 type switch(case TextBlock:);指针块满足 ContentBlock 接口但无法 匹配,会被 BuildRequest 静默丢弃,导致历史在 LLM 端完全消失。
ReasoningContent(OpenAI/DeepSeek 风格)目前与 Thinking 合并处理——cago 的 ThinkingBlock 兼容两者。 ThinkingBlock.Signature 仅在 Anthropic 流式 thinking 模式必填,DB schema 当前未持久化此字段; 重放时缺 Signature 可能导致 Anthropic 拒绝继续多轮 thinking——这是已知 follow-up(见 plan 风险章节)。
Types ¶
type AIContext ¶
type AIContext struct {
OpenTabs []TabInfo `json:"openTabs"`
}
AIContext 前端传入的上下文信息
type EventTranslator ¶
type EventTranslator struct {
// contains filtered or unexported fields
}
EventTranslator 把 cago agent.Event 翻译成 OpsKat 现有 StreamEvent。
前端契约(type 字段名 + 内部字段)保持不变;这里只是从 cago 的 event 流里 反推出旧 provider 的事件形态,保证前端 ai:event:{convID} 监听者无感知。
翻译是有状态的:thinking → content / tool_start 之间的转移需要插入一条 "thinking_done",保持前端既有 stream contract。EventTranslator 实例每个对话每轮 1 个。
审批事件(approval_request / approval_result)由 app_ai.go 的 confirmFunc 直接 emit,不走 cago event 流,因此不在本适配器范围。
func NewStreamTranslator ¶
func NewStreamTranslator() *EventTranslator
NewStreamTranslator 创建一个新的事件翻译器。
func (*EventTranslator) Translate ¶
func (t *EventTranslator) Translate(ev agent.Event, emit func(StreamEvent))
Translate 处理一条 cago agent.Event,调用 emit 0..N 次发出对应 StreamEvent。
多发场景:thinking → content 转移会先发 "thinking_done" 再发 "content"。 不映射的 EventKind(如 EventMessageEnd / EventToolDelta)直接静默—— 前者由 EventTextDelta / EventTurnEnd 隐含,后者是 cago 流式工具参数增量, 旧 OpsKat StreamEvent 没有对应字段,可丢弃。
type Message ¶
type Message struct {
Role Role `json:"role"`
Content string `json:"content"`
Thinking string `json:"thinking,omitempty"` // Anthropic 格式
ReasoningContent string `json:"reasoning_content,omitempty"` // DeepSeek/OpenAI 格式
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"` // role=tool 时标识调用
}
Message 对话消息
func SplitForReplay ¶
SplitForReplay 把 OpsKat 的消息列表切分为「需要灌进 cago Conversation 的历史」+「本轮要发给 LLM 的最后一条用户文本」。
调用约定:messages 来自 SendAIMessage 入参,包含全部历史 + 末尾的新 user message。 如果末尾不是 user message(边界场景,比如纯历史回放),则全部归入 history、lastUserText = ""。
type ModelDefaults ¶
ModelDefaults 已知模型的默认参数
func GetModelDefaults ¶
func GetModelDefaults(model string) *ModelDefaults
GetModelDefaults 获取模型默认参数:前缀匹配(最长前缀优先),未知模型返回 nil
type ModelInfo ¶
type ModelInfo struct {
ID string `json:"id"`
}
ModelInfo 从 API 返回的模型信息
func FetchModels ¶
FetchModels 从 API 获取可用模型列表
type PermissionResponse ¶
type PermissionResponse struct {
Behavior string `json:"behavior"` // "allow" | "deny"
Message string `json:"message"` // deny 原因
}
PermissionResponse 权限响应
type PromptBuilder ¶
type PromptBuilder struct {
// contains filtered or unexported fields
}
PromptBuilder 动态构建 System Prompt
func NewPromptBuilder ¶
func NewPromptBuilder(language string, context AIContext) *PromptBuilder
NewPromptBuilder 创建 PromptBuilder
func (*PromptBuilder) Build ¶
func (b *PromptBuilder) Build() string
Build 构建运行时上下文 prompt,注入到 cago 模板的 {{.AppendSystem}} 位。 角色身份已经搬到 internal/ai/system_template.go 的模板 intro,此处只输出 每次 Send 都可能变化的动态段(语言 / Tab / 知识 / 错误恢复 / extension SKILL.md)。
func (*PromptBuilder) SetExtensionSkillMDs ¶
func (b *PromptBuilder) SetExtensionSkillMDs(mds map[string]string)
SetExtensionSkillMDs sets all extension SKILL.md contents to inject. Keys are extension names, values are the raw markdown.
type StreamEvent ¶
type StreamEvent struct {
Type string `json:"type"` // "content" | "tool_start" | "tool_result" | "approval_request" | "approval_result" | "agent_start" | "agent_end" | "queue_consumed" | "done" | "error" | "thinking" | "thinking_done" | "stopped" | "retry" | "usage" | "compacted"
// type=retry 时 Content 携带 attempt 序号(字符串形式,从 1 开始),RetryDelayMs 是下一次重试前的等待毫秒(用于前端倒计时同步)。
Content string `json:"content,omitempty"` // type=content/tool_result/approval_result/agent_end 时的文本
QueueID string `json:"queue_id,omitempty"` // type=queue_consumed 时的前端队列项 ID
ToolName string `json:"tool_name,omitempty"` // type=tool_start/tool_result 时的工具名
ToolInput string `json:"tool_input,omitempty"` // type=tool_start 时的输入摘要
ToolCallID string `json:"tool_call_id,omitempty"` // type=tool_start/tool_result 时的工具调用 ID,前端用于跨 turn 还原 tool_calls 历史
ConfirmID string `json:"confirm_id,omitempty"` // type=approval_request/approval_result 时的确认请求 ID
Error string `json:"error,omitempty"` // type=error 时的错误信息
AgentRole string `json:"agent_role,omitempty"` // type=agent_start/approval_request 时的角色描述
AgentTask string `json:"agent_task,omitempty"` // type=agent_start 时的任务描述
// approval_request 专用字段
Kind string `json:"kind,omitempty"` // "single" | "batch" | "grant" | "local_tool"
Items []permission.ApprovalItem `json:"items,omitempty"` // 审批项列表
Description string `json:"description,omitempty"` // grant 描述
SessionID string `json:"session_id,omitempty"` // grant session ID
Patterns []string `json:"patterns,omitempty"` // local_tool 默认 pattern 列表(与 sub-commands 对齐),前端预填可编辑
// type=usage 时的 token 统计(前端累加到当前 assistant 消息)
Usage *Usage `json:"usage,omitempty"`
// type=retry 时的等待毫秒;前端据此显示倒计时。0 表示无显式退避(立即重试)。
RetryDelayMs int `json:"retryDelayMs,omitempty"`
}
StreamEvent 流式响应事件
type SystemConfig ¶
type SystemConfig struct {
Provider cagoProvider.Provider
ProviderEntity *ai_provider_entity.AIProvider
APIKey string
Cwd string
SystemPrompt string
Model string
Tools []tool.Tool
LocalToolGate *aitool.LocalToolGate
}
SystemConfig 组装一个 coding.System 需要的所有依赖。 调用方持有 *coding.System + *agent.Runner,自己处理 Send / Cancel / Steer / Close。
- Provider:可选;测试场景用 providertest.Mock 注入。非 nil 时优先使用。
- ProviderEntity / APIKey:生产路径——传给 BuildProvider 构造 cago provider。
- Cwd:coding.New 必填参数(read/write/bash 等工具的工作目录),通常为 ~/.opskat。
- SystemPrompt:动态系统提示词,附加到 coding 默认 system 之后。
- Model:覆盖 provider 默认模型。
- Tools:额外注册到父 agent 的工具集,通常是 aitool.Tools()。
- aitool.LocalToolGate:可选,非 nil 时为 bash/write/edit 挂 PreToolUseHook 走用户审批。
type TabInfo ¶
type TabInfo struct {
Type string `json:"type"` // "ssh" | "database" | "redis" | "sftp"
AssetID int64 `json:"assetId"`
AssetName string `json:"assetName"`
}
TabInfo 当前打开的 Tab 信息
type ToolCall ¶
type ToolCall struct {
ID string `json:"id"`
Type string `json:"type"` // "function"
Function ToolFunction `json:"function"`
}
ToolCall AI 发起的工具调用
type ToolFunction ¶ added in v1.11.0
type ToolFunction struct {
Name string `json:"name"`
Arguments string `json:"arguments"` // JSON string
}
ToolFunction describes the function selected by an AI tool call. Keep this named so Wails can generate a typed frontend binding for it.
type Usage ¶
type Usage struct {
InputTokens int `json:"input_tokens,omitempty"`
OutputTokens int `json:"output_tokens,omitempty"`
CacheCreationTokens int `json:"cache_creation_tokens,omitempty"` // Anthropic cache write
CacheReadTokens int `json:"cache_read_tokens,omitempty"` // Anthropic cache read / OpenAI cached prompt tokens
}
Usage 本轮 LLM 调用的 token 使用情况 语义统一:InputTokens 仅包含本次真正新增的输入;CacheReadTokens / CacheCreationTokens 分开统计缓存命中与缓存写入,便于前端展示和成本核算。