dominds 1.3.1 → 1.4.2
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 +9 -2
- package/README.zh.md +9 -2
- package/dist/apps/app-lock-file.js +33 -57
- package/dist/apps/configuration-file.js +267 -0
- package/dist/apps/enabled-apps.js +217 -252
- package/dist/apps/manifest.js +132 -0
- package/dist/apps/resolution-file.js +80 -192
- package/dist/apps/workspace-app-state.js +8 -0
- package/dist/cli/disable.js +18 -22
- package/dist/cli/enable.js +20 -58
- package/dist/cli/install.js +74 -80
- package/dist/cli/uninstall.js +48 -25
- package/dist/cli/update.js +36 -80
- package/dist/docs/app-constitution.md +12 -7
- package/dist/docs/app-constitution.zh.md +13 -8
- package/dist/llm/kernel-driver/engine.js +10 -4
- package/dist/llm/kernel-driver/flow.js +93 -0
- package/dist/llm/kernel-driver/loop.js +4 -1
- package/dist/llm/kernel-driver/subdialog.js +5 -1
- package/dist/llm/kernel-driver/tellask-special.js +48 -6
- package/dist/server/server-core.js +19 -4
- package/dist/server/websocket-handler.js +26 -6
- package/dist/static/assets/{_basePickBy-CmziIRM9.js → _basePickBy-B2o4z1Hf.js} +3 -3
- package/dist/static/assets/{_basePickBy-CmziIRM9.js.map → _basePickBy-B2o4z1Hf.js.map} +1 -1
- package/dist/static/assets/{_baseUniq-CgDZxcD0.js → _baseUniq-CLmcxjdl.js} +2 -2
- package/dist/static/assets/{_baseUniq-CgDZxcD0.js.map → _baseUniq-CLmcxjdl.js.map} +1 -1
- package/dist/static/assets/{arc-Df9rjNNk.js → arc-CymD_KN7.js} +2 -2
- package/dist/static/assets/{arc-Df9rjNNk.js.map → arc-CymD_KN7.js.map} +1 -1
- package/dist/static/assets/{architectureDiagram-VXUJARFQ-Bif8topC.js → architectureDiagram-VXUJARFQ-DJQfSJUH.js} +7 -7
- package/dist/static/assets/{architectureDiagram-VXUJARFQ-Bif8topC.js.map → architectureDiagram-VXUJARFQ-DJQfSJUH.js.map} +1 -1
- package/dist/static/assets/{blockDiagram-VD42YOAC-D9Egoflr.js → blockDiagram-VD42YOAC-pHVz60D0.js} +7 -7
- package/dist/static/assets/{blockDiagram-VD42YOAC-D9Egoflr.js.map → blockDiagram-VD42YOAC-pHVz60D0.js.map} +1 -1
- package/dist/static/assets/{c4Diagram-YG6GDRKO-DBf1NeBf.js → c4Diagram-YG6GDRKO-B0WnCfAT.js} +3 -3
- package/dist/static/assets/{c4Diagram-YG6GDRKO-DBf1NeBf.js.map → c4Diagram-YG6GDRKO-B0WnCfAT.js.map} +1 -1
- package/dist/static/assets/{channel-Dc34yAJl.js → channel-CX9BlKil.js} +2 -2
- package/dist/static/assets/{channel-Dc34yAJl.js.map → channel-CX9BlKil.js.map} +1 -1
- package/dist/static/assets/{chunk-4BX2VUAB-B65G1dJI.js → chunk-4BX2VUAB-lXArRj3o.js} +2 -2
- package/dist/static/assets/{chunk-4BX2VUAB-B65G1dJI.js.map → chunk-4BX2VUAB-lXArRj3o.js.map} +1 -1
- package/dist/static/assets/{chunk-55IACEB6-CSDEOGl2.js → chunk-55IACEB6-CdqwynH9.js} +2 -2
- package/dist/static/assets/{chunk-55IACEB6-CSDEOGl2.js.map → chunk-55IACEB6-CdqwynH9.js.map} +1 -1
- package/dist/static/assets/{chunk-B4BG7PRW-Cb6W3QWJ.js → chunk-B4BG7PRW-Y-uXcJst.js} +5 -5
- package/dist/static/assets/{chunk-B4BG7PRW-Cb6W3QWJ.js.map → chunk-B4BG7PRW-Y-uXcJst.js.map} +1 -1
- package/dist/static/assets/{chunk-DI55MBZ5-ZAJWeVWH.js → chunk-DI55MBZ5-C5xSbRST.js} +4 -4
- package/dist/static/assets/{chunk-DI55MBZ5-ZAJWeVWH.js.map → chunk-DI55MBZ5-C5xSbRST.js.map} +1 -1
- package/dist/static/assets/{chunk-FMBD7UC4-DiwRlImb.js → chunk-FMBD7UC4-5uefwCjI.js} +2 -2
- package/dist/static/assets/{chunk-FMBD7UC4-DiwRlImb.js.map → chunk-FMBD7UC4-5uefwCjI.js.map} +1 -1
- package/dist/static/assets/{chunk-QN33PNHL-wilj7fb5.js → chunk-QN33PNHL-DzWVcvpI.js} +2 -2
- package/dist/static/assets/{chunk-QN33PNHL-wilj7fb5.js.map → chunk-QN33PNHL-DzWVcvpI.js.map} +1 -1
- package/dist/static/assets/{chunk-QZHKN3VN-DGmviJfR.js → chunk-QZHKN3VN-BrrvAZdP.js} +2 -2
- package/dist/static/assets/{chunk-QZHKN3VN-DGmviJfR.js.map → chunk-QZHKN3VN-BrrvAZdP.js.map} +1 -1
- package/dist/static/assets/{chunk-TZMSLE5B-Nm5wTXa_.js → chunk-TZMSLE5B-DyKOlPTY.js} +2 -2
- package/dist/static/assets/{chunk-TZMSLE5B-Nm5wTXa_.js.map → chunk-TZMSLE5B-DyKOlPTY.js.map} +1 -1
- package/dist/static/assets/{classDiagram-2ON5EDUG-BvUbXD6H.js → classDiagram-2ON5EDUG-FCrnlCWC.js} +6 -6
- package/dist/static/assets/{classDiagram-2ON5EDUG-BvUbXD6H.js.map → classDiagram-2ON5EDUG-FCrnlCWC.js.map} +1 -1
- package/dist/static/assets/{classDiagram-v2-WZHVMYZB-BvUbXD6H.js → classDiagram-v2-WZHVMYZB-FCrnlCWC.js} +6 -6
- package/dist/static/assets/{classDiagram-v2-WZHVMYZB-BvUbXD6H.js.map → classDiagram-v2-WZHVMYZB-FCrnlCWC.js.map} +1 -1
- package/dist/static/assets/{clone-0VLS7GaA.js → clone-BlI81KqZ.js} +2 -2
- package/dist/static/assets/{clone-0VLS7GaA.js.map → clone-BlI81KqZ.js.map} +1 -1
- package/dist/static/assets/{cose-bilkent-S5V4N54A-anaPs-75.js → cose-bilkent-S5V4N54A-yM7S2atz.js} +2 -2
- package/dist/static/assets/{cose-bilkent-S5V4N54A-anaPs-75.js.map → cose-bilkent-S5V4N54A-yM7S2atz.js.map} +1 -1
- package/dist/static/assets/{dagre-6UL2VRFP-YwdsZ11r.js → dagre-6UL2VRFP-BcweuZHt.js} +7 -7
- package/dist/static/assets/{dagre-6UL2VRFP-YwdsZ11r.js.map → dagre-6UL2VRFP-BcweuZHt.js.map} +1 -1
- package/dist/static/assets/{diagram-PSM6KHXK-5KQCf3h2.js → diagram-PSM6KHXK-D4-QwLW1.js} +8 -8
- package/dist/static/assets/{diagram-PSM6KHXK-5KQCf3h2.js.map → diagram-PSM6KHXK-D4-QwLW1.js.map} +1 -1
- package/dist/static/assets/{diagram-QEK2KX5R-Mf24XxZL.js → diagram-QEK2KX5R-BVbuejJn.js} +7 -7
- package/dist/static/assets/{diagram-QEK2KX5R-Mf24XxZL.js.map → diagram-QEK2KX5R-BVbuejJn.js.map} +1 -1
- package/dist/static/assets/{diagram-S2PKOQOG-DyQjD4D5.js → diagram-S2PKOQOG-pB6N6Tq_.js} +7 -7
- package/dist/static/assets/{diagram-S2PKOQOG-DyQjD4D5.js.map → diagram-S2PKOQOG-pB6N6Tq_.js.map} +1 -1
- package/dist/static/assets/{erDiagram-Q2GNP2WA-CEzTKw1u.js → erDiagram-Q2GNP2WA-DLKmthuw.js} +5 -5
- package/dist/static/assets/{erDiagram-Q2GNP2WA-CEzTKw1u.js.map → erDiagram-Q2GNP2WA-DLKmthuw.js.map} +1 -1
- package/dist/static/assets/{flowDiagram-NV44I4VS-DT821XSz.js → flowDiagram-NV44I4VS-BsBhWukh.js} +6 -6
- package/dist/static/assets/{flowDiagram-NV44I4VS-DT821XSz.js.map → flowDiagram-NV44I4VS-BsBhWukh.js.map} +1 -1
- package/dist/static/assets/{ganttDiagram-JELNMOA3-DlmeVsGg.js → ganttDiagram-JELNMOA3-Debz-J-C.js} +3 -3
- package/dist/static/assets/{ganttDiagram-JELNMOA3-DlmeVsGg.js.map → ganttDiagram-JELNMOA3-Debz-J-C.js.map} +1 -1
- package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-yAfyBG_d.js → gitGraphDiagram-V2S2FVAM-BnAPFBGR.js} +8 -8
- package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-yAfyBG_d.js.map → gitGraphDiagram-V2S2FVAM-BnAPFBGR.js.map} +1 -1
- package/dist/static/assets/{graph-BYv8vyWe.js → graph-DbzWiBNK.js} +3 -3
- package/dist/static/assets/{graph-BYv8vyWe.js.map → graph-DbzWiBNK.js.map} +1 -1
- package/dist/static/assets/{index-DMbwqOm6.js → index-B-8J28g7.js} +987 -1049
- package/dist/static/assets/index-B-8J28g7.js.map +1 -0
- package/dist/static/assets/{index-BiNcBn_U.css → index-CD5wtC_i.css} +1 -1
- package/dist/static/assets/{infoDiagram-HS3SLOUP-DaadramQ.js → infoDiagram-HS3SLOUP-CZ5hWoxV.js} +6 -6
- package/dist/static/assets/{infoDiagram-HS3SLOUP-DaadramQ.js.map → infoDiagram-HS3SLOUP-CZ5hWoxV.js.map} +1 -1
- package/dist/static/assets/{journeyDiagram-XKPGCS4Q-ftN8hxu3.js → journeyDiagram-XKPGCS4Q-CKN3oSxk.js} +5 -5
- package/dist/static/assets/{journeyDiagram-XKPGCS4Q-ftN8hxu3.js.map → journeyDiagram-XKPGCS4Q-CKN3oSxk.js.map} +1 -1
- package/dist/static/assets/{kanban-definition-3W4ZIXB7-BIXETQ-C.js → kanban-definition-3W4ZIXB7-BQCMklfJ.js} +3 -3
- package/dist/static/assets/{kanban-definition-3W4ZIXB7-BIXETQ-C.js.map → kanban-definition-3W4ZIXB7-BQCMklfJ.js.map} +1 -1
- package/dist/static/assets/{layout-OTbrj0Ye.js → layout-C5B58szc.js} +5 -5
- package/dist/static/assets/{layout-OTbrj0Ye.js.map → layout-C5B58szc.js.map} +1 -1
- package/dist/static/assets/{linear-CVfOC669.js → linear-_32fut6G.js} +2 -2
- package/dist/static/assets/{linear-CVfOC669.js.map → linear-_32fut6G.js.map} +1 -1
- package/dist/static/assets/{mindmap-definition-VGOIOE7T-D2zv5uI9.js → mindmap-definition-VGOIOE7T-C_goMzjx.js} +4 -4
- package/dist/static/assets/{mindmap-definition-VGOIOE7T-D2zv5uI9.js.map → mindmap-definition-VGOIOE7T-C_goMzjx.js.map} +1 -1
- package/dist/static/assets/{pieDiagram-ADFJNKIX-DaUXTsv7.js → pieDiagram-ADFJNKIX-BQ2n0cOB.js} +8 -8
- package/dist/static/assets/{pieDiagram-ADFJNKIX-DaUXTsv7.js.map → pieDiagram-ADFJNKIX-BQ2n0cOB.js.map} +1 -1
- package/dist/static/assets/{quadrantDiagram-AYHSOK5B-B7O2wPX9.js → quadrantDiagram-AYHSOK5B-BLg7_neg.js} +3 -3
- package/dist/static/assets/{quadrantDiagram-AYHSOK5B-B7O2wPX9.js.map → quadrantDiagram-AYHSOK5B-BLg7_neg.js.map} +1 -1
- package/dist/static/assets/{requirementDiagram-UZGBJVZJ-DpauVPY1.js → requirementDiagram-UZGBJVZJ-DwkJt0zi.js} +4 -4
- package/dist/static/assets/{requirementDiagram-UZGBJVZJ-DpauVPY1.js.map → requirementDiagram-UZGBJVZJ-DwkJt0zi.js.map} +1 -1
- package/dist/static/assets/{sankeyDiagram-TZEHDZUN-B3Hbfvad.js → sankeyDiagram-TZEHDZUN-DmxmatUB.js} +2 -2
- package/dist/static/assets/{sankeyDiagram-TZEHDZUN-B3Hbfvad.js.map → sankeyDiagram-TZEHDZUN-DmxmatUB.js.map} +1 -1
- package/dist/static/assets/{sequenceDiagram-WL72ISMW-KdbWByWT.js → sequenceDiagram-WL72ISMW-KHU_eApU.js} +4 -4
- package/dist/static/assets/{sequenceDiagram-WL72ISMW-KdbWByWT.js.map → sequenceDiagram-WL72ISMW-KHU_eApU.js.map} +1 -1
- package/dist/static/assets/{stateDiagram-FKZM4ZOC-yDOCVezC.js → stateDiagram-FKZM4ZOC-B3DBCxAL.js} +9 -9
- package/dist/static/assets/{stateDiagram-FKZM4ZOC-yDOCVezC.js.map → stateDiagram-FKZM4ZOC-B3DBCxAL.js.map} +1 -1
- package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-CpCJhvQO.js → stateDiagram-v2-4FDKWEC3-C-uIk7gh.js} +5 -5
- package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-CpCJhvQO.js.map → stateDiagram-v2-4FDKWEC3-C-uIk7gh.js.map} +1 -1
- package/dist/static/assets/{timeline-definition-IT6M3QCI-CHxuEjhV.js → timeline-definition-IT6M3QCI-SysEcQCC.js} +3 -3
- package/dist/static/assets/{timeline-definition-IT6M3QCI-CHxuEjhV.js.map → timeline-definition-IT6M3QCI-SysEcQCC.js.map} +1 -1
- package/dist/static/assets/{treemap-GDKQZRPO-Bsqu3wIy.js → treemap-GDKQZRPO-d0AbKEc4.js} +5 -5
- package/dist/static/assets/{treemap-GDKQZRPO-Bsqu3wIy.js.map → treemap-GDKQZRPO-d0AbKEc4.js.map} +1 -1
- package/dist/static/assets/{xychartDiagram-PRI3JC2R-RZy33lFF.js → xychartDiagram-PRI3JC2R-CmSQMxUh.js} +3 -3
- package/dist/static/assets/{xychartDiagram-PRI3JC2R-RZy33lFF.js.map → xychartDiagram-PRI3JC2R-CmSQMxUh.js.map} +1 -1
- package/dist/static/index.html +2 -2
- package/dist/tools/fs.js +1 -1
- package/package.json +9 -7
- package/dist/agent-priming.js +0 -2051
- package/dist/apps/installed-file.js +0 -207
- package/dist/apps/runtime-port.js +0 -91
- package/dist/docs/dominds-agent-priming.md +0 -218
- package/dist/docs/dominds-agent-priming.zh.md +0 -196
- package/dist/docs/drive-logic-context-refactor-plan.zh.md +0 -338
- package/dist/docs/keep-going.md +0 -176
- package/dist/docs/keep-going.zh.md +0 -162
- package/dist/docs/kernel-app-architecture.md +0 -286
- package/dist/docs/kernel-app-architecture.zh.md +0 -285
- package/dist/docs/showing-by-doing.md +0 -208
- package/dist/docs/showing-by-doing.zh.md +0 -177
- package/dist/docs/team-mgmt-toolset.md +0 -482
- package/dist/docs/team-mgmt-toolset.zh.md +0 -426
- package/dist/llm/driver-entry.js +0 -28
- package/dist/llm/driver-v2/context-health.js +0 -121
- package/dist/llm/driver-v2/context.js +0 -56
- package/dist/llm/driver-v2/core.js +0 -1545
- package/dist/llm/driver-v2/index.js +0 -26
- package/dist/llm/driver-v2/orchestrator.js +0 -158
- package/dist/llm/driver-v2/policy.js +0 -129
- package/dist/llm/driver-v2/restore-dialog-hierarchy.js +0 -73
- package/dist/llm/driver-v2/round.js +0 -366
- package/dist/llm/driver-v2/runtime-utils.js +0 -365
- package/dist/llm/driver-v2/saying-events.js +0 -20
- package/dist/llm/driver-v2/subdialog-txn.js +0 -42
- package/dist/llm/driver-v2/supdialog-response.js +0 -400
- package/dist/llm/driver-v2/tellask-bridge.js +0 -1148
- package/dist/llm/driver-v2/types.js +0 -10
- package/dist/llm/driver-v2-ref-only/context-health.js +0 -121
- package/dist/llm/driver-v2-ref-only/context.js +0 -17
- package/dist/llm/driver-v2-ref-only/core.js +0 -1710
- package/dist/llm/driver-v2-ref-only/index.js +0 -26
- package/dist/llm/driver-v2-ref-only/orchestrator.js +0 -158
- package/dist/llm/driver-v2-ref-only/policy.js +0 -129
- package/dist/llm/driver-v2-ref-only/restore-dialog-hierarchy.js +0 -73
- package/dist/llm/driver-v2-ref-only/round.js +0 -366
- package/dist/llm/driver-v2-ref-only/runtime-utils.js +0 -473
- package/dist/llm/driver-v2-ref-only/saying-events.js +0 -18
- package/dist/llm/driver-v2-ref-only/subdialog-txn.js +0 -42
- package/dist/llm/driver-v2-ref-only/supdialog-response.js +0 -453
- package/dist/llm/driver-v2-ref-only/tellask-bridge.js +0 -1178
- package/dist/llm/driver-v2-ref-only/types.js +0 -10
- package/dist/llm/driver.js +0 -4093
- package/dist/minds/promptdocs.js +0 -263
- package/dist/server/prompts-routes.js +0 -545
- package/dist/shared/team-mgmt-manual.js +0 -120
- package/dist/shared/types/prompts.js +0 -2
- package/dist/shared/types/tellask.js +0 -8
- package/dist/showing-by-doing.js +0 -1091
- package/dist/snippets/README.en.md +0 -3
- package/dist/snippets/README.md +0 -4
- package/dist/static/assets/index-DMbwqOm6.js.map +0 -1
- package/dist/tellask.js +0 -439
- package/dist/tools/context-health.js +0 -177
- package/dist/tools/diag.js +0 -583
- package/dist/tools/prompts/memory/en/errors.md +0 -155
- package/dist/tools/prompts/memory/en/index.md +0 -47
- package/dist/tools/prompts/memory/en/principles.md +0 -87
- package/dist/tools/prompts/memory/en/scenarios.md +0 -174
- package/dist/tools/prompts/memory/en/tools.md +0 -129
- package/dist/tools/prompts/memory/zh/errors.md +0 -155
- package/dist/tools/prompts/memory/zh/index.md +0 -47
- package/dist/tools/prompts/memory/zh/principles.md +0 -89
- package/dist/tools/prompts/memory/zh/scenarios.md +0 -174
- package/dist/tools/prompts/memory/zh/tools.md +0 -129
- package/dist/tools/team-mgmt.js +0 -3487
- package/dist/utils/task-doc.js +0 -236
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.INSTALLED_APPS_REL_PATH = void 0;
|
|
7
|
-
exports.loadInstalledAppsFile = loadInstalledAppsFile;
|
|
8
|
-
exports.writeInstalledAppsFile = writeInstalledAppsFile;
|
|
9
|
-
exports.upsertInstalledApp = upsertInstalledApp;
|
|
10
|
-
exports.removeInstalledApp = removeInstalledApp;
|
|
11
|
-
exports.setAppEnabled = setAppEnabled;
|
|
12
|
-
exports.setAppRuntimePort = setAppRuntimePort;
|
|
13
|
-
exports.findInstalledApp = findInstalledApp;
|
|
14
|
-
const promises_1 = __importDefault(require("fs/promises"));
|
|
15
|
-
const path_1 = __importDefault(require("path"));
|
|
16
|
-
const yaml_1 = __importDefault(require("yaml"));
|
|
17
|
-
const time_1 = require("../shared/utils/time");
|
|
18
|
-
exports.INSTALLED_APPS_REL_PATH = path_1.default.join('.apps', 'installed.yaml');
|
|
19
|
-
function isRecord(v) {
|
|
20
|
-
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
21
|
-
}
|
|
22
|
-
function asString(v) {
|
|
23
|
-
return typeof v === 'string' ? v : null;
|
|
24
|
-
}
|
|
25
|
-
function asBool(v) {
|
|
26
|
-
return typeof v === 'boolean' ? v : null;
|
|
27
|
-
}
|
|
28
|
-
function asNullableNumber(v) {
|
|
29
|
-
if (v === null)
|
|
30
|
-
return null;
|
|
31
|
-
if (typeof v === 'number' && Number.isFinite(v))
|
|
32
|
-
return v;
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
function parseSource(v, at) {
|
|
36
|
-
if (!isRecord(v))
|
|
37
|
-
return { ok: false, errorText: `Invalid ${at}: expected object` };
|
|
38
|
-
const kind = asString(v['kind']);
|
|
39
|
-
if (kind !== 'npx' && kind !== 'local') {
|
|
40
|
-
return { ok: false, errorText: `Invalid ${at}.kind: expected 'npx'|'local'` };
|
|
41
|
-
}
|
|
42
|
-
if (kind === 'npx') {
|
|
43
|
-
const spec = asString(v['spec']);
|
|
44
|
-
if (!spec || spec.trim() === '')
|
|
45
|
-
return { ok: false, errorText: `Invalid ${at}.spec: required` };
|
|
46
|
-
return { ok: true, source: { kind, spec } };
|
|
47
|
-
}
|
|
48
|
-
const pathAbs = asString(v['pathAbs']);
|
|
49
|
-
if (!pathAbs || pathAbs.trim() === '')
|
|
50
|
-
return { ok: false, errorText: `Invalid ${at}.pathAbs: required` };
|
|
51
|
-
return { ok: true, source: { kind, pathAbs } };
|
|
52
|
-
}
|
|
53
|
-
function parseRuntime(v, at) {
|
|
54
|
-
if (!isRecord(v))
|
|
55
|
-
return { ok: false, errorText: `Invalid ${at}: expected object` };
|
|
56
|
-
const portRaw = v['port'];
|
|
57
|
-
const port = asNullableNumber(portRaw);
|
|
58
|
-
if (port === null) {
|
|
59
|
-
if (portRaw !== null) {
|
|
60
|
-
return { ok: false, errorText: `Invalid ${at}.port: expected number|null` };
|
|
61
|
-
}
|
|
62
|
-
return { ok: true, runtime: { port: null } };
|
|
63
|
-
}
|
|
64
|
-
if (port < 0 || !Number.isInteger(port))
|
|
65
|
-
return { ok: false, errorText: `Invalid ${at}.port: expected non-negative integer|null` };
|
|
66
|
-
return { ok: true, runtime: { port: port } };
|
|
67
|
-
}
|
|
68
|
-
function parseEntry(v, at) {
|
|
69
|
-
if (!isRecord(v))
|
|
70
|
-
return { ok: false, errorText: `Invalid ${at}: expected object` };
|
|
71
|
-
const id = asString(v['id']);
|
|
72
|
-
if (!id || id.trim() === '')
|
|
73
|
-
return { ok: false, errorText: `Invalid ${at}.id: required` };
|
|
74
|
-
const enabled = asBool(v['enabled']);
|
|
75
|
-
if (enabled === null)
|
|
76
|
-
return { ok: false, errorText: `Invalid ${at}.enabled: boolean required` };
|
|
77
|
-
const installedAt = asString(v['installedAt']);
|
|
78
|
-
const updatedAt = asString(v['updatedAt']);
|
|
79
|
-
if (!installedAt || installedAt.trim() === '')
|
|
80
|
-
return { ok: false, errorText: `Invalid ${at}.installedAt: required` };
|
|
81
|
-
if (!updatedAt || updatedAt.trim() === '')
|
|
82
|
-
return { ok: false, errorText: `Invalid ${at}.updatedAt: required` };
|
|
83
|
-
const sourceParsed = parseSource(v['source'], `${at}.source`);
|
|
84
|
-
if (!sourceParsed.ok)
|
|
85
|
-
return sourceParsed;
|
|
86
|
-
const runtimeParsed = parseRuntime(v['runtime'] ?? { port: null }, `${at}.runtime`);
|
|
87
|
-
if (!runtimeParsed.ok)
|
|
88
|
-
return runtimeParsed;
|
|
89
|
-
// installJson is validated by install/update command on write. On read we keep permissive:
|
|
90
|
-
// kernel will fail fast later if it needs a missing field.
|
|
91
|
-
const installJson = v['installJson'];
|
|
92
|
-
if (!isRecord(installJson))
|
|
93
|
-
return { ok: false, errorText: `Invalid ${at}.installJson: expected object` };
|
|
94
|
-
return {
|
|
95
|
-
ok: true,
|
|
96
|
-
entry: {
|
|
97
|
-
id,
|
|
98
|
-
enabled,
|
|
99
|
-
source: sourceParsed.source,
|
|
100
|
-
runtime: runtimeParsed.runtime,
|
|
101
|
-
installJson: installJson,
|
|
102
|
-
installedAt,
|
|
103
|
-
updatedAt,
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
async function loadInstalledAppsFile(params) {
|
|
108
|
-
const filePathAbs = path_1.default.resolve(params.rtwsRootAbs, exports.INSTALLED_APPS_REL_PATH);
|
|
109
|
-
let raw;
|
|
110
|
-
try {
|
|
111
|
-
raw = await promises_1.default.readFile(filePathAbs, 'utf-8');
|
|
112
|
-
}
|
|
113
|
-
catch (err) {
|
|
114
|
-
const isEnoent = typeof err === 'object' &&
|
|
115
|
-
err !== null &&
|
|
116
|
-
'code' in err &&
|
|
117
|
-
err.code === 'ENOENT';
|
|
118
|
-
if (isEnoent) {
|
|
119
|
-
return { kind: 'ok', filePathAbs, file: { schemaVersion: 1, apps: [] } };
|
|
120
|
-
}
|
|
121
|
-
return {
|
|
122
|
-
kind: 'error',
|
|
123
|
-
filePathAbs,
|
|
124
|
-
errorText: err instanceof Error ? err.message : String(err),
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
let parsed;
|
|
128
|
-
try {
|
|
129
|
-
parsed = yaml_1.default.parse(raw);
|
|
130
|
-
}
|
|
131
|
-
catch (err) {
|
|
132
|
-
return {
|
|
133
|
-
kind: 'error',
|
|
134
|
-
filePathAbs,
|
|
135
|
-
errorText: `Failed to parse YAML: ${err instanceof Error ? err.message : String(err)}`,
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
if (!isRecord(parsed)) {
|
|
139
|
-
return { kind: 'error', filePathAbs, errorText: 'Invalid installed.yaml: expected object' };
|
|
140
|
-
}
|
|
141
|
-
const schemaVersion = parsed['schemaVersion'];
|
|
142
|
-
if (schemaVersion !== 1) {
|
|
143
|
-
return {
|
|
144
|
-
kind: 'error',
|
|
145
|
-
filePathAbs,
|
|
146
|
-
errorText: `Unsupported schemaVersion: ${String(schemaVersion)}`,
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
const appsRaw = parsed['apps'];
|
|
150
|
-
if (!Array.isArray(appsRaw)) {
|
|
151
|
-
return {
|
|
152
|
-
kind: 'error',
|
|
153
|
-
filePathAbs,
|
|
154
|
-
errorText: 'Invalid installed.yaml: apps must be an array',
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
const apps = [];
|
|
158
|
-
for (let i = 0; i < appsRaw.length; i += 1) {
|
|
159
|
-
const e = parseEntry(appsRaw[i], `apps[${i}]`);
|
|
160
|
-
if (!e.ok)
|
|
161
|
-
return { kind: 'error', filePathAbs, errorText: e.errorText };
|
|
162
|
-
apps.push(e.entry);
|
|
163
|
-
}
|
|
164
|
-
return { kind: 'ok', filePathAbs, file: { schemaVersion: 1, apps } };
|
|
165
|
-
}
|
|
166
|
-
async function writeInstalledAppsFile(params) {
|
|
167
|
-
const dirAbs = path_1.default.resolve(params.rtwsRootAbs, '.apps');
|
|
168
|
-
await promises_1.default.mkdir(dirAbs, { recursive: true });
|
|
169
|
-
const filePathAbs = path_1.default.resolve(params.rtwsRootAbs, exports.INSTALLED_APPS_REL_PATH);
|
|
170
|
-
const yamlText = yaml_1.default.stringify(params.file);
|
|
171
|
-
await promises_1.default.writeFile(filePathAbs, yamlText, 'utf-8');
|
|
172
|
-
}
|
|
173
|
-
function upsertInstalledApp(params) {
|
|
174
|
-
const apps = [...params.existing.apps];
|
|
175
|
-
const idx = apps.findIndex((a) => a.id === params.next.id);
|
|
176
|
-
if (idx >= 0) {
|
|
177
|
-
apps[idx] = params.next;
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
apps.push(params.next);
|
|
181
|
-
}
|
|
182
|
-
return { schemaVersion: 1, apps };
|
|
183
|
-
}
|
|
184
|
-
function removeInstalledApp(params) {
|
|
185
|
-
return { schemaVersion: 1, apps: params.existing.apps.filter((a) => a.id !== params.appId) };
|
|
186
|
-
}
|
|
187
|
-
function setAppEnabled(params) {
|
|
188
|
-
const now = (0, time_1.formatUnifiedTimestamp)(new Date());
|
|
189
|
-
const apps = params.existing.apps.map((a) => a.id === params.appId ? { ...a, enabled: params.enabled, updatedAt: now } : a);
|
|
190
|
-
return { schemaVersion: 1, apps };
|
|
191
|
-
}
|
|
192
|
-
function setAppRuntimePort(params) {
|
|
193
|
-
const existingApp = findInstalledApp(params.existing, params.appId);
|
|
194
|
-
if (!existingApp)
|
|
195
|
-
return params.existing;
|
|
196
|
-
if (existingApp.runtime.port === params.port)
|
|
197
|
-
return params.existing;
|
|
198
|
-
const now = (0, time_1.formatUnifiedTimestamp)(new Date());
|
|
199
|
-
const apps = params.existing.apps.map((a) => a.id === params.appId
|
|
200
|
-
? { ...a, runtime: { ...a.runtime, port: params.port }, updatedAt: now }
|
|
201
|
-
: a);
|
|
202
|
-
return { schemaVersion: 1, apps };
|
|
203
|
-
}
|
|
204
|
-
function findInstalledApp(file, appId) {
|
|
205
|
-
const found = file.apps.find((a) => a.id === appId);
|
|
206
|
-
return found ?? null;
|
|
207
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.resolveStableAppRuntimePort = resolveStableAppRuntimePort;
|
|
7
|
-
const node_net_1 = __importDefault(require("node:net"));
|
|
8
|
-
const STABLE_PORT_RANGE_START = 43000;
|
|
9
|
-
const STABLE_PORT_RANGE_END = 49999;
|
|
10
|
-
const PORT_MAX = 65535;
|
|
11
|
-
function isPositivePort(value) {
|
|
12
|
-
return (typeof value === 'number' &&
|
|
13
|
-
Number.isInteger(value) &&
|
|
14
|
-
value > 0 &&
|
|
15
|
-
value <= PORT_MAX &&
|
|
16
|
-
Number.isFinite(value));
|
|
17
|
-
}
|
|
18
|
-
function hashAppId(appId) {
|
|
19
|
-
// FNV-1a 32-bit hash for deterministic port probing order.
|
|
20
|
-
let hash = 0x811c9dc5;
|
|
21
|
-
for (let i = 0; i < appId.length; i += 1) {
|
|
22
|
-
hash ^= appId.charCodeAt(i);
|
|
23
|
-
hash = Math.imul(hash, 0x01000193);
|
|
24
|
-
}
|
|
25
|
-
return hash >>> 0;
|
|
26
|
-
}
|
|
27
|
-
function collectReservedPorts(existingApps, appId) {
|
|
28
|
-
const reserved = new Set();
|
|
29
|
-
for (const app of existingApps) {
|
|
30
|
-
if (app.id === appId)
|
|
31
|
-
continue;
|
|
32
|
-
if (isPositivePort(app.runtime.port)) {
|
|
33
|
-
reserved.add(app.runtime.port);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return reserved;
|
|
37
|
-
}
|
|
38
|
-
async function canBindPort(port) {
|
|
39
|
-
return await new Promise((resolve) => {
|
|
40
|
-
const server = node_net_1.default.createServer();
|
|
41
|
-
server.unref();
|
|
42
|
-
const finish = (ok) => {
|
|
43
|
-
server.removeAllListeners('error');
|
|
44
|
-
server.removeAllListeners('listening');
|
|
45
|
-
resolve(ok);
|
|
46
|
-
};
|
|
47
|
-
server.once('error', () => {
|
|
48
|
-
finish(false);
|
|
49
|
-
});
|
|
50
|
-
server.once('listening', () => {
|
|
51
|
-
server.close(() => finish(true));
|
|
52
|
-
});
|
|
53
|
-
server.listen({ host: '127.0.0.1', port, exclusive: true });
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
async function pickDeterministicAvailablePort(params) {
|
|
57
|
-
const rangeSize = STABLE_PORT_RANGE_END - STABLE_PORT_RANGE_START + 1;
|
|
58
|
-
if (rangeSize <= 0) {
|
|
59
|
-
throw new Error('Invalid stable app runtime port range configuration');
|
|
60
|
-
}
|
|
61
|
-
const baseHash = hashAppId(params.appId);
|
|
62
|
-
for (let i = 0; i < rangeSize; i += 1) {
|
|
63
|
-
const candidate = STABLE_PORT_RANGE_START + ((baseHash + i) % rangeSize);
|
|
64
|
-
if (params.reservedPorts.has(candidate))
|
|
65
|
-
continue;
|
|
66
|
-
if (await canBindPort(candidate))
|
|
67
|
-
return candidate;
|
|
68
|
-
}
|
|
69
|
-
throw new Error(`Failed to allocate stable runtime port for app '${params.appId}': no bindable port in ${STABLE_PORT_RANGE_START}-${STABLE_PORT_RANGE_END}`);
|
|
70
|
-
}
|
|
71
|
-
async function resolveStableAppRuntimePort(params) {
|
|
72
|
-
if (!params.installJson.frontend)
|
|
73
|
-
return null;
|
|
74
|
-
const reservedPorts = collectReservedPorts(params.existingApps, params.appId);
|
|
75
|
-
if (isPositivePort(params.existingRuntimePort)) {
|
|
76
|
-
if (reservedPorts.has(params.existingRuntimePort)) {
|
|
77
|
-
throw new Error(`Invalid installed apps state: runtime port ${params.existingRuntimePort} for '${params.appId}' collides with another installed app`);
|
|
78
|
-
}
|
|
79
|
-
return params.existingRuntimePort;
|
|
80
|
-
}
|
|
81
|
-
const defaultPort = params.installJson.frontend.defaultPort;
|
|
82
|
-
if (isPositivePort(defaultPort) &&
|
|
83
|
-
!reservedPorts.has(defaultPort) &&
|
|
84
|
-
(await canBindPort(defaultPort))) {
|
|
85
|
-
return defaultPort;
|
|
86
|
-
}
|
|
87
|
-
return await pickDeterministicAvailablePort({
|
|
88
|
-
appId: params.appId,
|
|
89
|
-
reservedPorts,
|
|
90
|
-
});
|
|
91
|
-
}
|
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
# Dominds Agent Priming: Guide the Agent to Show It to Itself
|
|
2
|
-
|
|
3
|
-
Chinese version: [中文版](./dominds-agent-priming.zh.md)
|
|
4
|
-
|
|
5
|
-
## Summary
|
|
6
|
-
|
|
7
|
-
Dominds has a real, runtime-enforced Tellask mechanism (`tellask* function call`) and a real, runtime-enforced Fresh Boots Reasoning
|
|
8
|
-
(FBR) mechanism (`freshBootsReasoning`). Even if system prompts explain these mechanisms in detail, most foundation models were not
|
|
9
|
-
trained in a world where “asking a teammate to run a shell command” is actually possible, so they often treat such text
|
|
10
|
-
as aspirational or hypothetical.
|
|
11
|
-
|
|
12
|
-
**Agent Priming** is a tiny, highly realistic “first impression” procedure executed at dialog creation time. It runs a
|
|
13
|
-
short, real Tellask + real return + real FBR + real distillation so the model gains _felt-sense_ that:
|
|
14
|
-
|
|
15
|
-
- teammate Tellasks are real and will be executed
|
|
16
|
-
- tool outputs are real and will be returned and persisted
|
|
17
|
-
- `freshBootsReasoning` FBR is real and will report back
|
|
18
|
-
- distillation is expected (extract the best, dedupe, reconcile), not “repeat each draft”
|
|
19
|
-
|
|
20
|
-
More precisely: it **guides the agent to show it to itself** — letting it personally walk through
|
|
21
|
-
(Tellask → return → FBR → distillation), moving from “I’ve heard this exists” to “I just used it”.
|
|
22
|
-
|
|
23
|
-
This is structurally related to the psychology notion of a **priming effect**: an early, concrete stimulus can
|
|
24
|
-
significantly shape subsequent expectations and behaviors. In Dominds we anchor this “priming” in **verifiable runtime
|
|
25
|
-
interactions**, instead of relying on longer, declarative system-prompt text.
|
|
26
|
-
|
|
27
|
-
As a consequence, we can **dramatically simplify system prompts**: keep only short, accurate statements of the
|
|
28
|
-
Tellask/FBR contracts, and rely on a real priming run to establish “this works here”.
|
|
29
|
-
|
|
30
|
-
Related docs:
|
|
31
|
-
|
|
32
|
-
- Tellask runtime: [`dialog-system.md`](./dialog-system.md)
|
|
33
|
-
- Terminology (Mainline/Sideline): [`dominds-terminology.md`](./dominds-terminology.md)
|
|
34
|
-
- FBR (`freshBootsReasoning`): [`fbr.md`](./fbr.md)
|
|
35
|
-
- Work language vs UI language: [`i18n.md`](./i18n.md)
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Goals
|
|
40
|
-
|
|
41
|
-
- Establish immediate trust that Tellask/return/persistence are real.
|
|
42
|
-
- Run a real `freshBootsReasoning` FBR loop at dialog creation.
|
|
43
|
-
- Build muscle memory for the timing contract: initiate FBR, wait for feedback, then synthesize/decide.
|
|
44
|
-
- Make distillation itself part of the “felt” experience (dedupe/reconcile/extract-the-best).
|
|
45
|
-
- Keep the procedure safe, small, and deterministic (default command: `uname -a`).
|
|
46
|
-
- Persist and display the interaction so it is credible from multiple angles (backend record + frontend transcript).
|
|
47
|
-
|
|
48
|
-
## Non-goals
|
|
49
|
-
|
|
50
|
-
- Running arbitrary user-provided commands as part of dialog creation.
|
|
51
|
-
- Collecting sensitive system information (beyond minimal OS/kernel identification).
|
|
52
|
-
- Replacing proper documentation: this is an experiential supplement, not the main spec.
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
## Definitions (user-facing)
|
|
57
|
-
|
|
58
|
-
- **Mainline dialog**: the primary thread where the user and the main agent interact.
|
|
59
|
-
- **Sideline dialog**: a temporary work thread created by Tellask / FBR, reporting results back to the mainline.
|
|
60
|
-
- **Tellask**: a structured request (`tellask({ targetAgentId: "<memberId>", sessionSlug: "<slug>", tellaskContent: "..." })`) from a tellasker to a tellaskee.
|
|
61
|
-
- **Shell specialist**: a teammate designated to run shell commands safely (configured via `shell_specialists`).
|
|
62
|
-
- **FBR**: Fresh Boots Reasoning, implemented as `freshBootsReasoning` (a tool-less sideline dialog). See [`fbr.md`](./fbr.md).
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## Runtime flow (at dialog creation)
|
|
67
|
-
|
|
68
|
-
Agent Priming runs **before** the first user message is processed, unless the user opts out.
|
|
69
|
-
|
|
70
|
-
### 1) Choose the shell execution path
|
|
71
|
-
|
|
72
|
-
1. If the team config includes at least one `shell_specialists` member, pick one deterministically (e.g. the first).
|
|
73
|
-
2. Otherwise, let the **Dominds runtime** execute the baseline command directly (not via agent tools).
|
|
74
|
-
|
|
75
|
-
Baseline command:
|
|
76
|
-
|
|
77
|
-
- `uname -a`
|
|
78
|
-
|
|
79
|
-
If `uname -a` fails (e.g. non-POSIX host), the runtime may fall back to a platform-appropriate equivalent, but the
|
|
80
|
-
default “muscle memory” path is intentionally `uname -a` because it is common, low-risk, and quick.
|
|
81
|
-
|
|
82
|
-
### 2) Real teammate Tellask: ask for `uname -a`
|
|
83
|
-
|
|
84
|
-
If a shell specialist member exists, the main agent (tellasker) issues **a real Tellask** to the shell specialist member
|
|
85
|
-
(tellaskee), in the server-wide work language.
|
|
86
|
-
|
|
87
|
-
The Tellask body should be short and operational:
|
|
88
|
-
|
|
89
|
-
- run exactly `uname -a`
|
|
90
|
-
- return raw output verbatim
|
|
91
|
-
- if `uname` fails: include error + one safe alternative command
|
|
92
|
-
|
|
93
|
-
### 3) Real FBR: reflect on what the environment implies
|
|
94
|
-
|
|
95
|
-
After obtaining the environment snapshot, the main agent issues a real `freshBootsReasoning` Tellask to trigger FBR.
|
|
96
|
-
|
|
97
|
-
The FBR body should include:
|
|
98
|
-
|
|
99
|
-
- the exact `uname -a` output (explicitly name the command; it may change in the future)
|
|
100
|
-
- the tool constraint (FBR has no tools; mainline tool availability is separate)
|
|
101
|
-
- the question: “What should I be careful about in this environment? Which CLI tools should I prioritize, and why?”
|
|
102
|
-
|
|
103
|
-
Optional parallel drafts:
|
|
104
|
-
|
|
105
|
-
- If the team member config enables `fbr_effort` (default `3`), the runtime creates multiple `freshBootsReasoning` FBR sideline
|
|
106
|
-
dialogs concurrently so the agent produces multiple independent “fresh boots” drafts for the mainline dialog to
|
|
107
|
-
distill.
|
|
108
|
-
- These drafts have **no stable identity mapping**, and there is no meaningful ordering requirement; the mainline dialog
|
|
109
|
-
should treat them as anonymous drafts rather than fixed personas.
|
|
110
|
-
- If `fbr_effort` is `0`, skip FBR.
|
|
111
|
-
- If `fbr_effort` is greater than `100`, the runtime errors out and stops priming (invalid config).
|
|
112
|
-
|
|
113
|
-
Phase boundary (critical):
|
|
114
|
-
|
|
115
|
-
- `freshBootsReasoning` 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
|
-
|
|
119
|
-
### 4) Distill into an “Agent Priming” note
|
|
120
|
-
|
|
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
|
|
122
|
-
dialog. It should be explicitly distilled (dedupe/reconcile/extract-the-best) rather than repeating each draft.
|
|
123
|
-
|
|
124
|
-
Implementation constraint (matches runtime behavior):
|
|
125
|
-
|
|
126
|
-
- Do not introduce a separate system-prompt assembly path for distillation.
|
|
127
|
-
- The runtime may use a non-persisted **internal prompt** to anchor “this generation is distillation”.
|
|
128
|
-
- The runtime may also include the shell snapshot and FBR drafts as “evidence” inside that internal prompt (for this
|
|
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.
|
|
132
|
-
|
|
133
|
-
Implementation note (internal prompt):
|
|
134
|
-
|
|
135
|
-
- The runtime may provide the driver with a non-persisted, non-rendered **internal prompt** (used only in the LLM
|
|
136
|
-
context for this drive) to explicitly anchor the generation as “distillation”.
|
|
137
|
-
- The internal prompt must not be written into dialog history or persisted storage (to avoid transcript pollution
|
|
138
|
-
across courses).
|
|
139
|
-
- The internal prompt is a per-drive task directive; it must not replace the system prompt or introduce a separate
|
|
140
|
-
system-prompt assembly path.
|
|
141
|
-
|
|
142
|
-
Implementation note (avoid Taskdoc bias):
|
|
143
|
-
|
|
144
|
-
- Distillation must be Taskdoc-agnostic: the same Agent Priming prefix can be reused across dialogs with different
|
|
145
|
-
Taskdocs.
|
|
146
|
-
- Therefore, the runtime may choose to **skip injecting Taskdoc** for the one distillation drive, so Taskdoc progress
|
|
147
|
-
or implementation details do not bias environment conclusions.
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## Persistence, caching, and reuse (in-process only)
|
|
152
|
-
|
|
153
|
-
### 1) Persist as real dialog records (backend + frontend)
|
|
154
|
-
|
|
155
|
-
All priming steps must be persisted as standard dialog artifacts (messages + events) and visible in the WebUI.
|
|
156
|
-
|
|
157
|
-
### 2) Process-wide cache (per agent)
|
|
158
|
-
|
|
159
|
-
To avoid repeating `uname -a` + FBR + distillation on every new dialog, the backend process may maintain an in-process cache
|
|
160
|
-
(lost on restart) keyed by the mainline agent id.
|
|
161
|
-
|
|
162
|
-
Reuse policy:
|
|
163
|
-
|
|
164
|
-
- If a valid cache entry exists, a new dialog may reuse the cached transcript and Agent Priming note.
|
|
165
|
-
- Reused entries should still be visible in the new dialog transcript, labeled as “reused from cache”.
|
|
166
|
-
|
|
167
|
-
### 2.5) Mainline choice must propagate to sideline dialogs
|
|
168
|
-
|
|
169
|
-
The priming choice selected at mainline dialog creation must propagate to all sideline dialogs under that root dialog.
|
|
170
|
-
|
|
171
|
-
Propagation semantics:
|
|
172
|
-
|
|
173
|
-
- Mainline chooses **Skip** (`skip`): all sideline dialogs must also **Skip** (`skip`).
|
|
174
|
-
- Mainline chooses **Do Again** (`do`) while cache exists: all sideline dialogs must also run fresh (`do`).
|
|
175
|
-
- Mainline chooses **Show it now** (`do`) when cache does not exist, or chooses **Reuse** (`reuse`):
|
|
176
|
-
sideline dialogs use **reuse-or-do** (`reuse`): reuse cache when available for that sideline agent;
|
|
177
|
-
otherwise run a fresh priming.
|
|
178
|
-
|
|
179
|
-
Notes:
|
|
180
|
-
|
|
181
|
-
- Different sideline agents may have different cache states; `reuse` is evaluated per sideline agent.
|
|
182
|
-
- Priming must not run invisibly in the background; it must be persisted and user-visible as standard dialog artifacts.
|
|
183
|
-
|
|
184
|
-
### 3) Carry across `clear_mind`
|
|
185
|
-
|
|
186
|
-
After each `clear_mind` (entering the next course), do not rely on reminders.
|
|
187
|
-
|
|
188
|
-
Instead, inject a small, stable **course prefix** into model context at the start of each course: a condensed transcript
|
|
189
|
-
(shell snapshot + FBR highlights + Priming note).
|
|
190
|
-
|
|
191
|
-
---
|
|
192
|
-
|
|
193
|
-
## UX requirements (WebUI)
|
|
194
|
-
|
|
195
|
-
### Display
|
|
196
|
-
|
|
197
|
-
- Render Agent Priming as a realistic transcript the user can inspect.
|
|
198
|
-
- Prefer a collapsible top section with clear labels:
|
|
199
|
-
- “Teammate Tellask (shell)”
|
|
200
|
-
- “FBR (`freshBootsReasoning`)"
|
|
201
|
-
- “Agent Priming”
|
|
202
|
-
|
|
203
|
-
### Opt-out
|
|
204
|
-
|
|
205
|
-
Dialog creation should provide an explicit opt-out to skip priming.
|
|
206
|
-
|
|
207
|
-
Additional UX constraints:
|
|
208
|
-
|
|
209
|
-
- If the dialog owner is a hidden shadow member, the default priming preference should be **Skip**.
|
|
210
|
-
- Shadow-member priming preferences should be stored separately from visible-member preferences (they should not affect each other).
|
|
211
|
-
|
|
212
|
-
---
|
|
213
|
-
|
|
214
|
-
## Safety notes
|
|
215
|
-
|
|
216
|
-
- Default to a single, low-risk command (`uname -a`).
|
|
217
|
-
- Do not run anything that modifies the filesystem or network as part of priming.
|
|
218
|
-
- Treat the priming transcript as user-visible by default; avoid including secrets or personally identifying details.
|