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/cli/read.js
CHANGED
|
@@ -10,15 +10,24 @@
|
|
|
10
10
|
* --no-hints Don't show hints
|
|
11
11
|
* --only-prompt Show only system prompt
|
|
12
12
|
* --only-mem Show only memories
|
|
13
|
+
* --audit Run built-in prompt audit checks
|
|
14
|
+
* --fail-on-audit-warning Exit non-zero when audit emits warnings
|
|
15
|
+
* --find <pattern> Find case-insensitive text in rendered output
|
|
13
16
|
* --help Show help
|
|
14
17
|
*/
|
|
15
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
19
|
exports.main = main;
|
|
20
|
+
const promises_1 = require("fs/promises");
|
|
21
|
+
const config_1 = require("../mcp/config");
|
|
17
22
|
const load_1 = require("../minds/load");
|
|
23
|
+
const team_1 = require("../team");
|
|
24
|
+
const registry_1 = require("../tools/registry");
|
|
18
25
|
function printUsage() {
|
|
19
|
-
console.log('Usage: dominds read [<member-id>] [--no-hints] [--only-prompt|--only-mem]');
|
|
26
|
+
console.log('Usage: dominds read [<member-id>] [--no-hints] [--only-prompt|--only-mem] [--audit] [--find <pattern>]');
|
|
20
27
|
console.log('');
|
|
21
28
|
console.log('Print agent system prompt and memories with filtering flags.');
|
|
29
|
+
console.log('`--audit` also includes static toolset checks (registry vs `.minds/mcp.yaml` declarations).');
|
|
30
|
+
console.log('When <member-id> is omitted, reads all visible team members.');
|
|
22
31
|
console.log('');
|
|
23
32
|
console.log("Note: rtws (runtime workspace) directory is `process.cwd()`. Use 'dominds -C <dir> read' to run in another rtws.");
|
|
24
33
|
console.log('');
|
|
@@ -27,12 +36,297 @@ function printUsage() {
|
|
|
27
36
|
console.log(' dominds read developer # Read specific member');
|
|
28
37
|
console.log(' dominds read --only-prompt # Show only system prompts');
|
|
29
38
|
console.log(' dominds read --only-mem # Show only memories');
|
|
39
|
+
console.log(' dominds read --only-prompt --audit');
|
|
40
|
+
console.log(' dominds read ux --only-prompt --find "pending Tellask"');
|
|
41
|
+
console.log(' dominds read --only-prompt --audit --fail-on-audit-warning');
|
|
30
42
|
}
|
|
31
|
-
|
|
32
|
-
|
|
43
|
+
function normalizeForDuplicateScan(line) {
|
|
44
|
+
return line
|
|
45
|
+
.trim()
|
|
46
|
+
.replace(/^[-*]\s+/, '')
|
|
47
|
+
.replace(/[`*_]/g, '')
|
|
48
|
+
.replace(/\s+/g, ' ')
|
|
49
|
+
.toLowerCase();
|
|
50
|
+
}
|
|
51
|
+
function buildPromptAudit(systemPrompt) {
|
|
52
|
+
const checks = [
|
|
53
|
+
{
|
|
54
|
+
id: 'collaboration_protocol',
|
|
55
|
+
label: 'Has collaboration protocol section',
|
|
56
|
+
pass: /## (Collaboration Protocol|协作协议)/.test(systemPrompt),
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 'response_closes_round',
|
|
60
|
+
label: 'Has "response closes call round" rule',
|
|
61
|
+
pass: /response closes that call round/.test(systemPrompt) ||
|
|
62
|
+
/收到回贴即表示该轮调用已结束/.test(systemPrompt),
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'pending_wait_guard',
|
|
66
|
+
label: 'Has pending tellask wait guard',
|
|
67
|
+
pass: /pending Tellask|pending tellask/.test(systemPrompt) ||
|
|
68
|
+
/存在明确 pending tellask/.test(systemPrompt),
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'relay_ban',
|
|
72
|
+
label: 'Has no-human-relay rule',
|
|
73
|
+
pass: /relay for executable teammate work/.test(systemPrompt) || /转发员/.test(systemPrompt),
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: 'tellask_function_boundary',
|
|
77
|
+
label: 'Has tellask vs function-calling boundary',
|
|
78
|
+
pass: /native function-calling/.test(systemPrompt) &&
|
|
79
|
+
(/is only for tellasking teammates\/@self\/@human/.test(systemPrompt) ||
|
|
80
|
+
/仅用于诉请队友\/@self\/@human/.test(systemPrompt)),
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: 'tellask_line_grammar',
|
|
84
|
+
label: 'Has tellask line-prefix grammar',
|
|
85
|
+
pass: /line-prefix grammar/.test(systemPrompt) || /逐行前缀语法/.test(systemPrompt),
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: 'fbr_phase_contract',
|
|
89
|
+
label: 'Has FBR phase contract',
|
|
90
|
+
pass: /FBR phase contract|FBR 阶段协议/.test(systemPrompt),
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: 'taskdoc_encapsulation',
|
|
94
|
+
label: 'Has Taskdoc encapsulation section',
|
|
95
|
+
pass: /Taskdoc encapsulation & access restrictions/.test(systemPrompt) ||
|
|
96
|
+
/差遣牒.*封装/.test(systemPrompt),
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
const hasDomindsRuntime = /Dominds runtime|genuine Codex CLI/.test(systemPrompt);
|
|
100
|
+
const hasCodexHostIdentity = /You are GPT-5\.2 running in the Codex CLI/.test(systemPrompt) ||
|
|
101
|
+
/^You are Codex CLI\.$/m.test(systemPrompt);
|
|
102
|
+
const toolSectionMarkers = ['\n## Intrinsic Tools\n', '\n## 内置工具\n'];
|
|
103
|
+
let duplicateScope = systemPrompt;
|
|
104
|
+
for (const marker of toolSectionMarkers) {
|
|
105
|
+
const idx = duplicateScope.indexOf(marker);
|
|
106
|
+
if (idx >= 0) {
|
|
107
|
+
duplicateScope = duplicateScope.slice(0, idx);
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const lineCounts = new Map();
|
|
112
|
+
const representative = new Map();
|
|
113
|
+
for (const rawLine of duplicateScope.split('\n')) {
|
|
114
|
+
const line = rawLine.trim();
|
|
115
|
+
if (line === '' || line.startsWith('#'))
|
|
116
|
+
continue;
|
|
117
|
+
const normalized = normalizeForDuplicateScan(line);
|
|
118
|
+
if (normalized.length < 24)
|
|
119
|
+
continue;
|
|
120
|
+
lineCounts.set(normalized, (lineCounts.get(normalized) ?? 0) + 1);
|
|
121
|
+
if (!representative.has(normalized))
|
|
122
|
+
representative.set(normalized, line);
|
|
123
|
+
}
|
|
124
|
+
const duplicates = Array.from(lineCounts.entries())
|
|
125
|
+
.filter(([, count]) => count > 1)
|
|
126
|
+
.sort((a, b) => b[1] - a[1])
|
|
127
|
+
.slice(0, 12)
|
|
128
|
+
.map(([normalized, count]) => ({
|
|
129
|
+
line: representative.get(normalized) ?? normalized,
|
|
130
|
+
count,
|
|
131
|
+
}));
|
|
132
|
+
const warnings = [];
|
|
133
|
+
for (const check of checks) {
|
|
134
|
+
if (!check.pass)
|
|
135
|
+
warnings.push(`Missing: ${check.label}`);
|
|
136
|
+
}
|
|
137
|
+
if (hasDomindsRuntime && hasCodexHostIdentity) {
|
|
138
|
+
warnings.push('Potential host identity conflict: both Dominds runtime and Codex host identity text found.');
|
|
139
|
+
}
|
|
140
|
+
if (duplicates.length > 0) {
|
|
141
|
+
warnings.push(`Detected ${duplicates.length} repeated prompt lines (top duplicates shown).`);
|
|
142
|
+
}
|
|
143
|
+
return { checks, duplicates, warnings };
|
|
144
|
+
}
|
|
145
|
+
function printPromptAudit(report) {
|
|
146
|
+
process.stdout.write('\n## Prompt Audit\n');
|
|
147
|
+
for (const check of report.checks) {
|
|
148
|
+
const tag = check.pass ? 'OK' : 'MISS';
|
|
149
|
+
process.stdout.write(`- [${tag}] ${check.label}\n`);
|
|
150
|
+
}
|
|
151
|
+
if (report.duplicates.length > 0) {
|
|
152
|
+
process.stdout.write('- Duplicate Lines (top):\n');
|
|
153
|
+
for (const d of report.duplicates) {
|
|
154
|
+
process.stdout.write(` - x${d.count}: ${d.line}\n`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
process.stdout.write('- Duplicate Lines: none\n');
|
|
159
|
+
}
|
|
160
|
+
if (report.warnings.length > 0) {
|
|
161
|
+
process.stdout.write('- Warnings:\n');
|
|
162
|
+
for (const warning of report.warnings) {
|
|
163
|
+
process.stdout.write(` - ${warning}\n`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
process.stdout.write('- Warnings: none\n');
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function listExplicitToolsets(member) {
|
|
171
|
+
if (!member.toolsets)
|
|
172
|
+
return [];
|
|
173
|
+
const out = [];
|
|
174
|
+
const seen = new Set();
|
|
175
|
+
for (const entry of member.toolsets) {
|
|
176
|
+
if (entry === '*' || entry.startsWith('!'))
|
|
177
|
+
continue;
|
|
178
|
+
if (seen.has(entry))
|
|
179
|
+
continue;
|
|
180
|
+
seen.add(entry);
|
|
181
|
+
out.push(entry);
|
|
182
|
+
}
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
185
|
+
async function readMcpDeclaredToolsets() {
|
|
186
|
+
const mcpPath = '.minds/mcp.yaml';
|
|
187
|
+
let raw;
|
|
188
|
+
try {
|
|
189
|
+
raw = await (0, promises_1.readFile)(mcpPath, 'utf8');
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
if (typeof err === 'object' &&
|
|
193
|
+
err !== null &&
|
|
194
|
+
'code' in err &&
|
|
195
|
+
err.code === 'ENOENT') {
|
|
196
|
+
return { kind: 'missing' };
|
|
197
|
+
}
|
|
198
|
+
return { kind: 'invalid', errorText: err instanceof Error ? err.message : String(err) };
|
|
199
|
+
}
|
|
200
|
+
const parsed = (0, config_1.parseMcpYaml)(raw);
|
|
201
|
+
if (!parsed.ok) {
|
|
202
|
+
return { kind: 'invalid', errorText: parsed.errorText };
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
kind: 'loaded',
|
|
206
|
+
declaredServerIds: new Set(parsed.serverIdsInYamlOrder),
|
|
207
|
+
invalidServerIds: new Set(parsed.invalidServers.map((s) => s.serverId)),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function buildToolsetAuditReport(params) {
|
|
211
|
+
const registeredToolsets = new Set(Object.keys((0, registry_1.listToolsets)()));
|
|
212
|
+
const byMember = [];
|
|
213
|
+
const warnings = [];
|
|
214
|
+
for (const memberId of params.targetMemberIds) {
|
|
215
|
+
const member = params.team.getMember(memberId);
|
|
216
|
+
if (!member)
|
|
217
|
+
continue;
|
|
218
|
+
const explicitToolsets = listExplicitToolsets(member);
|
|
219
|
+
const items = [];
|
|
220
|
+
for (const toolsetName of explicitToolsets) {
|
|
221
|
+
if (registeredToolsets.has(toolsetName)) {
|
|
222
|
+
items.push({ toolsetName, status: 'registered' });
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
if (params.mcp.kind === 'loaded' && params.mcp.declaredServerIds.has(toolsetName)) {
|
|
226
|
+
if (params.mcp.invalidServerIds.has(toolsetName)) {
|
|
227
|
+
items.push({ toolsetName, status: 'mcp_declared_invalid' });
|
|
228
|
+
warnings.push(`@${member.id}: toolset '${toolsetName}' is declared in mcp.yaml but server config is invalid.`);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
items.push({ toolsetName, status: 'mcp_declared_unloaded' });
|
|
232
|
+
}
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
items.push({ toolsetName, status: 'missing' });
|
|
236
|
+
warnings.push(`@${member.id}: toolset '${toolsetName}' is neither registered nor declared in mcp.yaml.`);
|
|
237
|
+
}
|
|
238
|
+
byMember.push({ memberId: member.id, memberName: member.name, items });
|
|
239
|
+
}
|
|
240
|
+
if (params.mcp.kind === 'invalid') {
|
|
241
|
+
warnings.push(`Invalid .minds/mcp.yaml; cannot reliably classify unresolved MCP toolsets: ${params.mcp.errorText}`);
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
mcp: params.mcp,
|
|
245
|
+
byMember,
|
|
246
|
+
warnings,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function printToolsetAudit(report) {
|
|
250
|
+
process.stdout.write('\n## Toolset Audit\n');
|
|
251
|
+
if (report.mcp.kind === 'missing') {
|
|
252
|
+
process.stdout.write('- MCP config: missing (`.minds/mcp.yaml` not found)\n');
|
|
253
|
+
}
|
|
254
|
+
else if (report.mcp.kind === 'invalid') {
|
|
255
|
+
process.stdout.write('- MCP config: invalid (`.minds/mcp.yaml` parse/read failed)\n');
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
process.stdout.write(`- MCP config: loaded (declared servers: ${report.mcp.declaredServerIds.size}, invalid server configs: ${report.mcp.invalidServerIds.size})\n`);
|
|
259
|
+
}
|
|
260
|
+
if (report.byMember.length === 0) {
|
|
261
|
+
process.stdout.write('- Members: none\n');
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
for (const memberReport of report.byMember) {
|
|
265
|
+
process.stdout.write(`- @${memberReport.memberId} (${memberReport.memberName}):\n`);
|
|
266
|
+
if (memberReport.items.length === 0) {
|
|
267
|
+
process.stdout.write(' - no explicit toolset declarations\n');
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
for (const item of memberReport.items) {
|
|
271
|
+
const label = item.status === 'registered'
|
|
272
|
+
? 'OK'
|
|
273
|
+
: item.status === 'mcp_declared_unloaded'
|
|
274
|
+
? 'DEFERRED'
|
|
275
|
+
: item.status === 'mcp_declared_invalid'
|
|
276
|
+
? 'INVALID'
|
|
277
|
+
: 'MISS';
|
|
278
|
+
process.stdout.write(` - [${label}] ${item.toolsetName}\n`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (report.warnings.length > 0) {
|
|
283
|
+
process.stdout.write('- Warnings:\n');
|
|
284
|
+
for (const warning of report.warnings) {
|
|
285
|
+
process.stdout.write(` - ${warning}\n`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
process.stdout.write('- Warnings: none\n');
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function collectFindMatches(text, pattern) {
|
|
293
|
+
const normalizedPattern = pattern.toLowerCase();
|
|
294
|
+
const lines = text.split('\n');
|
|
295
|
+
const matches = [];
|
|
296
|
+
for (let i = 0; i < lines.length; i++) {
|
|
297
|
+
const line = lines[i];
|
|
298
|
+
if (line.toLowerCase().includes(normalizedPattern)) {
|
|
299
|
+
matches.push({ line: i + 1, text: line });
|
|
300
|
+
if (matches.length >= 60)
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return matches;
|
|
305
|
+
}
|
|
306
|
+
function printFindResults(pattern, blocks) {
|
|
307
|
+
process.stdout.write(`\n## Find: "${pattern}"\n`);
|
|
308
|
+
let total = 0;
|
|
309
|
+
for (const block of blocks) {
|
|
310
|
+
const matches = collectFindMatches(block.text, pattern);
|
|
311
|
+
if (matches.length === 0)
|
|
312
|
+
continue;
|
|
313
|
+
total += matches.length;
|
|
314
|
+
process.stdout.write(`- ${block.name} (${matches.length}):\n`);
|
|
315
|
+
for (const match of matches) {
|
|
316
|
+
process.stdout.write(` - L${match.line}: ${match.text}\n`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (total === 0) {
|
|
320
|
+
process.stdout.write('- no matches\n');
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
function parseArgs(args) {
|
|
33
324
|
let memberId;
|
|
34
325
|
let onlyPrompt = false;
|
|
35
326
|
let onlyMem = false;
|
|
327
|
+
let audit = false;
|
|
328
|
+
let failOnAuditWarning = false;
|
|
329
|
+
const findPatterns = [];
|
|
36
330
|
for (let i = 0; i < args.length; i++) {
|
|
37
331
|
const arg = args[i];
|
|
38
332
|
if (arg === '--only-prompt') {
|
|
@@ -41,6 +335,20 @@ async function main() {
|
|
|
41
335
|
else if (arg === '--only-mem') {
|
|
42
336
|
onlyMem = true;
|
|
43
337
|
}
|
|
338
|
+
else if (arg === '--audit') {
|
|
339
|
+
audit = true;
|
|
340
|
+
}
|
|
341
|
+
else if (arg === '--fail-on-audit-warning') {
|
|
342
|
+
failOnAuditWarning = true;
|
|
343
|
+
}
|
|
344
|
+
else if (arg === '--find') {
|
|
345
|
+
const next = args[i + 1];
|
|
346
|
+
if (!next || next.startsWith('-')) {
|
|
347
|
+
throw new Error("Option '--find' requires a non-empty pattern argument.");
|
|
348
|
+
}
|
|
349
|
+
findPatterns.push(next);
|
|
350
|
+
i++;
|
|
351
|
+
}
|
|
44
352
|
else if (arg === '--no-hints') {
|
|
45
353
|
// Deprecated, but keep for compatibility
|
|
46
354
|
console.warn('Warning: --no-hints is deprecated, use --only-prompt or --only-mem instead');
|
|
@@ -53,23 +361,109 @@ async function main() {
|
|
|
53
361
|
memberId = arg;
|
|
54
362
|
}
|
|
55
363
|
else {
|
|
56
|
-
|
|
57
|
-
printUsage();
|
|
58
|
-
process.exit(1);
|
|
364
|
+
throw new Error(`Unexpected argument '${arg}'.`);
|
|
59
365
|
}
|
|
60
366
|
}
|
|
367
|
+
if (onlyPrompt && onlyMem) {
|
|
368
|
+
throw new Error("Options '--only-prompt' and '--only-mem' are mutually exclusive.");
|
|
369
|
+
}
|
|
370
|
+
return {
|
|
371
|
+
memberId,
|
|
372
|
+
onlyPrompt,
|
|
373
|
+
onlyMem,
|
|
374
|
+
audit,
|
|
375
|
+
failOnAuditWarning,
|
|
376
|
+
findPatterns,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
function resolveTargetMemberIds(team, memberId) {
|
|
380
|
+
if (memberId)
|
|
381
|
+
return [memberId];
|
|
382
|
+
const visibleIds = Object.values(team.members)
|
|
383
|
+
.filter((m) => m.hidden !== true)
|
|
384
|
+
.map((m) => m.id)
|
|
385
|
+
.sort((a, b) => a.localeCompare(b));
|
|
386
|
+
if (visibleIds.length > 0)
|
|
387
|
+
return visibleIds;
|
|
388
|
+
const fallback = team.getDefaultResponder();
|
|
389
|
+
if (!fallback)
|
|
390
|
+
throw new Error('No team members found.');
|
|
391
|
+
return [fallback.id];
|
|
392
|
+
}
|
|
393
|
+
async function main() {
|
|
394
|
+
const args = process.argv.slice(2);
|
|
395
|
+
let parsed;
|
|
396
|
+
try {
|
|
397
|
+
parsed = parseArgs(args);
|
|
398
|
+
}
|
|
399
|
+
catch (err) {
|
|
400
|
+
console.error('Error:', err instanceof Error ? err.message : String(err));
|
|
401
|
+
printUsage();
|
|
402
|
+
process.exit(1);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
61
405
|
try {
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
406
|
+
const team = await team_1.Team.load();
|
|
407
|
+
const targetMemberIds = resolveTargetMemberIds(team, parsed.memberId);
|
|
408
|
+
const isMultiMemberRun = targetMemberIds.length > 1;
|
|
409
|
+
const toolsetAudit = parsed.audit
|
|
410
|
+
? buildToolsetAuditReport({
|
|
411
|
+
team,
|
|
412
|
+
targetMemberIds,
|
|
413
|
+
mcp: await readMcpDeclaredToolsets(),
|
|
414
|
+
})
|
|
415
|
+
: undefined;
|
|
416
|
+
let auditWarningCount = 0;
|
|
417
|
+
for (let idx = 0; idx < targetMemberIds.length; idx++) {
|
|
418
|
+
const targetMemberId = targetMemberIds[idx];
|
|
419
|
+
const { agent, systemPrompt, memories } = await (0, load_1.loadAgentMinds)(targetMemberId, undefined, {
|
|
420
|
+
missingToolsetPolicy: parsed.audit ? 'silent' : 'warn',
|
|
421
|
+
});
|
|
422
|
+
const renderedMemoryBlocks = [];
|
|
67
423
|
for (const mem of memories) {
|
|
68
424
|
if ('content' in mem && typeof mem.content === 'string' && mem.content.trim()) {
|
|
69
|
-
|
|
425
|
+
renderedMemoryBlocks.push(mem.content.trim());
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
if (isMultiMemberRun) {
|
|
429
|
+
const sep = idx === 0 ? '' : '\n\n';
|
|
430
|
+
process.stdout.write(`${sep}===== @${agent.id} (${agent.name}) =====\n`);
|
|
431
|
+
}
|
|
432
|
+
if (!parsed.onlyMem) {
|
|
433
|
+
process.stdout.write(systemPrompt.trim() + '\n');
|
|
434
|
+
}
|
|
435
|
+
if (!parsed.onlyPrompt) {
|
|
436
|
+
for (const content of renderedMemoryBlocks) {
|
|
437
|
+
process.stdout.write('\n' + content + '\n');
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
if (parsed.audit) {
|
|
441
|
+
const report = buildPromptAudit(systemPrompt);
|
|
442
|
+
printPromptAudit(report);
|
|
443
|
+
auditWarningCount += report.warnings.length;
|
|
444
|
+
}
|
|
445
|
+
if (parsed.findPatterns.length > 0) {
|
|
446
|
+
const blocks = [];
|
|
447
|
+
if (!parsed.onlyMem) {
|
|
448
|
+
blocks.push({ name: `@${agent.id}/system_prompt`, text: systemPrompt });
|
|
449
|
+
}
|
|
450
|
+
if (!parsed.onlyPrompt) {
|
|
451
|
+
for (let i = 0; i < renderedMemoryBlocks.length; i++) {
|
|
452
|
+
blocks.push({ name: `@${agent.id}/memory_${i + 1}`, text: renderedMemoryBlocks[i] });
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
for (const pattern of parsed.findPatterns) {
|
|
456
|
+
printFindResults(pattern, blocks);
|
|
70
457
|
}
|
|
71
458
|
}
|
|
72
459
|
}
|
|
460
|
+
if (parsed.audit && toolsetAudit) {
|
|
461
|
+
printToolsetAudit(toolsetAudit);
|
|
462
|
+
auditWarningCount += toolsetAudit.warnings.length;
|
|
463
|
+
}
|
|
464
|
+
if (parsed.failOnAuditWarning && auditWarningCount > 0) {
|
|
465
|
+
process.exit(2);
|
|
466
|
+
}
|
|
73
467
|
}
|
|
74
468
|
catch (err) {
|
|
75
469
|
console.error('Error loading agent minds:', err instanceof Error ? err.message : String(err));
|
package/dist/dialog.js
CHANGED
|
@@ -628,6 +628,9 @@ class Dialog {
|
|
|
628
628
|
async funcCallRequested(funcId, funcName, argumentsStr) {
|
|
629
629
|
await this.dlgStore.funcCallRequested(this, funcId, funcName, argumentsStr);
|
|
630
630
|
}
|
|
631
|
+
async webSearchCall(payload) {
|
|
632
|
+
await this.dlgStore.webSearchCall(this, payload);
|
|
633
|
+
}
|
|
631
634
|
// Tellask call events (streaming mode - `!?@...` blocks)
|
|
632
635
|
async callingStart(validation) {
|
|
633
636
|
await this.dlgStore.callingStart(this, validation);
|
|
@@ -1014,6 +1017,7 @@ class DialogStore {
|
|
|
1014
1017
|
async callingFinish(_dialog, _callId) { }
|
|
1015
1018
|
// Function call event (non-streaming mode - single event)
|
|
1016
1019
|
async funcCallRequested(_dialog, _funcId, _funcName, _argumentsStr) { }
|
|
1020
|
+
async webSearchCall(_dialog, _payload) { }
|
|
1017
1021
|
/**
|
|
1018
1022
|
* Load current course number from persisted metadata
|
|
1019
1023
|
* This method should be implemented by subclasses to read from storage
|
package/dist/docs/design.md
CHANGED
|
@@ -555,6 +555,7 @@ dominds dialog start --taskdoc-path tasks/auth-system.tsk
|
|
|
555
555
|
- rtws hard rules:
|
|
556
556
|
- `*.tsk/**` is encapsulated Taskdoc state and is hard-denied for all general file tools.
|
|
557
557
|
- `.minds/**` is reserved rtws state (team config/memory/assets) and is hard-denied for all general file tools; manage it via dedicated tools like `team-mgmt`.
|
|
558
|
+
- DevOps context: ad-hoc temp scripts are a taboo. If a tool script is needed, align with teammates and the human, then formalize it in the rtws before use.
|
|
558
559
|
|
|
559
560
|
**Collaboration Example**:
|
|
560
561
|
|
package/dist/docs/design.zh.md
CHANGED
|
@@ -553,6 +553,7 @@ dominds dialog start --taskdoc-path tasks/auth-system.tsk
|
|
|
553
553
|
- rtws 硬性规则:
|
|
554
554
|
- `*.tsk/**` 是封装的差遣牒状态,所有通用文件工具都硬性拒绝。
|
|
555
555
|
- `.minds/**` 是保留的 rtws 状态(团队配置/内存/资产),所有通用文件工具都硬性拒绝;通过 `team-mgmt` 等专用工具进行管理。
|
|
556
|
+
- DevOps 场景:忌讳临时脚本。如需工具脚本,应与队友和人类对齐后,在 rtws 中正式设计/命名/规范化再使用。
|
|
556
557
|
|
|
557
558
|
**协作示例:**
|
|
558
559
|
|
|
@@ -164,8 +164,9 @@ flowchart TD
|
|
|
164
164
|
- Uses `subdialog.supdialog` reference (no registry lookup)
|
|
165
165
|
- No registration - supdialog relationship is inherent
|
|
166
166
|
- Supdialog is always the direct parent in the hierarchy
|
|
167
|
-
- `!?@tellasker` is the canonical Type A syntax: it always routes to the tellasker (the dialog that issued the current Tellask)
|
|
168
|
-
|
|
167
|
+
- `!?@tellasker` is the canonical Type A syntax: it always routes to the tellasker (the dialog that issued the current Tellask).
|
|
168
|
+
- This matters especially when the supdialog’s `agentId` is identical to the subdialog’s `agentId` (common when a sideline
|
|
169
|
+
is created via `!?@self`), where an explicit `!?@<supdialogAgentId>` is easier to get wrong by accident.
|
|
169
170
|
- The explicit `!?@<supdialogAgentId>` form is accepted as a semantic fallback for backwards compatibility, but is more
|
|
170
171
|
error-prone in FBR/self-subdialog cases.
|
|
171
172
|
|
|
@@ -193,6 +194,7 @@ Result:
|
|
|
193
194
|
- `!?@self` is an explicit “same persona” call that targets the **current dialog’s agentId** (not a separate teammate).
|
|
194
195
|
- This is an **unambiguous** syntax for self-tellasks and helps avoid accidental `@teammate`→`@teammate` self-tellasks caused by
|
|
195
196
|
echoing/quoting prior call headlines.
|
|
197
|
+
- In Dominds, `!?@self` Tellasks are treated as FBR and are driven under a stricter, tool-less policy; see [`fbr.md`](./fbr.md).
|
|
196
198
|
- **FBR itself should be common**, but the `!tellaskSession`-addressed variant should be rare. Prefer `!?@self` (TYPE C, transient)
|
|
197
199
|
for most FBR usage. Use `!?@self !tellaskSession ...` only when you explicitly want a resumable, long-lived “fresh boots session”
|
|
198
200
|
for a multi-step sub-problem.
|
|
@@ -269,14 +271,17 @@ Result (second call):
|
|
|
269
271
|
|
|
270
272
|
**Fresh Boots Reasoning (FBR) self-tellask syntax (default; most common)**: `!?@self`
|
|
271
273
|
|
|
272
|
-
- `!?@self` targets the current dialog’s agentId and creates a **new ephemeral subdialog**
|
|
274
|
+
- `!?@self` targets the current dialog’s agentId and creates a **new ephemeral subdialog** routed to the same agentId.
|
|
275
|
+
- The sideline dialog created by `!?@self` is FBR and is driven under a stricter, tool-less policy; see [`fbr.md`](./fbr.md).
|
|
273
276
|
- Use this for most Fresh Boots Reasoning sessions: isolate a single sub-problem, produce an answer, and return.
|
|
274
277
|
|
|
275
278
|
**Behavior**:
|
|
276
279
|
|
|
277
280
|
1. Current dialog **suspends**
|
|
278
281
|
2. Create **NEW subdialog** with the specified agentId
|
|
279
|
-
3. Drive the new subdialog
|
|
282
|
+
3. Drive the new subdialog:
|
|
283
|
+
- For general Type C, the subdialog is full-fledged (supcalls, teammate Tellasks, tools per config).
|
|
284
|
+
- For `!?@self`, runtime applies the FBR tool-less policy (no tools; restricted Tellasks).
|
|
280
285
|
4. Subdialog response flows back to parent
|
|
281
286
|
5. Parent **resumes** with subdialog's response
|
|
282
287
|
|
|
@@ -284,7 +289,7 @@ Result (second call):
|
|
|
284
289
|
|
|
285
290
|
- **No registry lookup** - always creates a new subdialog
|
|
286
291
|
- **Not registered** - no persistence across Tellasks
|
|
287
|
-
- The subdialog itself is fully capable
|
|
292
|
+
- The subdialog itself is fully capable **except** for `!?@self` FBR, which is tool-less and Tellask-restricted (see `fbr.md`).
|
|
288
293
|
- Only difference from TYPE B: no registry lookup/resume capability
|
|
289
294
|
- Used for one-off, independent tasks
|
|
290
295
|
|
|
@@ -1100,7 +1105,7 @@ sequenceDiagram
|
|
|
1100
1105
|
Driver-->>Sub: resume subdialog with response in context
|
|
1101
1106
|
```
|
|
1102
1107
|
|
|
1103
|
-
#### TYPE B: Registered Subdialog Tellask (`Tellask Session`) (`!?@agentId !tellaskSession tellaskSession
|
|
1108
|
+
#### TYPE B: Registered Subdialog Tellask (`Tellask Session`) (`!?@agentId !tellaskSession tellaskSession`; `!?@self !tellaskSession ...` is FBR tool-less)
|
|
1104
1109
|
|
|
1105
1110
|
```mermaid
|
|
1106
1111
|
sequenceDiagram
|
|
@@ -1125,7 +1130,7 @@ sequenceDiagram
|
|
|
1125
1130
|
end
|
|
1126
1131
|
```
|
|
1127
1132
|
|
|
1128
|
-
#### TYPE C: Transient Subdialog Tellask (`Fresh Tellask`) (`!?@agentId
|
|
1133
|
+
#### TYPE C: Transient Subdialog Tellask (`Fresh Tellask`) (`!?@agentId`; `!?@self` is FBR tool-less)
|
|
1129
1134
|
|
|
1130
1135
|
```mermaid
|
|
1131
1136
|
sequenceDiagram
|
|
@@ -189,6 +189,7 @@ LLM 发出:!?@orchestrator 我应该如何处理数据库迁移?
|
|
|
189
189
|
|
|
190
190
|
- `!?@self` 是一个显式的"相同角色"调用,指向**当前对话的 agentId**(不是单独队友)。
|
|
191
191
|
- 这是自调用的**明确**语法,有助于避免因回声/引用先前调用标题而导致的意外 `@teammate`→`@teammate` 自调用。
|
|
192
|
+
- 注意:在 Dominds 中,`!?@self` 会触发扪心自问(FBR)机制,并以更严格的“无工具”策略驱动;详见 [`fbr.zh.md`](./fbr.zh.md)。
|
|
192
193
|
- **FBR 本身应该很常见**,但使用 `!tellaskSession` 寻址的变体应该很罕见。对于大多数 FBR 使用,首选 `!?@self`(TYPE C,瞬态)。仅当你明确想要一个可恢复的、长期存在的"初心会话"用于多步骤子问题时,才使用 `!?@self !tellaskSession ...`。
|
|
193
194
|
|
|
194
195
|
**Tellask 会话键模式**:`<tellaskSession>` 使用与 `<mention-id>` 相同的标识符模式:`[a-zA-Z][a-zA-Z0-9_-]*`。解析在空白或标点处停止;任何尾随的标题文本在 tellaskSession 解析时被忽略。
|
|
@@ -261,14 +262,17 @@ LLM 再次发出:!?@researcher !tellaskSession market-analysis
|
|
|
261
262
|
|
|
262
263
|
**扪心自问 (FBR) 自调用语法(默认;最常见)**:`!?@self`
|
|
263
264
|
|
|
264
|
-
- `!?@self` 指向当前对话的 agentId
|
|
265
|
+
- `!?@self` 指向当前对话的 agentId,并创建一条路由到同一 agentId 的**新的临时子对话**。
|
|
266
|
+
- 由 `!?@self` 创建的支线对话属于 FBR,并以更严格的“无工具”策略驱动;详见 [`fbr.zh.md`](./fbr.zh.md)。
|
|
265
267
|
- 对于大多数扪心自问 会话使用此方式:隔离单个子问题,产生答案,然后返回。
|
|
266
268
|
|
|
267
269
|
**行为**:
|
|
268
270
|
|
|
269
271
|
1. 当前对话**挂起**
|
|
270
272
|
2. 使用指定的 agentId 创建**新的子对话**
|
|
271
|
-
3.
|
|
273
|
+
3. 驱动新的子对话:
|
|
274
|
+
- 一般 TYPE C 子对话是“完整能力”的(可上位调用、队友诉请、按配置使用工具)。
|
|
275
|
+
- `!?@self` 属于 FBR 特例:无工具、诉请受限(见 `fbr.zh.md`)。
|
|
272
276
|
4. 子对话的响应流回父级
|
|
273
277
|
5. 父级**恢复**,子对话的响应在上下文中
|
|
274
278
|
|
|
@@ -276,7 +280,7 @@ LLM 再次发出:!?@researcher !tellaskSession market-analysis
|
|
|
276
280
|
|
|
277
281
|
- **无注册表查找** - 总是创建新的子对话
|
|
278
282
|
- **不注册** - 在 Tellask 之间不持久化
|
|
279
|
-
-
|
|
283
|
+
- 子对话本身一般是“完整能力”的;但 `!?@self` FBR 是特例:无工具且诉请受限(见 `fbr.zh.md`)。
|
|
280
284
|
- 与 TYPE B 的唯一区别:无注册表查找/恢复能力
|
|
281
285
|
- 用于一次性的、独立的任务
|
|
282
286
|
|
|
@@ -40,6 +40,7 @@ Related docs:
|
|
|
40
40
|
|
|
41
41
|
- Establish immediate trust that Tellask/return/persistence are real.
|
|
42
42
|
- Run a real `!?@self` FBR loop at dialog creation.
|
|
43
|
+
- Build muscle memory for the timing contract: initiate FBR, wait for feedback, then synthesize/decide.
|
|
43
44
|
- Make distillation itself part of the “felt” experience (dedupe/reconcile/extract-the-best).
|
|
44
45
|
- Keep the procedure safe, small, and deterministic (default command: `uname -a`).
|
|
45
46
|
- Persist and display the interaction so it is credible from multiple angles (backend record + frontend transcript).
|
|
@@ -109,9 +110,15 @@ Optional parallel drafts:
|
|
|
109
110
|
- If `fbr_effort` is `0`, skip FBR.
|
|
110
111
|
- If `fbr_effort` is greater than `100`, the runtime errors out and stops priming (invalid config).
|
|
111
112
|
|
|
113
|
+
Phase boundary (critical):
|
|
114
|
+
|
|
115
|
+
- `!?@self` is the **initiation action**, not completed decision-making.
|
|
116
|
+
- Mainline must enter a wait phase until feedback from that FBR run returns.
|
|
117
|
+
- If `fbr_effort = N`, mainline must wait for all N drafts before distillation; do not finalize from partial drafts.
|
|
118
|
+
|
|
112
119
|
### 4) Distill into an “Agent Priming” note
|
|
113
120
|
|
|
114
|
-
|
|
121
|
+
After confirming feedback from that FBR run has been collected, the main agent writes a short, user-visible **Agent Priming** note via a **normal generation** in the mainline
|
|
115
122
|
dialog. It should be explicitly distilled (dedupe/reconcile/extract-the-best) rather than repeating each draft.
|
|
116
123
|
|
|
117
124
|
Implementation constraint (matches runtime behavior):
|
|
@@ -120,6 +127,8 @@ Implementation constraint (matches runtime behavior):
|
|
|
120
127
|
- The runtime may use a non-persisted **internal prompt** to anchor “this generation is distillation”.
|
|
121
128
|
- The runtime may also include the shell snapshot and FBR drafts as “evidence” inside that internal prompt (for this
|
|
122
129
|
drive only, not persisted), so distillation does not depend on any queue timing/concurrency details.
|
|
130
|
+
- During the Agent Priming lifecycle (from prelude start until the priming note is produced), runtime must suppress
|
|
131
|
+
diligence-push injections; restore normal diligence behavior only after priming completes.
|
|
123
132
|
|
|
124
133
|
Implementation note (internal prompt):
|
|
125
134
|
|
|
@@ -29,6 +29,7 @@ Dominds 的诉请(Tellask,`!?@...`)与扪心自问(FBR,`!?@self`)并
|
|
|
29
29
|
|
|
30
30
|
- 在对话一开始就建立“诉请/回传/持久化都是真的”的信任。
|
|
31
31
|
- 在对话一开始就跑通一次 `!?@self` 的 FBR 回路。
|
|
32
|
+
- 把“发起 FBR 后先等待回贴,再做综合决策”的时序固化为肌肉记忆。
|
|
32
33
|
- 把多份 FBR 草稿做一次**综合提炼**,把“取精华、去糟粕”的动作也变成体感的一部分。
|
|
33
34
|
- 过程足够小、可控、低风险(默认只执行 `uname -a`)。
|
|
34
35
|
- 记录从多角度都高度拟真:后端存档 + 前端可见的对话转录。
|
|
@@ -95,15 +96,22 @@ Dominds 的诉请(Tellask,`!?@...`)与扪心自问(FBR,`!?@self`)并
|
|
|
95
96
|
- 若 `fbr_effort` 为 `0`,则跳过 FBR。
|
|
96
97
|
- 若 `fbr_effort` 大于 `100`,运行时会报错并终止启动流程(配置错误)。
|
|
97
98
|
|
|
99
|
+
阶段边界(关键):
|
|
100
|
+
|
|
101
|
+
- `!?@self` 只是**发起动作**,不是“已完成决策”。
|
|
102
|
+
- 主线对话必须先进入等待态,直到该次 FBR 的回贴返回。
|
|
103
|
+
- 若 `fbr_effort = N`,主线必须等待全部 N 条回贴后再进入综合提炼;不得基于部分草稿提前定稿。
|
|
104
|
+
|
|
98
105
|
### 4)综合提炼成“智能体启动(Priming)”笔记
|
|
99
106
|
|
|
100
|
-
|
|
107
|
+
在确认该次 FBR 回贴已收齐后,主线智能体以一次**正常生成**在主线对话里追加一条短笔记(Agent Priming),让关键信息显性化、可检索,并体现“综合提炼”(去重/消冲突/抽取最有用的要点)。
|
|
101
108
|
|
|
102
109
|
实现约束(与运行时一致):
|
|
103
110
|
|
|
104
111
|
- “综合提炼”阶段**不应**通过拼装/拼接一段新的 system prompt 或引入一条独立的 system-prompt 组装路径。
|
|
105
112
|
- 运行时可以使用一条**internal prompt** 来锚定“本次生成就是综合提炼”。internal prompt 必须不落盘、不展示。
|
|
106
113
|
- FBR 草稿与 shell 回传等“证据材料”可以通过 internal prompt 一并提供给模型(仅用于本次 drive 的上下文,不写入对话历史),从而避免依赖“支线回复注入队列”的时序与并发细节。
|
|
114
|
+
- Agent Priming 生命周期(从序幕开始到 priming 笔记产出完成)内,运行时必须禁止注入 diligence-push(鞭策)消息;待 priming 结束后再恢复常规机制。
|
|
107
115
|
|
|
108
116
|
实现补充(internal prompt):
|
|
109
117
|
|