dominds 0.6.2 → 0.6.4
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/access-control.js +2 -2
- package/dist/agent-priming.js +826 -92
- package/dist/cli/read.js +406 -12
- package/dist/dialog.js +4 -0
- package/dist/docs/design.md +1 -0
- package/dist/docs/design.zh.md +1 -0
- package/dist/docs/dialog-system.md +12 -7
- package/dist/docs/dialog-system.zh.md +7 -3
- package/dist/docs/dominds-agent-priming.md +10 -1
- package/dist/docs/dominds-agent-priming.zh.md +9 -1
- package/dist/docs/dominds-terminology.md +8 -8
- package/dist/docs/fbr-implementation.md +77 -0
- package/dist/docs/fbr-implementation.zh.md +77 -0
- package/dist/docs/fbr.md +142 -141
- package/dist/docs/fbr.zh.md +129 -123
- package/dist/docs/keep-going.zh.md +162 -0
- package/dist/docs/showing-by-doing.md +208 -0
- package/dist/docs/showing-by-doing.zh.md +177 -0
- package/dist/docs/tellask-collab.md +250 -0
- package/dist/docs/tellask-collab.zh.md +254 -0
- package/dist/docs/txt-editing-tools.md +2 -2
- package/dist/docs/txt-editing-tools.zh.md +2 -2
- package/dist/llm/defaults.yaml +82 -4
- package/dist/llm/driver.js +280 -104
- package/dist/llm/gen/codex.js +49 -2
- package/dist/log.js +385 -30
- package/dist/mcp/supervisor.js +113 -40
- package/dist/minds/builtin/pangu/persona.zh.md +2 -2
- package/dist/minds/load.js +49 -284
- package/dist/minds/minds-i18n.js +2 -2
- package/dist/minds/promptdocs.js +263 -0
- package/dist/minds/system-prompt-parts.js +231 -0
- package/dist/minds/system-prompt.js +190 -223
- package/dist/persistence.js +66 -1
- package/dist/server/websocket-handler.js +14 -0
- package/dist/shared/diligence.js +40 -6
- package/dist/shared/utils/inter-dialog-format.js +3 -5
- package/dist/showing-by-doing.js +34 -31
- package/dist/snippets/README.en.md +3 -0
- package/dist/static/assets/{_baseUniq-C9vbtHF9.js → _baseUniq-C7IpU2Uk.js} +2 -2
- package/dist/static/assets/{_baseUniq-C9vbtHF9.js.map → _baseUniq-C7IpU2Uk.js.map} +1 -1
- package/dist/static/assets/{arc-hulXG01i.js → arc-1bhQqjON.js} +2 -2
- package/dist/static/assets/{arc-hulXG01i.js.map → arc-1bhQqjON.js.map} +1 -1
- package/dist/static/assets/{architectureDiagram-VXUJARFQ-DdLIAMT5.js → architectureDiagram-VXUJARFQ-CkEi1QpB.js} +6 -6
- package/dist/static/assets/{architectureDiagram-VXUJARFQ-DdLIAMT5.js.map → architectureDiagram-VXUJARFQ-CkEi1QpB.js.map} +1 -1
- package/dist/static/assets/{blockDiagram-VD42YOAC-DACsx66C.js → blockDiagram-VD42YOAC-DaBQ5-pY.js} +7 -7
- package/dist/static/assets/{blockDiagram-VD42YOAC-DACsx66C.js.map → blockDiagram-VD42YOAC-DaBQ5-pY.js.map} +1 -1
- package/dist/static/assets/{c4Diagram-YG6GDRKO-Cd5xZlLy.js → c4Diagram-YG6GDRKO-ChUgpgkP.js} +3 -3
- package/dist/static/assets/{c4Diagram-YG6GDRKO-Cd5xZlLy.js.map → c4Diagram-YG6GDRKO-ChUgpgkP.js.map} +1 -1
- package/dist/static/assets/{channel-NQehis0Z.js → channel-CxvmwllM.js} +2 -2
- package/dist/static/assets/{channel-NQehis0Z.js.map → channel-CxvmwllM.js.map} +1 -1
- package/dist/static/assets/{chunk-4BX2VUAB-DZDPl76b.js → chunk-4BX2VUAB-CKsrU2yk.js} +2 -2
- package/dist/static/assets/{chunk-4BX2VUAB-DZDPl76b.js.map → chunk-4BX2VUAB-CKsrU2yk.js.map} +1 -1
- package/dist/static/assets/{chunk-55IACEB6-CFSRDUbl.js → chunk-55IACEB6-BAau9SFt.js} +2 -2
- package/dist/static/assets/{chunk-55IACEB6-CFSRDUbl.js.map → chunk-55IACEB6-BAau9SFt.js.map} +1 -1
- package/dist/static/assets/{chunk-B4BG7PRW-BqQQ9M_z.js → chunk-B4BG7PRW--IiJ7W1m.js} +5 -5
- package/dist/static/assets/{chunk-B4BG7PRW-BqQQ9M_z.js.map → chunk-B4BG7PRW--IiJ7W1m.js.map} +1 -1
- package/dist/static/assets/{chunk-DI55MBZ5-FiFzz1Gh.js → chunk-DI55MBZ5-B83KrPQj.js} +4 -4
- package/dist/static/assets/{chunk-DI55MBZ5-FiFzz1Gh.js.map → chunk-DI55MBZ5-B83KrPQj.js.map} +1 -1
- package/dist/static/assets/{chunk-FMBD7UC4-DqqtCyWK.js → chunk-FMBD7UC4-BlDXzeza.js} +2 -2
- package/dist/static/assets/{chunk-FMBD7UC4-DqqtCyWK.js.map → chunk-FMBD7UC4-BlDXzeza.js.map} +1 -1
- package/dist/static/assets/{chunk-QN33PNHL-F0laQQ-J.js → chunk-QN33PNHL-B596W_v7.js} +2 -2
- package/dist/static/assets/{chunk-QN33PNHL-F0laQQ-J.js.map → chunk-QN33PNHL-B596W_v7.js.map} +1 -1
- package/dist/static/assets/{chunk-QZHKN3VN-CWhEZPaV.js → chunk-QZHKN3VN-UBBCxgBb.js} +2 -2
- package/dist/static/assets/{chunk-QZHKN3VN-CWhEZPaV.js.map → chunk-QZHKN3VN-UBBCxgBb.js.map} +1 -1
- package/dist/static/assets/{chunk-TZMSLE5B-Dx9cnwUy.js → chunk-TZMSLE5B-D-wCX2wJ.js} +2 -2
- package/dist/static/assets/{chunk-TZMSLE5B-Dx9cnwUy.js.map → chunk-TZMSLE5B-D-wCX2wJ.js.map} +1 -1
- package/dist/static/assets/{classDiagram-2ON5EDUG-Dp-dyEGy.js → classDiagram-2ON5EDUG-DvtmzPcu.js} +6 -6
- package/dist/static/assets/{classDiagram-2ON5EDUG-Dp-dyEGy.js.map → classDiagram-2ON5EDUG-DvtmzPcu.js.map} +1 -1
- package/dist/static/assets/{classDiagram-v2-WZHVMYZB-Dp-dyEGy.js → classDiagram-v2-WZHVMYZB-DvtmzPcu.js} +6 -6
- package/dist/static/assets/{classDiagram-v2-WZHVMYZB-Dp-dyEGy.js.map → classDiagram-v2-WZHVMYZB-DvtmzPcu.js.map} +1 -1
- package/dist/static/assets/{clone-C6mKvxs5.js → clone-DgJ0ZR-k.js} +2 -2
- package/dist/static/assets/{clone-C6mKvxs5.js.map → clone-DgJ0ZR-k.js.map} +1 -1
- package/dist/static/assets/{cose-bilkent-S5V4N54A-Dbwh3GoX.js → cose-bilkent-S5V4N54A-DXMyFQvy.js} +2 -2
- package/dist/static/assets/{cose-bilkent-S5V4N54A-Dbwh3GoX.js.map → cose-bilkent-S5V4N54A-DXMyFQvy.js.map} +1 -1
- package/dist/static/assets/{dagre-6UL2VRFP-BD_6e0Uk.js → dagre-6UL2VRFP-BdaUG-j_.js} +7 -7
- package/dist/static/assets/{dagre-6UL2VRFP-BD_6e0Uk.js.map → dagre-6UL2VRFP-BdaUG-j_.js.map} +1 -1
- package/dist/static/assets/{diagram-PSM6KHXK-BWt7Q59-.js → diagram-PSM6KHXK-NLiqKBzn.js} +7 -7
- package/dist/static/assets/{diagram-PSM6KHXK-BWt7Q59-.js.map → diagram-PSM6KHXK-NLiqKBzn.js.map} +1 -1
- package/dist/static/assets/{diagram-QEK2KX5R-D0BvBR_a.js → diagram-QEK2KX5R-D-0fyvY_.js} +6 -6
- package/dist/static/assets/{diagram-QEK2KX5R-D0BvBR_a.js.map → diagram-QEK2KX5R-D-0fyvY_.js.map} +1 -1
- package/dist/static/assets/{diagram-S2PKOQOG-D8uRdKXp.js → diagram-S2PKOQOG-BQ_FU59m.js} +6 -6
- package/dist/static/assets/{diagram-S2PKOQOG-D8uRdKXp.js.map → diagram-S2PKOQOG-BQ_FU59m.js.map} +1 -1
- package/dist/static/assets/{erDiagram-Q2GNP2WA-CQoifjFq.js → erDiagram-Q2GNP2WA-DyftKeuC.js} +5 -5
- package/dist/static/assets/{erDiagram-Q2GNP2WA-CQoifjFq.js.map → erDiagram-Q2GNP2WA-DyftKeuC.js.map} +1 -1
- package/dist/static/assets/{flowDiagram-NV44I4VS-CGhdeaG8.js → flowDiagram-NV44I4VS-9SGefONA.js} +6 -6
- package/dist/static/assets/{flowDiagram-NV44I4VS-CGhdeaG8.js.map → flowDiagram-NV44I4VS-9SGefONA.js.map} +1 -1
- package/dist/static/assets/{ganttDiagram-JELNMOA3-D8W0wb9H.js → ganttDiagram-JELNMOA3-k_WLhf-r.js} +3 -3
- package/dist/static/assets/{ganttDiagram-JELNMOA3-D8W0wb9H.js.map → ganttDiagram-JELNMOA3-k_WLhf-r.js.map} +1 -1
- package/dist/static/assets/{gitGraphDiagram-NY62KEGX-ChHni_jP.js → gitGraphDiagram-NY62KEGX-3eoLlCOY.js} +7 -7
- package/dist/static/assets/{gitGraphDiagram-NY62KEGX-ChHni_jP.js.map → gitGraphDiagram-NY62KEGX-3eoLlCOY.js.map} +1 -1
- package/dist/static/assets/{graph-BWoi_FgC.js → graph-vUevIs4s.js} +3 -3
- package/dist/static/assets/{graph-BWoi_FgC.js.map → graph-vUevIs4s.js.map} +1 -1
- package/dist/static/assets/{index-th_praGg.js → index-BNBG2CE1.js} +399 -68
- package/dist/static/assets/index-BNBG2CE1.js.map +1 -0
- package/dist/static/assets/{infoDiagram-WHAUD3N6-B_XKKZTV.js → infoDiagram-WHAUD3N6-CwEhVxkU.js} +5 -5
- package/dist/static/assets/{infoDiagram-WHAUD3N6-B_XKKZTV.js.map → infoDiagram-WHAUD3N6-CwEhVxkU.js.map} +1 -1
- package/dist/static/assets/{journeyDiagram-XKPGCS4Q-ChGuQ6T9.js → journeyDiagram-XKPGCS4Q-Dtdq4G4Q.js} +5 -5
- package/dist/static/assets/{journeyDiagram-XKPGCS4Q-ChGuQ6T9.js.map → journeyDiagram-XKPGCS4Q-Dtdq4G4Q.js.map} +1 -1
- package/dist/static/assets/{kanban-definition-3W4ZIXB7-BjWe623u.js → kanban-definition-3W4ZIXB7-Bli-AycJ.js} +3 -3
- package/dist/static/assets/{kanban-definition-3W4ZIXB7-BjWe623u.js.map → kanban-definition-3W4ZIXB7-Bli-AycJ.js.map} +1 -1
- package/dist/static/assets/{layout-BPyT310w.js → layout-CGlA8c09.js} +5 -5
- package/dist/static/assets/{layout-BPyT310w.js.map → layout-CGlA8c09.js.map} +1 -1
- package/dist/static/assets/{linear-xUsVjXWq.js → linear-Da2jDWL3.js} +2 -2
- package/dist/static/assets/{linear-xUsVjXWq.js.map → linear-Da2jDWL3.js.map} +1 -1
- package/dist/static/assets/{min-xFt7zeOd.js → min-Co741hTV.js} +3 -3
- package/dist/static/assets/{min-xFt7zeOd.js.map → min-Co741hTV.js.map} +1 -1
- package/dist/static/assets/{mindmap-definition-VGOIOE7T-DT_dvf2c.js → mindmap-definition-VGOIOE7T-DvkIjoq8.js} +4 -4
- package/dist/static/assets/{mindmap-definition-VGOIOE7T-DT_dvf2c.js.map → mindmap-definition-VGOIOE7T-DvkIjoq8.js.map} +1 -1
- package/dist/static/assets/{pieDiagram-ADFJNKIX-B1DQ-OaG.js → pieDiagram-ADFJNKIX-BGuGhTu8.js} +7 -7
- package/dist/static/assets/{pieDiagram-ADFJNKIX-B1DQ-OaG.js.map → pieDiagram-ADFJNKIX-BGuGhTu8.js.map} +1 -1
- package/dist/static/assets/{quadrantDiagram-AYHSOK5B-IHqyr3iT.js → quadrantDiagram-AYHSOK5B-DAZcrJMg.js} +3 -3
- package/dist/static/assets/{quadrantDiagram-AYHSOK5B-IHqyr3iT.js.map → quadrantDiagram-AYHSOK5B-DAZcrJMg.js.map} +1 -1
- package/dist/static/assets/{requirementDiagram-UZGBJVZJ-CKBpht7B.js → requirementDiagram-UZGBJVZJ-CXN0DxZs.js} +4 -4
- package/dist/static/assets/{requirementDiagram-UZGBJVZJ-CKBpht7B.js.map → requirementDiagram-UZGBJVZJ-CXN0DxZs.js.map} +1 -1
- package/dist/static/assets/{sankeyDiagram-TZEHDZUN-D2uGjv3i.js → sankeyDiagram-TZEHDZUN-B7-yAePZ.js} +2 -2
- package/dist/static/assets/{sankeyDiagram-TZEHDZUN-D2uGjv3i.js.map → sankeyDiagram-TZEHDZUN-B7-yAePZ.js.map} +1 -1
- package/dist/static/assets/{sequenceDiagram-WL72ISMW-wLFRhAKd.js → sequenceDiagram-WL72ISMW-DfBNY6h_.js} +4 -4
- package/dist/static/assets/{sequenceDiagram-WL72ISMW-wLFRhAKd.js.map → sequenceDiagram-WL72ISMW-DfBNY6h_.js.map} +1 -1
- package/dist/static/assets/{stateDiagram-FKZM4ZOC-BFGQTbx5.js → stateDiagram-FKZM4ZOC-BLo1xRVY.js} +9 -9
- package/dist/static/assets/{stateDiagram-FKZM4ZOC-BFGQTbx5.js.map → stateDiagram-FKZM4ZOC-BLo1xRVY.js.map} +1 -1
- package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-DF7AjJuk.js → stateDiagram-v2-4FDKWEC3-Dq7MAD0I.js} +5 -5
- package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-DF7AjJuk.js.map → stateDiagram-v2-4FDKWEC3-Dq7MAD0I.js.map} +1 -1
- package/dist/static/assets/{timeline-definition-IT6M3QCI-ChHFOb0o.js → timeline-definition-IT6M3QCI-ySWyBF3b.js} +3 -3
- package/dist/static/assets/{timeline-definition-IT6M3QCI-ChHFOb0o.js.map → timeline-definition-IT6M3QCI-ySWyBF3b.js.map} +1 -1
- package/dist/static/assets/{treemap-KMMF4GRG-BxaNvQU4.js → treemap-KMMF4GRG-DOp4sqOh.js} +4 -4
- package/dist/static/assets/{treemap-KMMF4GRG-BxaNvQU4.js.map → treemap-KMMF4GRG-DOp4sqOh.js.map} +1 -1
- package/dist/static/assets/{xychartDiagram-PRI3JC2R-CrNKeY_-.js → xychartDiagram-PRI3JC2R-vkmh67qb.js} +3 -3
- package/dist/static/assets/{xychartDiagram-PRI3JC2R-CrNKeY_-.js.map → xychartDiagram-PRI3JC2R-vkmh67qb.js.map} +1 -1
- package/dist/static/index.html +1 -1
- package/dist/team.js +29 -6
- package/dist/tool.js +56 -0
- package/dist/tools/builtins.js +4 -2
- package/dist/tools/context-health.js +7 -7
- package/dist/tools/os.js +267 -30
- package/dist/tools/pending-tellask-reminder.js +185 -0
- package/dist/tools/plan.js +1 -0
- package/dist/tools/ripgrep.js +145 -4
- package/dist/tools/shell-tools.js +21 -0
- package/dist/tools/team-mgmt.js +4 -4
- package/dist/tools/toolset-manual.js +74 -0
- package/dist/utils/task-doc.js +16 -16
- package/package.json +1 -1
- package/dist/minds/builtin/cmdr/persona.md +0 -3
- package/dist/minds/builtin/dijiang/knowledge.md +0 -287
- package/dist/minds/builtin/dijiang/persona.md +0 -7
- package/dist/static/assets/index-th_praGg.js.map +0 -1
- package/dist/static/testing/dom-observation-utils.js +0 -425
- package/dist/static/testing/e2e-test-helper.js +0 -3119
package/dist/mcp/supervisor.js
CHANGED
|
@@ -54,6 +54,7 @@ const server_runtime_1 = require("./server-runtime");
|
|
|
54
54
|
const tool_names_1 = require("./tool-names");
|
|
55
55
|
const log = (0, log_1.createLogger)('mcp/supervisor');
|
|
56
56
|
const MCP_YAML_PATH = path.join('.minds', 'mcp.yaml');
|
|
57
|
+
const MCP_TOOL_CALL_PROBLEM_PREFIX = 'mcp/tool_call_error/';
|
|
57
58
|
const serverStateById = new Map();
|
|
58
59
|
const toolOwnerByName = new Map();
|
|
59
60
|
const toolsetOwnerByName = new Map();
|
|
@@ -150,41 +151,54 @@ class McpServerDispatch {
|
|
|
150
151
|
}
|
|
151
152
|
}
|
|
152
153
|
async callToolForDialog(dlg, mcpToolName, args) {
|
|
154
|
+
const serverId = this.serverId;
|
|
155
|
+
const withActionableError = async (fn) => {
|
|
156
|
+
try {
|
|
157
|
+
const raw = await fn();
|
|
158
|
+
const out = await materializeMcpToolCallOutput({
|
|
159
|
+
dlg,
|
|
160
|
+
serverId,
|
|
161
|
+
toolName: mcpToolName,
|
|
162
|
+
raw,
|
|
163
|
+
});
|
|
164
|
+
clearMcpToolCallProblem(serverId);
|
|
165
|
+
return out;
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
const workLanguage = (0, runtime_language_1.getWorkLanguage)();
|
|
169
|
+
const errorText = err instanceof Error ? err.message : String(err);
|
|
170
|
+
upsertMcpToolCallProblem({
|
|
171
|
+
serverId,
|
|
172
|
+
toolName: mcpToolName,
|
|
173
|
+
errorText,
|
|
174
|
+
});
|
|
175
|
+
const msg = workLanguage === 'zh'
|
|
176
|
+
? `MCP 工具调用失败(详见 Problems 面板):${serverId}.${mcpToolName}: ${errorText}`
|
|
177
|
+
: `MCP tool call failed (see Problems panel): ${serverId}.${mcpToolName}: ${errorText}`;
|
|
178
|
+
const wrapped = new Error(msg);
|
|
179
|
+
// Attach the original error for debugging without relying on ErrorOptions typing.
|
|
180
|
+
wrapped.cause = err;
|
|
181
|
+
throw wrapped;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
153
184
|
if (this.cfg.truelyStateless) {
|
|
154
|
-
|
|
185
|
+
const sharedRuntime = this.sharedRuntime;
|
|
186
|
+
if (!sharedRuntime) {
|
|
155
187
|
throw new Error(`MCP server '${this.serverId}' missing shared runtime`);
|
|
156
188
|
}
|
|
157
|
-
|
|
158
|
-
return await materializeMcpToolCallOutput({
|
|
159
|
-
dlg,
|
|
160
|
-
serverId: this.serverId,
|
|
161
|
-
toolName: mcpToolName,
|
|
162
|
-
raw,
|
|
163
|
-
});
|
|
189
|
+
return await withActionableError(async () => await sharedRuntime.callToolRaw(mcpToolName, args));
|
|
164
190
|
}
|
|
165
191
|
const dialogKey = dlg.id.key();
|
|
166
192
|
const existing = this.leasesByDialogKey.get(dialogKey);
|
|
167
193
|
if (existing) {
|
|
168
194
|
this.attachLeaseReminder(dlg);
|
|
169
|
-
|
|
170
|
-
return await materializeMcpToolCallOutput({
|
|
171
|
-
dlg,
|
|
172
|
-
serverId: this.serverId,
|
|
173
|
-
toolName: mcpToolName,
|
|
174
|
-
raw,
|
|
175
|
-
});
|
|
195
|
+
return await withActionableError(async () => await existing.callToolRaw(mcpToolName, args));
|
|
176
196
|
}
|
|
177
197
|
if (this.stopRequested) {
|
|
178
198
|
const oneShot = await this.connectNewLeaseRuntime();
|
|
179
199
|
this.attachLeaseReminder(dlg);
|
|
180
200
|
try {
|
|
181
|
-
|
|
182
|
-
return await materializeMcpToolCallOutput({
|
|
183
|
-
dlg,
|
|
184
|
-
serverId: this.serverId,
|
|
185
|
-
toolName: mcpToolName,
|
|
186
|
-
raw,
|
|
187
|
-
});
|
|
201
|
+
return await withActionableError(async () => await oneShot.callToolRaw(mcpToolName, args));
|
|
188
202
|
}
|
|
189
203
|
finally {
|
|
190
204
|
oneShot.requestStop({ forceKillAfterMs: 3000 });
|
|
@@ -209,13 +223,7 @@ class McpServerDispatch {
|
|
|
209
223
|
}
|
|
210
224
|
const runtime = await init;
|
|
211
225
|
this.attachLeaseReminder(dlg);
|
|
212
|
-
|
|
213
|
-
return await materializeMcpToolCallOutput({
|
|
214
|
-
dlg,
|
|
215
|
-
serverId: this.serverId,
|
|
216
|
-
toolName: mcpToolName,
|
|
217
|
-
raw,
|
|
218
|
-
});
|
|
226
|
+
return await withActionableError(async () => await runtime.callToolRaw(mcpToolName, args));
|
|
219
227
|
}
|
|
220
228
|
async connectNewLeaseRuntime() {
|
|
221
229
|
const serverId = this.serverId;
|
|
@@ -280,14 +288,28 @@ let mindsDirWatcher;
|
|
|
280
288
|
let workspaceWatcher;
|
|
281
289
|
let pollTimer;
|
|
282
290
|
let debounceTimer;
|
|
283
|
-
let
|
|
291
|
+
let lastSeenMcpYamlSig;
|
|
284
292
|
let reloadChain = Promise.resolve();
|
|
293
|
+
let supervisorStarted = false;
|
|
285
294
|
function startMcpSupervisor() {
|
|
295
|
+
if (supervisorStarted)
|
|
296
|
+
return;
|
|
297
|
+
supervisorStarted = true;
|
|
286
298
|
reloadChain = reloadChain
|
|
287
299
|
.then(async () => await reloadNow('startup'))
|
|
288
300
|
.catch((err) => {
|
|
289
301
|
log.warn('MCP initial load failed', err);
|
|
290
302
|
});
|
|
303
|
+
// Initialize signature baseline (best-effort). This reduces false negatives in polling on filesystems
|
|
304
|
+
// with coarse mtime resolution.
|
|
305
|
+
reloadChain = reloadChain
|
|
306
|
+
.then(async () => {
|
|
307
|
+
const sig = await readMcpYamlSig();
|
|
308
|
+
lastSeenMcpYamlSig = sig;
|
|
309
|
+
})
|
|
310
|
+
.catch((err) => {
|
|
311
|
+
log.warn('MCP initial signature read failed', err);
|
|
312
|
+
});
|
|
291
313
|
// Best-effort file watch (fast feedback). `.minds/` may be wiped/recreated during a dev session,
|
|
292
314
|
// so watcher setup must be resilient and re-attempted at runtime.
|
|
293
315
|
void ensureMindsDirWatcher('startup');
|
|
@@ -299,6 +321,7 @@ function startMcpSupervisor() {
|
|
|
299
321
|
if (name !== '' && name !== path.dirname(MCP_YAML_PATH))
|
|
300
322
|
return;
|
|
301
323
|
void ensureMindsDirWatcher('rtws.watch');
|
|
324
|
+
scheduleReload('rtws.watch');
|
|
302
325
|
});
|
|
303
326
|
workspaceWatcher.on('error', () => {
|
|
304
327
|
if (workspaceWatcher) {
|
|
@@ -333,6 +356,8 @@ function stopMcpSupervisor() {
|
|
|
333
356
|
clearTimeout(debounceTimer);
|
|
334
357
|
debounceTimer = undefined;
|
|
335
358
|
}
|
|
359
|
+
lastSeenMcpYamlSig = undefined;
|
|
360
|
+
supervisorStarted = false;
|
|
336
361
|
}
|
|
337
362
|
function requestMcpServerRestart(serverId) {
|
|
338
363
|
return new Promise((resolve) => {
|
|
@@ -416,25 +441,32 @@ function scheduleReload(reason) {
|
|
|
416
441
|
});
|
|
417
442
|
}, 200);
|
|
418
443
|
}
|
|
419
|
-
async function
|
|
420
|
-
let mtimeMs;
|
|
444
|
+
async function readMcpYamlSig() {
|
|
421
445
|
try {
|
|
422
446
|
const st = await fs.promises.stat(MCP_YAML_PATH);
|
|
423
|
-
|
|
447
|
+
if (!st.isFile()) {
|
|
448
|
+
return `not_file/${st.size}/${st.mtimeMs}/${st.ctimeMs}`;
|
|
449
|
+
}
|
|
450
|
+
return `${st.size}/${st.mtimeMs}/${st.ctimeMs}`;
|
|
424
451
|
}
|
|
425
452
|
catch (err) {
|
|
426
453
|
const code = isRecord(err) && 'code' in err ? err.code : undefined;
|
|
427
454
|
if (code === 'ENOENT') {
|
|
428
|
-
|
|
429
|
-
}
|
|
430
|
-
else {
|
|
431
|
-
return;
|
|
455
|
+
return 'missing';
|
|
432
456
|
}
|
|
457
|
+
return 'error';
|
|
433
458
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
459
|
+
}
|
|
460
|
+
async function maybePollReload() {
|
|
461
|
+
const sig = await readMcpYamlSig();
|
|
462
|
+
if (lastSeenMcpYamlSig === undefined) {
|
|
463
|
+
lastSeenMcpYamlSig = sig;
|
|
464
|
+
return;
|
|
437
465
|
}
|
|
466
|
+
if (sig === lastSeenMcpYamlSig)
|
|
467
|
+
return;
|
|
468
|
+
lastSeenMcpYamlSig = sig;
|
|
469
|
+
scheduleReload('poll');
|
|
438
470
|
}
|
|
439
471
|
async function reloadNow(reason) {
|
|
440
472
|
let rawText;
|
|
@@ -542,6 +574,47 @@ function upsertWorkspaceConfigProblem(errorText) {
|
|
|
542
574
|
function clearWorkspaceConfigProblem() {
|
|
543
575
|
(0, problems_1.removeProblemsByPrefix)('mcp/workspace_config_error');
|
|
544
576
|
}
|
|
577
|
+
function upsertMcpToolCallProblem(args) {
|
|
578
|
+
const workLanguage = (0, runtime_language_1.getWorkLanguage)();
|
|
579
|
+
const normalizedErrorText = args.errorText.length > 10000 ? `${args.errorText.slice(0, 10000)}…` : args.errorText;
|
|
580
|
+
const hintLines = workLanguage === 'zh'
|
|
581
|
+
? [
|
|
582
|
+
'建议排查:',
|
|
583
|
+
`- 先释放租约:mcp_release({"serverId":"${args.serverId}"})`,
|
|
584
|
+
`- 重新打开/关闭浏览器窗口,避免 Playwright persistent context 残留`,
|
|
585
|
+
`- 查看 ${MCP_YAML_PATH} 是否已加载且配置正确(Problems 面板 / 后端日志)`,
|
|
586
|
+
]
|
|
587
|
+
: [
|
|
588
|
+
'Suggested checks:',
|
|
589
|
+
`- Release the lease first: mcp_release({"serverId":"${args.serverId}"})`,
|
|
590
|
+
`- Close/reopen browser windows to avoid leftover Playwright persistent contexts`,
|
|
591
|
+
`- Verify ${MCP_YAML_PATH} is loaded and valid (Problems panel / backend logs)`,
|
|
592
|
+
];
|
|
593
|
+
(0, problems_1.upsertProblem)({
|
|
594
|
+
kind: 'generic_problem',
|
|
595
|
+
source: 'system',
|
|
596
|
+
id: `${MCP_TOOL_CALL_PROBLEM_PREFIX}${sanitizePathSegment(args.serverId)}`,
|
|
597
|
+
severity: 'error',
|
|
598
|
+
timestamp: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
599
|
+
message: workLanguage === 'zh'
|
|
600
|
+
? `MCP 工具调用失败:${args.serverId}.${args.toolName}`
|
|
601
|
+
: `MCP tool call failed: ${args.serverId}.${args.toolName}`,
|
|
602
|
+
detail: {
|
|
603
|
+
text: [
|
|
604
|
+
`serverId=${args.serverId}`,
|
|
605
|
+
`toolName=${args.toolName}`,
|
|
606
|
+
'',
|
|
607
|
+
'error:',
|
|
608
|
+
normalizedErrorText,
|
|
609
|
+
'',
|
|
610
|
+
...hintLines,
|
|
611
|
+
].join('\n'),
|
|
612
|
+
},
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
function clearMcpToolCallProblem(serverId) {
|
|
616
|
+
(0, problems_1.removeProblemsByPrefix)(`${MCP_TOOL_CALL_PROBLEM_PREFIX}${sanitizePathSegment(serverId)}`);
|
|
617
|
+
}
|
|
545
618
|
async function applyWorkspaceConfig(config, invalidServers, serverIdsInYamlOrder, validServerIdsInYamlOrder, reason) {
|
|
546
619
|
log.info(`Applying MCP rtws config (${reason})`);
|
|
547
620
|
const invalidIds = new Set(invalidServers.map((s) => s.serverId));
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
|
|
47
47
|
2. **经授权响应其他智能体**:收到@fuxi 以外智能体以 `!?@pangu` 从第 0 列开头的诉请时,**不做任何操作预判**,立即 `!?@fuxi` 发起授权确认;获@fuxi 授权后,按要求执行并同步结果;未获授权,直接拒绝并同步。
|
|
48
48
|
|
|
49
|
-
3.
|
|
49
|
+
3. **通用执行要求**:若诉请模糊、存在潜在风险或超出自身操作边界,立即向诉请者+@fuxi 同步确认细节;若诉请涉及 .minds/ 目录,直接@fuxi 并向诉请者明确拒绝。
|
|
50
50
|
|
|
51
51
|
### 二、开创性工作(唯一主动介入,先商后做)
|
|
52
52
|
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
|
|
81
81
|
3. **与显在团队成员交流**:收到其@pangu 开头的诉请时,仅回复授权确认进展,不做操作承诺。
|
|
82
82
|
|
|
83
|
-
4. **交流频率**:执行诉请遇阻时立即以
|
|
83
|
+
4. **交流频率**:执行诉请遇阻时立即以 `!?@<诉请者>`+`!?@fuxi` 并列诉请,发现 rtws 问题时立即@fuxi。
|
|
84
84
|
|
|
85
85
|
## 行动准则
|
|
86
86
|
|
package/dist/minds/load.js
CHANGED
|
@@ -8,133 +8,15 @@ const promises_1 = require("fs/promises");
|
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const dialog_1 = require("../dialog");
|
|
10
10
|
const log_1 = require("../log");
|
|
11
|
-
const text_1 = require("../shared/i18n/text");
|
|
12
11
|
const runtime_language_1 = require("../shared/runtime-language");
|
|
13
12
|
const time_1 = require("../shared/utils/time");
|
|
14
13
|
const team_1 = require("../team");
|
|
15
14
|
const ctrl_1 = require("../tools/ctrl");
|
|
16
|
-
const
|
|
15
|
+
const shell_tools_1 = require("../tools/shell-tools");
|
|
16
|
+
const toolset_manual_1 = require("../tools/toolset-manual");
|
|
17
17
|
const minds_i18n_1 = require("./minds-i18n");
|
|
18
18
|
const system_prompt_1 = require("./system-prompt");
|
|
19
|
-
const
|
|
20
|
-
function isShellToolName(name) {
|
|
21
|
-
return SHELL_TOOL_NAMES.includes(name);
|
|
22
|
-
}
|
|
23
|
-
function listShellSpecialistMemberIds(team) {
|
|
24
|
-
const out = [];
|
|
25
|
-
for (const id of team.shellSpecialists) {
|
|
26
|
-
const member = team.getMember(id);
|
|
27
|
-
if (!member)
|
|
28
|
-
continue;
|
|
29
|
-
if (member.hidden === true)
|
|
30
|
-
continue;
|
|
31
|
-
out.push(id);
|
|
32
|
-
}
|
|
33
|
-
return out;
|
|
34
|
-
}
|
|
35
|
-
function buildShellPolicyPrompt(options) {
|
|
36
|
-
const { language, agentIsShellSpecialist, agentHasShellTools, agentHasReadonlyShell, shellSpecialistMemberIds, } = options;
|
|
37
|
-
const title = language === 'zh' ? '### Shell 执行策略(重要)' : '### Shell Execution Policy (Important)';
|
|
38
|
-
const shellSpecialists = shellSpecialistMemberIds.length > 0
|
|
39
|
-
? shellSpecialistMemberIds.map((id) => `@${id}`).join(', ')
|
|
40
|
-
: language === 'zh'
|
|
41
|
-
? '(未配置 shell 专员)'
|
|
42
|
-
: '(no shell specialists configured)';
|
|
43
|
-
if (agentIsShellSpecialist && agentHasShellTools) {
|
|
44
|
-
const body = language === 'zh'
|
|
45
|
-
? [
|
|
46
|
-
'你是本队的 shell 专员,具备 shell 执行能力(高风险)。使用前必须先做风险识别与最小化:',
|
|
47
|
-
'- 说明目的、预期输出/验证方式、预期工作目录与影响面。',
|
|
48
|
-
'- 优先选择只读命令;写入/删除/网络/权限相关操作必须解释理由与安全边界。',
|
|
49
|
-
'- 如果不确定命令后果,先提出更安全的替代方案或向人类/队友确认。',
|
|
50
|
-
'',
|
|
51
|
-
'当队友请求你执行命令时:请先复述你将执行的命令与风险边界,再执行,并按结构化格式回传 command/exit_code/stdout/stderr。',
|
|
52
|
-
'',
|
|
53
|
-
`本队 shell 专员列表:${shellSpecialists}`,
|
|
54
|
-
].join('\n')
|
|
55
|
-
: [
|
|
56
|
-
'You are a designated shell specialist and have shell execution capability (high-risk). Before using it, do risk identification and minimize blast radius:',
|
|
57
|
-
'- State intent, expected output/verification, expected working directory, and scope of impact.',
|
|
58
|
-
'- Prefer read-only commands; for writes/deletes/network/privilege-related actions, justify and state safety boundaries.',
|
|
59
|
-
'- If unsure about consequences, propose a safer alternative or confirm with a human/teammate first.',
|
|
60
|
-
'',
|
|
61
|
-
'When teammates ask you to run commands: restate the exact command and guardrails, then execute, and report back with a structured receipt: command/exit_code/stdout/stderr.',
|
|
62
|
-
'',
|
|
63
|
-
`Shell specialists in this team: ${shellSpecialists}`,
|
|
64
|
-
].join('\n');
|
|
65
|
-
return `${title}\n\n${body}`.trim();
|
|
66
|
-
}
|
|
67
|
-
if (agentIsShellSpecialist && !agentHasShellTools) {
|
|
68
|
-
const body = language === 'zh'
|
|
69
|
-
? [
|
|
70
|
-
'你被配置为 shell 专员,但当前没有可用的 shell 工具(团队配置错误)。',
|
|
71
|
-
'在未修复配置前:不要声称自己执行过命令;如需验证,请让人类修复 team.yaml 或把 shell 能力授予正确的成员。',
|
|
72
|
-
'',
|
|
73
|
-
`本队 shell 专员列表:${shellSpecialists}`,
|
|
74
|
-
].join('\n')
|
|
75
|
-
: [
|
|
76
|
-
'You are configured as a shell specialist, but you do not currently have shell tools available (team configuration error).',
|
|
77
|
-
'Until it is fixed: do not claim you ran any command; ask a human to fix team.yaml or grant shell tools to the correct specialist member.',
|
|
78
|
-
'',
|
|
79
|
-
`Shell specialists in this team: ${shellSpecialists}`,
|
|
80
|
-
].join('\n');
|
|
81
|
-
return `${title}\n\n${body}`.trim();
|
|
82
|
-
}
|
|
83
|
-
const body = language === 'zh'
|
|
84
|
-
? agentHasReadonlyShell
|
|
85
|
-
? [
|
|
86
|
-
'你不具备高权限 shell 工具(shell_cmd/stop_daemon/get_daemon_output)。',
|
|
87
|
-
'你已被明确授权使用 `readonly_shell` 自行执行只读命令(仅允许白名单命令前缀):请直接调用,不要去寻找 shell 专员代跑。',
|
|
88
|
-
'',
|
|
89
|
-
'当你需要的命令不在白名单内,或需要写入/删除/网络/长时间运行/进程管理等高风险能力时:再转交给具备 shell 工具的专员队友,并提供充分理由与可审查的命令提案:',
|
|
90
|
-
'- 你要达成的目标(why)',
|
|
91
|
-
'- 建议命令(what)+ 预期工作目录(cwd)+ 预期输出/验证方式(how to verify)',
|
|
92
|
-
'- 风险评估与安全边界(risk & guardrails)',
|
|
93
|
-
`可转交的 shell 专员队友:${shellSpecialists}`,
|
|
94
|
-
'',
|
|
95
|
-
'重要:如果你打算让队友执行命令,请在同一条消息里给出完整的 tellask 诉请块(以第 0 列开头的 `!?@<shell-specialist>` 行),不要只说“我会请某人运行”。',
|
|
96
|
-
'重要:在你看到 shell 专员的回执(command/exit_code/stdout/stderr)之前,不要声称“已运行/已通过/无错”。',
|
|
97
|
-
].join('\n')
|
|
98
|
-
: [
|
|
99
|
-
'你不具备 shell 工具(本环境仅 shell 专员可执行 shell):不要尝试“编造/假设”命令输出,也不要要求系统直接执行。',
|
|
100
|
-
'当你确实需要 shell 执行时:请转交给具备 shell 能力的专员队友,并提供充分理由与可审查的命令提案:',
|
|
101
|
-
'- 你要达成的目标(why)',
|
|
102
|
-
'- 建议命令(what)+ 预期工作目录(cwd)+ 预期输出/验证方式(how to verify)',
|
|
103
|
-
'- 风险评估与安全边界(risk & guardrails)',
|
|
104
|
-
`可转交的 shell 专员队友:${shellSpecialists}`,
|
|
105
|
-
'',
|
|
106
|
-
'重要:如果你打算让队友执行命令,请在同一条消息里给出完整的 tellask 诉请块(以第 0 列开头的 `!?@<shell-specialist>` 行),不要只说“我会请某人运行”。',
|
|
107
|
-
'重要:在你看到 shell 专员的回执(command/exit_code/stdout/stderr)之前,不要声称“已运行/已通过/无错”。',
|
|
108
|
-
].join('\n')
|
|
109
|
-
: agentHasReadonlyShell
|
|
110
|
-
? [
|
|
111
|
-
'You do not have high-risk shell tools (shell_cmd/stop_daemon/get_daemon_output).',
|
|
112
|
-
'You are explicitly authorized to use `readonly_shell` yourself for read-only inspection via its small allowlist. Call it directly; do not go looking for a shell specialist to run it for you.',
|
|
113
|
-
'',
|
|
114
|
-
'When the command you need is not in the allowlist, or you need high-risk capabilities like writes/deletes/network/long-running jobs/process management: delegate to a shell specialist teammate with a justified, reviewable proposal:',
|
|
115
|
-
'- Goal (why)',
|
|
116
|
-
'- Proposed command (what) + expected working directory (cwd) + expected output/verification (how to verify)',
|
|
117
|
-
'- Risk assessment and guardrails (risk & guardrails)',
|
|
118
|
-
'',
|
|
119
|
-
`Shell specialist teammates: ${shellSpecialists}`,
|
|
120
|
-
'',
|
|
121
|
-
'Important: if you intend to delegate, include the full tellask block (a column-0 `!?@<shell-specialist>` line) in the same message; do not just say “I will ask someone to run it”.',
|
|
122
|
-
'Important: do not claim “ran/passed/no errors” until you see the shell specialist’s receipt (command/exit_code/stdout/stderr).',
|
|
123
|
-
].join('\n')
|
|
124
|
-
: [
|
|
125
|
-
'You do not have shell tools configured (shell execution is restricted to designated specialists): do not fabricate/assume command output, and do not ask the system to execute commands directly.',
|
|
126
|
-
'When you truly need shell execution, delegate to a shell specialist teammate with a justified, reviewable proposal:',
|
|
127
|
-
'- Goal (why)',
|
|
128
|
-
'- Proposed command (what) + expected working directory (cwd) + expected output/verification (how to verify)',
|
|
129
|
-
'- Risk assessment and guardrails (risk & guardrails)',
|
|
130
|
-
'',
|
|
131
|
-
`Shell specialist teammates: ${shellSpecialists}`,
|
|
132
|
-
'',
|
|
133
|
-
'Important: if you intend to delegate, include the full tellask block (a column-0 `!?@<shell-specialist>` line) in the same message; do not just say “I will ask someone to run it”.',
|
|
134
|
-
'Important: do not claim “ran/passed/no errors” until you see the shell specialist’s receipt (command/exit_code/stdout/stderr).',
|
|
135
|
-
].join('\n');
|
|
136
|
-
return `${title}\n\n${body}`.trim();
|
|
137
|
-
}
|
|
19
|
+
const system_prompt_parts_1 = require("./system-prompt-parts");
|
|
138
20
|
async function readAgentMindResult(id, fn) {
|
|
139
21
|
const mindFn = path_1.default.join('.minds', 'team', id, fn);
|
|
140
22
|
try {
|
|
@@ -221,8 +103,9 @@ async function readMindsTextPreferred(options) {
|
|
|
221
103
|
}
|
|
222
104
|
return options.noFileDefault;
|
|
223
105
|
}
|
|
224
|
-
async function loadAgentMinds(agentId, dialog) {
|
|
106
|
+
async function loadAgentMinds(agentId, dialog, options) {
|
|
225
107
|
const workingLanguage = (0, runtime_language_1.getWorkLanguage)();
|
|
108
|
+
const missingToolsetPolicy = options?.missingToolsetPolicy ?? 'warn';
|
|
226
109
|
let team = await team_1.Team.load();
|
|
227
110
|
const agent = agentId === undefined ? team.getDefaultResponder() : team.getMember(agentId);
|
|
228
111
|
if (!agent)
|
|
@@ -260,10 +143,10 @@ async function loadAgentMinds(agentId, dialog) {
|
|
|
260
143
|
// policy and may carry shell tools.
|
|
261
144
|
const agentIsShellSpecialist = team.shellSpecialists.includes(agent.id) || agent.hidden === true;
|
|
262
145
|
const baseAgentTools = (() => {
|
|
263
|
-
const tools = agent.listTools();
|
|
146
|
+
const tools = agent.listTools({ onMissingToolset: missingToolsetPolicy });
|
|
264
147
|
if (agentIsShellSpecialist)
|
|
265
148
|
return tools;
|
|
266
|
-
return tools.filter((t) => !(t.type === 'func' && typeof t.name === 'string' && isShellToolName(t.name)));
|
|
149
|
+
return tools.filter((t) => !(t.type === 'func' && typeof t.name === 'string' && (0, shell_tools_1.isShellToolName)(t.name)));
|
|
267
150
|
})();
|
|
268
151
|
// Inject intrinsic dialog control tools as function tools (available to all agents).
|
|
269
152
|
const intrinsicFuncTools = [
|
|
@@ -288,38 +171,24 @@ async function loadAgentMinds(agentId, dialog) {
|
|
|
288
171
|
}
|
|
289
172
|
return out;
|
|
290
173
|
})();
|
|
174
|
+
const toolsetNames = agent
|
|
175
|
+
.listResolvedToolsetNames({ onMissing: missingToolsetPolicy })
|
|
176
|
+
.filter((name) => {
|
|
177
|
+
if (name === 'os')
|
|
178
|
+
return agentIsShellSpecialist;
|
|
179
|
+
return true;
|
|
180
|
+
});
|
|
181
|
+
const manualTools = (0, toolset_manual_1.buildToolsetManualTools)({
|
|
182
|
+
toolsetNames,
|
|
183
|
+
existingToolNames: new Set(agentTools.map((t) => t.name)),
|
|
184
|
+
});
|
|
185
|
+
if (manualTools.tools.length > 0) {
|
|
186
|
+
agentTools.push(...manualTools.tools);
|
|
187
|
+
}
|
|
291
188
|
const funcTools = agentTools.filter((t) => t.type === 'func');
|
|
292
|
-
const agentHasShellTools = funcTools.some((t) => isShellToolName(t.name));
|
|
189
|
+
const agentHasShellTools = funcTools.some((t) => (0, shell_tools_1.isShellToolName)(t.name));
|
|
293
190
|
const agentHasReadonlyShell = funcTools.some((t) => t.name === 'readonly_shell');
|
|
294
|
-
const shellSpecialistMemberIds = listShellSpecialistMemberIds(team);
|
|
295
|
-
const shellPolicyPrompt = buildShellPolicyPrompt({
|
|
296
|
-
language: workingLanguage,
|
|
297
|
-
agentIsShellSpecialist,
|
|
298
|
-
agentHasShellTools,
|
|
299
|
-
agentHasReadonlyShell,
|
|
300
|
-
shellSpecialistMemberIds,
|
|
301
|
-
});
|
|
302
|
-
const toolsetPromptText = (() => {
|
|
303
|
-
const toolsetNames = agent.listResolvedToolsetNames().filter((name) => {
|
|
304
|
-
if (name === 'os')
|
|
305
|
-
return agentIsShellSpecialist;
|
|
306
|
-
return true;
|
|
307
|
-
});
|
|
308
|
-
const blocks = toolsetNames
|
|
309
|
-
.map((toolsetName) => {
|
|
310
|
-
const promptI18n = (0, registry_1.getToolsetPromptI18n)(toolsetName);
|
|
311
|
-
const prompt = (0, text_1.getTextForLanguage)({ i18n: promptI18n, fallback: '' }, workingLanguage).trim();
|
|
312
|
-
if (prompt === '')
|
|
313
|
-
return '';
|
|
314
|
-
const title = workingLanguage === 'zh'
|
|
315
|
-
? `### Toolset 提示:${toolsetName}`
|
|
316
|
-
: `### Toolset prompt: ${toolsetName}`;
|
|
317
|
-
return `${title}\n\n${prompt}`;
|
|
318
|
-
})
|
|
319
|
-
.filter((b) => b !== '');
|
|
320
|
-
return blocks.join('\n\n');
|
|
321
|
-
})();
|
|
322
|
-
const memorySystemTitle = workingLanguage === 'zh' ? '### 记忆系统(重要)' : '### Memory System (Important)';
|
|
191
|
+
const shellSpecialistMemberIds = (0, shell_tools_1.listShellSpecialistMemberIds)(team);
|
|
323
192
|
const TEAM_MEMORY_TOOL_NAMES = [
|
|
324
193
|
'add_team_memory',
|
|
325
194
|
'replace_team_memory',
|
|
@@ -342,145 +211,41 @@ async function loadAgentMinds(agentId, dialog) {
|
|
|
342
211
|
const agentHasPersonalMemoryTools = funcTools.some((t) => isPersonalMemoryToolName(t.name));
|
|
343
212
|
const isSubdialog = dialog !== undefined && dialog.supdialog !== undefined;
|
|
344
213
|
const taskdocMaintainerId = dialog && dialog instanceof dialog_1.SubDialog ? dialog.rootDialog.agentId : agent.id;
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
]),
|
|
368
|
-
...(agentHasTeamMemoryTools
|
|
369
|
-
? [
|
|
370
|
-
'提示:你具备团队记忆工具(`add_team_memory` / `replace_team_memory` / `drop_team_memory` / `clear_team_memory`),可在必要时维护团队记忆(谨慎、少量、只写稳定约定)。',
|
|
371
|
-
]
|
|
372
|
-
: []),
|
|
373
|
-
...(agentHasPersonalMemoryTools
|
|
374
|
-
? [
|
|
375
|
-
'提示:你具备个人记忆工具(`add_memory` / `replace_memory` / `drop_memory` / `clear_memory`)。目标:维护你职责域的“rtws 索引”(关键文档/代码的准确路径 + 最小必要要点,如入口文件/关键符号/约定),让你在职责范围内尽量做到“0 次 ripgrep 就能开始干活”;一旦你修改了相关文件或发现记忆有过期/冲突,必须立刻用 `replace_memory` 把对应条目更新为最新事实。',
|
|
376
|
-
]
|
|
377
|
-
: []),
|
|
378
|
-
...(isSubdialog
|
|
379
|
-
? [
|
|
380
|
-
`工作流:先做事 → 再提炼(\`update_reminder\`;必要时整理差遣牒更新提案并诉请 \`@${taskdocMaintainerId}\` 合并写入)→ 然后 \`clear_mind\` 清空噪音。`,
|
|
381
|
-
]
|
|
382
|
-
: [
|
|
383
|
-
'工作流:先做事 → 再提炼(`update_reminder` + `change_mind(progress)`)→ 然后 `clear_mind` 清空噪音。',
|
|
384
|
-
]),
|
|
385
|
-
'当 context health 变黄/红:立刻停止继续大实现/大阅读;先提炼,再 clear。',
|
|
386
|
-
'不要把长日志/大段 tool output 直接塞进差遣牒;差遣牒只写结论+下一步;细节只保留必要摘录放提醒项。',
|
|
387
|
-
].join('\n');
|
|
388
|
-
}
|
|
389
|
-
const teamMemoryLine = '- Team memory: stable shared conventions (cross-task).';
|
|
390
|
-
const personalMemoryLine = '- Personal memory: stable personal habits/preferences and responsibility-scope knowledge. Maintain a compact responsibility-area rtws index (exact key doc/code paths + minimal key facts) to reduce repeat file reads; do not store per-task state.';
|
|
391
|
-
return [
|
|
392
|
-
'Dialog history and tool outputs are temporary: they accumulate quickly, become stale, and increase cognitive load. Within a course, you cannot truly drop that history except via `clear_mind`.',
|
|
393
|
-
'`clear_mind` starts a new course while preserving Taskdoc, reminders, and memory layers. Therefore, before clearing, distill key information into durable layers:',
|
|
394
|
-
'- Taskdoc (`*.tsk/`): team-shared task contract (goals/constraints/progress). Keep it small enough to read every course.',
|
|
395
|
-
`- When updating any Taskdoc section: each call replaces the entire section; always start from the current injected content and merge/compress; do not overwrite other contributors; add an explicit owner tag for entries you maintain (e.g., \`- [owner:@${agent.id}] ...\` or a \`### @${agent.id}\` block).`,
|
|
396
|
-
'- Taskdoc `progress` is the team’s shared bulletin board: distilled milestone snapshots (key decisions/current status/next steps), not raw logs.',
|
|
397
|
-
'- Important: the Taskdoc content is injected inline into the context (the latest as of this generation). Review the injected Taskdoc instead of trying to read files under `*.tsk/` via general file tools (they will be rejected).',
|
|
398
|
-
'- Convention: keep Taskdoc `constraints` focused on task-specific requirements. Do not duplicate global, system-enforced rules already stated in system prompt/tool docs (e.g. `.tsk/` encapsulation bans general file tools).',
|
|
399
|
-
'- Reminders (working set): your high-frequency per-dialog worklog + critical details (not a team bulletin board); keep it small (often 1–3 items), prefer `update_reminder` to compress/merge; delete when obsolete.',
|
|
400
|
-
teamMemoryLine,
|
|
401
|
-
personalMemoryLine,
|
|
402
|
-
'',
|
|
403
|
-
...(isSubdialog
|
|
404
|
-
? [
|
|
405
|
-
`You are currently in a subdialog: \`change_mind\` is not allowed here. When Taskdoc should be updated (especially the shared progress bulletin board), tellask the Taskdoc maintainer \`@${taskdocMaintainerId}\` with a fully merged replacement draft (full-section replacement). Do not claim it is updated until you see a receipt.`,
|
|
406
|
-
]
|
|
407
|
-
: [
|
|
408
|
-
'You are currently in the main dialog: you are responsible for keeping the team-shared Taskdoc coherent and up to date (especially the progress bulletin board). Merge proposals from teammates/subdialogs promptly and keep it concise.',
|
|
409
|
-
]),
|
|
410
|
-
...(agentHasTeamMemoryTools
|
|
411
|
-
? [
|
|
412
|
-
'Hint: you have team-memory tools (`add_team_memory` / `replace_team_memory` / `drop_team_memory` / `clear_team_memory`) and may maintain team memory when it is truly stable and worth sharing.',
|
|
413
|
-
]
|
|
414
|
-
: []),
|
|
415
|
-
...(agentHasPersonalMemoryTools
|
|
416
|
-
? [
|
|
417
|
-
'Hint: you have personal-memory tools (`add_memory` / `replace_memory` / `drop_memory` / `clear_memory`). Goal: maintain a compact responsibility-area rtws index (exact key doc/code paths + minimal key facts like entrypoints/key symbols/contracts) so you can start work with 0 ripgrep within your scope. If you changed those files or detect staleness/conflicts, immediately `replace_memory` to keep it accurate.',
|
|
418
|
-
]
|
|
419
|
-
: []),
|
|
420
|
-
...(isSubdialog
|
|
421
|
-
? [
|
|
422
|
-
`Workflow: do work → distill (\`update_reminder\`; when Taskdoc needs updates, draft a merged replacement and ask \`@${taskdocMaintainerId}\`) → then \`clear_mind\` to drop noise.`,
|
|
423
|
-
]
|
|
424
|
-
: [
|
|
425
|
-
'Workflow: do work → distill (`update_reminder` + `change_mind(progress)`) → then `clear_mind` to drop noise.',
|
|
426
|
-
]),
|
|
427
|
-
'When context health turns yellow/red: treat it as a hard stop; distill first, then clear.',
|
|
428
|
-
'Do not paste long logs/tool outputs into Taskdoc; Taskdoc should record decisions + next steps; keep only essential excerpts in reminders.',
|
|
429
|
-
].join('\n');
|
|
430
|
-
})();
|
|
431
|
-
const memorySystemPrompt = `${memorySystemTitle}\n\n${memorySystemBody}`;
|
|
432
|
-
const taskdocPolicyPrompt = (0, minds_i18n_1.taskdocCanonicalCopy)(workingLanguage);
|
|
433
|
-
// Generate tool usage text (shell policy + memory system + toolset prompts).
|
|
434
|
-
let toolUsageText;
|
|
435
|
-
let funcToolUsageText = '';
|
|
436
|
-
let funcToolRulesText = '';
|
|
437
|
-
toolUsageText = (() => {
|
|
438
|
-
const prefix = [shellPolicyPrompt, memorySystemPrompt, taskdocPolicyPrompt, toolsetPromptText]
|
|
439
|
-
.filter((b) => b.trim() !== '')
|
|
440
|
-
.join('\n\n');
|
|
441
|
-
return prefix;
|
|
442
|
-
})();
|
|
443
|
-
if (funcTools.length > 0) {
|
|
444
|
-
funcToolUsageText = funcTools
|
|
445
|
-
.map((tool) => {
|
|
446
|
-
// NOTE: Function-tool schemas may come from MCP and are treated as passthrough JSON Schema.
|
|
447
|
-
// Runtime inspection is unavoidable here because this is purely for human-readable help text.
|
|
448
|
-
const schema = tool.parameters;
|
|
449
|
-
const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
450
|
-
const requiredValue = schema['required'];
|
|
451
|
-
const required = Array.isArray(requiredValue) && requiredValue.every((v) => typeof v === 'string')
|
|
452
|
-
? requiredValue
|
|
453
|
-
: [];
|
|
454
|
-
const req = required.length > 0 ? required.join(', ') : (0, minds_i18n_1.noneRequiredFieldsText)(workingLanguage);
|
|
455
|
-
const propsValue = schema['properties'];
|
|
456
|
-
const propsRecord = isRecord(propsValue) ? propsValue : {};
|
|
457
|
-
const props = Object.entries(propsRecord)
|
|
458
|
-
.map(([k, v]) => {
|
|
459
|
-
const desc = isRecord(v) && 'description' in v && typeof v.description === 'string'
|
|
460
|
-
? v.description
|
|
461
|
-
: 'parameter';
|
|
462
|
-
return `- ${k}: ${desc}`;
|
|
463
|
-
})
|
|
464
|
-
.join('\n');
|
|
465
|
-
const labels = (0, minds_i18n_1.funcToolUsageLabels)(workingLanguage);
|
|
466
|
-
const toolDesc = (0, text_1.getTextForLanguage)({ i18n: tool.descriptionI18n, fallback: tool.description }, workingLanguage);
|
|
467
|
-
return `#### ${labels.toolLabel}: ${tool.name}\n\n${toolDesc}\n\n- ${labels.invocationLabel}: ${labels.invocationBody}\n- ${labels.requiredLabel}: ${req}\n- ${labels.parametersLabel}:\n${props}`.trim();
|
|
468
|
-
})
|
|
469
|
-
.join('\n\n');
|
|
470
|
-
funcToolRulesText = (0, minds_i18n_1.funcToolRulesText)(workingLanguage);
|
|
471
|
-
}
|
|
214
|
+
const promptdocContext = {
|
|
215
|
+
language: workingLanguage,
|
|
216
|
+
agentId: agent.id,
|
|
217
|
+
isSubdialog,
|
|
218
|
+
taskdocMaintainerId,
|
|
219
|
+
agentHasTeamMemoryTools,
|
|
220
|
+
agentHasPersonalMemoryTools,
|
|
221
|
+
agentIsShellSpecialist,
|
|
222
|
+
agentHasShellTools,
|
|
223
|
+
agentHasReadonlyShell,
|
|
224
|
+
shellSpecialistMemberIds,
|
|
225
|
+
};
|
|
226
|
+
const policyText = [
|
|
227
|
+
(0, system_prompt_parts_1.buildShellPolicyPrompt)(promptdocContext),
|
|
228
|
+
(0, system_prompt_parts_1.buildMemorySystemPrompt)(promptdocContext),
|
|
229
|
+
(0, minds_i18n_1.taskdocCanonicalCopy)(workingLanguage),
|
|
230
|
+
]
|
|
231
|
+
.filter((b) => b.trim() !== '')
|
|
232
|
+
.join('\n\n');
|
|
233
|
+
const intrinsicToolUsageText = (0, system_prompt_parts_1.buildIntrinsicToolUsageText)(workingLanguage, intrinsicFuncTools);
|
|
234
|
+
const toolsetManualIntro = (0, toolset_manual_1.formatToolsetManualIntro)(workingLanguage, manualTools.toolNames);
|
|
235
|
+
const funcToolRulesText = funcTools.length > 0 ? (0, minds_i18n_1.funcToolRulesText)(workingLanguage) : '';
|
|
472
236
|
const systemPrompt = (0, system_prompt_1.buildSystemPrompt)({
|
|
473
237
|
language: workingLanguage,
|
|
238
|
+
dialogScope: isSubdialog ? 'sideline' : 'mainline',
|
|
474
239
|
agent,
|
|
475
240
|
persona,
|
|
476
241
|
knowledge,
|
|
477
242
|
lessons,
|
|
478
243
|
envIntro,
|
|
479
244
|
teamIntro,
|
|
480
|
-
toolUsageText,
|
|
481
|
-
intrinsicToolInstructions: '',
|
|
482
|
-
funcToolUsageText,
|
|
483
245
|
funcToolRulesText,
|
|
246
|
+
policyText,
|
|
247
|
+
intrinsicToolUsageText,
|
|
248
|
+
toolsetManualIntro,
|
|
484
249
|
});
|
|
485
250
|
// composite this list by reading:
|
|
486
251
|
// - .minds/memory/team_shared/**/*.md
|