dominds 1.17.7 → 1.18.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/dist/dialog-fork.js +11 -5
- package/dist/dialog-instance-registry.js +1 -18
- package/dist/dialog.d.ts +21 -31
- package/dist/dialog.js +207 -56
- package/dist/docs/dialog-system.md +3 -2
- package/dist/docs/dialog-system.zh.md +3 -2
- package/dist/docs/tellask-collab.md +2 -1
- package/dist/docs/tellask-collab.zh.md +2 -1
- package/dist/llm/defaults.yaml +43 -0
- package/dist/llm/gen/anthropic.js +153 -12
- package/dist/llm/gen/codex.js +160 -10
- package/dist/llm/gen/openai-compatible.js +141 -81
- package/dist/llm/gen/openai.js +178 -12
- package/dist/llm/gen/tool-result-image-ingest.d.ts +17 -8
- package/dist/llm/gen/tool-result-image-ingest.js +127 -27
- package/dist/llm/gen.d.ts +13 -0
- package/dist/llm/kernel-driver/drive.js +79 -15
- package/dist/llm/kernel-driver/flow.js +158 -41
- package/dist/llm/kernel-driver/reply-guidance.d.ts +6 -6
- package/dist/llm/kernel-driver/reply-guidance.js +169 -2
- package/dist/llm/kernel-driver/runtime.d.ts +2 -2
- package/dist/llm/kernel-driver/subdialog.js +4 -0
- package/dist/llm/kernel-driver/tellask-special.d.ts +2 -0
- package/dist/llm/kernel-driver/tellask-special.js +11 -6
- package/dist/llm/kernel-driver/types.d.ts +14 -24
- package/dist/minds/system-prompt.js +8 -8
- package/dist/persistence.d.ts +6 -5
- package/dist/persistence.js +198 -39
- package/dist/priming.js +98 -3
- package/dist/runtime/driver-messages.d.ts +1 -0
- package/dist/runtime/driver-messages.js +32 -10
- package/dist/runtime/reply-prompt-copy.js +4 -4
- package/dist/server/api-routes.js +11 -43
- package/dist/server/websocket-handler.js +155 -10
- package/dist/tools/builtins.js +10 -4
- package/dist/tools/cmd-runner.js +110 -49
- package/dist/tools/picture.d.ts +3 -0
- package/dist/tools/picture.js +344 -0
- package/dist/tools/prompts/control/en/principles.md +4 -2
- package/dist/tools/prompts/control/en/scenarios.md +2 -1
- package/dist/tools/prompts/control/en/tools.md +6 -6
- package/dist/tools/prompts/control/zh/principles.md +4 -2
- package/dist/tools/prompts/control/zh/scenarios.md +2 -1
- package/dist/tools/prompts/control/zh/tools.md +1 -1
- package/dist/tools/prompts/ws_mod.en.md +1 -0
- package/dist/tools/prompts/ws_mod.zh.md +1 -0
- package/dist/tools/prompts/ws_read/en/tools.md +25 -5
- package/dist/tools/prompts/ws_read/zh/tools.md +25 -5
- package/package.json +4 -4
- package/webapp/dist/assets/{_basePickBy-u7tNFRWr.js → _basePickBy-BPJaiZdW.js} +3 -3
- package/webapp/dist/assets/{_basePickBy-u7tNFRWr.js.map → _basePickBy-BPJaiZdW.js.map} +1 -1
- package/webapp/dist/assets/{_baseUniq-CH9LRkiH.js → _baseUniq-BEetT15i.js} +2 -2
- package/webapp/dist/assets/{_baseUniq-CH9LRkiH.js.map → _baseUniq-BEetT15i.js.map} +1 -1
- package/webapp/dist/assets/{arc-Bo0Lw3ZP.js → arc-Dm7Zf36f.js} +2 -2
- package/webapp/dist/assets/{arc-Bo0Lw3ZP.js.map → arc-Dm7Zf36f.js.map} +1 -1
- package/webapp/dist/assets/{architectureDiagram-VXUJARFQ-Ckyr89Iw.js → architectureDiagram-VXUJARFQ-BpTPtkuo.js} +7 -7
- package/webapp/dist/assets/{architectureDiagram-VXUJARFQ-Ckyr89Iw.js.map → architectureDiagram-VXUJARFQ-BpTPtkuo.js.map} +1 -1
- package/webapp/dist/assets/{blockDiagram-VD42YOAC-BSXoLLq_.js → blockDiagram-VD42YOAC-C8fLN0iu.js} +7 -7
- package/webapp/dist/assets/{blockDiagram-VD42YOAC-BSXoLLq_.js.map → blockDiagram-VD42YOAC-C8fLN0iu.js.map} +1 -1
- package/webapp/dist/assets/{c4Diagram-YG6GDRKO-CgCG1cP0.js → c4Diagram-YG6GDRKO-BpPr62CH.js} +3 -3
- package/webapp/dist/assets/{c4Diagram-YG6GDRKO-CgCG1cP0.js.map → c4Diagram-YG6GDRKO-BpPr62CH.js.map} +1 -1
- package/webapp/dist/assets/{channel-Crbz0zgt.js → channel-EMYoPjW3.js} +2 -2
- package/webapp/dist/assets/{channel-Crbz0zgt.js.map → channel-EMYoPjW3.js.map} +1 -1
- package/webapp/dist/assets/{chunk-4BX2VUAB-BIIEb_5S.js → chunk-4BX2VUAB-CefNtjWG.js} +2 -2
- package/webapp/dist/assets/{chunk-4BX2VUAB-BIIEb_5S.js.map → chunk-4BX2VUAB-CefNtjWG.js.map} +1 -1
- package/webapp/dist/assets/{chunk-55IACEB6-CaJzGgc9.js → chunk-55IACEB6-C_X7T43V.js} +2 -2
- package/webapp/dist/assets/{chunk-55IACEB6-CaJzGgc9.js.map → chunk-55IACEB6-C_X7T43V.js.map} +1 -1
- package/webapp/dist/assets/{chunk-B4BG7PRW-DHQwhO9F.js → chunk-B4BG7PRW-BRe3_2oA.js} +5 -5
- package/webapp/dist/assets/{chunk-B4BG7PRW-DHQwhO9F.js.map → chunk-B4BG7PRW-BRe3_2oA.js.map} +1 -1
- package/webapp/dist/assets/{chunk-DI55MBZ5-CG1lO0R8.js → chunk-DI55MBZ5-CbvrsI_w.js} +4 -4
- package/webapp/dist/assets/{chunk-DI55MBZ5-CG1lO0R8.js.map → chunk-DI55MBZ5-CbvrsI_w.js.map} +1 -1
- package/webapp/dist/assets/{chunk-FMBD7UC4-DAUsTLPS.js → chunk-FMBD7UC4-ORmtkrtS.js} +2 -2
- package/webapp/dist/assets/{chunk-FMBD7UC4-DAUsTLPS.js.map → chunk-FMBD7UC4-ORmtkrtS.js.map} +1 -1
- package/webapp/dist/assets/{chunk-QN33PNHL-BfQs-QHE.js → chunk-QN33PNHL-LTAOVhWu.js} +2 -2
- package/webapp/dist/assets/{chunk-QN33PNHL-BfQs-QHE.js.map → chunk-QN33PNHL-LTAOVhWu.js.map} +1 -1
- package/webapp/dist/assets/{chunk-QZHKN3VN-C5iKQ6mQ.js → chunk-QZHKN3VN-ZoUM_4u5.js} +2 -2
- package/webapp/dist/assets/{chunk-QZHKN3VN-C5iKQ6mQ.js.map → chunk-QZHKN3VN-ZoUM_4u5.js.map} +1 -1
- package/webapp/dist/assets/{chunk-TZMSLE5B-CBShDwy2.js → chunk-TZMSLE5B-Gao4qrq7.js} +2 -2
- package/webapp/dist/assets/{chunk-TZMSLE5B-CBShDwy2.js.map → chunk-TZMSLE5B-Gao4qrq7.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-2ON5EDUG-DrfJDzYO.js → classDiagram-2ON5EDUG-uha1vIGN.js} +6 -6
- package/webapp/dist/assets/{classDiagram-2ON5EDUG-DrfJDzYO.js.map → classDiagram-2ON5EDUG-uha1vIGN.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-v2-WZHVMYZB-DrfJDzYO.js → classDiagram-v2-WZHVMYZB-uha1vIGN.js} +6 -6
- package/webapp/dist/assets/{classDiagram-v2-WZHVMYZB-DrfJDzYO.js.map → classDiagram-v2-WZHVMYZB-uha1vIGN.js.map} +1 -1
- package/webapp/dist/assets/{clone-Cd-48URG.js → clone-_9Ayb1Gp.js} +2 -2
- package/webapp/dist/assets/{clone-Cd-48URG.js.map → clone-_9Ayb1Gp.js.map} +1 -1
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-CCji0YN3.js → cose-bilkent-S5V4N54A-C8wDw3NY.js} +2 -2
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-CCji0YN3.js.map → cose-bilkent-S5V4N54A-C8wDw3NY.js.map} +1 -1
- package/webapp/dist/assets/{dagre-6UL2VRFP-B94p-Dpl.js → dagre-6UL2VRFP-BUSeNot0.js} +7 -7
- package/webapp/dist/assets/{dagre-6UL2VRFP-B94p-Dpl.js.map → dagre-6UL2VRFP-BUSeNot0.js.map} +1 -1
- package/webapp/dist/assets/{diagram-PSM6KHXK-DP-zGmAS.js → diagram-PSM6KHXK-CMZAksVC.js} +8 -8
- package/webapp/dist/assets/{diagram-PSM6KHXK-DP-zGmAS.js.map → diagram-PSM6KHXK-CMZAksVC.js.map} +1 -1
- package/webapp/dist/assets/{diagram-QEK2KX5R-DquJirs4.js → diagram-QEK2KX5R-BQKoRtwy.js} +7 -7
- package/webapp/dist/assets/{diagram-QEK2KX5R-DquJirs4.js.map → diagram-QEK2KX5R-BQKoRtwy.js.map} +1 -1
- package/webapp/dist/assets/{diagram-S2PKOQOG-Dt5W2t6V.js → diagram-S2PKOQOG-DjMG97kd.js} +7 -7
- package/webapp/dist/assets/{diagram-S2PKOQOG-Dt5W2t6V.js.map → diagram-S2PKOQOG-DjMG97kd.js.map} +1 -1
- package/webapp/dist/assets/{erDiagram-Q2GNP2WA-Bs0-2Rfj.js → erDiagram-Q2GNP2WA-BujwA137.js} +5 -5
- package/webapp/dist/assets/{erDiagram-Q2GNP2WA-Bs0-2Rfj.js.map → erDiagram-Q2GNP2WA-BujwA137.js.map} +1 -1
- package/webapp/dist/assets/{flowDiagram-NV44I4VS-cJjXWAlK.js → flowDiagram-NV44I4VS-DgwPjg4y.js} +6 -6
- package/webapp/dist/assets/{flowDiagram-NV44I4VS-cJjXWAlK.js.map → flowDiagram-NV44I4VS-DgwPjg4y.js.map} +1 -1
- package/webapp/dist/assets/{ganttDiagram-JELNMOA3-Du1AUaKm.js → ganttDiagram-JELNMOA3-Db2ykf3E.js} +3 -3
- package/webapp/dist/assets/{ganttDiagram-JELNMOA3-Du1AUaKm.js.map → ganttDiagram-JELNMOA3-Db2ykf3E.js.map} +1 -1
- package/webapp/dist/assets/{gitGraphDiagram-V2S2FVAM-D_jVOYOK.js → gitGraphDiagram-V2S2FVAM-D_gSifkv.js} +8 -8
- package/webapp/dist/assets/{gitGraphDiagram-V2S2FVAM-D_jVOYOK.js.map → gitGraphDiagram-V2S2FVAM-D_gSifkv.js.map} +1 -1
- package/webapp/dist/assets/{graph-CuF_sq4r.js → graph-BHjCU5xP.js} +3 -3
- package/webapp/dist/assets/{graph-CuF_sq4r.js.map → graph-BHjCU5xP.js.map} +1 -1
- package/webapp/dist/assets/{index-DAShQcjb.js → index-DLajsIDJ.js} +1363 -248
- package/webapp/dist/assets/{index-DAShQcjb.js.map → index-DLajsIDJ.js.map} +1 -1
- package/webapp/dist/assets/{infoDiagram-HS3SLOUP-CEFlo_Hl.js → infoDiagram-HS3SLOUP-BDba5pKs.js} +6 -6
- package/webapp/dist/assets/{infoDiagram-HS3SLOUP-CEFlo_Hl.js.map → infoDiagram-HS3SLOUP-BDba5pKs.js.map} +1 -1
- package/webapp/dist/assets/{journeyDiagram-XKPGCS4Q-zc2Q4Se9.js → journeyDiagram-XKPGCS4Q-CmJAbmlm.js} +5 -5
- package/webapp/dist/assets/{journeyDiagram-XKPGCS4Q-zc2Q4Se9.js.map → journeyDiagram-XKPGCS4Q-CmJAbmlm.js.map} +1 -1
- package/webapp/dist/assets/{kanban-definition-3W4ZIXB7-oT42RM2a.js → kanban-definition-3W4ZIXB7-DxQeBTDk.js} +3 -3
- package/webapp/dist/assets/{kanban-definition-3W4ZIXB7-oT42RM2a.js.map → kanban-definition-3W4ZIXB7-DxQeBTDk.js.map} +1 -1
- package/webapp/dist/assets/{layout-BvaOu3k2.js → layout-DteV_yE8.js} +5 -5
- package/webapp/dist/assets/{layout-BvaOu3k2.js.map → layout-DteV_yE8.js.map} +1 -1
- package/webapp/dist/assets/{linear-Cg-CjocS.js → linear-zItbPrND.js} +2 -2
- package/webapp/dist/assets/{linear-Cg-CjocS.js.map → linear-zItbPrND.js.map} +1 -1
- package/webapp/dist/assets/{mindmap-definition-VGOIOE7T-CVFVrU22.js → mindmap-definition-VGOIOE7T-BJXI7UqO.js} +4 -4
- package/webapp/dist/assets/{mindmap-definition-VGOIOE7T-CVFVrU22.js.map → mindmap-definition-VGOIOE7T-BJXI7UqO.js.map} +1 -1
- package/webapp/dist/assets/{pieDiagram-ADFJNKIX-Bai5CMos.js → pieDiagram-ADFJNKIX-BpM-aH2p.js} +8 -8
- package/webapp/dist/assets/{pieDiagram-ADFJNKIX-Bai5CMos.js.map → pieDiagram-ADFJNKIX-BpM-aH2p.js.map} +1 -1
- package/webapp/dist/assets/{quadrantDiagram-AYHSOK5B-BPXDO_2E.js → quadrantDiagram-AYHSOK5B-NXdIpA15.js} +3 -3
- package/webapp/dist/assets/{quadrantDiagram-AYHSOK5B-BPXDO_2E.js.map → quadrantDiagram-AYHSOK5B-NXdIpA15.js.map} +1 -1
- package/webapp/dist/assets/{requirementDiagram-UZGBJVZJ-Dgj9X9cE.js → requirementDiagram-UZGBJVZJ-D1AICAA0.js} +4 -4
- package/webapp/dist/assets/{requirementDiagram-UZGBJVZJ-Dgj9X9cE.js.map → requirementDiagram-UZGBJVZJ-D1AICAA0.js.map} +1 -1
- package/webapp/dist/assets/{sankeyDiagram-TZEHDZUN-Dc0mO4OD.js → sankeyDiagram-TZEHDZUN-WiReDPfo.js} +2 -2
- package/webapp/dist/assets/{sankeyDiagram-TZEHDZUN-Dc0mO4OD.js.map → sankeyDiagram-TZEHDZUN-WiReDPfo.js.map} +1 -1
- package/webapp/dist/assets/{sequenceDiagram-WL72ISMW-DZJTga0d.js → sequenceDiagram-WL72ISMW-Cw76oP8t.js} +4 -4
- package/webapp/dist/assets/{sequenceDiagram-WL72ISMW-DZJTga0d.js.map → sequenceDiagram-WL72ISMW-Cw76oP8t.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-FKZM4ZOC-RNxYatKM.js → stateDiagram-FKZM4ZOC-QjCeRczs.js} +9 -9
- package/webapp/dist/assets/{stateDiagram-FKZM4ZOC-RNxYatKM.js.map → stateDiagram-FKZM4ZOC-QjCeRczs.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-v2-4FDKWEC3-ADxYqWzo.js → stateDiagram-v2-4FDKWEC3-IClqxQ4s.js} +5 -5
- package/webapp/dist/assets/{stateDiagram-v2-4FDKWEC3-ADxYqWzo.js.map → stateDiagram-v2-4FDKWEC3-IClqxQ4s.js.map} +1 -1
- package/webapp/dist/assets/{timeline-definition-IT6M3QCI-Qx_h1e-i.js → timeline-definition-IT6M3QCI-BfyfTY7m.js} +3 -3
- package/webapp/dist/assets/{timeline-definition-IT6M3QCI-Qx_h1e-i.js.map → timeline-definition-IT6M3QCI-BfyfTY7m.js.map} +1 -1
- package/webapp/dist/assets/{treemap-GDKQZRPO-BHzYvXGn.js → treemap-GDKQZRPO-C5MiL6--.js} +5 -5
- package/webapp/dist/assets/{treemap-GDKQZRPO-BHzYvXGn.js.map → treemap-GDKQZRPO-C5MiL6--.js.map} +1 -1
- package/webapp/dist/assets/{xychartDiagram-PRI3JC2R-DGdjkYQQ.js → xychartDiagram-PRI3JC2R-ybaJrSry.js} +3 -3
- package/webapp/dist/assets/{xychartDiagram-PRI3JC2R-DGdjkYQQ.js.map → xychartDiagram-PRI3JC2R-ybaJrSry.js.map} +1 -1
- package/webapp/dist/index.html +1 -1
|
@@ -9,6 +9,7 @@ export declare function formatNewCourseStartPrompt(language: LanguageCode, args:
|
|
|
9
9
|
source: 'clear_mind' | 'critical_auto_clear';
|
|
10
10
|
}): string;
|
|
11
11
|
export declare function formatDiligenceAutoContinuePrompt(language: LanguageCode, diligenceText: string): string;
|
|
12
|
+
export declare function formatReminderContextGuide(language: LanguageCode): string;
|
|
12
13
|
export declare function formatReminderItemGuide(language: LanguageCode, reminderId: string, content: string, options?: {
|
|
13
14
|
meta?: unknown;
|
|
14
15
|
scope?: 'dialog' | 'personal' | 'agent_shared';
|
|
@@ -7,6 +7,7 @@ exports.formatRegisteredTellaskCallerUpdateNotice = formatRegisteredTellaskCalle
|
|
|
7
7
|
exports.formatRegisteredTellaskCalleeUpdateNotice = formatRegisteredTellaskCalleeUpdateNotice;
|
|
8
8
|
exports.formatNewCourseStartPrompt = formatNewCourseStartPrompt;
|
|
9
9
|
exports.formatDiligenceAutoContinuePrompt = formatDiligenceAutoContinuePrompt;
|
|
10
|
+
exports.formatReminderContextGuide = formatReminderContextGuide;
|
|
10
11
|
exports.formatReminderItemGuide = formatReminderItemGuide;
|
|
11
12
|
exports.formatQ4HDiligencePushBudgetExhausted = formatQ4HDiligencePushBudgetExhausted;
|
|
12
13
|
exports.formatDomindsNoteTellaskForTeammatesOnly = formatDomindsNoteTellaskForTeammatesOnly;
|
|
@@ -149,6 +150,25 @@ function formatDiligenceAutoContinuePrompt(language, diligenceText) {
|
|
|
149
150
|
trimmed,
|
|
150
151
|
].join('\n');
|
|
151
152
|
}
|
|
153
|
+
function formatReminderContextGuide(language) {
|
|
154
|
+
if (language === 'zh') {
|
|
155
|
+
return [
|
|
156
|
+
formatSystemNoticePrefix(language),
|
|
157
|
+
'以下是当前可见提醒项的运行时上下文投影。它们会按各自语义进入模型上下文(例如 self-reminder 保持 assistant-side 工作集语义),但不是我刚刚生成给用户的聊天正文。',
|
|
158
|
+
'在 WebUI 中,用户通过独立的 Reminder 小组件/面板项看到这些提醒,并能把它们和聊天正文区分开。',
|
|
159
|
+
'提醒项只作为工作集/状态参考;只有实际改变当前判断、计划或风险的信息,才需要提炼进后续有实质内容的对外回复。',
|
|
160
|
+
].join('\n');
|
|
161
|
+
}
|
|
162
|
+
return [
|
|
163
|
+
formatSystemNoticePrefix(language),
|
|
164
|
+
'The following visible reminders are runtime-added context projections. They enter model context according to their own semantics (for example, self-reminders keep assistant-side workset semantics), but they are not chat text I just generated for the user.',
|
|
165
|
+
'In the WebUI, the user sees these reminders through a separate Reminder widget/panel item and can distinguish them from the chat transcript.',
|
|
166
|
+
'Use reminders as workset/state references; only carry information into a later substantive outward reply when it materially changes current judgment, plan, or risk.',
|
|
167
|
+
].join('\n');
|
|
168
|
+
}
|
|
169
|
+
function formatReminderItemProjectionNote(language) {
|
|
170
|
+
return language === 'zh' ? 'Reminder 上下文投影条目:' : 'Reminder context projection item:';
|
|
171
|
+
}
|
|
152
172
|
function formatReminderItemGuide(language, reminderId, content, options) {
|
|
153
173
|
function isRecord(value) {
|
|
154
174
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
@@ -190,13 +210,15 @@ function formatReminderItemGuide(language, reminderId, content, options) {
|
|
|
190
210
|
: isPendingTellaskReminder && pendingTellaskCount === 0
|
|
191
211
|
? `If I have confirmed this is only noise cleanup and not an action step, I may run: delete_reminder({ "reminder_id": "${reminderId}" })`
|
|
192
212
|
: `If I need to delete this reminder, run: delete_reminder({ "reminder_id": "${reminderId}" })`;
|
|
213
|
+
const projectionNote = formatReminderItemProjectionNote(language);
|
|
214
|
+
const enProjectionPrefix = `${projectionNote} `;
|
|
193
215
|
if (language === 'zh') {
|
|
194
216
|
if (managementTool) {
|
|
195
217
|
const updateInstructionSafe = updateInstruction ?? `${managementTool}({ ... })`;
|
|
196
218
|
return [
|
|
197
219
|
`提醒项 [${reminderId}](工具状态)`,
|
|
198
220
|
'',
|
|
199
|
-
|
|
221
|
+
`${projectionNote}我把这条当作工具维护的状态参考。默认不在对外回复里专门确认、复述或总结它;只有它实际改变当前判断、计划或风险时,我才提炼真正相关的部分。`,
|
|
200
222
|
'',
|
|
201
223
|
`这条提醒项由工具 ${managementTool} 管理;如果我要调整它,就用 ${managementTool}(不要用 update_reminder)。`,
|
|
202
224
|
'',
|
|
@@ -211,7 +233,7 @@ function formatReminderItemGuide(language, reminderId, content, options) {
|
|
|
211
233
|
return [
|
|
212
234
|
`提醒项 [${reminderId}]`,
|
|
213
235
|
'',
|
|
214
|
-
|
|
236
|
+
`${projectionNote}这是带有 meta 控制更新规则的提醒项。我仍把它当作状态参考,但不要用 update_reminder 直接改写内容。`,
|
|
215
237
|
'',
|
|
216
238
|
`如果我要更新这条提醒项,不能用 update_reminder;请按此处理:${updateInstruction}`,
|
|
217
239
|
deleteInstruction,
|
|
@@ -224,7 +246,7 @@ function formatReminderItemGuide(language, reminderId, content, options) {
|
|
|
224
246
|
return [
|
|
225
247
|
`提醒项 [${reminderId}](换程接续信息)`,
|
|
226
248
|
'',
|
|
227
|
-
|
|
249
|
+
`${projectionNote}我把这条当作换程后快速恢复工作的接续包,不把它自动当成当前必须立刻执行的指令。`,
|
|
228
250
|
'',
|
|
229
251
|
'我应优先保留下一步行动、关键定位、运行/验证信息、容易丢的临时细节;不要重复差遣牒已覆盖的内容。进入新一程后,我的第一步就是以清醒头脑重新审视并整理更新:删除冗余、纠正偏激/失真思路、压缩成高质量提醒项。若目前只是粗略过桥笔记,进入新一程后我必须尽快收敛。',
|
|
230
252
|
'',
|
|
@@ -239,8 +261,8 @@ function formatReminderItemGuide(language, reminderId, content, options) {
|
|
|
239
261
|
`提醒项 [${reminderId}]${scope === 'personal' ? '(个人范围)' : ''}`,
|
|
240
262
|
'',
|
|
241
263
|
scope === 'personal'
|
|
242
|
-
?
|
|
243
|
-
:
|
|
264
|
+
? `${projectionNote}这是我给自己的个人范围显眼提示;在所有由我主理的后续对话里都会看到它。我不把它自动当成系统下发的下一步动作。`
|
|
265
|
+
: `${projectionNote}这是我给自己的显眼提示,用于保留当前对话里容易丢的工作信息;我不把它自动当成系统下发的下一步动作。`,
|
|
244
266
|
'',
|
|
245
267
|
scope === 'personal'
|
|
246
268
|
? '我应保持简洁、及时更新;不再需要时就删除。若它只对当前对话有效,应改写成 dialog 范围提醒而不是长期堆在个人范围里。'
|
|
@@ -257,7 +279,7 @@ function formatReminderItemGuide(language, reminderId, content, options) {
|
|
|
257
279
|
const updateInstructionSafe = updateInstruction ?? `${managementTool}({ ... })`;
|
|
258
280
|
return `REMINDER [${reminderId}] (TOOL STATE)
|
|
259
281
|
|
|
260
|
-
I treat this as a tool-maintained state reference. By default I should not explicitly acknowledge, restate, or summarize it in my outward reply; I should only extract the parts that materially change my current judgment, plan, or risk.
|
|
282
|
+
${enProjectionPrefix}I treat this as a tool-maintained state reference. By default I should not explicitly acknowledge, restate, or summarize it in my outward reply; I should only extract the parts that materially change my current judgment, plan, or risk.
|
|
261
283
|
|
|
262
284
|
This reminder is managed by tool ${managementTool}; if I need to change it, I should use ${managementTool} instead of update_reminder.
|
|
263
285
|
|
|
@@ -269,7 +291,7 @@ ${content}`;
|
|
|
269
291
|
if (updateInstruction) {
|
|
270
292
|
return `REMINDER [${reminderId}]
|
|
271
293
|
|
|
272
|
-
This reminder has a meta-controlled update path. I should still treat it as state/reference, and I must not rewrite it directly with update_reminder.
|
|
294
|
+
${enProjectionPrefix}This reminder has a meta-controlled update path. I should still treat it as state/reference, and I must not rewrite it directly with update_reminder.
|
|
273
295
|
|
|
274
296
|
If I need to update this reminder, I must not use update_reminder; follow instead: ${updateInstruction}
|
|
275
297
|
${deleteInstruction}
|
|
@@ -279,7 +301,7 @@ ${content}`;
|
|
|
279
301
|
if (isContinuationPackageReminder) {
|
|
280
302
|
return `REMINDER [${reminderId}] (CONTINUATION PACKAGE)
|
|
281
303
|
|
|
282
|
-
I treat this as resume information for the next course, not as an automatic must-do command.
|
|
304
|
+
${enProjectionPrefix}I treat this as resume information for the next course, not as an automatic must-do command.
|
|
283
305
|
|
|
284
306
|
I should keep the next step, key pointers, run/verify info, and easy-to-lose volatile details here. I should not duplicate Taskdoc content. In the new course, my first step is to review and rewrite this with a clear head: remove redundancy, correct biased or distorted bridge notes, and compress it into a high-quality reminder. If this is only a rough bridge note, I should reconcile it early in the new course.
|
|
285
307
|
|
|
@@ -291,8 +313,8 @@ ${content}`;
|
|
|
291
313
|
return `REMINDER [${reminderId}]${scope === 'personal' ? ' (PERSONAL SCOPE)' : ''}
|
|
292
314
|
|
|
293
315
|
${scope === 'personal'
|
|
294
|
-
?
|
|
295
|
-
:
|
|
316
|
+
? `${enProjectionPrefix}This is my conspicuous personal-scope reminder. I will keep seeing it in all later dialogs I lead, and I do not treat it as an automatically assigned next action.`
|
|
317
|
+
: `${enProjectionPrefix}This is my conspicuous self-reminder for easy-to-lose work details in the current dialog. I do not treat it as an automatically assigned next action.`}
|
|
296
318
|
|
|
297
319
|
${scope === 'personal'
|
|
298
320
|
? 'I should keep it concise, refresh it when needed, and delete it when obsolete. If it is only useful for the current dialog, I should rewrite it into dialog scope instead of letting personal scope accumulate noise.'
|
|
@@ -68,8 +68,8 @@ function buildSubdialogRoleHeaderCopy(args) {
|
|
|
68
68
|
const requester = `@${args.requesterId}`;
|
|
69
69
|
if (args.expectedReplyTool === undefined) {
|
|
70
70
|
return args.language === 'zh'
|
|
71
|
-
? `${requester}
|
|
72
|
-
: `${requester} has assigned you to handle the request content below. Call \`tellaskBack\` only when you truly need to ask back.`;
|
|
71
|
+
? `${requester} 已通过诉请安排你处理下述诉请内容。只有确实需要向上游回问、且现有规程无法直接判责时,才调用 \`tellaskBack\`。`
|
|
72
|
+
: `${requester} has assigned you to handle the request content below. Call \`tellaskBack\` only when you truly need to ask upstream back and existing SOP cannot directly identify another owner.`;
|
|
73
73
|
}
|
|
74
74
|
const kindLabel = (0, tellask_labels_1.getTellaskKindLabel)({
|
|
75
75
|
language: args.language,
|
|
@@ -77,8 +77,8 @@ function buildSubdialogRoleHeaderCopy(args) {
|
|
|
77
77
|
bracketed: true,
|
|
78
78
|
});
|
|
79
79
|
return args.language === 'zh'
|
|
80
|
-
? `${requester} 已通过${kindLabel}安排你处理下述诉请内容。等你准备好回复内容后,调用 \`${args.expectedReplyTool}\`
|
|
81
|
-
: `${requester} has assigned you, via this ${kindLabel}, to handle the request content below. Once your reply content is ready, call \`${args.expectedReplyTool}\` to deliver it. Call \`tellaskBack\` only when you truly need to ask back.`;
|
|
80
|
+
? `${requester} 已通过${kindLabel}安排你处理下述诉请内容。等你准备好回复内容后,调用 \`${args.expectedReplyTool}\` 完成回复。只有确实需要向上游回问、且现有规程无法直接判责时,才调用 \`tellaskBack\`。`
|
|
81
|
+
: `${requester} has assigned you, via this ${kindLabel}, to handle the request content below. Once your reply content is ready, call \`${args.expectedReplyTool}\` to deliver it. Call \`tellaskBack\` only when you truly need to ask upstream back and existing SOP cannot directly identify another owner.`;
|
|
82
82
|
}
|
|
83
83
|
function buildReplyObligationSuppressionGuideText(language) {
|
|
84
84
|
if (language === 'zh') {
|
|
@@ -2109,6 +2109,13 @@ async function handleGetTeamConfig(res) {
|
|
|
2109
2109
|
async function handleGetDialogs(res, status) {
|
|
2110
2110
|
try {
|
|
2111
2111
|
const rootDialogs = [];
|
|
2112
|
+
const allDialogIds = await persistence_1.DialogPersistence.listAllDialogIds(status);
|
|
2113
|
+
const subdialogCountByRootId = new Map();
|
|
2114
|
+
for (const dialogId of allDialogIds) {
|
|
2115
|
+
if (dialogId.selfId === dialogId.rootId)
|
|
2116
|
+
continue;
|
|
2117
|
+
subdialogCountByRootId.set(dialogId.rootId, (subdialogCountByRootId.get(dialogId.rootId) ?? 0) + 1);
|
|
2118
|
+
}
|
|
2112
2119
|
const ids = await persistence_1.DialogPersistence.listDialogs(status);
|
|
2113
2120
|
for (const id of ids) {
|
|
2114
2121
|
const dialogId = new dialog_1.DialogID(id);
|
|
@@ -2124,9 +2131,7 @@ async function handleGetDialogs(res, status) {
|
|
|
2124
2131
|
continue;
|
|
2125
2132
|
}
|
|
2126
2133
|
const waitingForFreshBootsReasoning = await detectWaitingForFreshBootsReasoning(dialogId, status);
|
|
2127
|
-
|
|
2128
|
-
const subPath = path.join(rootPath, 'subdialogs');
|
|
2129
|
-
const subdialogCount = await countSubdialogs(subPath);
|
|
2134
|
+
const subdialogCount = subdialogCountByRootId.get(meta.id) ?? 0;
|
|
2130
2135
|
if (!(await pathStillExistsForLookup(rootPath))) {
|
|
2131
2136
|
continue;
|
|
2132
2137
|
}
|
|
@@ -2170,45 +2175,6 @@ async function handleGetRunControlCounts(res) {
|
|
|
2170
2175
|
return true;
|
|
2171
2176
|
}
|
|
2172
2177
|
}
|
|
2173
|
-
/**
|
|
2174
|
-
* Count subdialog directories recursively
|
|
2175
|
-
*/
|
|
2176
|
-
async function countSubdialogs(dirPath) {
|
|
2177
|
-
try {
|
|
2178
|
-
const entries = await promises_1.default.readdir(dirPath, { withFileTypes: true });
|
|
2179
|
-
let count = 0;
|
|
2180
|
-
for (const entry of entries) {
|
|
2181
|
-
if (entry.isDirectory()) {
|
|
2182
|
-
const fullPath = path.join(dirPath, entry.name);
|
|
2183
|
-
const dialogYamlPath = path.join(fullPath, 'dialog.yaml');
|
|
2184
|
-
try {
|
|
2185
|
-
await promises_1.default.access(dialogYamlPath);
|
|
2186
|
-
// This directory contains dialog.yaml - it's a subdialog.
|
|
2187
|
-
count++;
|
|
2188
|
-
}
|
|
2189
|
-
catch (error) {
|
|
2190
|
-
if (getErrorCode(error) === 'ENOENT') {
|
|
2191
|
-
// Only a missing dialog.yaml means "keep recursing". Permission/I/O failures must stay
|
|
2192
|
-
// loud so operators can distinguish inaccessible paths from ordinary non-dialog dirs.
|
|
2193
|
-
count += await countSubdialogs(fullPath);
|
|
2194
|
-
continue;
|
|
2195
|
-
}
|
|
2196
|
-
throw error;
|
|
2197
|
-
}
|
|
2198
|
-
}
|
|
2199
|
-
}
|
|
2200
|
-
return count;
|
|
2201
|
-
}
|
|
2202
|
-
catch (error) {
|
|
2203
|
-
if (typeof error === 'object' &&
|
|
2204
|
-
error !== null &&
|
|
2205
|
-
'code' in error &&
|
|
2206
|
-
error.code === 'ENOENT') {
|
|
2207
|
-
return 0;
|
|
2208
|
-
}
|
|
2209
|
-
throw error;
|
|
2210
|
-
}
|
|
2211
|
-
}
|
|
2212
2178
|
/**
|
|
2213
2179
|
* Get full hierarchy (root + subdialogs) for a single root dialog
|
|
2214
2180
|
*/
|
|
@@ -2292,7 +2258,7 @@ async function handleGetDialogHierarchy(res, rootId, status) {
|
|
|
2292
2258
|
respondJson(res, 200, {
|
|
2293
2259
|
success: true,
|
|
2294
2260
|
hierarchy: {
|
|
2295
|
-
root: rootInfo,
|
|
2261
|
+
root: { ...rootInfo, subdialogCount: subdialogs.length },
|
|
2296
2262
|
subdialogs,
|
|
2297
2263
|
},
|
|
2298
2264
|
});
|
|
@@ -2331,6 +2297,7 @@ async function handleGetDialogListSubdialogNode(res, dialog) {
|
|
|
2331
2297
|
}
|
|
2332
2298
|
const latest = await loadDialogLatestForLookup(dialogId, status, 'handleGetDialogListSubdialogNode');
|
|
2333
2299
|
const waitingForFreshBootsReasoning = await detectWaitingForFreshBootsReasoning(dialogId, status);
|
|
2300
|
+
const rootSubdialogCount = await persistence_1.DialogPersistence.countAllSubdialogsUnderRoot(new dialog_1.DialogID(dialog.rootId), status);
|
|
2334
2301
|
const subdialogPath = persistence_1.DialogPersistence.getSubdialogPath(dialogId, status);
|
|
2335
2302
|
if (!(await pathStillExistsForLookup(subdialogPath))) {
|
|
2336
2303
|
respondJson(res, 404, { success: false, error: `Dialog not found in ${status}` });
|
|
@@ -2347,6 +2314,7 @@ async function handleGetDialogListSubdialogNode(res, dialog) {
|
|
|
2347
2314
|
subdialogNode: {
|
|
2348
2315
|
selfId: metadata.id,
|
|
2349
2316
|
rootId: dialog.rootId,
|
|
2317
|
+
rootSubdialogCount,
|
|
2350
2318
|
supdialogId: derivedSupdialogId,
|
|
2351
2319
|
agentId: metadata.agentId,
|
|
2352
2320
|
taskDocPath: metadata.taskDocPath,
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.shouldQueueUserSupplementAtGenerationBoundary = shouldQueueUserSupplementAtGenerationBoundary;
|
|
4
7
|
exports.handleWebSocketMessage = handleWebSocketMessage;
|
|
@@ -14,6 +17,9 @@ const evt_1 = require("@longrun-ai/kernel/evt");
|
|
|
14
17
|
const language_1 = require("@longrun-ai/kernel/types/language");
|
|
15
18
|
const storage_1 = require("@longrun-ai/kernel/types/storage");
|
|
16
19
|
const time_1 = require("@longrun-ai/kernel/utils/time");
|
|
20
|
+
const crypto_1 = require("crypto");
|
|
21
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
22
|
+
const path_1 = __importDefault(require("path"));
|
|
17
23
|
const ws_1 = require("ws");
|
|
18
24
|
const runtime_1 = require("../apps/runtime");
|
|
19
25
|
const global_dialog_event_broadcaster_1 = require("../bootstrap/global-dialog-event-broadcaster");
|
|
@@ -54,6 +60,113 @@ function normalizeDiligencePushMax(value) {
|
|
|
54
60
|
return 0;
|
|
55
61
|
return Math.floor(value);
|
|
56
62
|
}
|
|
63
|
+
const USER_IMAGE_ATTACHMENT_MAX_COUNT = 10;
|
|
64
|
+
const USER_IMAGE_ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024;
|
|
65
|
+
function userImageMimeTypeToExt(mimeType) {
|
|
66
|
+
switch (mimeType) {
|
|
67
|
+
case 'image/png':
|
|
68
|
+
return 'png';
|
|
69
|
+
case 'image/jpeg':
|
|
70
|
+
return 'jpg';
|
|
71
|
+
case 'image/webp':
|
|
72
|
+
return 'webp';
|
|
73
|
+
case 'image/gif':
|
|
74
|
+
return 'gif';
|
|
75
|
+
default:
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function sanitizeArtifactPathSegment(value) {
|
|
80
|
+
const cleaned = value.replace(/[^a-zA-Z0-9._-]/g, '_').replace(/_+/g, '_');
|
|
81
|
+
const trimmed = cleaned.replace(/^_+|_+$/g, '');
|
|
82
|
+
return trimmed.length > 0 ? trimmed.slice(0, 96) : 'item';
|
|
83
|
+
}
|
|
84
|
+
function parseUserImageAttachments(raw) {
|
|
85
|
+
if (raw === undefined)
|
|
86
|
+
return [];
|
|
87
|
+
if (!Array.isArray(raw)) {
|
|
88
|
+
throw new Error('attachments must be an array when provided');
|
|
89
|
+
}
|
|
90
|
+
if (raw.length > USER_IMAGE_ATTACHMENT_MAX_COUNT) {
|
|
91
|
+
throw new Error(`at most ${String(USER_IMAGE_ATTACHMENT_MAX_COUNT)} image attachments are allowed`);
|
|
92
|
+
}
|
|
93
|
+
return raw.map((item, index) => {
|
|
94
|
+
if (typeof item !== 'object' || item === null || Array.isArray(item)) {
|
|
95
|
+
throw new Error(`attachments[${String(index)}] must be an object`);
|
|
96
|
+
}
|
|
97
|
+
const record = item;
|
|
98
|
+
const kind = record['kind'];
|
|
99
|
+
const mimeType = record['mimeType'];
|
|
100
|
+
const byteLength = record['byteLength'];
|
|
101
|
+
const dataBase64 = record['dataBase64'];
|
|
102
|
+
if (kind !== 'image') {
|
|
103
|
+
throw new Error(`attachments[${String(index)}].kind must be image`);
|
|
104
|
+
}
|
|
105
|
+
if (typeof mimeType !== 'string' || userImageMimeTypeToExt(mimeType) === null) {
|
|
106
|
+
throw new Error(`attachments[${String(index)}].mimeType is unsupported`);
|
|
107
|
+
}
|
|
108
|
+
if (typeof byteLength !== 'number' ||
|
|
109
|
+
!Number.isFinite(byteLength) ||
|
|
110
|
+
byteLength <= 0 ||
|
|
111
|
+
byteLength > USER_IMAGE_ATTACHMENT_MAX_BYTES) {
|
|
112
|
+
throw new Error(`attachments[${String(index)}].byteLength must be between 1 and ${String(USER_IMAGE_ATTACHMENT_MAX_BYTES)}`);
|
|
113
|
+
}
|
|
114
|
+
if (typeof dataBase64 !== 'string' || dataBase64.trim() === '') {
|
|
115
|
+
throw new Error(`attachments[${String(index)}].dataBase64 is required`);
|
|
116
|
+
}
|
|
117
|
+
return { kind, mimeType, byteLength, dataBase64 };
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function isStrictBase64Payload(value) {
|
|
121
|
+
if (value.length === 0 || value.length % 4 !== 0)
|
|
122
|
+
return false;
|
|
123
|
+
return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value);
|
|
124
|
+
}
|
|
125
|
+
function prepareUserImageAttachments(attachments) {
|
|
126
|
+
return attachments.map((attachment, index) => {
|
|
127
|
+
if (!isStrictBase64Payload(attachment.dataBase64)) {
|
|
128
|
+
throw new Error(`attachments[${String(index)}].dataBase64 must be strict base64`);
|
|
129
|
+
}
|
|
130
|
+
const bytes = Buffer.from(attachment.dataBase64, 'base64');
|
|
131
|
+
if (bytes.length !== attachment.byteLength) {
|
|
132
|
+
throw new Error(`attachments[${String(index)}].byteLength mismatch: declared=${String(attachment.byteLength)} decoded=${String(bytes.length)}`);
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
mimeType: attachment.mimeType,
|
|
136
|
+
bytes,
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
async function persistPreparedUserImageAttachments(args) {
|
|
141
|
+
if (args.attachments.length === 0)
|
|
142
|
+
return undefined;
|
|
143
|
+
const eventsBase = persistence_1.DialogPersistence.getDialogEventsPath(args.dialog.id, args.dialog.status);
|
|
144
|
+
const safeMsgId = sanitizeArtifactPathSegment(args.msgId);
|
|
145
|
+
const contentItems = [];
|
|
146
|
+
for (let index = 0; index < args.attachments.length; index += 1) {
|
|
147
|
+
const attachment = args.attachments[index];
|
|
148
|
+
const ext = userImageMimeTypeToExt(attachment.mimeType);
|
|
149
|
+
if (ext === null) {
|
|
150
|
+
throw new Error(`attachments[${String(index)}].mimeType is unsupported`);
|
|
151
|
+
}
|
|
152
|
+
const relPath = path_1.default.posix.join('artifacts', 'user-input', safeMsgId, `${String(index + 1).padStart(2, '0')}-${(0, crypto_1.randomUUID)()}.${ext}`);
|
|
153
|
+
const absPath = path_1.default.join(eventsBase, ...relPath.split('/'));
|
|
154
|
+
await promises_1.default.mkdir(path_1.default.dirname(absPath), { recursive: true });
|
|
155
|
+
await promises_1.default.writeFile(absPath, attachment.bytes);
|
|
156
|
+
contentItems.push({
|
|
157
|
+
type: 'input_image',
|
|
158
|
+
mimeType: attachment.mimeType,
|
|
159
|
+
byteLength: attachment.bytes.length,
|
|
160
|
+
artifact: {
|
|
161
|
+
rootId: args.dialog.id.rootId,
|
|
162
|
+
selfId: args.dialog.id.selfId,
|
|
163
|
+
status: args.dialog.status,
|
|
164
|
+
relPath,
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return contentItems;
|
|
169
|
+
}
|
|
57
170
|
function parsePersistableDialogStatus(raw) {
|
|
58
171
|
if (raw !== 'running' && raw !== 'completed' && raw !== 'archived') {
|
|
59
172
|
return null;
|
|
@@ -230,6 +343,7 @@ async function queueUserSupplementAtGenerationBoundary(dialog, prompt) {
|
|
|
230
343
|
}
|
|
231
344
|
const queued = dialog.queueUserPromptAtGenerationBoundary({
|
|
232
345
|
prompt: prompt.content,
|
|
346
|
+
contentItems: prompt.contentItems,
|
|
233
347
|
msgId: prompt.msgId,
|
|
234
348
|
grammar: prompt.grammar,
|
|
235
349
|
userLanguageCode: prompt.userLanguageCode,
|
|
@@ -239,6 +353,7 @@ async function queueUserSupplementAtGenerationBoundary(dialog, prompt) {
|
|
|
239
353
|
course: dialog.currentCourse,
|
|
240
354
|
msgId: queued.msgId,
|
|
241
355
|
content: queued.prompt,
|
|
356
|
+
contentItems: queued.contentItems,
|
|
242
357
|
grammar: queued.grammar ?? 'markdown',
|
|
243
358
|
origin: 'user',
|
|
244
359
|
userLanguageCode: queued.userLanguageCode,
|
|
@@ -1135,6 +1250,7 @@ async function handleDisplayCourse(ws, packet) {
|
|
|
1135
1250
|
async function handleUserMsg2Dlg(ws, packet) {
|
|
1136
1251
|
try {
|
|
1137
1252
|
const { dialog: dialogIdent, content, msgId } = packet;
|
|
1253
|
+
const attachments = parseUserImageAttachments(packet.attachments);
|
|
1138
1254
|
const userLanguageCode = resolveUserLanguageCode(ws, packet.userLanguageCode);
|
|
1139
1255
|
// Basic validation
|
|
1140
1256
|
if (!dialogIdent || !content || !msgId) {
|
|
@@ -1170,6 +1286,7 @@ async function handleUserMsg2Dlg(ws, packet) {
|
|
|
1170
1286
|
grammar: 'markdown',
|
|
1171
1287
|
userLanguageCode,
|
|
1172
1288
|
};
|
|
1289
|
+
const preparedAttachments = prepareUserImageAttachments(attachments);
|
|
1173
1290
|
// If the dialog is already active for this WebSocket, runnable (status === 'running'),
|
|
1174
1291
|
// and has an event forwarder (subChan),
|
|
1175
1292
|
// drive it directly to preserve in-memory state (pending subdialogs, teammate tellask tracking, etc).
|
|
@@ -1187,12 +1304,21 @@ async function handleUserMsg2Dlg(ws, packet) {
|
|
|
1187
1304
|
existingDialog.status === 'running' &&
|
|
1188
1305
|
existingSub &&
|
|
1189
1306
|
existingSub.dialogKey === existingDialog.id.valueOf()) {
|
|
1190
|
-
const
|
|
1307
|
+
const contentItems = await persistPreparedUserImageAttachments({
|
|
1308
|
+
dialog: existingDialog,
|
|
1309
|
+
msgId: effectivePrompt.msgId,
|
|
1310
|
+
attachments: preparedAttachments,
|
|
1311
|
+
});
|
|
1312
|
+
const queuedAtBoundary = await queueUserSupplementAtGenerationBoundary(existingDialog, {
|
|
1313
|
+
...effectivePrompt,
|
|
1314
|
+
contentItems,
|
|
1315
|
+
});
|
|
1191
1316
|
if (queuedAtBoundary) {
|
|
1192
1317
|
return;
|
|
1193
1318
|
}
|
|
1194
1319
|
await (0, kernel_driver_1.driveDialogStream)(existingDialog, {
|
|
1195
1320
|
content: effectivePrompt.content,
|
|
1321
|
+
...(contentItems === undefined ? {} : { contentItems }),
|
|
1196
1322
|
msgId: effectivePrompt.msgId,
|
|
1197
1323
|
grammar: effectivePrompt.grammar,
|
|
1198
1324
|
userLanguageCode: effectivePrompt.userLanguageCode,
|
|
@@ -1220,12 +1346,21 @@ async function handleUserMsg2Dlg(ws, packet) {
|
|
|
1220
1346
|
return;
|
|
1221
1347
|
}
|
|
1222
1348
|
await setupWebSocketSubscription(ws, dialog);
|
|
1223
|
-
const
|
|
1349
|
+
const contentItems = await persistPreparedUserImageAttachments({
|
|
1350
|
+
dialog,
|
|
1351
|
+
msgId: effectivePrompt.msgId,
|
|
1352
|
+
attachments: preparedAttachments,
|
|
1353
|
+
});
|
|
1354
|
+
const queuedAtBoundary = await queueUserSupplementAtGenerationBoundary(dialog, {
|
|
1355
|
+
...effectivePrompt,
|
|
1356
|
+
contentItems,
|
|
1357
|
+
});
|
|
1224
1358
|
if (queuedAtBoundary) {
|
|
1225
1359
|
return;
|
|
1226
1360
|
}
|
|
1227
1361
|
await (0, kernel_driver_1.driveDialogStream)(dialog, {
|
|
1228
1362
|
content: effectivePrompt.content,
|
|
1363
|
+
...(contentItems === undefined ? {} : { contentItems }),
|
|
1229
1364
|
msgId: effectivePrompt.msgId,
|
|
1230
1365
|
grammar: effectivePrompt.grammar,
|
|
1231
1366
|
userLanguageCode: effectivePrompt.userLanguageCode,
|
|
@@ -1401,6 +1536,7 @@ async function handleResumeAll(ws, packet) {
|
|
|
1401
1536
|
async function handleReceiveHumanReply(ws, packet) {
|
|
1402
1537
|
try {
|
|
1403
1538
|
const { dialog: dialogIdent, content, msgId, questionId, continuationType } = packet;
|
|
1539
|
+
const attachments = parseUserImageAttachments(packet.attachments);
|
|
1404
1540
|
const userLanguageCode = resolveUserLanguageCode(ws, packet.userLanguageCode);
|
|
1405
1541
|
// Basic validation
|
|
1406
1542
|
if (!dialogIdent || !content || !msgId || !questionId) {
|
|
@@ -1436,14 +1572,7 @@ async function handleReceiveHumanReply(ws, packet) {
|
|
|
1436
1572
|
grammar: 'markdown',
|
|
1437
1573
|
userLanguageCode,
|
|
1438
1574
|
};
|
|
1439
|
-
const
|
|
1440
|
-
if (!removed.found) {
|
|
1441
|
-
ws.send(JSON.stringify({
|
|
1442
|
-
type: 'error',
|
|
1443
|
-
message: `Question ${questionId} not found in dialog ${dialogId}`,
|
|
1444
|
-
}));
|
|
1445
|
-
return;
|
|
1446
|
-
}
|
|
1575
|
+
const preparedAttachments = prepareUserImageAttachments(attachments);
|
|
1447
1576
|
// Restore the canonical dialog instances (root + subdialogs) to avoid duplicates.
|
|
1448
1577
|
const rootDialog = await (0, dialog_instance_registry_1.getOrRestoreRootDialog)(dialogIdObj.rootId, 'running');
|
|
1449
1578
|
if (!rootDialog) {
|
|
@@ -1460,6 +1589,14 @@ async function handleReceiveHumanReply(ws, packet) {
|
|
|
1460
1589
|
}
|
|
1461
1590
|
// Ensure the requesting WebSocket receives q4h_answered and subsequent resume stream events.
|
|
1462
1591
|
await setupWebSocketSubscription(ws, dialog);
|
|
1592
|
+
const removed = await persistence_1.DialogPersistence.removeQuestion4HumanState(dialogIdObj, questionId);
|
|
1593
|
+
if (!removed.found) {
|
|
1594
|
+
ws.send(JSON.stringify({
|
|
1595
|
+
type: 'error',
|
|
1596
|
+
message: `Question ${questionId} not found in dialog ${dialogId}`,
|
|
1597
|
+
}));
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1463
1600
|
const removedQuestion = removed.removedQuestion;
|
|
1464
1601
|
if (!removedQuestion) {
|
|
1465
1602
|
throw new Error(`Q4H remove invariant violation: found=true but removedQuestion missing (rootId=${dialog.id.rootId} selfId=${dialog.id.selfId} questionId=${questionId})`);
|
|
@@ -1469,6 +1606,11 @@ async function handleReceiveHumanReply(ws, packet) {
|
|
|
1469
1606
|
throw new Error(`Q4H remove invariant violation: missing callId on answered question ` +
|
|
1470
1607
|
`(rootId=${dialog.id.rootId} selfId=${dialog.id.selfId} questionId=${questionId})`);
|
|
1471
1608
|
}
|
|
1609
|
+
const contentItems = await persistPreparedUserImageAttachments({
|
|
1610
|
+
dialog,
|
|
1611
|
+
msgId: effectivePrompt.msgId,
|
|
1612
|
+
attachments: preparedAttachments,
|
|
1613
|
+
});
|
|
1472
1614
|
const askHumanOriginCourse = removedQuestion.callSiteRef.course;
|
|
1473
1615
|
const askHumanCarryoverContent = (0, inter_dialog_format_1.formatTellaskCarryoverResultContent)({
|
|
1474
1616
|
originCourse: askHumanOriginCourse,
|
|
@@ -1487,6 +1629,7 @@ async function handleReceiveHumanReply(ws, packet) {
|
|
|
1487
1629
|
originCourse: (0, storage_1.toCallingCourseNumber)(askHumanOriginCourse),
|
|
1488
1630
|
calling_genseq: removedQuestion.callSiteRef.callingGenseq,
|
|
1489
1631
|
carryoverContent: askHumanCarryoverContent,
|
|
1632
|
+
contentItems,
|
|
1490
1633
|
});
|
|
1491
1634
|
await dialog.addChatMessages(askHumanResultMirror);
|
|
1492
1635
|
// Emit q4h_answered event for answered question
|
|
@@ -1505,6 +1648,7 @@ async function handleReceiveHumanReply(ws, packet) {
|
|
|
1505
1648
|
prompt: effectivePrompt.content,
|
|
1506
1649
|
msgId: effectivePrompt.msgId,
|
|
1507
1650
|
grammar: effectivePrompt.grammar,
|
|
1651
|
+
contentItems,
|
|
1508
1652
|
userLanguageCode: effectivePrompt.userLanguageCode,
|
|
1509
1653
|
q4hAnswerCallId: askHumanCallId,
|
|
1510
1654
|
});
|
|
@@ -1520,6 +1664,7 @@ async function handleReceiveHumanReply(ws, packet) {
|
|
|
1520
1664
|
// The continuation input carries correlation only; it does not persist another user prompt fact.
|
|
1521
1665
|
await (0, kernel_driver_1.driveDialogStream)(dialog, {
|
|
1522
1666
|
content: effectivePrompt.content,
|
|
1667
|
+
...(contentItems === undefined ? {} : { contentItems }),
|
|
1523
1668
|
msgId: effectivePrompt.msgId,
|
|
1524
1669
|
grammar: effectivePrompt.grammar,
|
|
1525
1670
|
userLanguageCode: effectivePrompt.userLanguageCode,
|
package/dist/tools/builtins.js
CHANGED
|
@@ -16,6 +16,7 @@ const mcp_1 = require("./mcp");
|
|
|
16
16
|
const mem_1 = require("./mem");
|
|
17
17
|
const os_1 = require("./os");
|
|
18
18
|
const pending_tellask_reminder_1 = require("./pending-tellask-reminder");
|
|
19
|
+
const picture_1 = require("./picture");
|
|
19
20
|
const registry_1 = require("./registry");
|
|
20
21
|
const ripgrep_1 = require("./ripgrep");
|
|
21
22
|
const team_mgmt_1 = require("./team_mgmt");
|
|
@@ -50,6 +51,8 @@ function manualSpecFor(toolsetId) {
|
|
|
50
51
|
(0, registry_1.registerTool)(fs_1.moveFileTool);
|
|
51
52
|
(0, registry_1.registerTool)(fs_1.moveDirTool);
|
|
52
53
|
(0, registry_1.registerTool)(txt_1.readFileTool);
|
|
54
|
+
(0, registry_1.registerTool)(picture_1.readPictureTool);
|
|
55
|
+
(0, registry_1.registerTool)(picture_1.writePictureTool);
|
|
53
56
|
(0, registry_1.registerTool)(txt_1.createNewFileTool);
|
|
54
57
|
(0, registry_1.registerTool)(txt_1.overwriteEntireFileTool);
|
|
55
58
|
(0, registry_1.registerTool)(txt_1.prepareFileRangeEditTool);
|
|
@@ -182,6 +185,7 @@ for (const tool of team_mgmt_1.teamMgmtTools) {
|
|
|
182
185
|
(0, registry_1.registerToolset)('ws_read', [
|
|
183
186
|
fs_1.listDirTool,
|
|
184
187
|
txt_1.readFileTool,
|
|
188
|
+
picture_1.readPictureTool,
|
|
185
189
|
ripgrep_1.ripgrepFilesTool,
|
|
186
190
|
ripgrep_1.ripgrepSnippetsTool,
|
|
187
191
|
ripgrep_1.ripgrepCountTool,
|
|
@@ -191,8 +195,8 @@ for (const tool of team_mgmt_1.teamMgmtTools) {
|
|
|
191
195
|
(0, registry_1.setToolsetMeta)('ws_read', {
|
|
192
196
|
source: 'dominds',
|
|
193
197
|
descriptionI18n: {
|
|
194
|
-
en: 'rtws read-only access: list directories, read
|
|
195
|
-
zh: '
|
|
198
|
+
en: 'rtws read-only access: list directories, read text/images, and search code/content to gather facts safely.',
|
|
199
|
+
zh: '运行时工作区只读访问:列目录、读文本/图片、检索代码与文本,用于安全获取事实。',
|
|
196
200
|
},
|
|
197
201
|
promptFilesI18n: promptFilesFor('ws_read'),
|
|
198
202
|
manualSpec: manualSpecFor('ws_read'),
|
|
@@ -205,6 +209,8 @@ for (const tool of team_mgmt_1.teamMgmtTools) {
|
|
|
205
209
|
fs_1.moveFileTool,
|
|
206
210
|
fs_1.moveDirTool,
|
|
207
211
|
txt_1.readFileTool,
|
|
212
|
+
picture_1.readPictureTool,
|
|
213
|
+
picture_1.writePictureTool,
|
|
208
214
|
txt_1.createNewFileTool,
|
|
209
215
|
txt_1.overwriteEntireFileTool,
|
|
210
216
|
txt_1.prepareFileAppendTool,
|
|
@@ -222,8 +228,8 @@ for (const tool of team_mgmt_1.teamMgmtTools) {
|
|
|
222
228
|
(0, registry_1.setToolsetMeta)('ws_mod', {
|
|
223
229
|
source: 'dominds',
|
|
224
230
|
descriptionI18n: {
|
|
225
|
-
en: 'rtws read/write access: inspect, create, move, delete,
|
|
226
|
-
zh: '
|
|
231
|
+
en: 'rtws read/write access: inspect, create, move, delete, precisely edit text files, and read/write workspace images.',
|
|
232
|
+
zh: '运行时工作区读写访问:检查、创建、移动、删除、精确编辑文本文件,并读写工作区图片。',
|
|
227
233
|
},
|
|
228
234
|
promptFilesI18n: promptFilesFor('ws_mod'),
|
|
229
235
|
manualSpec: manualSpecFor('ws_mod'),
|