dominds 1.26.1 → 1.26.3
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 +2 -0
- package/README.zh.md +2 -0
- package/dist/cli/webui.js +14 -4
- package/dist/docs/cli-usage.md +1 -1
- package/dist/docs/cli-usage.zh.md +1 -1
- package/dist/llm/gen/mock.js +11 -3
- package/dist/llm/kernel-driver/context-health.d.ts +1 -0
- package/dist/llm/kernel-driver/context-health.js +7 -0
- package/dist/llm/kernel-driver/drive.js +23 -30
- package/dist/llm/kernel-driver/idle-reminder-wake.js +6 -2
- package/dist/llm/kernel-driver/reminder-context.d.ts +25 -0
- package/dist/llm/kernel-driver/reminder-context.js +81 -0
- package/dist/llm/kernel-driver/reply-guidance.js +10 -4
- package/dist/llm/kernel-driver/tellask-special.js +50 -35
- package/dist/mcp/supervisor.js +2 -2
- package/dist/minds/system-prompt-parts.js +30 -30
- package/dist/minds/system-prompt.js +55 -40
- package/dist/persistence.js +15 -1
- package/dist/runtime/driver-messages.d.ts +32 -7
- package/dist/runtime/driver-messages.js +279 -118
- package/dist/runtime/inter-dialog-format.js +24 -12
- package/dist/runtime/reply-prompt-copy.d.ts +8 -8
- package/dist/runtime/reply-prompt-copy.js +69 -38
- package/dist/server/certificates.js +65 -25
- package/dist/server/network-hosts.js +42 -29
- package/dist/server.js +4 -4
- package/dist/tools/mcp.js +12 -12
- package/dist/tools/prompts/control/en/index.md +2 -2
- package/dist/tools/prompts/control/en/principles.md +12 -12
- package/dist/tools/prompts/control/en/scenarios.md +5 -5
- package/dist/tools/prompts/control/en/tools.md +10 -10
- package/dist/tools/prompts/control/zh/index.md +3 -3
- package/dist/tools/prompts/control/zh/principles.md +12 -12
- package/dist/tools/prompts/control/zh/scenarios.md +7 -7
- package/dist/tools/prompts/control/zh/tools.md +11 -11
- package/dist/tools/prompts/mcp_admin/en/principles.md +4 -4
- package/dist/tools/prompts/mcp_admin/en/scenarios.md +1 -1
- package/dist/tools/prompts/mcp_admin/en/tools.md +3 -3
- package/dist/tools/prompts/mcp_admin/zh/principles.md +4 -4
- package/dist/tools/prompts/mcp_admin/zh/scenarios.md +1 -1
- package/dist/tools/prompts/mcp_admin/zh/tools.md +3 -3
- package/dist/tools/team_mgmt-mcp-manual.js +12 -12
- package/package.json +3 -2
- package/webapp/dist/assets/{_basePickBy-DUivPKf7.js → _basePickBy-DTJFxmut.js} +3 -3
- package/webapp/dist/assets/{_basePickBy-DUivPKf7.js.map → _basePickBy-DTJFxmut.js.map} +1 -1
- package/webapp/dist/assets/{_baseUniq-hcs024vD.js → _baseUniq-CVu4lo4P.js} +2 -2
- package/webapp/dist/assets/{_baseUniq-hcs024vD.js.map → _baseUniq-CVu4lo4P.js.map} +1 -1
- package/webapp/dist/assets/{arc-Dr6-FXp5.js → arc-4mEKx1Qr.js} +2 -2
- package/webapp/dist/assets/{arc-Dr6-FXp5.js.map → arc-4mEKx1Qr.js.map} +1 -1
- package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-DXqcDq4R.js → architectureDiagram-2XIMDMQ5-CmUkdSiN.js} +7 -7
- package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-DXqcDq4R.js.map → architectureDiagram-2XIMDMQ5-CmUkdSiN.js.map} +1 -1
- package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-IIP6LGXS.js → blockDiagram-WCTKOSBZ-CijmZ89y.js} +7 -7
- package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-IIP6LGXS.js.map → blockDiagram-WCTKOSBZ-CijmZ89y.js.map} +1 -1
- package/webapp/dist/assets/{c4Diagram-IC4MRINW-D_d3F9XD.js → c4Diagram-IC4MRINW-D0GcQMKs.js} +3 -3
- package/webapp/dist/assets/{c4Diagram-IC4MRINW-D_d3F9XD.js.map → c4Diagram-IC4MRINW-D0GcQMKs.js.map} +1 -1
- package/webapp/dist/assets/{channel-CWWjsXtU.js → channel-6pgfGez4.js} +2 -2
- package/webapp/dist/assets/{channel-CWWjsXtU.js.map → channel-6pgfGez4.js.map} +1 -1
- package/webapp/dist/assets/{chunk-4BX2VUAB-BF4yph2W.js → chunk-4BX2VUAB-BQDAaqXK.js} +2 -2
- package/webapp/dist/assets/{chunk-4BX2VUAB-BF4yph2W.js.map → chunk-4BX2VUAB-BQDAaqXK.js.map} +1 -1
- package/webapp/dist/assets/{chunk-55IACEB6-Hn3CmDYz.js → chunk-55IACEB6-DGYbZ_6j.js} +2 -2
- package/webapp/dist/assets/{chunk-55IACEB6-Hn3CmDYz.js.map → chunk-55IACEB6-DGYbZ_6j.js.map} +1 -1
- package/webapp/dist/assets/{chunk-FMBD7UC4-C05pl9Ov.js → chunk-FMBD7UC4-EVNnQ_SU.js} +2 -2
- package/webapp/dist/assets/{chunk-FMBD7UC4-C05pl9Ov.js.map → chunk-FMBD7UC4-EVNnQ_SU.js.map} +1 -1
- package/webapp/dist/assets/{chunk-JSJVCQXG-BVlq_BAS.js → chunk-JSJVCQXG-BSQe2NHw.js} +2 -2
- package/webapp/dist/assets/{chunk-JSJVCQXG-BVlq_BAS.js.map → chunk-JSJVCQXG-BSQe2NHw.js.map} +1 -1
- package/webapp/dist/assets/{chunk-KX2RTZJC-BQoaRWif.js → chunk-KX2RTZJC-I1LMYfrr.js} +2 -2
- package/webapp/dist/assets/{chunk-KX2RTZJC-BQoaRWif.js.map → chunk-KX2RTZJC-I1LMYfrr.js.map} +1 -1
- package/webapp/dist/assets/{chunk-NQ4KR5QH-0okCAXtW.js → chunk-NQ4KR5QH-C9HmN9dA.js} +4 -4
- package/webapp/dist/assets/{chunk-NQ4KR5QH-0okCAXtW.js.map → chunk-NQ4KR5QH-C9HmN9dA.js.map} +1 -1
- package/webapp/dist/assets/{chunk-QZHKN3VN-DEiprgz-.js → chunk-QZHKN3VN-73ijGXNd.js} +2 -2
- package/webapp/dist/assets/{chunk-QZHKN3VN-DEiprgz-.js.map → chunk-QZHKN3VN-73ijGXNd.js.map} +1 -1
- package/webapp/dist/assets/{chunk-WL4C6EOR-B-Xkb3lo.js → chunk-WL4C6EOR-DeVu-9ac.js} +6 -6
- package/webapp/dist/assets/{chunk-WL4C6EOR-B-Xkb3lo.js.map → chunk-WL4C6EOR-DeVu-9ac.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-VBA2DB6C-DCCQrdwF.js → classDiagram-VBA2DB6C-2HURCFLk.js} +7 -7
- package/webapp/dist/assets/{classDiagram-VBA2DB6C-DCCQrdwF.js.map → classDiagram-VBA2DB6C-2HURCFLk.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-DCCQrdwF.js → classDiagram-v2-RAHNMMFH-2HURCFLk.js} +7 -7
- package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-DCCQrdwF.js.map → classDiagram-v2-RAHNMMFH-2HURCFLk.js.map} +1 -1
- package/webapp/dist/assets/{clone-Drtik9pk.js → clone-BNPlfGMh.js} +2 -2
- package/webapp/dist/assets/{clone-Drtik9pk.js.map → clone-BNPlfGMh.js.map} +1 -1
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-BBWvHErL.js → cose-bilkent-S5V4N54A-BeoZCFA5.js} +2 -2
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-BBWvHErL.js.map → cose-bilkent-S5V4N54A-BeoZCFA5.js.map} +1 -1
- package/webapp/dist/assets/{dagre-KLK3FWXG-2qk0ikdt.js → dagre-KLK3FWXG-DYxCt50h.js} +7 -7
- package/webapp/dist/assets/{dagre-KLK3FWXG-2qk0ikdt.js.map → dagre-KLK3FWXG-DYxCt50h.js.map} +1 -1
- package/webapp/dist/assets/{diagram-E7M64L7V-C1DbHDbf.js → diagram-E7M64L7V-BWxcTI3B.js} +8 -8
- package/webapp/dist/assets/{diagram-E7M64L7V-C1DbHDbf.js.map → diagram-E7M64L7V-BWxcTI3B.js.map} +1 -1
- package/webapp/dist/assets/{diagram-IFDJBPK2-DToz8zk9.js → diagram-IFDJBPK2-BAIPE4Rn.js} +7 -7
- package/webapp/dist/assets/{diagram-IFDJBPK2-DToz8zk9.js.map → diagram-IFDJBPK2-BAIPE4Rn.js.map} +1 -1
- package/webapp/dist/assets/{diagram-P4PSJMXO-B9V-tQMe.js → diagram-P4PSJMXO-CvcxPsVp.js} +7 -7
- package/webapp/dist/assets/{diagram-P4PSJMXO-B9V-tQMe.js.map → diagram-P4PSJMXO-CvcxPsVp.js.map} +1 -1
- package/webapp/dist/assets/{erDiagram-INFDFZHY-CV68FwGf.js → erDiagram-INFDFZHY-BDO90e-f.js} +5 -5
- package/webapp/dist/assets/{erDiagram-INFDFZHY-CV68FwGf.js.map → erDiagram-INFDFZHY-BDO90e-f.js.map} +1 -1
- package/webapp/dist/assets/{flowDiagram-PKNHOUZH-CW06almb.js → flowDiagram-PKNHOUZH-hd4TorKR.js} +7 -7
- package/webapp/dist/assets/{flowDiagram-PKNHOUZH-CW06almb.js.map → flowDiagram-PKNHOUZH-hd4TorKR.js.map} +1 -1
- package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-C96NncCU.js → ganttDiagram-A5KZAMGK-mID1sFSl.js} +3 -3
- package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-C96NncCU.js.map → ganttDiagram-A5KZAMGK-mID1sFSl.js.map} +1 -1
- package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-CAuIexWi.js → gitGraphDiagram-K3NZZRJ6-DaA7yodM.js} +8 -8
- package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-CAuIexWi.js.map → gitGraphDiagram-K3NZZRJ6-DaA7yodM.js.map} +1 -1
- package/webapp/dist/assets/{graph-CvhwAY6w.js → graph-B86JxOkQ.js} +3 -3
- package/webapp/dist/assets/{graph-CvhwAY6w.js.map → graph-B86JxOkQ.js.map} +1 -1
- package/webapp/dist/assets/{index-BOO_zFrI.js → index-DYO4ZL8y.js} +369 -389
- package/webapp/dist/assets/{index-BOO_zFrI.js.map → index-DYO4ZL8y.js.map} +1 -1
- package/webapp/dist/assets/{infoDiagram-LFFYTUFH-C16Sckpz.js → infoDiagram-LFFYTUFH-DxF36W9g.js} +6 -6
- package/webapp/dist/assets/{infoDiagram-LFFYTUFH-C16Sckpz.js.map → infoDiagram-LFFYTUFH-DxF36W9g.js.map} +1 -1
- package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-oNG6I0p3.js → ishikawaDiagram-PHBUUO56-wvAzRzSO.js} +2 -2
- package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-oNG6I0p3.js.map → ishikawaDiagram-PHBUUO56-wvAzRzSO.js.map} +1 -1
- package/webapp/dist/assets/{journeyDiagram-4ABVD52K-437hhFHC.js → journeyDiagram-4ABVD52K-CIBXsttK.js} +5 -5
- package/webapp/dist/assets/{journeyDiagram-4ABVD52K-437hhFHC.js.map → journeyDiagram-4ABVD52K-CIBXsttK.js.map} +1 -1
- package/webapp/dist/assets/{kanban-definition-K7BYSVSG-DsCV_Tpx.js → kanban-definition-K7BYSVSG-DQTPyM5m.js} +3 -3
- package/webapp/dist/assets/{kanban-definition-K7BYSVSG-DsCV_Tpx.js.map → kanban-definition-K7BYSVSG-DQTPyM5m.js.map} +1 -1
- package/webapp/dist/assets/{layout-BttZf7fQ.js → layout-BG7IzQAG.js} +5 -5
- package/webapp/dist/assets/{layout-BttZf7fQ.js.map → layout-BG7IzQAG.js.map} +1 -1
- package/webapp/dist/assets/{linear-B75vD4Ho.js → linear-5XR-mXYw.js} +2 -2
- package/webapp/dist/assets/{linear-B75vD4Ho.js.map → linear-5XR-mXYw.js.map} +1 -1
- package/webapp/dist/assets/{mindmap-definition-YRQLILUH-DA1-XaNi.js → mindmap-definition-YRQLILUH-BwTQE6uN.js} +4 -4
- package/webapp/dist/assets/{mindmap-definition-YRQLILUH-DA1-XaNi.js.map → mindmap-definition-YRQLILUH-BwTQE6uN.js.map} +1 -1
- package/webapp/dist/assets/{pieDiagram-SKSYHLDU-Bx6hUJ4Q.js → pieDiagram-SKSYHLDU-ZYB35zd5.js} +8 -8
- package/webapp/dist/assets/{pieDiagram-SKSYHLDU-Bx6hUJ4Q.js.map → pieDiagram-SKSYHLDU-ZYB35zd5.js.map} +1 -1
- package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-zyduIle0.js → quadrantDiagram-337W2JSQ-BM041Q-W.js} +3 -3
- package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-zyduIle0.js.map → quadrantDiagram-337W2JSQ-BM041Q-W.js.map} +1 -1
- package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-BgfjyEJM.js → requirementDiagram-Z7DCOOCP-r_xMoroM.js} +4 -4
- package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-BgfjyEJM.js.map → requirementDiagram-Z7DCOOCP-r_xMoroM.js.map} +1 -1
- package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-lmOWaczS.js → sankeyDiagram-WA2Y5GQK-Ju2-t24N.js} +2 -2
- package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-lmOWaczS.js.map → sankeyDiagram-WA2Y5GQK-Ju2-t24N.js.map} +1 -1
- package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-DqJz-iYI.js → sequenceDiagram-2WXFIKYE-D83Bocd1.js} +4 -4
- package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-DqJz-iYI.js.map → sequenceDiagram-2WXFIKYE-D83Bocd1.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-RAJIS63D-CngWYuX-.js → stateDiagram-RAJIS63D-mTmpZzpU.js} +9 -9
- package/webapp/dist/assets/{stateDiagram-RAJIS63D-CngWYuX-.js.map → stateDiagram-RAJIS63D-mTmpZzpU.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-BxyHvrvU.js → stateDiagram-v2-FVOUBMTO-BCn7mFeH.js} +5 -5
- package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-BxyHvrvU.js.map → stateDiagram-v2-FVOUBMTO-BCn7mFeH.js.map} +1 -1
- package/webapp/dist/assets/{timeline-definition-YZTLITO2-C7t6WVS3.js → timeline-definition-YZTLITO2-C1QBcYz8.js} +3 -3
- package/webapp/dist/assets/{timeline-definition-YZTLITO2-C7t6WVS3.js.map → timeline-definition-YZTLITO2-C1QBcYz8.js.map} +1 -1
- package/webapp/dist/assets/{treemap-KZPCXAKY-BDZ3n5TC.js → treemap-KZPCXAKY-BEyfK-Fo.js} +5 -5
- package/webapp/dist/assets/{treemap-KZPCXAKY-BDZ3n5TC.js.map → treemap-KZPCXAKY-BEyfK-Fo.js.map} +1 -1
- package/webapp/dist/assets/{vennDiagram-LZ73GAT5-CEw7GPed.js → vennDiagram-LZ73GAT5-C6SZhLMq.js} +2 -2
- package/webapp/dist/assets/{vennDiagram-LZ73GAT5-CEw7GPed.js.map → vennDiagram-LZ73GAT5-C6SZhLMq.js.map} +1 -1
- package/webapp/dist/assets/{xychartDiagram-JWTSCODW-DmS8BiaA.js → xychartDiagram-JWTSCODW-BUlvexnm.js} +3 -3
- package/webapp/dist/assets/{xychartDiagram-JWTSCODW-DmS8BiaA.js.map → xychartDiagram-JWTSCODW-BUlvexnm.js.map} +1 -1
- package/webapp/dist/index.html +1 -1
package/README.md
CHANGED
|
@@ -257,6 +257,8 @@ Platform note:
|
|
|
257
257
|
|
|
258
258
|
Dominds always keeps an HTTP listener. When a valid certificate matching the current `--host` exists under `~/.dominds/certs/`, Dominds also starts HTTPS. Certificates match DNS/IP hostnames, not ports, so one certificate covers all Dominds WebUI ports on that host.
|
|
259
259
|
|
|
260
|
+
Dominds generates certificates through npm dependencies, so no separate `openssl` command is required.
|
|
261
|
+
|
|
260
262
|
```bash
|
|
261
263
|
# Create a 10-year self-signed certificate for detected non-loopback LAN hosts
|
|
262
264
|
dominds cert create
|
package/README.zh.md
CHANGED
|
@@ -196,6 +196,8 @@ dominds
|
|
|
196
196
|
|
|
197
197
|
Dominds 默认始终提供 HTTP 监听;当 `~/.dominds/certs/` 下存在匹配当前 `--host` 的有效证书时,会额外启用 HTTPS。证书按 DNS/IP 主机名匹配,不绑定端口,因此同一张证书可覆盖该主机上的所有 Dominds WebUI 端口。
|
|
198
198
|
|
|
199
|
+
证书由 Dominds 通过 npm 依赖生成,无需额外安装 `openssl` 等系统命令。
|
|
200
|
+
|
|
199
201
|
```bash
|
|
200
202
|
# 自动为检测到的一个或多个非 loopback LAN 主机创建 10 年有效的自签名证书
|
|
201
203
|
dominds cert create
|
package/dist/cli/webui.js
CHANGED
|
@@ -164,17 +164,19 @@ async function main(args = process.argv.slice(2)) {
|
|
|
164
164
|
host: started.urlHost,
|
|
165
165
|
port: started.port,
|
|
166
166
|
})}`);
|
|
167
|
+
let httpsEndpoint;
|
|
167
168
|
if (started.httpsPort !== undefined && started.httpsUrlHost !== undefined) {
|
|
169
|
+
httpsEndpoint = { host: started.httpsUrlHost, port: started.httpsPort };
|
|
168
170
|
const httpsBaseUrl = (0, auth_1.formatServerOrigin)({
|
|
169
171
|
scheme: 'https',
|
|
170
|
-
host:
|
|
171
|
-
port:
|
|
172
|
+
host: httpsEndpoint.host,
|
|
173
|
+
port: httpsEndpoint.port,
|
|
172
174
|
});
|
|
173
175
|
log.info(`HTTPS WebUI ready: ${httpsBaseUrl}`);
|
|
174
176
|
log.debug(`HTTPS WebSocket endpoint: ${formatWebSocketEndpoint({
|
|
175
177
|
scheme: 'wss',
|
|
176
|
-
host:
|
|
177
|
-
port:
|
|
178
|
+
host: httpsEndpoint.host,
|
|
179
|
+
port: httpsEndpoint.port,
|
|
178
180
|
})}`);
|
|
179
181
|
}
|
|
180
182
|
if (auth.kind === 'enabled') {
|
|
@@ -185,6 +187,14 @@ async function main(args = process.argv.slice(2)) {
|
|
|
185
187
|
authKey: auth.key,
|
|
186
188
|
});
|
|
187
189
|
log.info(`auto auth url (sensitive): ${autoAuthUrl}`);
|
|
190
|
+
if (httpsEndpoint !== undefined) {
|
|
191
|
+
log.info(`HTTPS auto auth url (sensitive): ${(0, auth_1.formatAutoAuthUrl)({
|
|
192
|
+
scheme: 'https',
|
|
193
|
+
host: httpsEndpoint.host,
|
|
194
|
+
port: httpsEndpoint.port,
|
|
195
|
+
authKey: auth.key,
|
|
196
|
+
})}`);
|
|
197
|
+
}
|
|
188
198
|
if (shouldOpen) {
|
|
189
199
|
log.debug(`Opening browser: ${autoAuthUrl}`);
|
|
190
200
|
openInBrowser(autoAuthUrl);
|
package/dist/docs/cli-usage.md
CHANGED
|
@@ -153,7 +153,7 @@ dominds cert create [--host <host>] [--days <days>] [--force]
|
|
|
153
153
|
dominds cert status [--host <host>] [--port <port>] [--origin]
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
-
Create or inspect local HTTPS certificates for the Dominds WebUI. Certificates live in `~/.dominds/certs/` and match DNS/IP hostnames, not ports; one certificate covers every WebUI port on that host.
|
|
156
|
+
Create or inspect local HTTPS certificates for the Dominds WebUI. Dominds generates certificates through npm dependencies, so no separate `openssl` command is required. Certificates live in `~/.dominds/certs/` and match DNS/IP hostnames, not ports; one certificate covers every WebUI port on that host.
|
|
157
157
|
|
|
158
158
|
**Options:**
|
|
159
159
|
|
|
@@ -160,7 +160,7 @@ dominds cert create [--host <host>] [--days <days>] [--force]
|
|
|
160
160
|
dominds cert status [--host <host>] [--port <port>] [--origin]
|
|
161
161
|
```
|
|
162
162
|
|
|
163
|
-
创建或检查 Dominds WebUI 的本机 HTTPS
|
|
163
|
+
创建或检查 Dominds WebUI 的本机 HTTPS 证书。证书由 Dominds 通过 npm 依赖生成,无需额外安装 `openssl` 等系统命令。证书保存在 `~/.dominds/certs/`,按 DNS/IP 主机名匹配,不绑定端口;同一张证书可覆盖该主机上的所有 WebUI 端口。
|
|
164
164
|
|
|
165
165
|
**选项:**
|
|
166
166
|
|
package/dist/llm/gen/mock.js
CHANGED
|
@@ -326,9 +326,17 @@ class MockGen {
|
|
|
326
326
|
if (trimmed !== '') {
|
|
327
327
|
variants.add(trimmed.toLowerCase());
|
|
328
328
|
}
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
329
|
+
const tellaskStatusPrefixes = [
|
|
330
|
+
'\n[Dominds 诉请状态]\n',
|
|
331
|
+
'\n[Dominds tellask status]\n',
|
|
332
|
+
'\n[Dominds 等待人类回复]\n',
|
|
333
|
+
'\n[Dominds waiting for human answer]\n',
|
|
334
|
+
'\n[Dominds 等待队友回贴]\n',
|
|
335
|
+
'\n[Dominds waiting for teammate reply]\n',
|
|
336
|
+
'\n[Dominds 队友回贴状态]\n',
|
|
337
|
+
'\n[Dominds teammate reply status]\n',
|
|
338
|
+
];
|
|
339
|
+
const tellaskStatusIndex = Math.max(...tellaskStatusPrefixes.map((prefix) => trimmed.lastIndexOf(prefix)));
|
|
332
340
|
if (tellaskStatusIndex >= 0) {
|
|
333
341
|
const strippedTellaskStatus = trimmed.slice(0, tellaskStatusIndex).trim();
|
|
334
342
|
if (strippedTellaskStatus !== '') {
|
|
@@ -7,6 +7,7 @@ export type KernelDriverContextHealthDecision = Readonly<{
|
|
|
7
7
|
}>;
|
|
8
8
|
export declare const KERNEL_DRIVER_DEFAULT_CRITICAL_COUNTDOWN_GENERATIONS = 5;
|
|
9
9
|
export declare const KERNEL_DRIVER_DEFAULT_CAUTION_REMEDIATION_CADENCE_GENERATIONS = 10;
|
|
10
|
+
export declare function getContextHealthRemediationLevel(snapshot: ContextHealthSnapshot | undefined): 'caution' | 'critical' | undefined;
|
|
10
11
|
export declare function resetContextHealthRoundState(dialogKey: string): void;
|
|
11
12
|
export declare function resolveCriticalCountdownRemaining(dialogKey: string, snapshot: ContextHealthSnapshot | undefined): number;
|
|
12
13
|
export declare function consumeCriticalCountdown(dialogKey: string): number;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.KERNEL_DRIVER_DEFAULT_CAUTION_REMEDIATION_CADENCE_GENERATIONS = exports.KERNEL_DRIVER_DEFAULT_CRITICAL_COUNTDOWN_GENERATIONS = void 0;
|
|
4
|
+
exports.getContextHealthRemediationLevel = getContextHealthRemediationLevel;
|
|
4
5
|
exports.resetContextHealthRoundState = resetContextHealthRoundState;
|
|
5
6
|
exports.resolveCriticalCountdownRemaining = resolveCriticalCountdownRemaining;
|
|
6
7
|
exports.consumeCriticalCountdown = consumeCriticalCountdown;
|
|
@@ -9,6 +10,12 @@ exports.decideKernelDriverContextHealth = decideKernelDriverContextHealth;
|
|
|
9
10
|
exports.KERNEL_DRIVER_DEFAULT_CRITICAL_COUNTDOWN_GENERATIONS = 5;
|
|
10
11
|
exports.KERNEL_DRIVER_DEFAULT_CAUTION_REMEDIATION_CADENCE_GENERATIONS = 10;
|
|
11
12
|
const stateByDialogKey = new Map();
|
|
13
|
+
function getContextHealthRemediationLevel(snapshot) {
|
|
14
|
+
if (snapshot?.kind !== 'available') {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
return snapshot.level === 'caution' || snapshot.level === 'critical' ? snapshot.level : undefined;
|
|
18
|
+
}
|
|
12
19
|
function getOrCreateState(dialogKey) {
|
|
13
20
|
const existing = stateByDialogKey.get(dialogKey);
|
|
14
21
|
if (existing)
|
|
@@ -34,6 +34,7 @@ const context_health_1 = require("./context-health");
|
|
|
34
34
|
const events_1 = require("./events");
|
|
35
35
|
const fbr_1 = require("./fbr");
|
|
36
36
|
const guardrails_1 = require("./guardrails");
|
|
37
|
+
const reminder_context_1 = require("./reminder-context");
|
|
37
38
|
const reply_guidance_1 = require("./reply-guidance");
|
|
38
39
|
const runtime_1 = require("./runtime");
|
|
39
40
|
const tellask_special_1 = require("./tellask-special");
|
|
@@ -254,31 +255,29 @@ function isUserOriginPrompt(prompt) {
|
|
|
254
255
|
return false;
|
|
255
256
|
return prompt.origin === 'user' && normalizeQ4HAnswerCallId(prompt.q4hAnswerCallId) === undefined;
|
|
256
257
|
}
|
|
257
|
-
function resolveReminderContextFollowingDialogState(prompt, currentTurnDialogMsgsForContext) {
|
|
258
|
-
if (prompt === undefined || currentTurnDialogMsgsForContext.length === 0)
|
|
259
|
-
return 'none';
|
|
260
|
-
return prompt.origin === 'user' ? 'user_message' : 'runtime_notice';
|
|
261
|
-
}
|
|
262
|
-
function resolveReminderContextHealthState(snapshot) {
|
|
263
|
-
const remediationLevel = getContextHealthRemediationLevel(snapshot);
|
|
264
|
-
return remediationLevel === undefined ? 'normal' : remediationLevel;
|
|
265
|
-
}
|
|
266
258
|
async function resolveReminderContextFooterState(args) {
|
|
267
259
|
const latest = await persistence_1.DialogPersistence.loadDialogLatest(args.dlg.id, args.dlg.status);
|
|
268
260
|
const deferredReplyReassertion = latest?.deferredReplyReassertion;
|
|
269
261
|
const activeReplyObligation = await persistence_1.DialogPersistence.loadActiveTellaskReplyObligation(args.dlg.id, args.dlg.status);
|
|
270
262
|
const pendingUserInterjectionReply = latest?.pendingUserInterjectionReply !== undefined;
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
263
|
+
const hasDeferredReplyReassertion = deferredReplyReassertion?.reason === 'user_interjection_with_parked_original_task';
|
|
264
|
+
const hasActiveReplyObligation = activeReplyObligation !== undefined;
|
|
265
|
+
// Business scenario: a user can reopen a completed Side Dialog to ask a follow-up. A recorded
|
|
266
|
+
// final response with no active/parked reply task means the old handoff has already been
|
|
267
|
+
// reported back; if a real user message is now present, the footer should say "talk with the
|
|
268
|
+
// user now" instead of making the model infer that from old transcript/reminder context.
|
|
269
|
+
const hasCompletedHandoffWithoutPendingReply = latest?.sideDialogFinalResponse !== undefined &&
|
|
270
|
+
!hasDeferredReplyReassertion &&
|
|
271
|
+
!hasActiveReplyObligation;
|
|
272
|
+
return (0, reminder_context_1.resolveReminderContextFooterStateFromSignals)({
|
|
273
|
+
prompt: args.prompt,
|
|
274
|
+
currentTurnDialogMsgsForContext: args.currentTurnDialogMsgsForContext,
|
|
275
|
+
contextHealth: args.dlg.getLastContextHealth(),
|
|
278
276
|
pendingUserInterjectionReply,
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
277
|
+
hasCompletedHandoffWithoutPendingReply,
|
|
278
|
+
hasDeferredReplyReassertion,
|
|
279
|
+
hasActiveReplyObligation,
|
|
280
|
+
});
|
|
282
281
|
}
|
|
283
282
|
function splitDialogMsgsForReminderInsertion(args) {
|
|
284
283
|
const msgId = args.currentPrompt?.msgId;
|
|
@@ -722,12 +721,6 @@ const TELLASK_SPECIAL_VIRTUAL_TOOLS = [
|
|
|
722
721
|
const CONTEXT_HEALTH_TOOL_RESULT_VISIBLE_BYTE_LIMIT = 2000;
|
|
723
722
|
const CONTEXT_HEALTH_LARGE_TOOL_RETURN_UNAVAILABLE_ZH = '这次函数返回内容太大,清理头脑之前不会显示给你。';
|
|
724
723
|
const CONTEXT_HEALTH_LARGE_TOOL_RETURN_UNAVAILABLE_EN = 'This function returned too much content. It will not be shown to you before you clear your mind.';
|
|
725
|
-
function getContextHealthRemediationLevel(snapshot) {
|
|
726
|
-
if (snapshot?.kind !== 'available') {
|
|
727
|
-
return undefined;
|
|
728
|
-
}
|
|
729
|
-
return snapshot.level === 'caution' || snapshot.level === 'critical' ? snapshot.level : undefined;
|
|
730
|
-
}
|
|
731
724
|
function pickContextHealthForLargeToolResultVisibility(args) {
|
|
732
725
|
if (args.current?.kind === 'available') {
|
|
733
726
|
return args.current;
|
|
@@ -809,7 +802,7 @@ function countToolResultVisibleBytes(output) {
|
|
|
809
802
|
return bytes;
|
|
810
803
|
}
|
|
811
804
|
function applyContextHealthToolResultVisibilityLimit(args) {
|
|
812
|
-
if (getContextHealthRemediationLevel(args.contextHealth) === undefined) {
|
|
805
|
+
if ((0, context_health_1.getContextHealthRemediationLevel)(args.contextHealth) === undefined) {
|
|
813
806
|
return { output: args.output, largeReturnUnavailable: false };
|
|
814
807
|
}
|
|
815
808
|
const visibleBytes = countToolResultVisibleBytes(args.output);
|
|
@@ -1336,7 +1329,7 @@ function formatInvalidFuncCallRuntimeGuide(language, call) {
|
|
|
1336
1329
|
const indexLine = call.toolCallIndex === undefined ? undefined : `- toolCallIndex: ${String(call.toolCallIndex)}`;
|
|
1337
1330
|
if (language === 'en') {
|
|
1338
1331
|
return [
|
|
1339
|
-
'[Runtime notice]
|
|
1332
|
+
'[Runtime notice] Your previous response tried to call a tool, but the tool call was malformed and could not be run.',
|
|
1340
1333
|
'',
|
|
1341
1334
|
`- provider: ${call.provider}`,
|
|
1342
1335
|
`- callId: ${call.callId}`,
|
|
@@ -1348,13 +1341,13 @@ function formatInvalidFuncCallRuntimeGuide(language, call) {
|
|
|
1348
1341
|
'```',
|
|
1349
1342
|
...(indexLine === undefined ? [] : [indexLine]),
|
|
1350
1343
|
'',
|
|
1351
|
-
'Treat that
|
|
1344
|
+
'Treat that tool call as failed. Do not assume the tool ran. Continue the current task; if you still need a tool, call it again with a real tool name and valid arguments.',
|
|
1352
1345
|
]
|
|
1353
1346
|
.filter((line) => line.length > 0)
|
|
1354
1347
|
.join('\n');
|
|
1355
1348
|
}
|
|
1356
1349
|
return [
|
|
1357
|
-
'[
|
|
1350
|
+
'[Dominds 提示] 你上一轮尝试调用工具,但工具调用格式无效,Dominds 没有执行它。',
|
|
1358
1351
|
'',
|
|
1359
1352
|
`- provider: ${call.provider}`,
|
|
1360
1353
|
`- callId: ${call.callId}`,
|
|
@@ -1366,7 +1359,7 @@ function formatInvalidFuncCallRuntimeGuide(language, call) {
|
|
|
1366
1359
|
'```',
|
|
1367
1360
|
...(indexLine === undefined ? [] : [indexLine]),
|
|
1368
1361
|
'',
|
|
1369
|
-
'
|
|
1362
|
+
'请把这次工具调用视为失败,不要假设工具已经执行。继续当前任务;如果仍需要工具,请重新发起一次工具名明确、参数有效的调用。',
|
|
1370
1363
|
]
|
|
1371
1364
|
.filter((line) => line.length > 0)
|
|
1372
1365
|
.join('\n');
|
|
@@ -89,15 +89,19 @@ function buildAggregatedWakePromptContent(events) {
|
|
|
89
89
|
return `${String(index + 1)}. ${eventText}`;
|
|
90
90
|
})
|
|
91
91
|
.join('\n\n');
|
|
92
|
+
// Business scenario: several reminder/environment wakes arrived while the dialog was idle.
|
|
93
|
+
// The model needs the events as state updates, but they are not a new human request and should
|
|
94
|
+
// not trigger a standalone acknowledgement. Say the product meaning plainly instead of exposing
|
|
95
|
+
// internal "runtime event" wording.
|
|
92
96
|
return language === 'zh'
|
|
93
97
|
? `${prefix}
|
|
94
|
-
|
|
98
|
+
以下是对话空闲期间 Dominds 收到的环境事件。这些事件不是新的用户指令。
|
|
95
99
|
|
|
96
100
|
${body}
|
|
97
101
|
|
|
98
102
|
请结合当前任务上下文继续推进;若这些事件不影响当前工作,不要发送占位式确认。`
|
|
99
103
|
: `${prefix}
|
|
100
|
-
The following
|
|
104
|
+
The following environment events reached Dominds while the dialog was idle. These events are not new user instructions.
|
|
101
105
|
|
|
102
106
|
${body}
|
|
103
107
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ContextHealthSnapshot } from '@longrun-ai/kernel/types/context-health';
|
|
2
|
+
import type { ReminderContextBusiness, ReminderContextFollowingMessage, ReminderContextFooterState, ReminderContextHealth } from '../../runtime/driver-messages';
|
|
3
|
+
import type { ChatMessage } from '../client';
|
|
4
|
+
import type { KernelDriverPrompt } from './types';
|
|
5
|
+
export declare function resolveReminderContextFollowingMessage(args: {
|
|
6
|
+
prompt: KernelDriverPrompt | undefined;
|
|
7
|
+
currentTurnDialogMsgsForContext: readonly ChatMessage[];
|
|
8
|
+
}): ReminderContextFollowingMessage;
|
|
9
|
+
export declare function resolveReminderContextHealth(snapshot: ContextHealthSnapshot | undefined): ReminderContextHealth;
|
|
10
|
+
export declare function resolveReminderContextBusinessState(args: {
|
|
11
|
+
followingMessage: ReminderContextFollowingMessage;
|
|
12
|
+
pendingUserInterjectionReply: boolean;
|
|
13
|
+
hasCompletedHandoffWithoutPendingReply: boolean;
|
|
14
|
+
hasDeferredReplyReassertion: boolean;
|
|
15
|
+
hasActiveReplyObligation: boolean;
|
|
16
|
+
}): ReminderContextBusiness;
|
|
17
|
+
export declare function resolveReminderContextFooterStateFromSignals(args: {
|
|
18
|
+
prompt: KernelDriverPrompt | undefined;
|
|
19
|
+
currentTurnDialogMsgsForContext: readonly ChatMessage[];
|
|
20
|
+
contextHealth: ContextHealthSnapshot | undefined;
|
|
21
|
+
pendingUserInterjectionReply: boolean;
|
|
22
|
+
hasCompletedHandoffWithoutPendingReply: boolean;
|
|
23
|
+
hasDeferredReplyReassertion: boolean;
|
|
24
|
+
hasActiveReplyObligation: boolean;
|
|
25
|
+
}): ReminderContextFooterState;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveReminderContextFollowingMessage = resolveReminderContextFollowingMessage;
|
|
4
|
+
exports.resolveReminderContextHealth = resolveReminderContextHealth;
|
|
5
|
+
exports.resolveReminderContextBusinessState = resolveReminderContextBusinessState;
|
|
6
|
+
exports.resolveReminderContextFooterStateFromSignals = resolveReminderContextFooterStateFromSignals;
|
|
7
|
+
const context_health_1 = require("./context-health");
|
|
8
|
+
function resolveReminderContextFollowingMessage(args) {
|
|
9
|
+
if (args.prompt === undefined || args.currentTurnDialogMsgsForContext.length === 0) {
|
|
10
|
+
return { kind: 'none' };
|
|
11
|
+
}
|
|
12
|
+
if (args.prompt.origin !== 'user') {
|
|
13
|
+
return { kind: 'runtime_notice' };
|
|
14
|
+
}
|
|
15
|
+
return typeof args.prompt.q4hAnswerCallId === 'string' &&
|
|
16
|
+
args.prompt.q4hAnswerCallId.trim() !== ''
|
|
17
|
+
? { kind: 'human_answer' }
|
|
18
|
+
: { kind: 'user_message' };
|
|
19
|
+
}
|
|
20
|
+
function resolveReminderContextHealth(snapshot) {
|
|
21
|
+
const remediationLevel = (0, context_health_1.getContextHealthRemediationLevel)(snapshot);
|
|
22
|
+
return remediationLevel === undefined ? { kind: 'normal' } : { kind: remediationLevel };
|
|
23
|
+
}
|
|
24
|
+
function resolveReminderContextBusinessState(args) {
|
|
25
|
+
if (args.followingMessage.kind === 'human_answer') {
|
|
26
|
+
// askHuman answers resume a waiting task. They are not fresh user follow-ups and should not
|
|
27
|
+
// inherit interjection or completed-handoff wording from adjacent durable state.
|
|
28
|
+
return { kind: 'none' };
|
|
29
|
+
}
|
|
30
|
+
if (args.followingMessage.kind === 'user_message' &&
|
|
31
|
+
args.hasCompletedHandoffWithoutPendingReply) {
|
|
32
|
+
// Business scenario: the requester-side work has already received its final report, and now a
|
|
33
|
+
// user is speaking again inside that completed Side Dialog. Dominds can know this from durable
|
|
34
|
+
// handoff state; the model should hear the simple product meaning directly instead of guessing
|
|
35
|
+
// from older task context or reminder-maintenance references.
|
|
36
|
+
return { kind: 'user_followup_after_completed_handoff' };
|
|
37
|
+
}
|
|
38
|
+
if (args.pendingUserInterjectionReply) {
|
|
39
|
+
// User-visible reply gaps take priority over handoff continuation state. The completed
|
|
40
|
+
// handoff case is most specific: Dominds already knows the old delegated task is done. The
|
|
41
|
+
// footer should say there is no old handoff to advance and the model should handle the current
|
|
42
|
+
// user message normally. Do not narrow this to "only answer" or "do not organize reminders":
|
|
43
|
+
// a user may explicitly ask for reminder cleanup/correction as the current conversation topic.
|
|
44
|
+
//
|
|
45
|
+
// This branch may run on a later tool-followup turn where no user message immediately
|
|
46
|
+
// follows the reminder block anymore. That is still the same pending user follow-up; do not
|
|
47
|
+
// demote it to generic auto-continuation wording just because the prompt itself is absent
|
|
48
|
+
// on this retry/continuation round.
|
|
49
|
+
if (args.hasCompletedHandoffWithoutPendingReply) {
|
|
50
|
+
return { kind: 'user_followup_after_completed_handoff' };
|
|
51
|
+
}
|
|
52
|
+
if (args.hasDeferredReplyReassertion) {
|
|
53
|
+
return { kind: 'pending_user_interjection_with_parked_reply' };
|
|
54
|
+
}
|
|
55
|
+
if (args.hasActiveReplyObligation) {
|
|
56
|
+
return { kind: 'pending_user_interjection_with_active_reply' };
|
|
57
|
+
}
|
|
58
|
+
return { kind: 'pending_user_interjection' };
|
|
59
|
+
}
|
|
60
|
+
if (args.hasActiveReplyObligation) {
|
|
61
|
+
return { kind: 'active_reply_obligation' };
|
|
62
|
+
}
|
|
63
|
+
return { kind: 'none' };
|
|
64
|
+
}
|
|
65
|
+
function resolveReminderContextFooterStateFromSignals(args) {
|
|
66
|
+
const followingMessage = resolveReminderContextFollowingMessage({
|
|
67
|
+
prompt: args.prompt,
|
|
68
|
+
currentTurnDialogMsgsForContext: args.currentTurnDialogMsgsForContext,
|
|
69
|
+
});
|
|
70
|
+
return {
|
|
71
|
+
followingMessage,
|
|
72
|
+
contextHealth: resolveReminderContextHealth(args.contextHealth),
|
|
73
|
+
business: resolveReminderContextBusinessState({
|
|
74
|
+
followingMessage,
|
|
75
|
+
pendingUserInterjectionReply: args.pendingUserInterjectionReply,
|
|
76
|
+
hasCompletedHandoffWithoutPendingReply: args.hasCompletedHandoffWithoutPendingReply,
|
|
77
|
+
hasDeferredReplyReassertion: args.hasDeferredReplyReassertion,
|
|
78
|
+
hasActiveReplyObligation: args.hasActiveReplyObligation,
|
|
79
|
+
}),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -38,6 +38,12 @@ function buildPromptContentWithExactReplyToolName(args) {
|
|
|
38
38
|
];
|
|
39
39
|
const directive = args.activeReplyDirective;
|
|
40
40
|
if (!directive) {
|
|
41
|
+
// Business scenario: a user can come back to a Side Dialog after its final reply has already
|
|
42
|
+
// been delivered to the requester. At that point the business obligation is complete and the
|
|
43
|
+
// visible user is simply asking a follow-up in this dialog. Old assignment text and reply tool
|
|
44
|
+
// names remain in transcript history, so the model may otherwise "finish" the old request
|
|
45
|
+
// again. Dominds has already checked durable reply state here; the prompt says the current
|
|
46
|
+
// business expectation directly: answer/continue this conversation normally.
|
|
41
47
|
if (isFbrSideDialog) {
|
|
42
48
|
return args.prompt.content;
|
|
43
49
|
}
|
|
@@ -50,13 +56,13 @@ function buildPromptContentWithExactReplyToolName(args) {
|
|
|
50
56
|
const note = args.language === 'zh'
|
|
51
57
|
? [
|
|
52
58
|
noActivePrefix,
|
|
53
|
-
'
|
|
54
|
-
'
|
|
59
|
+
'Dominds 已经判断好:当前没有别的对话在等你发送最终回贴。',
|
|
60
|
+
'本轮按当前对话正常交流即可;如果用户提出了问题,就直接回答这个问题。',
|
|
55
61
|
].join('\n')
|
|
56
62
|
: [
|
|
57
63
|
noActivePrefix,
|
|
58
|
-
'
|
|
59
|
-
'
|
|
64
|
+
'Dominds has already decided that no other dialog is waiting for your final reply right now.',
|
|
65
|
+
'Handle this as a normal turn in the current conversation; if the user asked a question, answer that question directly.',
|
|
60
66
|
].join('\n');
|
|
61
67
|
return `${note}\n\n${args.prompt.content}`;
|
|
62
68
|
}
|
|
@@ -40,7 +40,7 @@ const TELLASK_SPECIAL_FUNCTION_NAMES = [
|
|
|
40
40
|
'freshBootsReasoning',
|
|
41
41
|
];
|
|
42
42
|
const MULTIPLE_ASKHUMAN_CALLS_ERROR = '不允许一轮多次调用 askHuman,必须单次调用问所有问题。 Do not call askHuman multiple times in one round; ask all questions in a single askHuman call.';
|
|
43
|
-
const MULTIPLE_REPLY_TELLASK_CALLS_ERROR = '
|
|
43
|
+
const MULTIPLE_REPLY_TELLASK_CALLS_ERROR = '不允许一轮多次调用回复工具;只能用当前诉请要求的那个回复工具发送最终结果。 Do not call multiple reply tools in one round; send the final result with the one reply tool required by the current tellask.';
|
|
44
44
|
function isTellaskCallFunctionName(name) {
|
|
45
45
|
return TELLASK_SPECIAL_FUNCTION_NAMES.includes(name);
|
|
46
46
|
}
|
|
@@ -63,6 +63,11 @@ function formatReplyFuncResult(args) {
|
|
|
63
63
|
? `已通过 \`${args.replyCallName}\` 送达回复。`
|
|
64
64
|
: `Reply delivered via \`${args.replyCallName}\`.`;
|
|
65
65
|
}
|
|
66
|
+
// Business scenario: the model called a reply tool when Dominds durable state says either "wrong
|
|
67
|
+
// reply path" or "nothing is waiting for this reply anymore". These are programmatic facts from the
|
|
68
|
+
// active reply record, not something the model should infer from transcript history. Keep the
|
|
69
|
+
// tool result actionable: name the exact tool to use, or tell the model to stop trying to send a
|
|
70
|
+
// reply and continue the current local conversation.
|
|
66
71
|
function formatReplyFuncErrorResult(args) {
|
|
67
72
|
const language = (0, work_language_1.getWorkLanguage)();
|
|
68
73
|
if (language === 'zh') {
|
|
@@ -74,11 +79,11 @@ function formatReplyFuncErrorResult(args) {
|
|
|
74
79
|
return (`错误:当前精确应调用 \`${args.expectedCallName}\`,而不是 \`${args.attemptedCallName}\`。\n\n` +
|
|
75
80
|
`请改用 \`${args.expectedCallName}({ replyContent })\`。`);
|
|
76
81
|
case 'no_active':
|
|
77
|
-
return (
|
|
78
|
-
|
|
82
|
+
return (`错误:当前没有别的对话在等你发送最终回贴。\n\n` +
|
|
83
|
+
`你刚才调用的 \`${args.attemptedCallName}\` 这次不会送达给别的对话。请按当前对话正常交流;如果用户提出了问题,就直接回答这个问题。`);
|
|
79
84
|
case 'no_pending':
|
|
80
|
-
return (
|
|
81
|
-
|
|
85
|
+
return (`错误:这条回贴任务已经不再等待本对话送达(可能已回复或已失效)。\n\n` +
|
|
86
|
+
`你刚才调用的 \`${args.attemptedCallName}\` 这次不会送达给别的对话。请按当前对话正常交流;如果用户提出了问题,就直接回答这个问题。`);
|
|
82
87
|
}
|
|
83
88
|
}
|
|
84
89
|
switch (args.reason) {
|
|
@@ -89,11 +94,11 @@ function formatReplyFuncErrorResult(args) {
|
|
|
89
94
|
return (`Error: the exact reply tool for the current state is \`${args.expectedCallName}\`, not \`${args.attemptedCallName}\`.\n\n` +
|
|
90
95
|
`Call \`${args.expectedCallName}({ replyContent })\` instead.`);
|
|
91
96
|
case 'no_active':
|
|
92
|
-
return ('Error:
|
|
93
|
-
`
|
|
97
|
+
return ('Error: no other dialog is waiting for your final reply right now.\n\n' +
|
|
98
|
+
`Your \`${args.attemptedCallName}\` call will not deliver anything to another dialog this time. Handle this as a normal turn in the current conversation; if the user asked a question, answer that question directly.`);
|
|
94
99
|
case 'no_pending':
|
|
95
|
-
return ('Error:
|
|
96
|
-
`
|
|
100
|
+
return ('Error: this reply task is no longer waiting for delivery from this dialog; it may already be resolved or no longer valid.\n\n' +
|
|
101
|
+
`Your \`${args.attemptedCallName}\` call will not deliver anything to another dialog this time. Handle this as a normal turn in the current conversation; if the user asked a question, answer that question directly.`);
|
|
97
102
|
}
|
|
98
103
|
}
|
|
99
104
|
function buildAssignmentReplyDirective(args) {
|
|
@@ -554,49 +559,54 @@ function formatPendingTellaskFuncResultContent(name, startedAtMs, callId) {
|
|
|
554
559
|
const elapsedSec = Math.floor(elapsedMs / 1000);
|
|
555
560
|
return language === 'zh' ? `${elapsedSec} 秒` : `${elapsedSec}s`;
|
|
556
561
|
})();
|
|
562
|
+
// Business scenario: a tool call has been accepted and dispatched, but no answer has arrived
|
|
563
|
+
// yet. This tool result is a waiting status, not the teammate/human answer body. If the copy
|
|
564
|
+
// exposes only call IDs and "tellask status", models often treat it as a result and continue
|
|
565
|
+
// with invented content. Say plainly who we are waiting for and that Dominds will add the real
|
|
566
|
+
// answer later.
|
|
557
567
|
if (name === 'askHuman') {
|
|
558
568
|
return language === 'zh'
|
|
559
569
|
? [
|
|
560
|
-
'[Dominds
|
|
570
|
+
'[Dominds 等待人类回复]',
|
|
561
571
|
'',
|
|
562
|
-
'
|
|
572
|
+
'你已经向人类提问,当前仍在等待回答。',
|
|
563
573
|
'',
|
|
564
574
|
...(callId ? [`- callId: ${callId}`] : []),
|
|
565
575
|
`- 已等待: ${elapsed}`,
|
|
566
576
|
'',
|
|
567
|
-
'
|
|
577
|
+
'这不是回答正文。若人类稍后回复,Dominds 会把对应结果补入后续上下文。',
|
|
568
578
|
].join('\n')
|
|
569
579
|
: [
|
|
570
|
-
'[Dominds
|
|
580
|
+
'[Dominds waiting for human answer]',
|
|
571
581
|
'',
|
|
572
|
-
'
|
|
582
|
+
'You already asked the human and are still waiting for their answer.',
|
|
573
583
|
'',
|
|
574
584
|
...(callId ? [`- callId: ${callId}`] : []),
|
|
575
585
|
`- Elapsed: ${elapsed}`,
|
|
576
586
|
'',
|
|
577
|
-
'This is not
|
|
587
|
+
'This is not the answer body. If the human replies later, Dominds will add the result to later context.',
|
|
578
588
|
].join('\n');
|
|
579
589
|
}
|
|
580
590
|
return language === 'zh'
|
|
581
591
|
? [
|
|
582
|
-
'[Dominds
|
|
592
|
+
'[Dominds 等待队友回贴]',
|
|
583
593
|
'',
|
|
584
|
-
|
|
594
|
+
`你已经发出 \`${name}\`,当前仍在等待队友回贴。`,
|
|
585
595
|
'',
|
|
586
596
|
...(callId ? [`- callId: ${callId}`] : []),
|
|
587
597
|
`- 已等待: ${elapsed}`,
|
|
588
598
|
'',
|
|
589
|
-
'
|
|
599
|
+
'这不是回贴正文。若稍后收到回贴,Dominds 会把对应结果补入后续上下文。',
|
|
590
600
|
].join('\n')
|
|
591
601
|
: [
|
|
592
|
-
'[Dominds
|
|
602
|
+
'[Dominds waiting for teammate reply]',
|
|
593
603
|
'',
|
|
594
|
-
|
|
604
|
+
`You already sent \`${name}\` and are still waiting for the teammate's reply.`,
|
|
595
605
|
'',
|
|
596
606
|
...(callId ? [`- callId: ${callId}`] : []),
|
|
597
607
|
`- Elapsed: ${elapsed}`,
|
|
598
608
|
'',
|
|
599
|
-
'This is not reply
|
|
609
|
+
'This is not the reply body. If a reply arrives later, Dominds will add the result to later context.',
|
|
600
610
|
].join('\n');
|
|
601
611
|
}
|
|
602
612
|
function formatResolvedTellaskFuncResultContent(args) {
|
|
@@ -605,55 +615,60 @@ function formatResolvedTellaskFuncResultContent(args) {
|
|
|
605
615
|
if (callId === '') {
|
|
606
616
|
throw new Error(`tellask status formatter invariant violation: empty callId for ${args.name}`);
|
|
607
617
|
}
|
|
618
|
+
// Business scenario: a previously dispatched teammate request is being summarized back into
|
|
619
|
+
// context as status. For `pending`, there is still no reply body. For `completed`/`failed`, the
|
|
620
|
+
// actual reply/failure fact is injected separately. The model-facing text must keep those
|
|
621
|
+
// separate so the model neither hallucinates a pending result nor treats this status line as the
|
|
622
|
+
// teammate's answer.
|
|
608
623
|
if (language === 'zh') {
|
|
609
624
|
if (args.status === 'pending') {
|
|
610
625
|
return [
|
|
611
|
-
'[Dominds
|
|
626
|
+
'[Dominds 等待队友回贴]',
|
|
612
627
|
'',
|
|
613
|
-
`\`${args.name}\`
|
|
628
|
+
`\`${args.name}\` 仍在等待队友回贴,当前没有回贴正文。`,
|
|
614
629
|
'',
|
|
615
630
|
`- callId: ${callId}`,
|
|
616
631
|
'',
|
|
617
|
-
'
|
|
632
|
+
'不要把这条状态当作回贴正文;若稍后收到回贴,Dominds 会补入对应结果。',
|
|
618
633
|
].join('\n');
|
|
619
634
|
}
|
|
620
635
|
const statusLabel = args.status === 'completed' ? '已收到回贴' : '已失败收口';
|
|
621
636
|
return [
|
|
622
|
-
'[Dominds
|
|
637
|
+
'[Dominds 队友回贴状态]',
|
|
623
638
|
'',
|
|
624
|
-
`\`${args.name}\`
|
|
639
|
+
`\`${args.name}\` ${statusLabel},对应结果已作为独立上下文补入。`,
|
|
625
640
|
'',
|
|
626
641
|
`- callId: ${callId}`,
|
|
627
642
|
'',
|
|
628
|
-
'
|
|
643
|
+
'请以那条独立结果为准;不要把这条状态当作回贴正文。',
|
|
629
644
|
].join('\n');
|
|
630
645
|
}
|
|
631
646
|
if (args.status === 'pending') {
|
|
632
647
|
return [
|
|
633
|
-
'[Dominds
|
|
648
|
+
'[Dominds waiting for teammate reply]',
|
|
634
649
|
'',
|
|
635
|
-
`\`${args.name}\` is still waiting for
|
|
650
|
+
`\`${args.name}\` is still waiting for the teammate's reply; there is no reply body yet.`,
|
|
636
651
|
'',
|
|
637
652
|
`- callId: ${callId}`,
|
|
638
653
|
'',
|
|
639
|
-
'Do not treat this
|
|
654
|
+
'Do not treat this status as the reply body. If a reply arrives later, Dominds will add the result.',
|
|
640
655
|
].join('\n');
|
|
641
656
|
}
|
|
642
657
|
const statusLabel = args.status === 'completed' ? 'has received a reply' : 'has failed/closed';
|
|
643
658
|
return [
|
|
644
|
-
'[Dominds
|
|
659
|
+
'[Dominds teammate reply status]',
|
|
645
660
|
'',
|
|
646
|
-
`\`${args.name}\` ${statusLabel}; the corresponding
|
|
661
|
+
`\`${args.name}\` ${statusLabel}; the corresponding result is present separately in context.`,
|
|
647
662
|
'',
|
|
648
663
|
`- callId: ${callId}`,
|
|
649
664
|
'',
|
|
650
|
-
'Use
|
|
665
|
+
'Use that separate result as authoritative; do not treat this status as the reply body.',
|
|
651
666
|
].join('\n');
|
|
652
667
|
}
|
|
653
668
|
function formatResolvedAskHumanResultContent() {
|
|
654
669
|
return (0, work_language_1.getWorkLanguage)() === 'zh'
|
|
655
|
-
? '
|
|
656
|
-
: '
|
|
670
|
+
? '人类已经回答;请参考 askHuman 结果气泡。'
|
|
671
|
+
: 'The human has answered; refer to the askHuman result bubble.';
|
|
657
672
|
}
|
|
658
673
|
function buildPendingTellaskFuncResult(args) {
|
|
659
674
|
return {
|
package/dist/mcp/supervisor.js
CHANGED
|
@@ -927,14 +927,14 @@ function upsertMcpToolCallProblem(args) {
|
|
|
927
927
|
const hintLines = workLanguage === 'zh'
|
|
928
928
|
? [
|
|
929
929
|
'建议排查:',
|
|
930
|
-
`- 如果需要全局重建该 MCP server,直接调用 mcp_restart({"serverId":"${args.serverId}"})
|
|
930
|
+
`- 如果需要全局重建该 MCP server,直接调用 mcp_restart({"serverId":"${args.serverId}"});它成功后会清理旧连接/进程的全部 lease`,
|
|
931
931
|
`- 如果只想丢弃当前对话的连接,再调用 mcp_release({"serverId":"${args.serverId}"})`,
|
|
932
932
|
`- 重新打开/关闭浏览器窗口,避免 Playwright persistent context 残留`,
|
|
933
933
|
`- 查看 ${MCP_YAML_PATH} 是否已加载且配置正确(Problems 面板 / 后端日志)`,
|
|
934
934
|
]
|
|
935
935
|
: [
|
|
936
936
|
'Suggested checks:',
|
|
937
|
-
`- To rebuild this MCP server globally, call mcp_restart({"serverId":"${args.serverId}"}) directly; a successful restart clears all leases on the old
|
|
937
|
+
`- To rebuild this MCP server globally, call mcp_restart({"serverId":"${args.serverId}"}) directly; a successful restart clears all leases on the old connection/process`,
|
|
938
938
|
`- To discard only this dialog's connection, call mcp_release({"serverId":"${args.serverId}"})`,
|
|
939
939
|
`- Close/reopen browser windows to avoid leftover Playwright persistent contexts`,
|
|
940
940
|
`- Verify ${MCP_YAML_PATH} is loaded and valid (Problems panel / backend logs)`,
|