package ai import "context" // Message 对话消息(OpenAI 兼容协议)。Agent 多轮可带 tool_calls / tool 角色。 type Message struct { Role string `json:"role"` Content string `json:"content,omitempty"` ToolCalls []ToolCall `json:"tool_calls,omitempty"` ToolCallID string `json:"tool_call_id,omitempty"` Name string `json:"name,omitempty"` } // ToolCall OpenAI function tool_call。 type ToolCall struct { ID string `json:"id"` Type string `json:"type"` Function ToolCallFunc `json:"function"` } type ToolCallFunc struct { Name string `json:"name"` Arguments string `json:"arguments"` } // ChatReq 在 stub 时代字段上演进,前端契约不变;新增 schema/model 可选字段。 type ChatReq struct { Action string `json:"action"` Prompt string `json:"prompt"` SQL string `json:"sql"` Driver string `json:"driver"` Database string `json:"database"` Error string `json:"error"` Schema string `json:"schema,omitempty"` // 前端注入的库表列上下文 Model string `json:"model,omitempty"` } type ChatRes struct { Content string `json:"content"` SQL string `json:"sql,omitempty"` } // Provider AI 提供方抽象。本轮只做非流式 Complete; // Stream(ctx, req) (<-chan string, error) 预留,SSE 流式留待后续版本。 type Provider interface { Name() string Complete(ctx context.Context, req ChatReq) (ChatRes, error) } // Default 按当前配置选择 Provider;stub 时或远端配置缺 key(免鉴权除外)回落 stub(离线占位)。 func Default() Provider { cfg := LoadConfig() if cfg.Provider == "" || cfg.Provider == "stub" { return stubProvider{} } if cfg.APIKey == "" && cfg.AuthStyle != AuthNone { return stubProvider{} } return NewRemoteProvider(cfg) }