min-agent 0.5.0 → 0.6.0
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.
- package/README.md +32 -18
- package/dist/cli.js +538 -12
- package/docs/API.md +25 -8
- package/package.json +6 -6
- package/skills/self-config/SKILL.md +7 -3
- package/skills/self-config/reference.md +8 -4
- package/dist/agent.js +0 -1342
- package/dist/assistant-stream.js +0 -131
- package/dist/cli/commands/chat.js +0 -13
- package/dist/cli/commands/exec.js +0 -35
- package/dist/cli/commands/history.js +0 -58
- package/dist/cli/commands/index.js +0 -241
- package/dist/cli/commands/init.js +0 -18
- package/dist/cli/commands/mcp.js +0 -173
- package/dist/cli/commands/memory.js +0 -87
- package/dist/cli/commands/models.js +0 -21
- package/dist/cli/commands/permission.js +0 -12
- package/dist/cli/commands/rules.js +0 -33
- package/dist/cli/commands/sandbox.js +0 -13
- package/dist/cli/commands/serve.js +0 -9
- package/dist/cli/commands/setup.js +0 -4
- package/dist/cli/commands/shared.js +0 -16
- package/dist/cli/commands/skills.js +0 -119
- package/dist/cli/commands/think.js +0 -12
- package/dist/cli/commands/update.js +0 -7
- package/dist/cli/commands/write-config.js +0 -52
- package/dist/cli/errors.js +0 -36
- package/dist/cli/exec-prompt.js +0 -26
- package/dist/cli/option-helpers.js +0 -65
- package/dist/cli/program.js +0 -217
- package/dist/clipboard.js +0 -142
- package/dist/code-mode.js +0 -184
- package/dist/compaction.js +0 -644
- package/dist/config.js +0 -470
- package/dist/confirm.js +0 -172
- package/dist/context-window.js +0 -246
- package/dist/doom-loop.js +0 -278
- package/dist/fetch-timeout.js +0 -152
- package/dist/http-approvals.js +0 -60
- package/dist/http.js +0 -119
- package/dist/instructions.js +0 -196
- package/dist/logger.js +0 -95
- package/dist/markdown.js +0 -259
- package/dist/mcp.js +0 -1036
- package/dist/memory-cli.js +0 -33
- package/dist/memory.js +0 -295
- package/dist/model-catalog.js +0 -285
- package/dist/output.js +0 -76
- package/dist/paste-handler.js +0 -41
- package/dist/permission-cli.js +0 -40
- package/dist/plugins.js +0 -131
- package/dist/pricing.js +0 -119
- package/dist/provider.js +0 -63
- package/dist/question-format.js +0 -60
- package/dist/reasoning-stream.js +0 -158
- package/dist/sandbox-cli.js +0 -79
- package/dist/sandbox.js +0 -403
- package/dist/save-throttle.js +0 -45
- package/dist/scope.js +0 -23
- package/dist/serve/common.js +0 -425
- package/dist/serve/routes-chat.js +0 -367
- package/dist/serve/routes-mcp.js +0 -212
- package/dist/serve/routes-memory.js +0 -95
- package/dist/serve/routes-meta.js +0 -233
- package/dist/serve/routes-sessions.js +0 -61
- package/dist/serve/routes-skills.js +0 -70
- package/dist/serve.js +0 -138
- package/dist/sessions.js +0 -265
- package/dist/skills.js +0 -599
- package/dist/structured-output.js +0 -29
- package/dist/synthetic.js +0 -7
- package/dist/think-cli.js +0 -36
- package/dist/thinking-wire.js +0 -228
- package/dist/thinking.js +0 -142
- package/dist/title-gen.js +0 -55
- package/dist/token-display.js +0 -39
- package/dist/tool-display.js +0 -178
- package/dist/tool-output.js +0 -126
- package/dist/tools/apply_patch.js +0 -265
- package/dist/tools/atomic-file.js +0 -35
- package/dist/tools/backend.js +0 -61
- package/dist/tools/bash.js +0 -231
- package/dist/tools/code_search.js +0 -98
- package/dist/tools/edit.js +0 -68
- package/dist/tools/explore.js +0 -232
- package/dist/tools/glob.js +0 -40
- package/dist/tools/grep.js +0 -174
- package/dist/tools/index.js +0 -34
- package/dist/tools/question.js +0 -54
- package/dist/tools/read.js +0 -109
- package/dist/tools/search-searxng.js +0 -223
- package/dist/tools/search-serper.js +0 -189
- package/dist/tools/task.js +0 -165
- package/dist/tools/todo.js +0 -213
- package/dist/tools/web_fetch.js +0 -195
- package/dist/tools/web_search.js +0 -228
- package/dist/tools/write.js +0 -55
- package/dist/tui/App.js +0 -126
- package/dist/tui/ConfirmBar.js +0 -66
- package/dist/tui/InputBar.js +0 -616
- package/dist/tui/MessageList.js +0 -718
- package/dist/tui/ModelPicker.js +0 -113
- package/dist/tui/QuestionBar.js +0 -136
- package/dist/tui/SessionPicker.js +0 -79
- package/dist/tui/Spinner.js +0 -6
- package/dist/tui/StatusBar.js +0 -22
- package/dist/tui/ThinkPicker.js +0 -77
- package/dist/tui/agent-runner.js +0 -223
- package/dist/tui/bracketed-paste.js +0 -37
- package/dist/tui/caret-pos.js +0 -179
- package/dist/tui/caret.js +0 -69
- package/dist/tui/click-count.js +0 -13
- package/dist/tui/diff-view.js +0 -61
- package/dist/tui/drag-state.js +0 -49
- package/dist/tui/hydrate.js +0 -129
- package/dist/tui/index.js +0 -258
- package/dist/tui/input-history.js +0 -125
- package/dist/tui/layout.js +0 -105
- package/dist/tui/mouse.js +0 -46
- package/dist/tui/overlay-input.js +0 -12
- package/dist/tui/paste-draft.js +0 -173
- package/dist/tui/prompt-queue.js +0 -24
- package/dist/tui/selection.js +0 -232
- package/dist/tui/session-switch.js +0 -28
- package/dist/tui/slash-commands.js +0 -123
- package/dist/tui/slash-handler.js +0 -589
- package/dist/tui/text-width.js +0 -113
- package/dist/tui/theme.js +0 -12
- package/dist/tui/token-info.js +0 -7
- package/dist/tui/tool-children.js +0 -19
- package/dist/tui/types.js +0 -1
- package/dist/tui/undo-stack.js +0 -14
- package/dist/tui/use-sgr-mouse.js +0 -29
- package/dist/tui-chat.js +0 -456
- package/dist/updater.js +0 -116
- package/dist/xml-search.js +0 -194
- package/docs/superpowers/plans/2026-08-16-batch1-tui-improvements.md +0 -1510
- package/docs/superpowers/plans/2026-08-16-batch2-cli-tools-api.md +0 -2105
- package/docs/superpowers/plans/2026-08-16-batch3-config-engineering.md +0 -1595
- package/docs/superpowers/plans/2026-08-16-input-caret.md +0 -782
- package/docs/superpowers/plans/2026-08-20-tui-completeness.md +0 -873
- package/docs/superpowers/plans/2026-08-20-unified-tui-default.md +0 -631
- package/docs/superpowers/plans/2026-08-23-input-paste-attachments.md +0 -475
- package/docs/superpowers/plans/2026-08-23-thinking-wire-profile.md +0 -450
- package/docs/superpowers/specs/2026-08-16-batch1-tui-improvements-design.md +0 -183
- package/docs/superpowers/specs/2026-08-16-batch2-cli-tools-api-design.md +0 -220
- package/docs/superpowers/specs/2026-08-16-batch3-config-engineering-design.md +0 -196
- package/docs/superpowers/specs/2026-08-16-input-caret-design.md +0 -63
- package/docs/superpowers/specs/2026-08-17-mouse-selection-design.md +0 -116
- package/docs/superpowers/specs/2026-08-20-config-http-alignment-design.md +0 -47
- package/docs/superpowers/specs/2026-08-20-mcp-plugins-alignment-design.md +0 -37
- package/docs/superpowers/specs/2026-08-20-sandbox-permissions-design.md +0 -68
- package/docs/superpowers/specs/2026-08-20-tui-completeness-design.md +0 -273
- package/docs/superpowers/specs/2026-08-20-unified-tui-default-design.md +0 -165
- package/docs/superpowers/specs/2026-08-23-input-paste-attachments-design.md +0 -174
- package/docs/superpowers/specs/2026-08-23-thinking-wire-profile-design.md +0 -140
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
# 输入框粘贴图片与文本片段设计
|
|
2
|
-
|
|
3
|
-
日期: 2026-08-23
|
|
4
|
-
状态: 已批准(方案 1:输入框内原子标记)
|
|
5
|
-
|
|
6
|
-
## 问题
|
|
7
|
-
|
|
8
|
-
交互会话的输入框不能把剪贴板图片挂到当前草稿:贴图只能 `/paste`(立刻发送)或 `/attach <路径>`。多行文本粘贴会整段铺进输入框,末尾换行还可能被当成 Enter 误发送。
|
|
9
|
-
|
|
10
|
-
## 目标
|
|
11
|
-
|
|
12
|
-
1. 剪贴板图片用 Ctrl+V 插到光标处,显示为 `[图片 #N]`,写完说明再 Enter 发送
|
|
13
|
-
2. 一次粘贴只要超过一行,收成 `[粘贴 #N · X 行]`,发送时带上全文
|
|
14
|
-
3. 单行粘贴仍直接插入
|
|
15
|
-
4. 标记在输入框里是原子块:左右移、退格、Delete、点击都不拆开
|
|
16
|
-
5. 只有附件、没打字也可以发送
|
|
17
|
-
|
|
18
|
-
## 不做
|
|
19
|
-
|
|
20
|
-
- 不改 HTTP `/v1/paste`,不新增配置项,不改 `skills/self-config`
|
|
21
|
-
- 不把 Cmd+V 从终端抢过来(macOS 贴图用 Ctrl+V)
|
|
22
|
-
- 不把附件正文写入 `input-history.json`
|
|
23
|
-
- 不做拖拽文件进终端、不做输入框内 Shift 选区
|
|
24
|
-
- `/paste [t]` 仍是立刻发送剪贴板图片,不改成挂草稿
|
|
25
|
-
|
|
26
|
-
## 设计决策
|
|
27
|
-
|
|
28
|
-
| 决策 | 结论 |
|
|
29
|
-
|------|------|
|
|
30
|
-
| 呈现 | 草稿字符串里每个附件一个私有区码点;屏幕上画成标记 |
|
|
31
|
-
| 文本门槛 | 规范化后仍含换行 → 片段;否则当普通字插入 |
|
|
32
|
-
| 贴图快捷键 | Ctrl+V 读系统剪贴板;无图时静默 |
|
|
33
|
-
| `/paste` | 保持立刻发送 |
|
|
34
|
-
| 斜杠命令 | `display` 去空白后以 `/` 开头则走现有命令处理,附件不进入对话 |
|
|
35
|
-
| 历史 | 只存展开后的短标记字面量,不存图片/长文;翻历史不会恢复附件 |
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## 1. 数据模型
|
|
40
|
-
|
|
41
|
-
`InputBar` 继续用 `{ value, caretIndex }`。`caretIndex` 仍是 `Array.from(value)` 的码点下标。
|
|
42
|
-
|
|
43
|
-
每个附件占用 **一个** Unicode 私有区码点,从 `U+E000` 起按插入顺序分配,本条草稿内不复用。旁路表:
|
|
44
|
-
|
|
45
|
-
```ts
|
|
46
|
-
type DraftAttachment =
|
|
47
|
-
| { kind: "image"; id: number; data: Buffer; mimeType: string }
|
|
48
|
-
| { kind: "snippet"; id: number; text: string; lineCount: number }
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
`id` 按类型分开从 1 递增:`[图片 #1]` 与 `[粘贴 #1 · 3 行]` 可以同时存在。
|
|
52
|
-
|
|
53
|
-
屏幕标记(用户可见,无实现细节):
|
|
54
|
-
|
|
55
|
-
- 图片:`[图片 #${id}]`
|
|
56
|
-
- 片段:`[粘贴 #${id} · ${lineCount} 行]`
|
|
57
|
-
|
|
58
|
-
未在旁路表中的私有区字符按宽 1 的 `�` 绘制,不当附件。
|
|
59
|
-
|
|
60
|
-
每次编辑后扫描 `value`:旁路表里码点已不在 `value` 中的条目删除(退格、Ctrl+U/K/W、Ctrl+C 清空都走这条)。Ctrl+C 清空或提交成功后:`value` 清空,旁路表清空,两个计数器回到 1。
|
|
61
|
-
|
|
62
|
-
折行与点击:该码点是一个 cluster,显示宽度为 `min(displayWidth(标记), 输入区宽度)`。过宽时单独占一行,绘制时末尾用 `…` 截断;点击该行任一单元格都落在这一个码点上。硬件光标列用展开后的显示宽度计算,与现有 IME 锚点一致。
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## 2. 文本粘贴
|
|
67
|
-
|
|
68
|
-
挂载输入框时打开 bracketed paste(`CSI ? 2004 h`),卸载时关闭(`CSI ? 2004 l`),与现有鼠标协议一起写 stdout。
|
|
69
|
-
|
|
70
|
-
在 InputBar 已有的 raw stdin 监听里拼包:`ESC[200~` 起、`ESC[201~` 止。包收齐前 `useInput` 丢掉这段输入(含 Ink 剥掉 ESC 后的 `[200~` / `[201~` 碎片),避免插两遍,也避免粘贴里的换行走现有「末尾 `\r`/`\n` 当 Enter」逻辑。
|
|
71
|
-
|
|
72
|
-
粘贴正文处理(纯函数,可单测):
|
|
73
|
-
|
|
74
|
-
1. `\r\n` 与 `\r` 全部变成 `\n`
|
|
75
|
-
2. 去掉**末尾一个** `\n`(编辑器复制常带)
|
|
76
|
-
3. 若仍含 `\n`:分配片段码点,插入光标处,`lineCount = text.split("\n").length`
|
|
77
|
-
4. 否则:当普通文本插入(与打字相同)
|
|
78
|
-
|
|
79
|
-
片段正文上限 **1_000_000** 个 UTF-16 码元。超过则不插入,系统提示 `粘贴内容过大,未附加`。
|
|
80
|
-
|
|
81
|
-
单行过长仍插入,不收成片段。
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## 3. 图片粘贴
|
|
86
|
-
|
|
87
|
-
`useInput` 在现有 `Ctrl+B` 之后、吞掉其它 Ctrl 组合之前处理 `key.ctrl && input === "v"`:调用已有 `getClipboardImage()`。
|
|
88
|
-
|
|
89
|
-
- 有图且 `data.length <=` 现有 `MAX_IMAGE_BYTES`(5MB):插入图片码点,MIME 用剪贴板返回值
|
|
90
|
-
- 有图但超过 5MB:提示 `图片超过 5MB,未附加`,不插入
|
|
91
|
-
- 无图:静默返回(不提示),避免想贴字时误按 Ctrl+V 刷警告
|
|
92
|
-
|
|
93
|
-
Mac 上 Cmd+V 仍由终端注入文字。README 与 `/help` 写明贴图用 Ctrl+V。
|
|
94
|
-
|
|
95
|
-
---
|
|
96
|
-
|
|
97
|
-
## 4. 编辑
|
|
98
|
-
|
|
99
|
-
因为每个标记是一个码点,现有 `moveCaretHorizontal` / `backspaceAt` / `deleteAt` 已整块移动或删除。`Ctrl+W` / `Ctrl+K` / `Ctrl+U` 按现有「删一段字符串」处理,事后扫描丢掉孤儿附件。
|
|
100
|
-
|
|
101
|
-
点击:先按展开后的显示列命中 cluster,再映射回 `value` 码点下标;点在标记上时 caret 落在该码点前(与现在点在某字前一致),再按右键一次跳过整块。
|
|
102
|
-
|
|
103
|
-
Enter:`display` 去空白后非空,**或**旁路表非空,即可发送。发送后清空草稿与表。
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
## 5. 提交与展示
|
|
108
|
-
|
|
109
|
-
`onSubmit` 改为接收一次提交的结构化结果:
|
|
110
|
-
|
|
111
|
-
```ts
|
|
112
|
-
type SubmittedPrompt = {
|
|
113
|
-
display: string
|
|
114
|
-
content: string | Array<{ type: "text"; text: string } | { type: "image"; image: Buffer; mimeType: string }>
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
`display`:把 `value` 里的附件码点换成标记文案,用于对话区用户气泡和输入历史。
|
|
119
|
-
|
|
120
|
-
`content` 按 `value` 从左到右展开:
|
|
121
|
-
|
|
122
|
-
- 连续普通字合成一个 `text` part
|
|
123
|
-
- 片段换成一个 `text` part,正文前后各单独一行分隔:`--- 粘贴 #${id} ---`
|
|
124
|
-
- 图片一个 `image` part(`Buffer` + `mimeType`)
|
|
125
|
-
|
|
126
|
-
若没有任何图片 part,`content` 收成单个字符串(与现在 `messages.push({ content: text })` 兼容)。有图片则为数组。
|
|
127
|
-
|
|
128
|
-
`tui-chat`:`addMessage` 用 `display`;`messages.push({ role: "user", content })` 用 `content`。`lastUserMessage` 存 `display`。
|
|
129
|
-
|
|
130
|
-
`display` 去空白后以 `/` 开头:原样交给现有 `handleSlashCommand`,旁路表丢弃、不写入 `messages`(避免 `/help` 误带一张图)。否则按上面的 `content` 入列。
|
|
131
|
-
|
|
132
|
-
超限提示不进输入框正文:`InputBar` 增加 `onNotice(text: string)`,`tui-chat` 接到现有系统消息通道(与 `/paste` 失败提示同一处)。
|
|
133
|
-
|
|
134
|
-
输入历史:`pushInput` 写入 `display`(短标记,无二进制、无片段全文)。从历史上召回的标记是普通字符,旁路表为空。
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## 6. 文件与同步
|
|
139
|
-
|
|
140
|
-
| 文件 | 改动 |
|
|
141
|
-
|------|------|
|
|
142
|
-
| `src/tui/paste-draft.ts`(新) | 规范化粘贴、单行/多行判定、码点分配、展开 `display`/`content`、孤儿回收;无 React |
|
|
143
|
-
| `src/tui/bracketed-paste.ts`(新) | 从 stdin 块里扫描 bracketed paste 包 |
|
|
144
|
-
| `src/tui/caret-pos.ts` / `text-width.ts` | cluster 宽度可注入「此码点显示宽」;`visualRows` / 点击换算认识附件宽 |
|
|
145
|
-
| `src/tui/InputBar.tsx` | 打开/关闭 bracketed paste、粘贴包、Ctrl+V、旁路表、`onNotice`、按新规则提交 |
|
|
146
|
-
| `src/tui/index.tsx` / `App.tsx` | `onSubmit` 改为 `SubmittedPrompt`;透传 `onNotice` |
|
|
147
|
-
| `src/tui-chat.ts` | 按 `display`/`content` 入列;斜杠判定见上;`onNotice` 走系统消息 |
|
|
148
|
-
| `src/tui/slash-handler.ts` | `/help` 快捷键增加 Ctrl+V 贴图、多行粘贴收成片段 |
|
|
149
|
-
| `README.md` | 中英快捷键各补一句 |
|
|
150
|
-
| `docs/API.md` | 不改(TUI 便利,协议不变) |
|
|
151
|
-
|
|
152
|
-
`/paste`、`/attach`、CLI `-i` 行为不变。
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
## 7. 测试
|
|
157
|
-
|
|
158
|
-
纯函数(`tests/paste-draft.test.ts`、`tests/bracketed-paste.test.ts`,必要时扩 `tests/caret-pos.test.ts`):
|
|
159
|
-
|
|
160
|
-
- 单行;`a\nb`;`a\nb\n` 去掉末尾换行后仍是两行片段;仅 `hello\n` → 单行插入
|
|
161
|
-
- 片段展开顺序:字 + 图 + 片段不错位;无图时 `content` 为字符串
|
|
162
|
-
- 删除码点后旁路表回收;清空后计数从 1 再起
|
|
163
|
-
- 超 1_000_000 码元拒绝;标记过宽时点击仍落在该码点
|
|
164
|
-
- bracketed paste 扫描:跨 chunk、内含 `\n`/`\r`、无结束符时保持缓冲
|
|
165
|
-
|
|
166
|
-
`InputBar` 不测 Ink 渲染。stdin 夹具覆盖:粘贴多行不提交;粘贴中的 `useInput` 碎片不插入。
|
|
167
|
-
|
|
168
|
-
## 错误文案
|
|
169
|
-
|
|
170
|
-
| 情况 | 文案 |
|
|
171
|
-
|------|------|
|
|
172
|
-
| 图片 > 5MB | `图片超过 5MB,未附加` |
|
|
173
|
-
| 片段 > 1_000_000 码元 | `粘贴内容过大,未附加` |
|
|
174
|
-
| Ctrl+V 无图 | (无文案) |
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# 思考线协议适配 — 设计文档
|
|
2
|
-
|
|
3
|
-
**日期:** 2026-08-23
|
|
4
|
-
**状态:** 已批准(启发式 + 400 改参重试并缓存)
|
|
5
|
-
|
|
6
|
-
## 问题
|
|
7
|
-
|
|
8
|
-
用户配置是统一的 `off | low | medium | high | max`,但上游 chat 请求的思考字段因模型和网关而异。min-agent 目前一律发送:
|
|
9
|
-
|
|
10
|
-
```json
|
|
11
|
-
{ "reasoning_effort": "<档位>", "thinking": { "type": "enabled" | "disabled" } }
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
MiniMax-M3(经 Console Go 等网关)只接受 `thinking.type` 为 `adaptive` 或 `disabled`,收到 `enabled` 会 400。官方 OpenAI 则可能根本不认 `thinking` 对象。
|
|
15
|
-
|
|
16
|
-
模型目录(`models.lonae.com`)只提供上下文窗口和 effort 列表,**不提供** `thinking.type` 的合法取值。MiniMax-M3 的 `reasoningOptions` 甚至是空数组,目录查找成功也无法避免这次 400。
|
|
17
|
-
|
|
18
|
-
## 目标
|
|
19
|
-
|
|
20
|
-
1. 用户侧配置、`/think`、CLI `--think`、HTTP `/v1/thinking` 仍只用五档英文强度,不暴露 `adaptive` / `enabled` / `xhigh`
|
|
21
|
-
2. 发出请求前按 `(providerHost, modelId)` 选择线协议:启发式先发对
|
|
22
|
-
3. 若仍 400 且错误可解析为思考字段约束,静默改 profile、**同一请求只重试一次**,并把学到的 profile 写入本地缓存
|
|
23
|
-
4. 目录继续只负责窗口和档位列表;线协议与目录解耦
|
|
24
|
-
|
|
25
|
-
## 不做
|
|
26
|
-
|
|
27
|
-
- 不扩展 Lonae catalog schema
|
|
28
|
-
- 不把 `adaptive` 放进 `/think` 选择器或配置值
|
|
29
|
-
- 不为 MiniMax-M3 把选择器收成「开/关」(非 `off` 一律当开思考;档位无深度时仍发对应 `reasoning_effort`,由上游忽略)
|
|
30
|
-
- 不重试非思考类 400,不二次以上重试
|
|
31
|
-
- 不把 wire profile 写入 `config.json`
|
|
32
|
-
- 不改变 compaction、reasoning 流式折叠、TUI 思考块展示
|
|
33
|
-
|
|
34
|
-
## 设计决策
|
|
35
|
-
|
|
36
|
-
| 决策 | 结论 |
|
|
37
|
-
|------|------|
|
|
38
|
-
| 用户配置 | 仍是 `off\|low\|medium\|high\|max`;`thinkingEnabled = thinking !== "off"` |
|
|
39
|
-
| 线协议层 | 独立 wire profile,不塞进 Lonae 缓存条目 |
|
|
40
|
-
| 解析顺序 | 学习缓存 → 启发式 → 默认 `enabled-disabled` + `reasoning_effort` |
|
|
41
|
-
| 注入点 | 现有 `modelFetch` / `withThinkingBody`,可读写 URL 与 JSON body |
|
|
42
|
-
| 400 | 仅当 body 可解析为思考字段约束时改 profile 并重试一次;对用户静默 |
|
|
43
|
-
| 缓存文件 | `~/.min-agent/thinking-wire-cache.json`(`MIN_AGENT_CONFIG_DIR` 下同路径),TTL 7 天 |
|
|
44
|
-
| OpenAI 官方 | `provider.type === "openai"` → 不发 `thinking` 对象 |
|
|
45
|
-
| MiniMax | `modelId` 或 hostname 含 `minimax`(大小写不敏感)→ `adaptive-disabled` |
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
## 1. Wire profile
|
|
50
|
-
|
|
51
|
-
```ts
|
|
52
|
-
type ThinkingTypeMode = "enabled-disabled" | "adaptive-disabled" | "omit"
|
|
53
|
-
type EffortMode = "reasoning_effort" | "omit"
|
|
54
|
-
|
|
55
|
-
interface ThinkingWireProfile {
|
|
56
|
-
version: 1
|
|
57
|
-
thinkingType: ThinkingTypeMode
|
|
58
|
-
effort: EffortMode
|
|
59
|
-
timestamp: number
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
`applyThinkingToChatBody(body, spec, profile)`:
|
|
64
|
-
|
|
65
|
-
- `effort === "reasoning_effort"`:写 `reasoning_effort`(现有 `toWireEffort` 结果);`omit` 则删除该键
|
|
66
|
-
- `thinkingType === "omit"`:删除 `thinking`
|
|
67
|
-
- 否则写 `thinking.type`:开思考时 `enabled` 或 `adaptive`,关思考时 `disabled`
|
|
68
|
-
|
|
69
|
-
`ThinkingRequestBody` 仍表示用户意图(`reasoningEffort` + `thinkingEnabled`),不把 profile 放进 ALS。fetch 时用请求 URL 的 host 和 body 里的 `model` 解析 profile。
|
|
70
|
-
|
|
71
|
-
缓存键:`${hostname.toLowerCase()}::${modelId.toLowerCase()}`。hostname 从请求 URL 取;取不到则只用 `modelId`。
|
|
72
|
-
|
|
73
|
-
---
|
|
74
|
-
|
|
75
|
-
## 2. 启发式
|
|
76
|
-
|
|
77
|
-
在学习缓存未命中时:
|
|
78
|
-
|
|
79
|
-
1. `modelId` 或 hostname 包含 `minimax` → `{ thinkingType: "adaptive-disabled", effort: "reasoning_effort" }`
|
|
80
|
-
2. 当前 provider `type === "openai"` → `{ thinkingType: "omit", effort: "reasoning_effort" }`
|
|
81
|
-
3. 否则 → `{ thinkingType: "enabled-disabled", effort: "reasoning_effort" }`
|
|
82
|
-
|
|
83
|
-
启发式结果不写磁盘。只有 400 学到的 profile 才持久化,以便覆盖错误启发式。
|
|
84
|
-
|
|
85
|
-
`toWireEffort` 规则不变:`off` → `none`;`max` 仍按目录/`openai` 映射 `xhigh`。
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
## 3. 400 探测
|
|
90
|
-
|
|
91
|
-
仅处理 chat completions 的 JSON body 请求。流程:
|
|
92
|
-
|
|
93
|
-
1. 按当前 profile 注入后 `fetch`
|
|
94
|
-
2. 若 `response.ok` 或状态不是 400:原样返回(仍走现有 `foldReasoningInChatResponse`)
|
|
95
|
-
3. 读 400 body(`text()`)。用纯函数 `parseThinkingWireHint(text)` 得到对 profile 的补丁
|
|
96
|
-
4. 补丁相对当前 profile **有变化** 才更新内存+磁盘,用新 profile 重写 body,**重试一次**
|
|
97
|
-
5. 第二次无论成败都不再为思考字段重试;失败则把第二次响应交给 SDK(若第二次未发出,把第一次 400 用已读文本重建 `Response`)
|
|
98
|
-
|
|
99
|
-
`parseThinkingWireHint` 识别:
|
|
100
|
-
|
|
101
|
-
| 错误文本形态 | 补丁 |
|
|
102
|
-
|--------------|------|
|
|
103
|
-
| `thinking.type` 且 `allowed` 列表含 `adaptive` 与 `disabled` | `thinkingType: "adaptive-disabled"` |
|
|
104
|
-
| `thinking.type` 且 `allowed` 含 `enabled` 与 `disabled` | `thinkingType: "enabled-disabled"` |
|
|
105
|
-
| `Unknown parameter` / `unknown parameter` 指向 `thinking` | `thinkingType: "omit"` |
|
|
106
|
-
| 同上指向 `reasoning_effort` | `effort: "omit"` |
|
|
107
|
-
|
|
108
|
-
列表解析忽略大小写与空白。无法识别或补丁无变化 → 不重试。
|
|
109
|
-
|
|
110
|
-
并发:两个请求可能同时 400 再各写一次缓存,可接受,不引入锁。内存 Map + 磁盘与 `model-catalog` 相同模式。TTL 7 天;过期条目当未命中,可再次学习。`version !== 1` 的条目忽略。
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## 4. 错误与界面
|
|
115
|
-
|
|
116
|
-
重试对用户不可见:没有「改参」「adaptive」提示。两次都失败时沿用现有 `AI_APICallError` 展示。
|
|
117
|
-
|
|
118
|
-
`/think`、状态栏「思考 high」、HTTP `GET/POST /v1/thinking` 的字段与文案不变。
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## 5. 文档与测试
|
|
123
|
-
|
|
124
|
-
同步:
|
|
125
|
-
|
|
126
|
-
- `skills/self-config/SKILL.md`:请求按模型/网关映射 `thinking` / `reasoning_effort`,并提及学习缓存文件;不写探测实现细节
|
|
127
|
-
- `skills/self-config/reference.md`:环境变量表旁可注明缓存文件名(若该文件已列目录缓存)
|
|
128
|
-
- `docs/API.md`:用户可见 thinking 枚举不变;不必描述 wire 字段
|
|
129
|
-
- `README.md`:不增加线协议说明
|
|
130
|
-
- `/help`:不改
|
|
131
|
-
|
|
132
|
-
测试(纯函数 + fetch 包装):
|
|
133
|
-
|
|
134
|
-
- `applyThinkingToChatBody` 三种 `thinkingType` × 开/关、`effort` omit
|
|
135
|
-
- 启发式:minimax 模型名、minimax host、openai type、默认
|
|
136
|
-
- `parseThinkingWireHint`:本次 MiniMax 原文、unknown parameter、无法识别
|
|
137
|
-
- fetch:400 可解析 → 第二次请求 body 已改且只发两次;不可解析 → 只发一次
|
|
138
|
-
- 缓存读写、过期、version 不匹配
|
|
139
|
-
|
|
140
|
-
实现落点:`src/thinking.ts` 扩展拼 body 与 hint 解析;新建 `src/thinking-wire.ts`(profile 解析、启发式、缓存)以免 `thinking.ts` 再膨胀;`src/provider.ts` 的 `modelFetch` 接 400 重试。测试放 `tests/thinking.test.ts` 与 `tests/thinking-wire.test.ts`。
|