Files
opsxdb/server/internal/aitools/schema.go
T
logan 2336c9433c feat(ai): Agent SSE + Anthropic/responses tools + P1 确认写
- Agent 支持 SSE(步骤边推、正文分块),JSON 非流式 fallback
- tool calling 覆盖 openai-chat / anthropic / responses(单测解析回灌)
- P1:mcp.json mode=read_write 才可写;需 confirm_danger;Agent 剥离模型自带令牌
- GET /api/ai/mcp-status、POST /api/ai/agent/confirm;审计 source=mcp|agent
2026-10-15 13:00:40 +08:00

118 lines
4.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package aitools
// ToolSpec 工具元数据:MCP stdio 与侧栏 Agent(OpenAI tools)共用同一份契约。 // Logan.Li
type ToolSpec struct {
Name string
Description string
Properties map[string]any
Required []string
}
// ToolSpecs P0 七工具 schema(顺序与 ToolNames 一致)。
func ToolSpecs() []ToolSpec {
connID := map[string]any{"type": "string", "description": "Saved connection id from opsxdb_list_connections"}
database := map[string]any{"type": "string", "description": "Database / schema / Redis DB index"}
return []ToolSpec{
{
Name: ToolListConnections,
Description: "List whitelisted OpsxDB connections (id/name/driver/host/port/database; never passwords).",
Properties: map[string]any{},
},
{
Name: ToolListDatabases,
Description: "List databases for a connection.",
Properties: map[string]any{"connection_id": connID},
Required: []string{"connection_id"},
},
{
Name: ToolListTables,
Description: "List tables/views (or engine equivalents) in a database.",
Properties: map[string]any{"connection_id": connID, "database": database},
Required: []string{"connection_id"},
},
{
Name: ToolDescribeTable,
Description: "Describe columns and metadata for a table.",
Properties: map[string]any{
"connection_id": connID,
"database": database,
"table": map[string]any{"type": "string", "description": "Table name"},
},
Required: []string{"connection_id", "table"},
},
{
Name: ToolGetSchemaContext,
Description: "Compact schema text for LLM context (capped ~4k chars).",
Properties: map[string]any{
"connection_id": connID,
"database": database,
"max_tables": map[string]any{"type": "integer", "description": "Max tables to include (default 40)"},
},
Required: []string{"connection_id"},
},
{
Name: ToolExecuteQuery,
Description: "Execute SQL. Default read-only (SELECT/SHOW/EXPLAIN/WITH…SELECT). Writes require mcp.json mode=read_write AND confirm_danger=true (never auto). Default limit 100, max 500.",
Properties: map[string]any{
"connection_id": connID,
"sql": map[string]any{"type": "string", "description": "SQL statement"},
"database": database,
"limit": map[string]any{"type": "integer", "description": "Row limit (default 100, max 500)"},
"confirm_danger": map[string]any{"type": "boolean", "description": "Required for writes when mode=read_write; Agent UI sets this only after user confirms"},
},
Required: []string{"connection_id", "sql"},
},
{
Name: ToolExecuteRedisCommand,
Description: "Execute Redis command. Default read-only whitelist. Writes require mode=read_write AND confirm_danger=true. FLUSH*/KEYS/CONFIG always denied.",
Properties: map[string]any{
"connection_id": connID,
"command": map[string]any{"type": "string", "description": "Single Redis command line"},
"database": database,
"confirm_danger": map[string]any{"type": "boolean", "description": "Required for writes when mode=read_write"},
},
Required: []string{"connection_id", "command"},
},
}
}
// InputSchema 返回 JSON Schema object(MCP raw schema / OpenAI parameters)。
func (t ToolSpec) InputSchema() map[string]any {
schema := map[string]any{
"type": "object",
"properties": t.Properties,
}
if len(t.Required) > 0 {
schema["required"] = t.Required
}
if t.Properties == nil {
schema["properties"] = map[string]any{}
}
return schema
}
// OpenAITool OpenAI chat.completions tools[] 一项。
type OpenAITool struct {
Type string `json:"type"`
Function struct {
Name string `json:"name"`
Description string `json:"description"`
Parameters map[string]any `json:"parameters"`
} `json:"function"`
}
// OpenAITools 供 Agent / DeepSeek 等 openai-chat 兼容协议挂载。
func OpenAITools() []OpenAITool {
specs := ToolSpecs()
out := make([]OpenAITool, 0, len(specs))
for _, s := range specs {
var t OpenAITool
t.Type = "function"
t.Function.Name = s.Name
t.Function.Description = s.Description
t.Function.Parameters = s.InputSchema()
out = append(out, t)
}
return out
}