min-agent 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,98 @@
1
+ import { tool, jsonSchema, streamText, stepCountIs } from "ai";
2
+ import { resolveModel } from "../provider.js";
3
+ import { createTools } from "./index.js";
4
+ import { getMcpTools } from "../mcp.js";
5
+ import { getSkillsTool, getSkills } from "../skills.js";
6
+ import { loadPluginTools } from "../plugins.js";
7
+ import { DoomLoopDetector } from "../doom-loop.js";
8
+ import { stripThinkingFromAssistantText } from "../assistant-stream.js";
9
+ import { truncateToolOutput } from "../tool-output.js";
10
+ const SUB_AGENT_MAX_STEPS = 15;
11
+ const SUB_AGENT_SYSTEM = `You are a focused sub-agent executing a specific task. Complete the task thoroughly and return a clear result.
12
+
13
+ Rules:
14
+ - Focus only on the assigned task
15
+ - Be thorough but concise
16
+ - Use tools as needed to complete the task
17
+ - Return a clear summary of what you did and the result
18
+
19
+ Working directory: ${process.cwd()}
20
+ Platform: ${process.platform}
21
+ Date: ${new Date().toDateString()}`;
22
+ export function createTaskTool(modelId) {
23
+ return tool({
24
+ description: `Launch a sub-agent to execute a task independently. The sub-agent has its own context and tools. Use this for:
25
+ - Parallel execution: call multiple tasks at once for independent work
26
+ - Context isolation: keep the main conversation clean while the sub-agent explores
27
+ - Delegation: hand off well-defined subtasks (search, analysis, file operations)
28
+
29
+ The sub-agent can read/write files, run commands, search, and use all available tools.
30
+ Call multiple tasks in parallel when the work is independent.`,
31
+ inputSchema: jsonSchema({
32
+ type: "object",
33
+ properties: {
34
+ description: { type: "string", description: "Short description of the task (shown to user)" },
35
+ prompt: { type: "string", description: "Detailed instructions for the sub-agent" },
36
+ },
37
+ required: ["description", "prompt"],
38
+ }),
39
+ execute: async ({ description, prompt }) => {
40
+ console.log(`\x1b[90m ┌─ Sub-agent: ${description}\x1b[0m`);
41
+ try {
42
+ const result = await runSubAgent(prompt, modelId);
43
+ console.log(`\x1b[90m └─ ✓ Done\x1b[0m`);
44
+ return truncateToolOutput(result, { direction: "head" }).content;
45
+ }
46
+ catch (err) {
47
+ console.log(`\x1b[90m └─ ✗ Failed: ${err.message}\x1b[0m`);
48
+ return `Sub-agent error: ${err.message}`;
49
+ }
50
+ },
51
+ });
52
+ }
53
+ async function runSubAgent(prompt, modelId) {
54
+ const model = resolveModel(modelId);
55
+ // Build tools for sub-agent (no task tool to prevent recursion)
56
+ const builtinTools = createTools();
57
+ const mcpTools = getMcpTools();
58
+ const pluginTools = await loadPluginTools();
59
+ const skills = getSkills();
60
+ const allTools = { ...builtinTools, ...pluginTools };
61
+ for (const [id, t] of Object.entries(mcpTools))
62
+ allTools[id] = t;
63
+ if (skills.length > 0)
64
+ allTools["skill"] = getSkillsTool();
65
+ // Remove task tool from sub-agent to prevent infinite recursion
66
+ delete allTools["task"];
67
+ const messages = [{ role: "user", content: prompt }];
68
+ const doomLoop = new DoomLoopDetector();
69
+ const result = streamText({
70
+ model,
71
+ system: SUB_AGENT_SYSTEM,
72
+ messages,
73
+ tools: allTools,
74
+ stopWhen: stepCountIs(SUB_AGENT_MAX_STEPS),
75
+ maxRetries: 2,
76
+ onError() { },
77
+ });
78
+ let assistantText = "";
79
+ for await (const event of result.fullStream) {
80
+ switch (event.type) {
81
+ case "text-delta":
82
+ assistantText += event.text;
83
+ break;
84
+ case "tool-call":
85
+ if (doomLoop.record(event.toolName, event.input)) {
86
+ return assistantText + "\n\n[Sub-agent stopped: doom loop detected]";
87
+ }
88
+ console.log(`\x1b[90m │ ⚡ ${event.toolName}\x1b[0m`);
89
+ break;
90
+ case "tool-result":
91
+ break;
92
+ case "error":
93
+ return assistantText + `\n\n[Sub-agent error: ${event.error}]`;
94
+ }
95
+ }
96
+ const cleaned = stripThinkingFromAssistantText(assistantText);
97
+ return cleaned || "(sub-agent produced no output)";
98
+ }
@@ -0,0 +1,88 @@
1
+ import { tool, jsonSchema } from "ai";
2
+ let todos = [];
3
+ let nextId = 1;
4
+ export function getTodos() {
5
+ return todos;
6
+ }
7
+ export function resetTodos() {
8
+ todos = [];
9
+ nextId = 1;
10
+ }
11
+ function formatTodos() {
12
+ if (todos.length === 0)
13
+ return "No tasks.";
14
+ const icons = {
15
+ pending: "○",
16
+ in_progress: "◐",
17
+ done: "●",
18
+ cancelled: "✕",
19
+ };
20
+ return todos
21
+ .map((t) => ` ${icons[t.status]} #${t.id} ${t.text}`)
22
+ .join("\n");
23
+ }
24
+ function printTodos() {
25
+ if (todos.length === 0)
26
+ return;
27
+ console.log(`\x1b[90m ┌─ Tasks${"─".repeat(36)}\x1b[0m`);
28
+ for (const t of todos) {
29
+ const icon = t.status === "done" ? "\x1b[32m●\x1b[0m"
30
+ : t.status === "in_progress" ? "\x1b[33m◐\x1b[0m"
31
+ : t.status === "cancelled" ? "\x1b[90m✕\x1b[0m"
32
+ : "\x1b[90m○\x1b[0m";
33
+ const dim = t.status === "done" || t.status === "cancelled" ? "\x1b[90m" : "";
34
+ const reset = dim ? "\x1b[0m" : "";
35
+ console.log(`\x1b[90m │\x1b[0m ${icon} ${dim}#${t.id} ${t.text}${reset}`);
36
+ }
37
+ console.log(`\x1b[90m └${"─".repeat(44)}\x1b[0m`);
38
+ }
39
+ export const todoTool = tool({
40
+ description: `Create or update tasks to track progress. Use this FREQUENTLY to:
41
+ - Plan multi-step work by creating tasks upfront
42
+ - Mark tasks as in_progress when starting them
43
+ - Mark tasks as done when completed
44
+ - Give the user visibility into your progress
45
+
46
+ To create new tasks: provide items with "text" and optionally "status" (defaults to "pending").
47
+ To update existing tasks: provide items with "id" and "status".
48
+ You can mix creates and updates in one call.`,
49
+ inputSchema: jsonSchema({
50
+ type: "object",
51
+ properties: {
52
+ todos: {
53
+ type: "array",
54
+ description: "List of tasks to create or update",
55
+ items: {
56
+ type: "object",
57
+ properties: {
58
+ text: { type: "string", description: "Task description (for new tasks)" },
59
+ status: { type: "string", description: "Status: pending, in_progress, done, cancelled" },
60
+ id: { type: "number", description: "Task ID (for updating existing tasks)" },
61
+ },
62
+ },
63
+ },
64
+ },
65
+ required: ["todos"],
66
+ }),
67
+ execute: async ({ todos: items }) => {
68
+ for (const item of items) {
69
+ if (item.id) {
70
+ // Update existing
71
+ const existing = todos.find((t) => t.id === item.id);
72
+ if (existing && item.status) {
73
+ existing.status = item.status;
74
+ }
75
+ }
76
+ else if (item.text) {
77
+ // Create new
78
+ todos.push({
79
+ id: nextId++,
80
+ text: item.text,
81
+ status: item.status ?? "pending",
82
+ });
83
+ }
84
+ }
85
+ printTodos();
86
+ return formatTodos();
87
+ },
88
+ });
package/docs/API.md CHANGED
@@ -1,216 +1,312 @@
1
1
  # min-agent HTTP API
2
2
 
3
- 通过 `min-agent serve` 启动本地 HTTP 服务,以编程方式调用与 CLI `chat` 相同的代理能力(同一套 MCP、技能、规则、工具与模型配置)。
3
+ `min-agent serve` 启动本地 HTTP 服务,以编程方式调用代理能力。
4
4
 
5
5
  ## 启动
6
6
 
7
7
  ```bash
8
8
  min-agent serve
9
- min-agent serve --host 127.0.0.1 --port 8787
10
- min-agent serve -p 3030
9
+ min-agent serve --host 0.0.0.0 --port 3000
11
10
  ```
12
11
 
13
- 环境变量(可选):
14
-
15
- | 变量 | 说明 |
16
- |------|------|
17
- | `MIN_AGENT_SERVE_HOST` | 默认监听地址,默认 `127.0.0.1` |
18
- | `MIN_AGENT_SERVE_PORT` | 默认端口,默认 `8787` |
19
- | `MIN_AGENT_SERVE_TOKEN` | 若设置,则所有除 `OPTIONS` 外的请求须带 `Authorization: Bearer <token>` |
20
- | `MIN_AGENT_SERVE_CORS` | 设为 `1` 或 `true` 时添加 `Access-Control-Allow-Origin: *`(仅开发跨域时使用) |
21
-
22
- 启动后进程内 **`--yes` 等效**:危险 shell 等确认会自动通过,请勿把未鉴权服务暴露到公网。
12
+ | 环境变量 | 说明 |
13
+ |----------|------|
14
+ | `MIN_AGENT_SERVE_HOST` | 监听地址(默认 `127.0.0.1`) |
15
+ | `MIN_AGENT_SERVE_PORT` | 端口(默认 `8787`) |
16
+ | `MIN_AGENT_SERVE_TOKEN` | Bearer token 鉴权 |
17
+ | `MIN_AGENT_SERVE_CORS` | 设为 `1` 启用 CORS |
23
18
 
24
19
  ---
25
20
 
26
- ## 通用约定
21
+ ## 端点一览
27
22
 
28
- - **Base URL**:`http://<host>:<port>`
29
- - **请求体**:JSON,`Content-Type: application/json`
30
- - **响应体**:JSON,除非注明为 SSE
31
- - **工作目录**:与启动 `serve` 时的 `process.cwd()` 一致(影响 `read`/`bash` 等工具路径)
32
- - **单例初始化**:进程启动时连接 MCP、扫描技能并加载规则;之后请求复用该状态。修改规则文件后可调用下方「重载规则」接口或重启进程
23
+ | 方法 | 路径 | 说明 |
24
+ |------|------|------|
25
+ | GET | `/health` | 存活检查 |
26
+ | GET | `/v1/meta` | 运行环境 |
27
+ | GET | `/v1/models` | 模型列表 |
28
+ | GET | `/v1/context` | 上下文窗口信息 |
29
+ | GET | `/v1/project` | 项目扫描 |
30
+ | POST | `/v1/chat` | 对话 |
31
+ | POST | `/v1/code` | Code 模式对话 |
32
+ | POST | `/v1/paste` | 图片+文本对话 |
33
+ | POST | `/v1/chat/compact` | 手动压缩会话 |
34
+ | POST | `/v1/chat/reload-instructions` | 重载规则 |
35
+ | GET | `/v1/sessions` | 列出会话 |
36
+ | DELETE | `/v1/sessions/:id` | 删除会话 |
37
+ | GET | `/v1/memory` | 列出记忆 |
38
+ | POST | `/v1/memory` | 添加记忆 |
39
+ | GET | `/v1/memory/search?q=xxx` | 搜索记忆 |
40
+ | DELETE | `/v1/memory/:index` | 删除记忆 |
41
+ | GET | `/v1/mcp` | MCP 状态 |
42
+ | POST | `/v1/mcp` | 添加 MCP 服务器 |
43
+ | DELETE | `/v1/mcp/:name` | 删除 MCP 服务器 |
44
+ | GET | `/v1/skills` | 技能列表 |
45
+ | GET | `/v1/rules` | 已加载规则 |
33
46
 
34
47
  ---
35
48
 
36
49
  ## `GET /health`
37
50
 
38
- 存活检查。
51
+ ```json
52
+ { "ok": true, "service": "min-agent", "version": "0.1.0" }
53
+ ```
39
54
 
40
- **响应 200**
55
+ ## `GET /v1/meta`
41
56
 
42
57
  ```json
43
- {
44
- "ok": true,
45
- "service": "min-agent",
46
- "version": "0.1.0"
47
- }
58
+ { "version": "0.1.0", "cwd": "/path/to/project", "instructions_chars": 1234 }
48
59
  ```
49
60
 
50
- ---
61
+ ## `GET /v1/models`
51
62
 
52
- ## `GET /v1/meta`
63
+ ```json
64
+ { "default_model": "gpt-4o", "models": ["gpt-4o", "gpt-4o-mini"] }
65
+ ```
53
66
 
54
- 运行环境摘要。
67
+ ## `GET /v1/context`
55
68
 
56
- **响应 200**
69
+ ```json
70
+ { "context_window": 128000, "model": "gpt-4o" }
71
+ ```
72
+
73
+ ## `GET /v1/project`
57
74
 
58
75
  ```json
59
76
  {
60
- "version": "0.1.0",
61
- "cwd": "/path/to/project",
62
- "instructions_chars": 1234
77
+ "project": {
78
+ "directory": "/path",
79
+ "isGitRepo": true,
80
+ "branch": "main",
81
+ "languages": ["TypeScript"],
82
+ "framework": "Next.js",
83
+ "packageManager": "bun",
84
+ "entryFiles": ["src/index.ts"],
85
+ "configFiles": ["package.json", "tsconfig.json"],
86
+ "summary": "..."
87
+ }
63
88
  }
64
89
  ```
65
90
 
66
91
  ---
67
92
 
68
- ## `GET /v1/models`
93
+ ## `POST /v1/chat`
69
94
 
70
- 从当前配置的 OpenAI 兼容提供商拉取模型列表(与 CLI `min-agent models` 同源)。
95
+ | 字段 | 类型 | 说明 |
96
+ |------|------|------|
97
+ | `message` | string | 用户消息(与 `messages` 二选一) |
98
+ | `messages` | array | 完整 ModelMessage[] |
99
+ | `model` | string | 覆盖模型 |
100
+ | `stream` | boolean | SSE 流式 |
101
+ | `session_id` | string | 恢复会话 |
102
+ | `images` | string[] | 本地图片路径 |
71
103
 
72
- **响应 200**
104
+ ### 非流式响应
73
105
 
74
106
  ```json
75
107
  {
76
- "default_model": "gpt-4.1",
77
- "models": ["gpt-4.1", "gpt-4o-mini", "..."]
108
+ "messages": [...],
109
+ "assistant": { "role": "assistant", "content": "..." },
110
+ "tool_calls": [{ "name": "bash", "input": {...} }],
111
+ "tool_results": [{ "name": "bash", "output": "..." }],
112
+ "session_id": "abc123",
113
+ "step_count": 2,
114
+ "usage": { "inputTokens": 1200, "outputTokens": 300 },
115
+ "has_error": false,
116
+ "aborted": false
78
117
  }
79
118
  ```
80
119
 
81
- ---
120
+ ### 流式 SSE 事件
82
121
 
83
- ## `POST /v1/chat/reload-instructions`
122
+ | type | 字段 | 说明 |
123
+ |------|------|------|
124
+ | `assistant` | text | 正文增量 |
125
+ | `thinking` | text | 思考片段 |
126
+ | `tool_call` | name, input | 工具调用 |
127
+ | `tool_result` | name, output | 工具返回 |
128
+ | `compaction` | line | 压缩进度 |
129
+ | `error` | message | 错误 |
130
+ | `done` | step_count, usage, messages, session_id | 结束 |
131
+ | `fatal` | message | 致命错误 |
84
132
 
85
- 重新从磁盘加载 `AGENTS.md`、规则与 `config.json` 中的 instructions 片段(不重启 MCP)。
133
+ ---
86
134
 
87
- **响应 200**
135
+ ## `POST /v1/code`
88
136
 
137
+ Code 模式对话(项目感知 prompt + explore 工具)。请求体与 `/v1/chat` 相同。
138
+
139
+ 响应额外包含:
89
140
  ```json
90
- {
91
- "ok": true,
92
- "instructions_chars": 1234
93
- }
141
+ { "mode": "code", "project": { "languages": [...], ... }, ... }
94
142
  ```
95
143
 
96
144
  ---
97
145
 
98
- ## `POST /v1/chat`
99
-
100
- 执行一轮或多轮对话(与 CLI 使用相同的 `streamText` + 工具集)。
146
+ ## `POST /v1/paste`
101
147
 
102
- ### 请求体字段
148
+ 图片 + 文本多模态对话。
103
149
 
104
150
  | 字段 | 类型 | 说明 |
105
151
  |------|------|------|
106
- | `message` | `string` | 单轮:用户消息文本。与 `messages` 二选一(会话续写见下) |
107
- | `messages` | `array` | 多轮:完整 `ModelMessage[]`(与 AI SDK 一致:`role` + `content`)。最后一轮通常为用户消息 |
108
- | `model` | `string` | 可选,覆盖默认模型 |
109
- | `stream` | `boolean` | `true` 时使用 **SSE** 流式返回 |
110
- | `session_id` | `string` | 可选,从 `~/.min-agent/sessions/<id>.json` 恢复历史,并追加本条 `message` 为新用户轮 |
111
- | `images` | `string[]` | 可选,本地图片路径(相对 cwd 或绝对路径),须与顶层 `message` 一起使用,用于构造多模态用户消息 |
152
+ | `image_base64` | string | **必填** Base64 图片数据 |
153
+ | `mime_type` | string | MIME 类型(默认 `image/png`) |
154
+ | `message` | string | 文本 prompt |
155
+ | `model` | string | 覆盖模型 |
156
+ | `session_id` | string | 追加到会话 |
157
+ | `stream` | boolean | SSE 流式 |
112
158
 
113
- ### 会话续写 `session_id`
159
+ ---
114
160
 
115
- - 请求体必须包含 **`message`**(新用户发言)
116
- - 服务端加载该会话已有 `messages`,追加新用户消息后调用模型,并在本轮结束后 **写回同一 `session_id`**
161
+ ## `POST /v1/chat/compact`
117
162
 
118
- ### 非流式 `stream: false`(默认)
163
+ ```json
164
+ // 请求
165
+ { "session_id": "abc123" }
166
+ // 响应
167
+ { "ok": true, "compacted": true, "message_count": 5 }
168
+ ```
119
169
 
120
- **响应 200**
170
+ ## `POST /v1/chat/reload-instructions`
121
171
 
122
172
  ```json
123
- {
124
- "messages": [ ... ],
125
- "assistant": { "role": "assistant", "content": "..." },
126
- "tool_calls": [{ "name": "bash", "input": { "command": "ls" } }],
127
- "tool_results": [{ "name": "bash", "output": "..." }],
128
- "session_id": "abc123",
129
- "step_count": 2,
130
- "usage": { "inputTokens": 1200, "outputTokens": 300, "totalTokens": 1500 },
131
- "has_error": false,
132
- "aborted": false
133
- }
173
+ { "ok": true, "instructions_chars": 1234 }
134
174
  ```
135
175
 
136
- - `messages`:已包含本轮助手回复(就地追加,与 CLI 行为一致)
137
- - `tool_results` 中单条输出过长时会被截断并附带说明后缀
138
- - 未使用 `session_id` 时 `session_id` 字段为 `undefined`/省略
176
+ ---
139
177
 
140
- ### 流式 `stream: true`
178
+ ## `GET /v1/sessions`
141
179
 
142
- - **Headers**:`Content-Type: text/event-stream`
143
- - **Body**:SSE,每条事件为一行 `data: <json>\n\n`
180
+ ```json
181
+ { "sessions": [{ "id": "abc", "title": "Fix bug", "updated": "...", "messageCount": 12 }] }
182
+ ```
144
183
 
145
- 事件 `type` 取值:
184
+ ## `DELETE /v1/sessions/:id`
146
185
 
147
- | `type` | 字段 | 说明 |
148
- |--------|------|------|
149
- | `assistant` | `text` | 助手正文增量(已剥离思考块,与入库内容一致) |
150
- | `thinking` | `text` | 模型泄漏的思考片段(若存在) |
151
- | `tool_call` | `name`, `input` | 工具调用开始 |
152
- | `tool_result` | `name`, `output` | 工具返回(可能截断) |
153
- | `compaction` | `line` | 上下文压缩进度说明 |
154
- | `error` | `message` | 流内模型/鉴权类错误事件 |
155
- | `done` | `step_count`, `usage`, `has_error`, `aborted`, `messages`, `session_id?` | 本轮结束;之后连接关闭 |
156
- | `fatal` | `message` | 服务异常,随后关闭 |
186
+ ```json
187
+ { "ok": true, "deleted": "abc123" }
188
+ ```
157
189
 
158
- 客户端断开连接时会 **Abort** 正在进行的生成;若已有部分正文,仍可能写入 `messages` 中的 assistant(与 CLI Ctrl+C 行为对齐)。
190
+ ---
159
191
 
160
- ### 错误 HTTP 状态
192
+ ## `GET /v1/memory`
161
193
 
162
- | 状态 | 说明 |
163
- |------|------|
164
- | `400` | JSON 无效或缺少 `message`/`messages` |
165
- | `401` | 配置了 `MIN_AGENT_SERVE_TOKEN` 但未携带合法 Bearer |
166
- | `404` | `session_id` 不存在 |
167
- | `413` | 请求体超过约 2MB |
168
- | `415` | 非 `application/json` |
169
- | `500` | 未配置提供商等内部错误 |
194
+ ```json
195
+ { "memories": [{ "content": "...", "tags": [...], "created": "..." }] }
196
+ ```
170
197
 
171
- ---
198
+ ## `POST /v1/memory`
199
+
200
+ ```json
201
+ // 请求
202
+ { "content": "prefer TypeScript", "tags": ["preference"] }
203
+ // 响应
204
+ { "ok": true, "memory": {...} }
205
+ ```
206
+
207
+ ## `GET /v1/memory/search?q=typescript`
172
208
 
173
- ## `OPTIONS *`
209
+ ```json
210
+ { "results": [{ "content": "...", "tags": [...], "index": 0 }] }
211
+ ```
174
212
 
175
- 当启用 `MIN_AGENT_SERVE_CORS` 时,用于浏览器预检;返回 `204`。
213
+ ## `DELETE /v1/memory/:index`
214
+
215
+ ```json
216
+ { "ok": true, "deleted": 1 }
217
+ ```
176
218
 
177
219
  ---
178
220
 
179
- ## 示例
221
+ ## `GET /v1/mcp`
180
222
 
181
- ### curl:单轮非流式
223
+ ```json
224
+ { "servers": { "filesystem": { "connected": true, "tools": ["read_file", "write_file"] } } }
225
+ ```
182
226
 
183
- ```bash
184
- curl -sS http://127.0.0.1:8787/v1/chat \
185
- -H "Content-Type: application/json" \
186
- -d '{"message":"List files in current directory","model":"gpt-4o-mini"}'
227
+ ## `POST /v1/mcp`
228
+
229
+ ```json
230
+ // 本地 stdio
231
+ { "name": "fs", "command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"] }
232
+ // 远程
233
+ { "name": "remote", "url": "https://mcp.example.com", "token": "xxx" }
187
234
  ```
188
235
 
189
- ### curl:SSE 流式
236
+ ```json
237
+ { "ok": true, "name": "fs" }
238
+ ```
190
239
 
191
- ```bash
192
- curl -sS -N http://127.0.0.1:8787/v1/chat \
193
- -H "Content-Type: application/json" \
194
- -d '{"message":"Say hi in one sentence","stream":true}'
240
+ ## `DELETE /v1/mcp/:name`
241
+
242
+ ```json
243
+ { "ok": true, "deleted": "fs" }
195
244
  ```
196
245
 
197
- ### 带鉴权
246
+ ---
198
247
 
199
- ```bash
200
- export MIN_AGENT_SERVE_TOKEN=secret
201
- min-agent serve &
202
- curl -sS http://127.0.0.1:8787/health \
203
- -H "Authorization: Bearer secret"
248
+ ## `GET /v1/skills`
249
+
250
+ ```json
251
+ { "skills": [{ "name": "git-workflow", "description": "...", "location": "..." }] }
252
+ ```
253
+
254
+ ## `GET /v1/rules`
255
+
256
+ ```json
257
+ { "count": 2, "rules": [{ "source": "~/.min-agent/rules.md", "chars": 456 }] }
204
258
  ```
205
259
 
206
260
  ---
207
261
 
208
- ## 与 OpenCode / 其他客户端的对比说明
262
+ ## 错误码
209
263
 
210
- API **不是** OpenAI Chat Completions 的完全兼容实现;字段与事件名为 min-agent 专用。若需对接现有 OpenAI SDK,请在网关层做映射。
264
+ | 状态 | 说明 |
265
+ |------|------|
266
+ | 400 | 请求参数错误 |
267
+ | 401 | 未授权 |
268
+ | 404 | 资源不存在 |
269
+ | 413 | 请求体过大(>2MB) |
270
+ | 415 | Content-Type 不是 JSON |
271
+ | 500 | 内部错误 |
211
272
 
212
273
  ---
213
274
 
214
- ## 版本
275
+ ## 示例
276
+
277
+ ```bash
278
+ # 对话
279
+ curl http://127.0.0.1:8787/v1/chat \
280
+ -H "Content-Type: application/json" \
281
+ -d '{"message":"list files"}'
282
+
283
+ # 流式
284
+ curl -N http://127.0.0.1:8787/v1/chat \
285
+ -H "Content-Type: application/json" \
286
+ -d '{"message":"say hi","stream":true}'
287
+
288
+ # Code 模式
289
+ curl http://127.0.0.1:8787/v1/code \
290
+ -H "Content-Type: application/json" \
291
+ -d '{"message":"add error handling to login"}'
292
+
293
+ # 图片
294
+ curl http://127.0.0.1:8787/v1/paste \
295
+ -H "Content-Type: application/json" \
296
+ -d '{"image_base64":"iVBOR...","message":"分析这张图"}'
215
297
 
216
- 文档与实现随仓库版本迭代;`GET /health` 中的 `version` 来自项目根目录 `package.json`。
298
+ # 添加 MCP
299
+ curl -X POST http://127.0.0.1:8787/v1/mcp \
300
+ -H "Content-Type: application/json" \
301
+ -d '{"name":"fs","command":["npx","-y","@modelcontextprotocol/server-filesystem","/tmp"]}'
302
+
303
+ # 添加记忆
304
+ curl -X POST http://127.0.0.1:8787/v1/memory \
305
+ -H "Content-Type: application/json" \
306
+ -d '{"content":"prefer TypeScript","tags":["preference"]}'
307
+
308
+ # 压缩会话
309
+ curl -X POST http://127.0.0.1:8787/v1/chat/compact \
310
+ -H "Content-Type: application/json" \
311
+ -d '{"session_id":"abc123"}'
312
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "min-agent",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "description": "Minimal AI coding agent with tool use, MCP, and skills support",
6
6
  "license": "MIT",