dominds 1.27.3 → 1.27.5
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/dist/dialog-fork.js +2 -1
- package/dist/dialog.d.ts +3 -3
- package/dist/dialog.js +7 -4
- package/dist/docs/dialog-system.md +4 -4
- package/dist/docs/dialog-system.zh.md +4 -4
- package/dist/docs/diligence-push.md +6 -3
- package/dist/docs/diligence-push.zh.md +1 -1
- package/dist/llm/api-quirks.d.ts +1 -0
- package/dist/llm/api-quirks.js +3 -1
- package/dist/llm/defaults.yaml +8 -4
- package/dist/llm/gen/openai-compatible.js +14 -1
- package/dist/llm/kernel-driver/drive.js +67 -40
- package/dist/llm/kernel-driver/tellask-special.js +2 -2
- package/dist/mcp/supervisor.js +4 -1
- package/dist/minds/system-prompt-parts.js +30 -30
- package/dist/minds/system-prompt.js +6 -4
- package/dist/persistence.js +65 -16
- package/dist/priming.js +2 -3
- package/dist/runtime/driver-messages.js +42 -28
- package/dist/runtime/reply-prompt-copy.js +6 -5
- package/dist/server/websocket-handler.js +3 -3
- package/dist/shared-reminders.js +2 -2
- package/dist/tool.d.ts +7 -4
- package/dist/tool.js +10 -4
- package/dist/tools/app-reminders.js +4 -3
- package/dist/tools/ctrl.js +4 -1
- package/dist/tools/pending-tellask-reminder.js +1 -0
- package/dist/tools/prompts/control/en/index.md +3 -3
- package/dist/tools/prompts/control/en/principles.md +4 -4
- package/dist/tools/prompts/control/en/scenarios.md +10 -3
- package/dist/tools/prompts/control/en/tools.md +4 -4
- package/dist/tools/prompts/control/zh/index.md +3 -3
- package/dist/tools/prompts/control/zh/principles.md +4 -4
- package/dist/tools/prompts/control/zh/scenarios.md +10 -3
- package/dist/tools/prompts/control/zh/tools.md +4 -4
- package/dist/tools/team_mgmt-manual.js +2 -2
- package/package.json +4 -4
- package/webapp/package.json +0 -1
package/dist/dialog-fork.js
CHANGED
|
@@ -483,9 +483,10 @@ async function appendForkBaselineState(plan, baselineSideDialogCreatedRecords) {
|
|
|
483
483
|
ownerName: reminder.owner?.name,
|
|
484
484
|
meta: reminder.meta,
|
|
485
485
|
echoback: reminder.echoback,
|
|
486
|
-
scope: reminder.scope
|
|
486
|
+
scope: reminder.scope,
|
|
487
487
|
createdAt: reminder.createdAt ?? baselineTs,
|
|
488
488
|
priority: reminder.priority ?? 'medium',
|
|
489
|
+
renderMode: reminder.renderMode,
|
|
489
490
|
})),
|
|
490
491
|
};
|
|
491
492
|
const q4hRecord = {
|
package/dist/dialog.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ import { ChatMessage, FuncResultMsg, TellaskCarryoverMsg, TellaskResultMsg } fro
|
|
|
21
21
|
import type { ToolResultImageIngest, UserImageIngest } from './llm/gen';
|
|
22
22
|
import { type SharedReminderTarget } from './shared-reminders';
|
|
23
23
|
import type { JsonValue } from './tool';
|
|
24
|
-
import { Reminder, ReminderOptions, ReminderOwner } from './tool';
|
|
24
|
+
import { Reminder, ReminderOptions, ReminderOwner, ReminderUpdateOptions } from './tool';
|
|
25
25
|
export declare class InvalidReminderIndexError extends Error {
|
|
26
26
|
readonly index: number;
|
|
27
27
|
readonly total: number;
|
|
@@ -265,9 +265,9 @@ export declare abstract class Dialog {
|
|
|
265
265
|
* Post a dialog event using the standard event registry.
|
|
266
266
|
*/
|
|
267
267
|
postEvent(event: DialogEvent): void;
|
|
268
|
-
addReminder(content: string, owner
|
|
268
|
+
addReminder(content: string, owner: ReminderOwner | undefined, meta: JsonValue | undefined, position: number | undefined, options: ReminderOptions): Reminder;
|
|
269
269
|
deleteReminder(index: number): Reminder;
|
|
270
|
-
updateReminder(index: number, content: string, meta?: JsonValue, options?:
|
|
270
|
+
updateReminder(index: number, content: string, meta?: JsonValue, options?: ReminderUpdateOptions): Reminder;
|
|
271
271
|
clearReminders(): void;
|
|
272
272
|
listVisibleReminderTargets(): Promise<VisibleReminderTarget[]>;
|
|
273
273
|
listVisibleReminders(): Promise<Reminder[]>;
|
package/dist/dialog.js
CHANGED
|
@@ -478,13 +478,16 @@ class Dialog {
|
|
|
478
478
|
//
|
|
479
479
|
// Reminder management methods
|
|
480
480
|
addReminder(content, owner, meta, position, options) {
|
|
481
|
+
if (options === undefined) {
|
|
482
|
+
throw new Error('Dialog.addReminder requires explicit reminder options');
|
|
483
|
+
}
|
|
481
484
|
const reminder = (0, tool_1.materializeReminder)({
|
|
482
485
|
content,
|
|
483
486
|
owner,
|
|
484
487
|
meta,
|
|
485
|
-
echoback: options
|
|
486
|
-
scope: options
|
|
487
|
-
renderMode: options
|
|
488
|
+
echoback: options.echoback,
|
|
489
|
+
scope: options.scope,
|
|
490
|
+
renderMode: options.renderMode,
|
|
488
491
|
});
|
|
489
492
|
const insertIndex = position !== undefined ? position : this.reminders.length;
|
|
490
493
|
if (insertIndex < 0 || insertIndex > this.reminders.length) {
|
|
@@ -651,7 +654,7 @@ class Dialog {
|
|
|
651
654
|
renderRevision: (0, tool_1.computeReminderRenderRevision)(r),
|
|
652
655
|
echoback: (0, tool_1.reminderEchoBackEnabled)(r),
|
|
653
656
|
scope: r.scope,
|
|
654
|
-
renderMode: r.renderMode
|
|
657
|
+
renderMode: r.renderMode,
|
|
655
658
|
}));
|
|
656
659
|
}
|
|
657
660
|
emitFullRemindersUpdate(reminders) {
|
|
@@ -159,21 +159,21 @@ This ensures crash recovery and enables the backend to resume from any persisted
|
|
|
159
159
|
|
|
160
160
|
When a dialog still carries an inter-dialog reply obligation, but the user temporarily interjects and asks it to handle a local question first, the system must distinguish between the **UI projection** and the **true driving source state**.
|
|
161
161
|
|
|
162
|
-
Plainly: the system should answer the user's interjection first. Once the user receives a visible answer, the backend records that answer as A2H (Answer to Human) in Human Attention so the user can find and acknowledge it even if the dialog immediately continues automatically. In addition to recovering A2H from visible `saying`, the LLM may also produce structured `answering` output (or call the equivalent `answerHuman` tool entry) to create A2H directly.
|
|
162
|
+
Plainly: the system should answer the user's interjection first. Once the user receives a visible answer, the backend records that answer as A2H (Answer to Human) in Human Attention so the user can find and acknowledge it even if the dialog immediately continues automatically. In addition to recovering A2H from visible `saying`, the LLM may also produce structured `answering` output (or call the equivalent `answerHuman` tool entry) to create A2H directly. A2H may also carry a human-facing status explanation when the expected action is to stop and wait, such as while pending active callees are still running.
|
|
163
163
|
|
|
164
164
|
**Normative semantics**:
|
|
165
165
|
|
|
166
166
|
1. Every user interjection message is driven as a complete normal round.
|
|
167
167
|
2. If that round needs tools, the system MUST finish the full tool round and any post-tool follow-up before treating the interjection as answered.
|
|
168
168
|
3. A visible assistant `saying` settles the pending user-interjection reply only when no same-round function/tellask call remains after that `saying`.
|
|
169
|
-
4. The model may also produce structured `answering` output (or call `answerHuman({ answerContent })`) to express "this is an answer for the human." That output is always appended to the dialog's `a2h.yaml`, but it is not the same thing as a Side Dialog's formal reply to its requester.
|
|
169
|
+
4. The model may also produce structured `answering` output (or call `answerHuman({ answerContent })`) to express "this is an answer or status for the human." That output is always appended to the dialog's `a2h.yaml`, but it is not the same thing as a Side Dialog's formal reply to its requester.
|
|
170
170
|
5. If an inter-dialog reply obligation still exists after the interjection is answered, it remains ordinary durable reply-obligation state. Subsequent continuation is driven by the normal business paths: queued prompts, reply reminders, diligence push, or explicit resume when the dialog is genuinely blocked.
|
|
171
|
-
6. A2H disappears when the user acknowledges it. This is intentionally "read then burn"; `answerRef` only links back to the course/genseq that produced the
|
|
171
|
+
6. A2H disappears when the user acknowledges it. This is intentionally "read then burn"; `answerRef` only links back to the course/genseq that produced the A2H item. When A2H comes from visible `saying`, the canonical text remains in the transcript; when it comes from structured `answering`, the A2H item itself carries that one-way output text.
|
|
172
172
|
7. The Human Attention panel shows Q4H and A2H together. Q4H waits for a human answer; A2H waits only for human acknowledgement.
|
|
173
173
|
|
|
174
174
|
**Strict boundary**: a formal `askHuman` answer is not part of this "user interjection" category. As soon as a prompt carries a real `q4hAnswerCallId`, it belongs to the askHuman reply channel and semantically continues an already-materialized question/answer chain; it must never be downgraded into temporary local side-chat.
|
|
175
175
|
|
|
176
|
-
**Modeling boundary**: Dominds does not structurally model "current human question context", does not maintain coordinates for "which human question this A2H
|
|
176
|
+
**Modeling boundary**: Dominds does not structurally model "current human question context", does not maintain coordinates for "which human question or status boundary this A2H addresses", and does not store `userInterjection` coordinates in A2H. `a2h` / `answering` is only one-way structured modeling at the LLM output layer: the model produced text meant for the human, and the runtime put it into the human-acknowledgement queue. Questions, interjections, wait boundaries, task obligations, and continuation duties remain represented by existing business facts such as prompts, Q4H, reply obligations, active callees, and queued prompts.
|
|
177
177
|
|
|
178
178
|
**Key point**: pending user-interjection reply and inter-dialog reply obligation are independent business facts. Reminder/footer copy can use those two facts directly: if the interjection is still pending, prioritize answering the user; if it is settled and the reply obligation remains active, continue toward the required inter-dialog closure.
|
|
179
179
|
|
|
@@ -158,21 +158,21 @@ askerDialog 可以在执行期间接收来自当前需向它回复的支线对
|
|
|
158
158
|
|
|
159
159
|
当某个对话仍带有跨对话回复义务,但用户临时插话要求它先处理本地问题时,系统必须区分**UI 投影**与**真实驱动源状态**。
|
|
160
160
|
|
|
161
|
-
直白地说:先把用户这次插话接住并答完。用户看到可见答复后,后端把这条答复记录成 A2H(Answer to Human)放进“待人处理”,这样即使对话马上自动续推,用户也能找到并确认已阅。除了从可见 `saying` 恢复 A2H 之外,LLM 还可以产生结构化 `answering` 输出(或调用等价的 `answerHuman` 工具入口)直接形成 A2H
|
|
161
|
+
直白地说:先把用户这次插话接住并答完。用户看到可见答复后,后端把这条答复记录成 A2H(Answer to Human)放进“待人处理”,这样即使对话马上自动续推,用户也能找到并确认已阅。除了从可见 `saying` 恢复 A2H 之外,LLM 还可以产生结构化 `answering` 输出(或调用等价的 `answerHuman` 工具入口)直接形成 A2H。当预期动作是停下来等待时,A2H 也可以承载给人类看的状态说明,例如仍有 pending active callees 在运行。
|
|
162
162
|
|
|
163
163
|
**规范语义**:
|
|
164
164
|
|
|
165
165
|
1. 每条用户插话消息都按正常驱动轮完整执行。
|
|
166
166
|
2. 若该轮需要工具,则必须先完整跑完该工具轮及其 post-tool follow-up,之后才可认为插话已答完。
|
|
167
167
|
3. 只有当模型产生可见 `saying`,且该 `saying` 后同轮没有普通 function/tellask call 继续挂起时,才用这条 `saying` 结算“待回复用户插话”。
|
|
168
|
-
4. 模型也可以产生结构化 `answering` 输出(或调用 `answerHuman({ answerContent })
|
|
168
|
+
4. 模型也可以产生结构化 `answering` 输出(或调用 `answerHuman({ answerContent })`)来表达“这是给人类看的答复或状态说明”。该输出无条件追加到该对话的 `a2h.yaml`,但它不等价于支线对话对诉请者的正式回贴。
|
|
169
169
|
5. 如果插话答完后仍有跨对话回复义务,它保持为普通的 durable reply-obligation 状态;后续由正常业务路径推进:queued prompt、回贴提醒、鞭策续推,或在对话确实阻塞时由显式 resume 触发。
|
|
170
|
-
6. 用户 Ack 以后 A2H 立即消失,语义是“阅后即焚”;`answerRef`
|
|
170
|
+
6. 用户 Ack 以后 A2H 立即消失,语义是“阅后即焚”;`answerRef` 只回链到产生该 A2H 条目的 course/genseq,用于定位来源生成轮。若 A2H 来自可见 `saying`,正文真源仍在 transcript 中;若来自结构化 `answering`,A2H 条目本身承载该单向输出正文。
|
|
171
171
|
7. “待人处理”面板同时显示 Q4H 与 A2H:Q4H 等人回答,A2H 只等人确认已阅。
|
|
172
172
|
|
|
173
173
|
**严格边界**:`askHuman` 的正式回答不属于这里的“用户插话”。只要一条 prompt 带着真实的 `q4hAnswerCallId`,它就属于 askHuman 回复通道,语义上是在继续已 materialize 的提问/应答链路,绝不能被压入“本地临时插话聊天”。
|
|
174
174
|
|
|
175
|
-
**建模边界**:Dominds 不对“当前人类问题上下文”做结构化业务建模,不维护“这个 A2H
|
|
175
|
+
**建模边界**:Dominds 不对“当前人类问题上下文”做结构化业务建模,不维护“这个 A2H 对应哪一个人类问题或等待边界”的坐标,也不把 `userInterjection` 坐标写进 A2H。`a2h` / `answering` 只是 LLM 输出层面的单向结构化建模:模型产生一段给人类看的文本,运行时把它放入待人确认队列。问题/插话/等待边界/任务义务本身仍由既有 prompt、Q4H、reply obligation、active callees、queued prompt 等业务事实表达。
|
|
176
176
|
|
|
177
177
|
**关键点**:“是否还有用户插话待可见回复”和“是否还有跨对话回复义务”是两个独立业务事实。提醒项 footer 可以直接用这两个事实定制:插话尚未答复时优先答人;插话已答复且回复义务仍 active 时,继续按跨对话回贴要求收口。
|
|
178
178
|
|
|
@@ -21,9 +21,12 @@ This document specifies two related runtime controls:
|
|
|
21
21
|
- **Required tool-use control**: for ordinary main and side dialog rounds, the Diligence Push
|
|
22
22
|
checkbox controls whether the provider request must end through a Dominds tool call. When checked,
|
|
23
23
|
the model is expected to call a tool such as `askHuman`, `tellask*`, `replyTellask*`, or another
|
|
24
|
-
runtime-provided function instead of stopping with a plain-text question/final answer.
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
runtime-provided function instead of stopping with a plain-text question/final answer. If no
|
|
25
|
+
substantive tool should be called, `answerHuman` is the expected completion path for that required
|
|
26
|
+
tool round. This is intentional for wait boundaries such as pending active callees: the model
|
|
27
|
+
should explain the wait state through `answerHuman` and then stop for the reply to arrive, rather
|
|
28
|
+
than continue spinning through ordinary tool calls. FBR middle rounds are the intentional
|
|
29
|
+
exception: they may run with no callable tools; FBR closure requires one of the conclusion tools.
|
|
27
30
|
|
|
28
31
|
## Goals
|
|
29
32
|
|
|
@@ -12,7 +12,7 @@ Dominds 主线对话旨在长期运行。主线对话"停止"(变为空闲)
|
|
|
12
12
|
本文档指定两个相关但不同的运行时控制:
|
|
13
13
|
|
|
14
14
|
- **自动续推注入**:仅针对**主线对话**,当驱动程序即将停止、且没有 Q4H 或 pending active callee dispatch 时,运行时会自动发送一个简短的鞭策语(渲染为正常的用户气泡)并继续生成。pending tellask 是后台被诉请者事实,不是阻塞态;但在没有其它具体驱动来源时,它表示主线已经到达可 idle 的后台等待边界,不应靠鞭策语保持主线空转。
|
|
15
|
-
- **强制工具调用控制**:对于普通的主线/支线对话轮次,`鞭策` 勾选项控制本轮 provider 请求是否必须通过 Dominds 工具结束。勾选时,模型应通过 `askHuman`、`tellask*`、`replyTellask*`
|
|
15
|
+
- **强制工具调用控制**:对于普通的主线/支线对话轮次,`鞭策` 勾选项控制本轮 provider 请求是否必须通过 Dominds 工具结束。勾选时,模型应通过 `askHuman`、`tellask*`、`replyTellask*` 或其他运行时函数完成这一轮,而不是用普通文本直接收尾。若确实没有其它实质工具应调用,`answerHuman` 就是该强制工具轮次的预期收口路径。等待 pending active callees 这类边界属于预期场景:模型应通过 `answerHuman` 说明当前等待状态,然后停止等待回贴到达,而不是继续调用普通工具空转。FBR 中间轮是刻意例外:它们可以处于无可调用工具状态;FBR 收口阶段则必须调用两个结论工具之一。
|
|
16
16
|
|
|
17
17
|
## 目标
|
|
18
18
|
|
package/dist/llm/api-quirks.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { LlmRetryStrategy } from './gen';
|
|
|
5
5
|
export type LlmFailureKind = 'retriable' | 'rejected' | 'fatal';
|
|
6
6
|
export declare const KIMI_CODE_API_QUIRK = "kimi-code";
|
|
7
7
|
export declare const MINIMAX_REASONING_DETAILS_API_QUIRK = "minimax-reasoning-details";
|
|
8
|
+
export declare const MINIMAX_THINKING_TYPE_API_QUIRK = "minimax-thinking-type";
|
|
8
9
|
export declare const SAME_CONTEXT_EMPTY_RESPONSE_API_QUIRK = "same-context-empty-response";
|
|
9
10
|
export declare const VOLCENGINE_INVALID_PARAMETER_AGGRESSIVE_RETRY_API_QUIRK = "volcengine-invalid-parameter-aggressive-retry";
|
|
10
11
|
export type LlmFailureSummary = {
|
package/dist/llm/api-quirks.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.XCODE_BEST_STREAM_INTERNAL_ERROR_CODE = exports.VOLCENGINE_INVALID_PARAMETER_AGGRESSIVE_RETRY_API_QUIRK = exports.SAME_CONTEXT_EMPTY_RESPONSE_API_QUIRK = exports.MINIMAX_REASONING_DETAILS_API_QUIRK = exports.KIMI_CODE_API_QUIRK = void 0;
|
|
3
|
+
exports.XCODE_BEST_STREAM_INTERNAL_ERROR_CODE = exports.VOLCENGINE_INVALID_PARAMETER_AGGRESSIVE_RETRY_API_QUIRK = exports.SAME_CONTEXT_EMPTY_RESPONSE_API_QUIRK = exports.MINIMAX_THINKING_TYPE_API_QUIRK = exports.MINIMAX_REASONING_DETAILS_API_QUIRK = exports.KIMI_CODE_API_QUIRK = void 0;
|
|
4
4
|
exports.normalizeProviderApiQuirks = normalizeProviderApiQuirks;
|
|
5
5
|
exports.createLlmFailureQuirkHandlerSession = createLlmFailureQuirkHandlerSession;
|
|
6
6
|
const persistence_errors_1 = require("../persistence-errors");
|
|
7
7
|
exports.KIMI_CODE_API_QUIRK = 'kimi-code';
|
|
8
8
|
exports.MINIMAX_REASONING_DETAILS_API_QUIRK = 'minimax-reasoning-details';
|
|
9
|
+
// MiniMax's `/v1` API rejects `thinking.type: 'enabled'`; rewrites the request `thinking` form to use `adaptive` instead.
|
|
10
|
+
exports.MINIMAX_THINKING_TYPE_API_QUIRK = 'minimax-thinking-type';
|
|
9
11
|
exports.SAME_CONTEXT_EMPTY_RESPONSE_API_QUIRK = 'same-context-empty-response';
|
|
10
12
|
exports.VOLCENGINE_INVALID_PARAMETER_AGGRESSIVE_RETRY_API_QUIRK = 'volcengine-invalid-parameter-aggressive-retry';
|
|
11
13
|
const DOMINDS_LLM_EMPTY_RESPONSE_ERROR_CODE = 'DOMINDS_LLM_EMPTY_RESPONSE';
|
package/dist/llm/defaults.yaml
CHANGED
|
@@ -177,6 +177,7 @@ providers:
|
|
|
177
177
|
apiType: openai-compatible
|
|
178
178
|
apiQuirks:
|
|
179
179
|
- minimax-reasoning-details
|
|
180
|
+
- minimax-thinking-type
|
|
180
181
|
baseUrl: https://api.minimaxi.com/v1
|
|
181
182
|
apiKeyEnvVar: MINIMAX_CN_TP_API_KEY
|
|
182
183
|
tech_spec_url: https://platform.minimaxi.com/docs/api-reference/text-openai-api
|
|
@@ -186,7 +187,7 @@ providers:
|
|
|
186
187
|
thinking:
|
|
187
188
|
prominent: true
|
|
188
189
|
type: boolean|object
|
|
189
|
-
description: OpenAI-compatible MiniMax thinking control. Set true to send thinking.type=
|
|
190
|
+
description: OpenAI-compatible MiniMax thinking control. Set true to send thinking.type=adaptive, false to send thinking.type=disabled, or provide the provider-specific thinking object documented by MiniMax. Leave unset to use the provider/model default.
|
|
190
191
|
reasoning_split:
|
|
191
192
|
prominent: true
|
|
192
193
|
type: boolean
|
|
@@ -245,6 +246,7 @@ providers:
|
|
|
245
246
|
apiType: openai-compatible
|
|
246
247
|
apiQuirks:
|
|
247
248
|
- minimax-reasoning-details
|
|
249
|
+
- minimax-thinking-type
|
|
248
250
|
baseUrl: https://api.minimaxi.com/v1
|
|
249
251
|
apiKeyEnvVar: MINIMAX_CN_API_KEY
|
|
250
252
|
tech_spec_url: https://platform.minimaxi.com/docs/api-reference/text-openai-api
|
|
@@ -254,7 +256,7 @@ providers:
|
|
|
254
256
|
thinking:
|
|
255
257
|
prominent: true
|
|
256
258
|
type: boolean|object
|
|
257
|
-
description: OpenAI-compatible MiniMax thinking control. Set true to send thinking.type=
|
|
259
|
+
description: OpenAI-compatible MiniMax thinking control. Set true to send thinking.type=adaptive, false to send thinking.type=disabled, or provide the provider-specific thinking object documented by MiniMax. Leave unset to use the provider/model default.
|
|
258
260
|
reasoning_split:
|
|
259
261
|
prominent: true
|
|
260
262
|
type: boolean
|
|
@@ -313,6 +315,7 @@ providers:
|
|
|
313
315
|
apiType: openai-compatible
|
|
314
316
|
apiQuirks:
|
|
315
317
|
- minimax-reasoning-details
|
|
318
|
+
- minimax-thinking-type
|
|
316
319
|
baseUrl: https://api.minimax.io/v1
|
|
317
320
|
apiKeyEnvVar: MINIMAX_TP_API_KEY
|
|
318
321
|
tech_spec_url: https://platform.minimax.io/docs/api-reference/text-openai-api
|
|
@@ -322,7 +325,7 @@ providers:
|
|
|
322
325
|
thinking:
|
|
323
326
|
prominent: true
|
|
324
327
|
type: boolean|object
|
|
325
|
-
description: OpenAI-compatible MiniMax thinking control. Set true to send thinking.type=
|
|
328
|
+
description: OpenAI-compatible MiniMax thinking control. Set true to send thinking.type=adaptive, false to send thinking.type=disabled, or provide the provider-specific thinking object documented by MiniMax. Leave unset to use the provider/model default.
|
|
326
329
|
reasoning_split:
|
|
327
330
|
prominent: true
|
|
328
331
|
type: boolean
|
|
@@ -381,6 +384,7 @@ providers:
|
|
|
381
384
|
apiType: openai-compatible
|
|
382
385
|
apiQuirks:
|
|
383
386
|
- minimax-reasoning-details
|
|
387
|
+
- minimax-thinking-type
|
|
384
388
|
baseUrl: https://api.minimax.io/v1
|
|
385
389
|
apiKeyEnvVar: MINIMAX_API_KEY
|
|
386
390
|
tech_spec_url: https://platform.minimax.io/docs/api-reference/text-openai-api
|
|
@@ -390,7 +394,7 @@ providers:
|
|
|
390
394
|
thinking:
|
|
391
395
|
prominent: true
|
|
392
396
|
type: boolean|object
|
|
393
|
-
description: OpenAI-compatible MiniMax thinking control. Set true to send thinking.type=
|
|
397
|
+
description: OpenAI-compatible MiniMax thinking control. Set true to send thinking.type=adaptive, false to send thinking.type=disabled, or provide the provider-specific thinking object documented by MiniMax. Leave unset to use the provider/model default.
|
|
394
398
|
reasoning_split:
|
|
395
399
|
prominent: true
|
|
396
400
|
type: boolean
|
|
@@ -641,6 +641,11 @@ function isMiniMaxReasoningDetailsProvider(providerConfig) {
|
|
|
641
641
|
return false;
|
|
642
642
|
return (0, api_quirks_1.normalizeProviderApiQuirks)(providerConfig).has(api_quirks_1.MINIMAX_REASONING_DETAILS_API_QUIRK);
|
|
643
643
|
}
|
|
644
|
+
function isMiniMaxThinkingTypeProvider(providerConfig) {
|
|
645
|
+
if (providerConfig === undefined)
|
|
646
|
+
return false;
|
|
647
|
+
return (0, api_quirks_1.normalizeProviderApiQuirks)(providerConfig).has(api_quirks_1.MINIMAX_THINKING_TYPE_API_QUIRK);
|
|
648
|
+
}
|
|
644
649
|
function isKimiCodeReasoningEffort(value) {
|
|
645
650
|
return typeof value === 'string' && KIMI_CODE_REASONING_EFFORTS.has(value);
|
|
646
651
|
}
|
|
@@ -841,7 +846,15 @@ function buildOpenAiCompatibleExtraParams(args) {
|
|
|
841
846
|
if (thinking === undefined && reasoningEffort === undefined && reasoningSplit === undefined) {
|
|
842
847
|
return {};
|
|
843
848
|
}
|
|
844
|
-
|
|
849
|
+
// `thinking` is narrowed to `boolean | Record<string, unknown> | undefined` because the
|
|
850
|
+
// `string` branch threw above. MiniMax rejects `type: 'enabled'`; rewrite both the
|
|
851
|
+
// boolean true form and the explicit object form to `adaptive`.
|
|
852
|
+
const isMiniMaxThinkingType = isMiniMaxThinkingTypeProvider(args.providerConfig);
|
|
853
|
+
const thinkingPayload = typeof thinking === 'boolean'
|
|
854
|
+
? { type: thinking ? (isMiniMaxThinkingType ? 'adaptive' : 'enabled') : 'disabled' }
|
|
855
|
+
: thinking !== undefined && isMiniMaxThinkingType && thinking.type === 'enabled'
|
|
856
|
+
? { ...thinking, type: 'adaptive' }
|
|
857
|
+
: thinking;
|
|
845
858
|
return {
|
|
846
859
|
...(thinkingPayload !== undefined ? { thinking: thinkingPayload } : {}),
|
|
847
860
|
...(reasoningEffort !== undefined ? { reasoning_effort: reasoningEffort } : {}),
|
|
@@ -359,38 +359,41 @@ async function maybeResolveAnsweredUserInterjection(args) {
|
|
|
359
359
|
return undefined;
|
|
360
360
|
}
|
|
361
361
|
const course = args.dlg.activeGenCourseOrUndefined ?? args.dlg.currentCourse;
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
},
|
|
377
|
-
};
|
|
378
|
-
const existingAnswers = await persistence_1.DialogPersistence.loadAnswersToHumanState(args.dlg.id, args.dlg.status);
|
|
379
|
-
if (!existingAnswers.some((item) => item.id === answer.id)) {
|
|
380
|
-
await persistence_1.DialogPersistence.appendAnswerToHumanState(args.dlg.id, answer, args.dlg.status);
|
|
381
|
-
const metadata = await persistence_1.DialogPersistence.loadDialogMetadata(args.dlg.id, args.dlg.status);
|
|
382
|
-
const taskDocPath = metadata?.taskDocPath ?? args.dlg.taskDocPath ?? '';
|
|
383
|
-
const event = {
|
|
384
|
-
type: 'new_a2h_answered',
|
|
385
|
-
answer: {
|
|
386
|
-
...answer,
|
|
387
|
-
selfId: args.dlg.id.selfId,
|
|
388
|
-
rootId: args.dlg.id.rootId,
|
|
389
|
-
agentId: metadata?.agentId ?? args.dlg.agentId,
|
|
390
|
-
taskDocPath,
|
|
362
|
+
const answer = args.recordAnswerToHuman
|
|
363
|
+
? {
|
|
364
|
+
id: `a2h-${Buffer.from([
|
|
365
|
+
args.dlg.id.rootId,
|
|
366
|
+
args.dlg.id.selfId,
|
|
367
|
+
`c${String(course)}`,
|
|
368
|
+
`g${String(args.assistantSayingGenseq)}`,
|
|
369
|
+
pending.msgId,
|
|
370
|
+
].join('|')).toString('base64url')}`,
|
|
371
|
+
content: args.assistantSayingContent,
|
|
372
|
+
answeredAt: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
373
|
+
answerRef: {
|
|
374
|
+
course,
|
|
375
|
+
genseq: args.assistantSayingGenseq,
|
|
391
376
|
},
|
|
392
|
-
}
|
|
393
|
-
|
|
377
|
+
}
|
|
378
|
+
: undefined;
|
|
379
|
+
if (answer !== undefined) {
|
|
380
|
+
const existingAnswers = await persistence_1.DialogPersistence.loadAnswersToHumanState(args.dlg.id, args.dlg.status);
|
|
381
|
+
if (!existingAnswers.some((item) => item.id === answer.id)) {
|
|
382
|
+
await persistence_1.DialogPersistence.appendAnswerToHumanState(args.dlg.id, answer, args.dlg.status);
|
|
383
|
+
const metadata = await persistence_1.DialogPersistence.loadDialogMetadata(args.dlg.id, args.dlg.status);
|
|
384
|
+
const taskDocPath = metadata?.taskDocPath ?? args.dlg.taskDocPath ?? '';
|
|
385
|
+
const event = {
|
|
386
|
+
type: 'new_a2h_answered',
|
|
387
|
+
answer: {
|
|
388
|
+
...answer,
|
|
389
|
+
selfId: args.dlg.id.selfId,
|
|
390
|
+
rootId: args.dlg.id.rootId,
|
|
391
|
+
agentId: metadata?.agentId ?? args.dlg.agentId,
|
|
392
|
+
taskDocPath,
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
(0, evt_registry_1.postDialogEvent)(args.dlg, event);
|
|
396
|
+
}
|
|
394
397
|
}
|
|
395
398
|
await persistence_1.DialogPersistence.mutateDialogLatest(args.dlg.id, (previous) => {
|
|
396
399
|
const previousPending = previous.pendingUserInterjectionReply;
|
|
@@ -437,7 +440,7 @@ function resolveToolUseRequirement(dlg, policy) {
|
|
|
437
440
|
// For ordinary Dominds dialog rounds, the Diligence Push checkbox controls the provider-level
|
|
438
441
|
// obligation directly. The numeric Diligence Push budget only limits automatic runtime prompts;
|
|
439
442
|
// it must not downgrade the round into ordinary chat where the model can stop by asking/answering
|
|
440
|
-
// in plain text instead of calling askHuman/tellask/reply tools.
|
|
443
|
+
// in plain text instead of calling askHuman/answerHuman/tellask/reply tools.
|
|
441
444
|
return dlg.disableDiligencePush ? 'auto' : 'required';
|
|
442
445
|
}
|
|
443
446
|
function resolveModelInfo(providerCfg, model) {
|
|
@@ -746,7 +749,7 @@ const TELLASK_SPECIAL_VIRTUAL_TOOLS = [
|
|
|
746
749
|
type: 'func',
|
|
747
750
|
name: 'answerHuman',
|
|
748
751
|
followupMode: 'deferred',
|
|
749
|
-
description: 'Record the current human-facing answer for human attention.',
|
|
752
|
+
description: 'Record the current human-facing answer or status for human attention. Use this to finish the current required-tool round when no other substantive tool should be called, especially to explain that this dialog is waiting for pending active callees or tellask replies.',
|
|
750
753
|
parameters: {
|
|
751
754
|
type: 'object',
|
|
752
755
|
properties: {
|
|
@@ -778,7 +781,7 @@ function formatContextHealthLargeToolReturnUnavailable(args) {
|
|
|
778
781
|
'',
|
|
779
782
|
'不要再尝试获取各种大段的输出,都不会显示给你。现在先做两件事:',
|
|
780
783
|
'1. 把需要回传给主线对话的结论、证据定位和风险整理清楚。',
|
|
781
|
-
'2.
|
|
784
|
+
'2. 用当前对话范围(scope=dialog)提醒项写明本路对话任务目标,并把下一程恢复当前支线工作需要的信息带过桥。',
|
|
782
785
|
'',
|
|
783
786
|
'然后调用 clear_mind({}) 开启新一程,并尽快完成当前支线回复。',
|
|
784
787
|
'',
|
|
@@ -790,7 +793,7 @@ function formatContextHealthLargeToolReturnUnavailable(args) {
|
|
|
790
793
|
'',
|
|
791
794
|
'不要再尝试获取各种大段的输出,都不会显示给你。现在先做两件事:',
|
|
792
795
|
'1. 把下一程对话需要知道的此程细节信息写入差遣牒合适章节。',
|
|
793
|
-
'2.
|
|
796
|
+
'2. 对于不适合差遣牒章节覆盖、但下一程恢复当前对话需要的信息,用当前对话范围(scope=dialog)提醒项写明本路对话任务目标并带过桥。',
|
|
794
797
|
'',
|
|
795
798
|
'然后调用 clear_mind({}) 开启新一程。',
|
|
796
799
|
'',
|
|
@@ -803,7 +806,7 @@ function formatContextHealthLargeToolReturnUnavailable(args) {
|
|
|
803
806
|
'',
|
|
804
807
|
'Do not try again to fetch any kind of large output; it still will not be shown. Do two things now:',
|
|
805
808
|
'1. Organize the conclusions, evidence pointers, and risks that need to go back to the Mainline dialog.',
|
|
806
|
-
'2.
|
|
809
|
+
'2. Use current-dialog scoped (scope=dialog) reminders to state this dialog task goal and carry over the details needed to resume this Sideline dialog in the next course.',
|
|
807
810
|
'',
|
|
808
811
|
'Then call clear_mind({}) to start a new course, and finish the current Sideline dialog reply as soon as possible.',
|
|
809
812
|
'',
|
|
@@ -815,7 +818,7 @@ function formatContextHealthLargeToolReturnUnavailable(args) {
|
|
|
815
818
|
'',
|
|
816
819
|
'Do not try again to fetch any kind of large output; it still will not be shown. Do two things now:',
|
|
817
820
|
'1. Write the details from this course that the next course needs into the appropriate Taskdoc sections.',
|
|
818
|
-
'2.
|
|
821
|
+
'2. For information that does not fit a Taskdoc section but is needed to resume this dialog in the next course, use current-dialog scoped (scope=dialog) reminders to state this dialog task goal and carry it over.',
|
|
819
822
|
'',
|
|
820
823
|
'Then call clear_mind({}) to start a new course.',
|
|
821
824
|
'',
|
|
@@ -3825,6 +3828,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
3825
3828
|
const currentRoundAnsweringGenseq = dlg.activeGenSeqOrUndefined;
|
|
3826
3829
|
const hasCurrentRoundAnsweringOutput = currentRoundAnsweringGenseq !== undefined &&
|
|
3827
3830
|
lastAssistantAnsweringGenseq === currentRoundAnsweringGenseq;
|
|
3831
|
+
let pendingVisibleUserInterjectionAnswer;
|
|
3828
3832
|
if (userInterjectionMsgIdForVisibleAnswer !== undefined &&
|
|
3829
3833
|
!hasCurrentRoundAnsweringOutput) {
|
|
3830
3834
|
const streamedCurrentRoundSayingContent = batchOutputs.length === 0 &&
|
|
@@ -3835,14 +3839,25 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
3835
3839
|
lastAssistantSayingGenseq !== previousAssistantSayingGenseq
|
|
3836
3840
|
? lastAssistantSayingGenseq
|
|
3837
3841
|
: null;
|
|
3838
|
-
|
|
3839
|
-
dlg,
|
|
3842
|
+
pendingVisibleUserInterjectionAnswer = {
|
|
3840
3843
|
userPromptMsgId: userInterjectionMsgIdForVisibleAnswer,
|
|
3841
3844
|
assistantSayingContent: currentRoundAssistantSayingContent ?? streamedCurrentRoundSayingContent,
|
|
3842
3845
|
assistantSayingGenseq: currentRoundAssistantSayingGenseq ?? streamedCurrentRoundSayingGenseq,
|
|
3843
3846
|
functionCallGenseqs: currentRoundFunctionCallGenseqs,
|
|
3844
|
-
}
|
|
3847
|
+
};
|
|
3845
3848
|
}
|
|
3849
|
+
const settleVisibleUserInterjectionAnswer = async (recordAnswerToHuman) => {
|
|
3850
|
+
const pendingAnswer = pendingVisibleUserInterjectionAnswer;
|
|
3851
|
+
if (pendingAnswer === undefined) {
|
|
3852
|
+
return;
|
|
3853
|
+
}
|
|
3854
|
+
pendingVisibleUserInterjectionAnswer = undefined;
|
|
3855
|
+
await maybeResolveAnsweredUserInterjection({
|
|
3856
|
+
dlg,
|
|
3857
|
+
...pendingAnswer,
|
|
3858
|
+
recordAnswerToHuman,
|
|
3859
|
+
});
|
|
3860
|
+
};
|
|
3846
3861
|
if (routed.tellaskToolOutputs.length > 0) {
|
|
3847
3862
|
newMsgs.push(...routed.tellaskToolOutputs);
|
|
3848
3863
|
}
|
|
@@ -3905,6 +3920,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
3905
3920
|
}
|
|
3906
3921
|
await persistDialogFbrState(dlg, undefined);
|
|
3907
3922
|
dlg.setFbrConclusionToolsEnabled(false);
|
|
3923
|
+
await settleVisibleUserInterjectionAnswer(false);
|
|
3908
3924
|
break;
|
|
3909
3925
|
}
|
|
3910
3926
|
if (inspection.kind === 'rejected') {
|
|
@@ -3924,6 +3940,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
3924
3940
|
await persistDialogFbrState(dlg, nextFbrState);
|
|
3925
3941
|
dlg.setFbrConclusionToolsEnabled((0, fbr_1.isFbrFinalizationState)(nextFbrState));
|
|
3926
3942
|
pendingPrompt = buildKernelDriverFbrPrompt(dlg, nextFbrState);
|
|
3943
|
+
await settleVisibleUserInterjectionAnswer(true);
|
|
3927
3944
|
continue;
|
|
3928
3945
|
}
|
|
3929
3946
|
fbrConclusion = {
|
|
@@ -3943,6 +3960,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
3943
3960
|
}
|
|
3944
3961
|
await persistDialogFbrState(dlg, undefined);
|
|
3945
3962
|
dlg.setFbrConclusionToolsEnabled(false);
|
|
3963
|
+
await settleVisibleUserInterjectionAnswer(false);
|
|
3946
3964
|
break;
|
|
3947
3965
|
}
|
|
3948
3966
|
if (routed.shouldStopAfterReplyTool) {
|
|
@@ -3962,12 +3980,14 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
3962
3980
|
call.name === 'replyTellaskBack')
|
|
3963
3981
|
.map((call) => call.name),
|
|
3964
3982
|
});
|
|
3983
|
+
await settleVisibleUserInterjectionAnswer(false);
|
|
3965
3984
|
break;
|
|
3966
3985
|
}
|
|
3967
3986
|
const queuedNewCoursePrompt = await consumeQueuedNewCourseRuntimePromptForSameDrive(dlg);
|
|
3968
3987
|
if (queuedNewCoursePrompt !== undefined) {
|
|
3969
3988
|
pendingPrompt = queuedNewCoursePrompt;
|
|
3970
3989
|
skipTaskdocForThisDrive = false;
|
|
3990
|
+
await settleVisibleUserInterjectionAnswer(true);
|
|
3971
3991
|
continue;
|
|
3972
3992
|
}
|
|
3973
3993
|
// Start an immediate post-tool generation only when this round produced tool outputs that
|
|
@@ -4009,6 +4029,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
4009
4029
|
remindersVer: dlg.remindersVer,
|
|
4010
4030
|
pubRemindersVer,
|
|
4011
4031
|
});
|
|
4032
|
+
await settleVisibleUserInterjectionAnswer(true);
|
|
4012
4033
|
break;
|
|
4013
4034
|
}
|
|
4014
4035
|
if (dlg.remindersVer > pubRemindersVer) {
|
|
@@ -4032,6 +4053,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
4032
4053
|
pubRemindersVer,
|
|
4033
4054
|
});
|
|
4034
4055
|
await preserveDiligenceBudgetAcrossQ4H(dlg);
|
|
4056
|
+
await settleVisibleUserInterjectionAnswer(false);
|
|
4035
4057
|
break;
|
|
4036
4058
|
}
|
|
4037
4059
|
if (!shouldStartImmediatePostToolGeneration) {
|
|
@@ -4053,6 +4075,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
4053
4075
|
rootId: dlg.id.rootId,
|
|
4054
4076
|
selfId: dlg.id.selfId,
|
|
4055
4077
|
});
|
|
4078
|
+
await settleVisibleUserInterjectionAnswer(false);
|
|
4056
4079
|
break;
|
|
4057
4080
|
}
|
|
4058
4081
|
const healthFirst = await maybeContinueWithHealthPromptBeforeDiligence({
|
|
@@ -4065,6 +4088,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
4065
4088
|
if (healthFirst.resetTaskdoc) {
|
|
4066
4089
|
skipTaskdocForThisDrive = false;
|
|
4067
4090
|
}
|
|
4091
|
+
await settleVisibleUserInterjectionAnswer(true);
|
|
4068
4092
|
continue;
|
|
4069
4093
|
}
|
|
4070
4094
|
const next = await maybeContinueWithDiligencePrompt({
|
|
@@ -4074,6 +4098,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
4074
4098
|
});
|
|
4075
4099
|
if (next.kind === 'continue') {
|
|
4076
4100
|
pendingPrompt = next.prompt;
|
|
4101
|
+
await settleVisibleUserInterjectionAnswer(true);
|
|
4077
4102
|
continue;
|
|
4078
4103
|
}
|
|
4079
4104
|
lastToolRoundStopDiagnostics = buildToolRoundStopDiagnostics({
|
|
@@ -4088,6 +4113,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
4088
4113
|
remindersVer: dlg.remindersVer,
|
|
4089
4114
|
pubRemindersVer,
|
|
4090
4115
|
});
|
|
4116
|
+
await settleVisibleUserInterjectionAnswer(false);
|
|
4091
4117
|
break;
|
|
4092
4118
|
}
|
|
4093
4119
|
await repairMissingImmediateFollowupTrigger({
|
|
@@ -4102,6 +4128,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
4102
4128
|
resolvingImmediateToolResultUserPromptMsgId = resolvingImmediateToolResultForUserPrompt
|
|
4103
4129
|
? currentUserPromptMsgId
|
|
4104
4130
|
: undefined;
|
|
4131
|
+
await settleVisibleUserInterjectionAnswer(true);
|
|
4105
4132
|
continue;
|
|
4106
4133
|
}
|
|
4107
4134
|
catch (err) {
|
|
@@ -2101,8 +2101,8 @@ async function executeReplyTellaskCall(args) {
|
|
|
2101
2101
|
function formatAnswerHumanResultContent(args) {
|
|
2102
2102
|
const language = (0, work_language_1.getWorkLanguage)();
|
|
2103
2103
|
return language === 'zh'
|
|
2104
|
-
?
|
|
2105
|
-
: `Recorded the answer for the human.\n\n${args.answerContent}`;
|
|
2104
|
+
? `已记录给人类的答复或状态说明。\n\n${args.answerContent}`
|
|
2105
|
+
: `Recorded the answer or status for the human.\n\n${args.answerContent}`;
|
|
2106
2106
|
}
|
|
2107
2107
|
async function recordAnswerToHuman(args) {
|
|
2108
2108
|
const answer = {
|
package/dist/mcp/supervisor.js
CHANGED
|
@@ -109,7 +109,10 @@ function ensureLeaseReminder(dlg, serverId) {
|
|
|
109
109
|
'',
|
|
110
110
|
`This MCP server is treated as non-stateless; the current dialog holds an underlying process/connection with explicit lifecycle management.`,
|
|
111
111
|
].join('\n');
|
|
112
|
-
dlg.addReminder(content, owner, makeLeaseReminderMeta(serverId)
|
|
112
|
+
dlg.addReminder(content, owner, makeLeaseReminderMeta(serverId), undefined, {
|
|
113
|
+
scope: 'dialog',
|
|
114
|
+
renderMode: 'markdown',
|
|
115
|
+
});
|
|
113
116
|
}
|
|
114
117
|
class McpServerDispatch {
|
|
115
118
|
serverId;
|