dominds 1.27.4 → 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/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 +2 -2
- package/dist/llm/kernel-driver/tellask-special.js +2 -2
- package/dist/minds/system-prompt.js +6 -4
- package/dist/runtime/reply-prompt-copy.js +6 -5
- package/dist/server/websocket-handler.js +3 -3
- package/dist/tools/team_mgmt-manual.js +2 -2
- package/package.json +4 -4
- package/webapp/package.json +0 -1
|
@@ -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 } : {}),
|
|
@@ -440,7 +440,7 @@ function resolveToolUseRequirement(dlg, policy) {
|
|
|
440
440
|
// For ordinary Dominds dialog rounds, the Diligence Push checkbox controls the provider-level
|
|
441
441
|
// obligation directly. The numeric Diligence Push budget only limits automatic runtime prompts;
|
|
442
442
|
// it must not downgrade the round into ordinary chat where the model can stop by asking/answering
|
|
443
|
-
// in plain text instead of calling askHuman/tellask/reply tools.
|
|
443
|
+
// in plain text instead of calling askHuman/answerHuman/tellask/reply tools.
|
|
444
444
|
return dlg.disableDiligencePush ? 'auto' : 'required';
|
|
445
445
|
}
|
|
446
446
|
function resolveModelInfo(providerCfg, model) {
|
|
@@ -749,7 +749,7 @@ const TELLASK_SPECIAL_VIRTUAL_TOOLS = [
|
|
|
749
749
|
type: 'func',
|
|
750
750
|
name: 'answerHuman',
|
|
751
751
|
followupMode: 'deferred',
|
|
752
|
-
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.',
|
|
753
753
|
parameters: {
|
|
754
754
|
type: 'object',
|
|
755
755
|
properties: {
|
|
@@ -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 = {
|
|
@@ -287,7 +287,7 @@ function buildTellaskInteractionRules(language) {
|
|
|
287
287
|
'- `tellask`:用于可恢复的长线诉请(必须提供 `targetAgentId` / `sessionSlug` / `tellaskContent`)。',
|
|
288
288
|
'- `tellaskSessionless`:用于一次性诉请(必须提供 `targetAgentId` / `tellaskContent`);它不能接着旧任务改要求,后续再次调用只是另一件独立任务,不会影响旧任务继续执行,也不会打扰同一队友正在执行的其它独立诉请。不要把智能体队友当成需要排队说话的真人同事。',
|
|
289
289
|
'- `askHuman`:用于 Q4H(向人类请求必要澄清/决策/授权/缺失输入)。',
|
|
290
|
-
'- `answerHuman
|
|
290
|
+
'- `answerHuman`:用于把当前要给人类看的答复或状态说明记录为 A2H(answer to human);当本轮必须使用工具、但确实没有其它实质工具应调用时,用它完成当前工具轮次。特别是正在等待 active callees 或诉请回贴、唯一正确动作是说明情况并等待时,应调用 `answerHuman({ answerContent })` 收口;不要用它向队友回贴。',
|
|
291
291
|
'- `freshBootsReasoning`:用于发起扪心自问(FBR)支线(`tellaskContent` 必填,`effort` 可选)。',
|
|
292
292
|
],
|
|
293
293
|
en: [
|
|
@@ -295,7 +295,7 @@ function buildTellaskInteractionRules(language) {
|
|
|
295
295
|
'- `tellask`: resumable tellask (requires `targetAgentId` / `sessionSlug` / `tellaskContent`).',
|
|
296
296
|
'- `tellaskSessionless`: one-shot tellask (requires `targetAgentId` / `tellaskContent`); it cannot continue an earlier task or change its requirements. Later calls are separate tasks and do not affect earlier work for the same teammate. Do not treat agent teammates like human coworkers who need you to wait in line to talk.',
|
|
297
297
|
'- `askHuman`: Q4H for necessary clarification/decision/authorization/missing input.',
|
|
298
|
-
'- `answerHuman`: record the current human-facing answer as A2H (answer to human); do not use it to reply to teammates.',
|
|
298
|
+
'- `answerHuman`: record the current human-facing answer or status as A2H (answer to human). When this round must use a tool but no other substantive tool should be called, use it to complete the current tool round. Especially while waiting for active callees or tellask replies, when the only correct action is to explain the situation and wait, call `answerHuman({ answerContent })` to close the round; do not use it to reply to teammates.',
|
|
299
299
|
'- `freshBootsReasoning`: starts an FBR Side Dialog (requires `tellaskContent`, optional `effort`).',
|
|
300
300
|
],
|
|
301
301
|
});
|
|
@@ -306,11 +306,13 @@ function buildFunctionToolRules(language, funcToolRulesText) {
|
|
|
306
306
|
zh: [
|
|
307
307
|
'- 回答必须基于可观测事实;为获取事实优先使用可用工具,缺乏观测事实时明确说明并请求/补充获取,不得臆测。',
|
|
308
308
|
`- 你必须通过原生 function-calling 发起函数工具调用。请提供严格的 JSON 参数对象,并尽量匹配工具 schema。Dominds 会对 schema 做 best-effort 校验(例如 required / additionalProperties:false / 基础 type / primitive enum / primitive const);其余复杂关键字(pattern/format/min/max/oneOf 等)与语义约束以工具报错为准。${funcToolRulesText}`,
|
|
309
|
+
'- 若本轮被要求调用工具,但当前确实没有应调用的事实获取/执行/诉请/回贴工具,且唯一合理动作是停止并等待(例如等待 active callees 或诉请回贴),调用 `answerHuman({ answerContent })` 说明当前等待状态并完成本工具轮次;不要为了满足工具要求而重复调用无意义的普通工具。',
|
|
309
310
|
'- 若遇到权限/沙盒/工具不可用:按要求申请升级或发起 Q4H;禁止编造结果。',
|
|
310
311
|
],
|
|
311
312
|
en: [
|
|
312
313
|
'- Answers must be grounded in observed facts. Use available tools to obtain facts; if facts are missing, say so and request/obtain them—do not guess.',
|
|
313
314
|
`- You must invoke function tools via native function-calling. Provide a valid JSON object for the tool's arguments and match the tool schema as closely as possible. Dominds performs best-effort schema validation (for example required / additionalProperties:false / basic types / primitive enum / primitive const); other complex keywords (pattern/format/min/max/oneOf etc.) and semantic constraints are enforced via tool errors.${funcToolRulesText}`,
|
|
315
|
+
'- If this round requires a tool call but there is truly no fact-gathering, action, tellask, or reply tool that should be called, and the only reasonable action is to stop and wait (for example waiting for active callees or tellask replies), call `answerHuman({ answerContent })` to explain the current wait state and complete this tool round; do not repeat meaningless ordinary tool calls just to satisfy the tool requirement.',
|
|
314
316
|
'- If a tool is unavailable due to permissions/sandboxing, request escalation or ask Q4H; do not fabricate results.',
|
|
315
317
|
],
|
|
316
318
|
});
|
|
@@ -409,7 +411,7 @@ function buildSystemPrompt(input) {
|
|
|
409
411
|
- 回问诉请:支线对话用 \`tellaskBack\` 回问诉请者以澄清。
|
|
410
412
|
- 扪心自问(FBR):由 \`freshBootsReasoning\` 触发的“无工具”支线推理机制。
|
|
411
413
|
- 向人请示(Q4H):通过 \`askHuman\` 向人类请求必要的澄清/决策/授权/缺失输入。
|
|
412
|
-
- 答复人类(A2H):通过 \`answerHuman\`
|
|
414
|
+
- 答复人类(A2H):通过 \`answerHuman\` 记录当前要给人类看的答复或状态说明。
|
|
413
415
|
- 长线诉请:使用 \`tellask\` + \`sessionSlug\` 的可恢复多轮协作。
|
|
414
416
|
- 一次性诉请:一次性、不可恢复的诉请。
|
|
415
417
|
- 主线对话:承载共享差遣牒并负责整体推进的对话。
|
|
@@ -510,7 +512,7 @@ System notices convey important state changes (e.g., context caution/critical, D
|
|
|
510
512
|
- TellaskBack: a Side Dialog uses \`tellaskBack\` to ask the tellasker for clarification.
|
|
511
513
|
- Fresh Boots Reasoning (FBR): a tool-less Side Dialog reasoning mechanism triggered by \`freshBootsReasoning\`.
|
|
512
514
|
- Q4H (Question for Human): use \`askHuman\` to request necessary clarification/decision/authorization/missing input from a human.
|
|
513
|
-
- A2H (Answer to Human): use \`answerHuman\` to record the current human-facing answer.
|
|
515
|
+
- A2H (Answer to Human): use \`answerHuman\` to record the current human-facing answer or status.
|
|
514
516
|
- Tellask Session: resumable multi-turn work using \`tellask\` with \`sessionSlug\`.
|
|
515
517
|
- Fresh Tellask: a one-shot, non-resumable Tellask.
|
|
516
518
|
- Main Dialog: the dialog that owns the shared Taskdoc and overall progress.
|
|
@@ -165,9 +165,10 @@ function buildReplyToolReminderText(args) {
|
|
|
165
165
|
].join('\n');
|
|
166
166
|
}
|
|
167
167
|
// Business scenario: the model produced structured `answering` (or called `answerHuman`) while a
|
|
168
|
-
// Side Dialog still owes a formal reply to its requester. A2H is a human-attention
|
|
169
|
-
// intentionally not the requester delivery channel. Keep this as a reply-tool
|
|
170
|
-
// plain-text answer can use the same direct-fallback recovery semantics as
|
|
168
|
+
// Side Dialog still owes a formal reply to its requester. A2H is a human-attention answer or status
|
|
169
|
+
// record; it is intentionally not the requester delivery channel. Keep this as a reply-tool
|
|
170
|
+
// reminder so a later plain-text answer can use the same direct-fallback recovery semantics as
|
|
171
|
+
// ordinary reminders.
|
|
171
172
|
function buildAnsweringReplyReminderText(args) {
|
|
172
173
|
const prefix = args.language === 'zh'
|
|
173
174
|
? exports.ANSWERING_REPLY_REMINDER_PREFIX_ZH
|
|
@@ -182,14 +183,14 @@ function buildAnsweringReplyReminderText(args) {
|
|
|
182
183
|
? [
|
|
183
184
|
prefix,
|
|
184
185
|
'',
|
|
185
|
-
'`answering` / `answerHuman` 只会记录给人类看的 A2H
|
|
186
|
+
'`answering` / `answerHuman` 只会记录给人类看的 A2H 答复或状态说明,不会把正式回贴送达诉请者。',
|
|
186
187
|
'',
|
|
187
188
|
`${replyTarget} 还在等你完成${kindLabel}的回贴。若最终内容已经准备好,请现在调用 \`${args.directive.expectedReplyCallName}({ replyContent })\` 发送;不要用 \`answering\` 或 \`answerHuman\` 代替诉请者回贴。`,
|
|
188
189
|
].join('\n')
|
|
189
190
|
: [
|
|
190
191
|
prefix,
|
|
191
192
|
'',
|
|
192
|
-
'`answering` / `answerHuman` only records an A2H answer for the human. It does not deliver the formal reply to the requester.',
|
|
193
|
+
'`answering` / `answerHuman` only records an A2H answer or status for the human. It does not deliver the formal reply to the requester.',
|
|
193
194
|
'',
|
|
194
195
|
`${replyTarget} is still waiting for your ${kindLabel} reply. If the final content is ready, call \`${args.directive.expectedReplyCallName}({ replyContent })\` now; do not use \`answering\` or \`answerHuman\` as the requester reply path.`,
|
|
195
196
|
].join('\n');
|
|
@@ -1340,12 +1340,12 @@ async function handleAckA2H(ws, packet) {
|
|
|
1340
1340
|
if (removed === null || !removed.found) {
|
|
1341
1341
|
ws.send(JSON.stringify({
|
|
1342
1342
|
type: 'error',
|
|
1343
|
-
message: `A2H
|
|
1343
|
+
message: `A2H item ${answerId} not found in dialog ${dialogIdent.selfId}`,
|
|
1344
1344
|
}));
|
|
1345
1345
|
return;
|
|
1346
1346
|
}
|
|
1347
1347
|
if (removedStatus === null) {
|
|
1348
|
-
throw new Error(`A2H Ack invariant violation: removed
|
|
1348
|
+
throw new Error(`A2H Ack invariant violation: removed item without status ${answerId}`);
|
|
1349
1349
|
}
|
|
1350
1350
|
const event = {
|
|
1351
1351
|
type: 'a2h_acknowledged',
|
|
@@ -1359,7 +1359,7 @@ async function handleAckA2H(ws, packet) {
|
|
|
1359
1359
|
log.error('Error processing A2H Ack:', error);
|
|
1360
1360
|
ws.send(JSON.stringify({
|
|
1361
1361
|
type: 'error',
|
|
1362
|
-
message: `Failed to acknowledge A2H
|
|
1362
|
+
message: `Failed to acknowledge A2H item: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1363
1363
|
}));
|
|
1364
1364
|
}
|
|
1365
1365
|
}
|
|
@@ -114,7 +114,7 @@ async function renderTeamMgmtGuideContent(language, topicsRaw = []) {
|
|
|
114
114
|
'`model_param_options` 可选:用于记录该 provider 支持的 `.minds/team.yaml model_params` 选项(文档用途)。',
|
|
115
115
|
'`apiQuirks` 可选:写在 `providers.<providerKey>.apiQuirks`,类型是 `string|string[]`;需要多个 quirk 时用数组,例如 `apiQuirks: [same-context-empty-response]`。它是 provider 级 transport / 网关兼容开关,用来描述“这个供应商/网关的 API 有非标准行为”,不是 `.minds/team.yaml` 的成员参数,也不是 `model_params`。',
|
|
116
116
|
'使用原则:只有在你确认某个上游网关确实偏离了标准协议,而且 Dominds 已为这个偏差实现了命名 quirk 时才配置;不要把它当作随意调参入口。当前实现里,未知 quirk 值通常不会报错,但也不会带来任何效果。',
|
|
117
|
-
'当前已知示例:OpenAI Responses 包装层支持 `apiQuirks: xcode.best`(或数组里包含它),用于识别 vendor keepalive、处理 xcode.best 特有的失败模式,以及把网关返回的 HTML 版 502 Bad Gateway 错误页和 `500 auth_unavailable: no auth available` 这类基础设施失败归类为 conservative 策略重试。OpenAI-compatible Chat Completions 包装层支持 `apiQuirks: same-context-empty-response`,用于“同一对话 generation 上下文连续返回 empty response”时先做少量临时重试;支持 `apiQuirks: volcengine-invalid-parameter-aggressive-retry`,用于火山方舟 Coding Plan 偶发 `400 InvalidParameter` 但同 payload 可重放成功的场景,将其归类为 aggressive 策略重试;支持内置 `kimi-code` provider 使用的 `apiQuirks: kimi-code`,用于 Kimi Code 专用 User-Agent(`KimiCLI/Dominds/<version>`)、`prompt_cache_key` 和 `thinking`/`reasoning_effort` 请求整形;也支持 `apiQuirks: minimax-reasoning-details`,用于 MiniMax OpenAI-compatible `/v1` 默认启用 `reasoning_split: true`,并跨轮完整保留 `reasoning_details
|
|
117
|
+
'当前已知示例:OpenAI Responses 包装层支持 `apiQuirks: xcode.best`(或数组里包含它),用于识别 vendor keepalive、处理 xcode.best 特有的失败模式,以及把网关返回的 HTML 版 502 Bad Gateway 错误页和 `500 auth_unavailable: no auth available` 这类基础设施失败归类为 conservative 策略重试。OpenAI-compatible Chat Completions 包装层支持 `apiQuirks: same-context-empty-response`,用于“同一对话 generation 上下文连续返回 empty response”时先做少量临时重试;支持 `apiQuirks: volcengine-invalid-parameter-aggressive-retry`,用于火山方舟 Coding Plan 偶发 `400 InvalidParameter` 但同 payload 可重放成功的场景,将其归类为 aggressive 策略重试;支持内置 `kimi-code` provider 使用的 `apiQuirks: kimi-code`,用于 Kimi Code 专用 User-Agent(`KimiCLI/Dominds/<version>`)、`prompt_cache_key` 和 `thinking`/`reasoning_effort` 请求整形;也支持 `apiQuirks: minimax-reasoning-details`,用于 MiniMax OpenAI-compatible `/v1` 默认启用 `reasoning_split: true`,并跨轮完整保留 `reasoning_details`;支持 `apiQuirks: minimax-thinking-type`,用于把请求里的 `thinking: true` / `thinking: { type: "enabled" }` 归一化为 `thinking: { type: "adaptive" }`(MiniMax 的 `/v1` API 拒绝 `enabled`,只接受 `adaptive` / `disabled`)。最小示例:\n```yaml\nproviders:\n my_gateway:\n apiType: openai-compatible\n baseUrl: https://example.invalid/v1\n apiKeyEnvVar: MY_GATEWAY_API_KEY\n apiQuirks: same-context-empty-response\n models:\n my_model: { name: "upstream-model-id" }\n```',
|
|
118
118
|
'边界提醒:`apiQuirks` 只影响实现里显式消费它的 provider/generator。就当前实现看,OpenAI Responses 与 OpenAI-compatible 路径会读取它;不要假设所有 `apiType` 都支持或需要它。若配置后行为仍异常,应继续检查上游网关文档、抓流事件类型,并结合 `team_mgmt_check_provider(...)` / 运行日志排查。',
|
|
119
119
|
])
|
|
120
120
|
: fmtHeader('.minds/llm.yaml') +
|
|
@@ -128,7 +128,7 @@ async function renderTeamMgmtGuideContent(language, topicsRaw = []) {
|
|
|
128
128
|
'Optional: `model_param_options` documents `.minds/team.yaml model_params` knobs (documentation only).',
|
|
129
129
|
'`apiQuirks` is optional under `providers.<providerKey>.apiQuirks`, with type `string|string[]`; use an array for multiple quirks, for example `apiQuirks: [same-context-empty-response]`. It is a provider-level transport / gateway compatibility switch for non-standard upstream API behavior. It is not a `.minds/team.yaml` member field and not part of `model_params`.',
|
|
130
130
|
'Use it only when you have confirmed that an upstream gateway deviates from the expected protocol and Dominds has an explicitly named quirk for that deviation. Do not treat it as a generic tuning field. In the current implementation, unknown quirk values are usually ignored rather than rejected, so a typo may silently do nothing.',
|
|
131
|
-
'Known current example: the OpenAI Responses wrapper supports `apiQuirks: xcode.best` (or an array containing it) for vendor keepalive recognition, xcode.best-specific failures, and gateway-returned HTML 502 Bad Gateway plus `500 auth_unavailable: no auth available` infrastructure failures. The OpenAI-compatible Chat Completions wrapper supports `apiQuirks: same-context-empty-response` for repeated empty responses in the same dialog generation context; `apiQuirks: volcengine-invalid-parameter-aggressive-retry` for Volcano Ark Coding Plan transient `400 InvalidParameter` failures where the same payload can succeed on replay, classified as aggressive retry; `apiQuirks: kimi-code` for the built-in Kimi Code provider request shaping: `KimiCLI/Dominds/<version>` User-Agent, `prompt_cache_key`, and `thinking`/`reasoning_effort`; and `apiQuirks: minimax-reasoning-details` for MiniMax OpenAI-compatible `/v1`, enabling `reasoning_split: true` by default and preserving `reasoning_details` across turns. Minimal example:\n```yaml\nproviders:\n my_gateway:\n apiType: openai-compatible\n baseUrl: https://example.invalid/v1\n apiKeyEnvVar: MY_GATEWAY_API_KEY\n apiQuirks: same-context-empty-response\n models:\n my_model: { name: "upstream-model-id" }\n```',
|
|
131
|
+
'Known current example: the OpenAI Responses wrapper supports `apiQuirks: xcode.best` (or an array containing it) for vendor keepalive recognition, xcode.best-specific failures, and gateway-returned HTML 502 Bad Gateway plus `500 auth_unavailable: no auth available` infrastructure failures. The OpenAI-compatible Chat Completions wrapper supports `apiQuirks: same-context-empty-response` for repeated empty responses in the same dialog generation context; `apiQuirks: volcengine-invalid-parameter-aggressive-retry` for Volcano Ark Coding Plan transient `400 InvalidParameter` failures where the same payload can succeed on replay, classified as aggressive retry; `apiQuirks: kimi-code` for the built-in Kimi Code provider request shaping: `KimiCLI/Dominds/<version>` User-Agent, `prompt_cache_key`, and `thinking`/`reasoning_effort`; and `apiQuirks: minimax-reasoning-details` for MiniMax OpenAI-compatible `/v1`, enabling `reasoning_split: true` by default and preserving `reasoning_details` across turns; `apiQuirks: minimax-thinking-type` for the MiniMax `/v1` endpoint, which only accepts `thinking.type` in `{adaptive, disabled}` and rejects `enabled`, so the request-side `thinking: true` and the object form `thinking: { type: "enabled" }` are both normalized to `thinking: { type: "adaptive" }`. Minimal example:\n```yaml\nproviders:\n my_gateway:\n apiType: openai-compatible\n baseUrl: https://example.invalid/v1\n apiKeyEnvVar: MY_GATEWAY_API_KEY\n apiQuirks: same-context-empty-response\n models:\n my_model: { name: "upstream-model-id" }\n```',
|
|
132
132
|
'Boundary reminder: `apiQuirks` only affects providers/generators that explicitly read it in code. In the current implementation, the OpenAI Responses and OpenAI-compatible paths consume it; do not assume every `apiType` supports or needs it. If behavior is still wrong after setting it, continue with upstream gateway docs, raw stream event inspection, and `team_mgmt_check_provider(...)` / runtime logs.',
|
|
133
133
|
]);
|
|
134
134
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dominds",
|
|
3
|
-
"version": "1.27.
|
|
3
|
+
"version": "1.27.5",
|
|
4
4
|
"description": "Dominds CLI and aggregation shell for the LongRun AI kernel/runtime packages.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"publishConfig": {
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
"ws": "^8.21.0",
|
|
55
55
|
"yaml": "^2.9.0",
|
|
56
56
|
"zod": "^4.4.3",
|
|
57
|
-
"@longrun-ai/codex-auth": "0.
|
|
58
|
-
"@longrun-ai/kernel": "1.17.
|
|
59
|
-
"@longrun-ai/shell": "1.17.
|
|
57
|
+
"@longrun-ai/codex-auth": "0.15.0",
|
|
58
|
+
"@longrun-ai/kernel": "1.17.5",
|
|
59
|
+
"@longrun-ai/shell": "1.17.5"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/node": "^25.9.1",
|