dominds 1.17.7 → 1.18.1

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.
Files changed (138) hide show
  1. package/dist/dialog-fork.js +11 -5
  2. package/dist/dialog-instance-registry.js +1 -18
  3. package/dist/dialog.d.ts +21 -31
  4. package/dist/dialog.js +207 -56
  5. package/dist/docs/dialog-system.md +3 -2
  6. package/dist/docs/dialog-system.zh.md +3 -2
  7. package/dist/docs/tellask-collab.md +2 -1
  8. package/dist/docs/tellask-collab.zh.md +2 -1
  9. package/dist/llm/defaults.yaml +43 -0
  10. package/dist/llm/gen/anthropic.js +153 -12
  11. package/dist/llm/gen/codex.js +160 -10
  12. package/dist/llm/gen/openai-compatible.js +141 -81
  13. package/dist/llm/gen/openai.js +178 -12
  14. package/dist/llm/gen/tool-result-image-ingest.d.ts +17 -8
  15. package/dist/llm/gen/tool-result-image-ingest.js +127 -27
  16. package/dist/llm/gen.d.ts +13 -0
  17. package/dist/llm/kernel-driver/drive.js +66 -11
  18. package/dist/llm/kernel-driver/flow.js +158 -41
  19. package/dist/llm/kernel-driver/reply-guidance.d.ts +6 -6
  20. package/dist/llm/kernel-driver/reply-guidance.js +169 -2
  21. package/dist/llm/kernel-driver/runtime.d.ts +2 -2
  22. package/dist/llm/kernel-driver/subdialog.js +4 -0
  23. package/dist/llm/kernel-driver/tellask-special.d.ts +2 -0
  24. package/dist/llm/kernel-driver/tellask-special.js +11 -6
  25. package/dist/llm/kernel-driver/types.d.ts +14 -24
  26. package/dist/minds/system-prompt.js +8 -8
  27. package/dist/persistence.d.ts +6 -5
  28. package/dist/persistence.js +198 -39
  29. package/dist/priming.js +98 -3
  30. package/dist/runtime/reply-prompt-copy.js +4 -4
  31. package/dist/server/api-routes.js +11 -43
  32. package/dist/server/websocket-handler.js +155 -10
  33. package/dist/tools/builtins.js +10 -4
  34. package/dist/tools/cmd-runner.js +110 -49
  35. package/dist/tools/picture.d.ts +3 -0
  36. package/dist/tools/picture.js +344 -0
  37. package/dist/tools/prompts/control/en/principles.md +4 -2
  38. package/dist/tools/prompts/control/en/scenarios.md +2 -1
  39. package/dist/tools/prompts/control/en/tools.md +6 -6
  40. package/dist/tools/prompts/control/zh/principles.md +4 -2
  41. package/dist/tools/prompts/control/zh/scenarios.md +2 -1
  42. package/dist/tools/prompts/control/zh/tools.md +1 -1
  43. package/dist/tools/prompts/ws_mod.en.md +1 -0
  44. package/dist/tools/prompts/ws_mod.zh.md +1 -0
  45. package/dist/tools/prompts/ws_read/en/tools.md +25 -5
  46. package/dist/tools/prompts/ws_read/zh/tools.md +25 -5
  47. package/package.json +3 -3
  48. package/webapp/dist/assets/{_basePickBy-u7tNFRWr.js → _basePickBy-BVw20Ovi.js} +3 -3
  49. package/webapp/dist/assets/{_basePickBy-u7tNFRWr.js.map → _basePickBy-BVw20Ovi.js.map} +1 -1
  50. package/webapp/dist/assets/{_baseUniq-CH9LRkiH.js → _baseUniq-CC3eeeLB.js} +2 -2
  51. package/webapp/dist/assets/{_baseUniq-CH9LRkiH.js.map → _baseUniq-CC3eeeLB.js.map} +1 -1
  52. package/webapp/dist/assets/{arc-Bo0Lw3ZP.js → arc-BPNg5quK.js} +2 -2
  53. package/webapp/dist/assets/{arc-Bo0Lw3ZP.js.map → arc-BPNg5quK.js.map} +1 -1
  54. package/webapp/dist/assets/{architectureDiagram-VXUJARFQ-Ckyr89Iw.js → architectureDiagram-VXUJARFQ-DEwxvxTH.js} +7 -7
  55. package/webapp/dist/assets/{architectureDiagram-VXUJARFQ-Ckyr89Iw.js.map → architectureDiagram-VXUJARFQ-DEwxvxTH.js.map} +1 -1
  56. package/webapp/dist/assets/{blockDiagram-VD42YOAC-BSXoLLq_.js → blockDiagram-VD42YOAC-CW4e-9Re.js} +7 -7
  57. package/webapp/dist/assets/{blockDiagram-VD42YOAC-BSXoLLq_.js.map → blockDiagram-VD42YOAC-CW4e-9Re.js.map} +1 -1
  58. package/webapp/dist/assets/{c4Diagram-YG6GDRKO-CgCG1cP0.js → c4Diagram-YG6GDRKO-C_Oo6p3W.js} +3 -3
  59. package/webapp/dist/assets/{c4Diagram-YG6GDRKO-CgCG1cP0.js.map → c4Diagram-YG6GDRKO-C_Oo6p3W.js.map} +1 -1
  60. package/webapp/dist/assets/{channel-Crbz0zgt.js → channel-Coenmsri.js} +2 -2
  61. package/webapp/dist/assets/{channel-Crbz0zgt.js.map → channel-Coenmsri.js.map} +1 -1
  62. package/webapp/dist/assets/{chunk-4BX2VUAB-BIIEb_5S.js → chunk-4BX2VUAB-DboKwEgN.js} +2 -2
  63. package/webapp/dist/assets/{chunk-4BX2VUAB-BIIEb_5S.js.map → chunk-4BX2VUAB-DboKwEgN.js.map} +1 -1
  64. package/webapp/dist/assets/{chunk-55IACEB6-CaJzGgc9.js → chunk-55IACEB6-CigdIIKh.js} +2 -2
  65. package/webapp/dist/assets/{chunk-55IACEB6-CaJzGgc9.js.map → chunk-55IACEB6-CigdIIKh.js.map} +1 -1
  66. package/webapp/dist/assets/{chunk-B4BG7PRW-DHQwhO9F.js → chunk-B4BG7PRW-Ddyy9ljI.js} +5 -5
  67. package/webapp/dist/assets/{chunk-B4BG7PRW-DHQwhO9F.js.map → chunk-B4BG7PRW-Ddyy9ljI.js.map} +1 -1
  68. package/webapp/dist/assets/{chunk-DI55MBZ5-CG1lO0R8.js → chunk-DI55MBZ5-DKF482NF.js} +4 -4
  69. package/webapp/dist/assets/{chunk-DI55MBZ5-CG1lO0R8.js.map → chunk-DI55MBZ5-DKF482NF.js.map} +1 -1
  70. package/webapp/dist/assets/{chunk-FMBD7UC4-DAUsTLPS.js → chunk-FMBD7UC4-Cmer1XmU.js} +2 -2
  71. package/webapp/dist/assets/{chunk-FMBD7UC4-DAUsTLPS.js.map → chunk-FMBD7UC4-Cmer1XmU.js.map} +1 -1
  72. package/webapp/dist/assets/{chunk-QN33PNHL-BfQs-QHE.js → chunk-QN33PNHL-BEb0-N6n.js} +2 -2
  73. package/webapp/dist/assets/{chunk-QN33PNHL-BfQs-QHE.js.map → chunk-QN33PNHL-BEb0-N6n.js.map} +1 -1
  74. package/webapp/dist/assets/{chunk-QZHKN3VN-C5iKQ6mQ.js → chunk-QZHKN3VN-Cp8kW-dX.js} +2 -2
  75. package/webapp/dist/assets/{chunk-QZHKN3VN-C5iKQ6mQ.js.map → chunk-QZHKN3VN-Cp8kW-dX.js.map} +1 -1
  76. package/webapp/dist/assets/{chunk-TZMSLE5B-CBShDwy2.js → chunk-TZMSLE5B-wpwmaWSZ.js} +2 -2
  77. package/webapp/dist/assets/{chunk-TZMSLE5B-CBShDwy2.js.map → chunk-TZMSLE5B-wpwmaWSZ.js.map} +1 -1
  78. package/webapp/dist/assets/{classDiagram-2ON5EDUG-DrfJDzYO.js → classDiagram-2ON5EDUG-Br4_7l1n.js} +6 -6
  79. package/webapp/dist/assets/{classDiagram-2ON5EDUG-DrfJDzYO.js.map → classDiagram-2ON5EDUG-Br4_7l1n.js.map} +1 -1
  80. package/webapp/dist/assets/{classDiagram-v2-WZHVMYZB-DrfJDzYO.js → classDiagram-v2-WZHVMYZB-Br4_7l1n.js} +6 -6
  81. package/webapp/dist/assets/{classDiagram-v2-WZHVMYZB-DrfJDzYO.js.map → classDiagram-v2-WZHVMYZB-Br4_7l1n.js.map} +1 -1
  82. package/webapp/dist/assets/{clone-Cd-48URG.js → clone-BZuYd0eH.js} +2 -2
  83. package/webapp/dist/assets/{clone-Cd-48URG.js.map → clone-BZuYd0eH.js.map} +1 -1
  84. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-CCji0YN3.js → cose-bilkent-S5V4N54A-C8uOdBEN.js} +2 -2
  85. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-CCji0YN3.js.map → cose-bilkent-S5V4N54A-C8uOdBEN.js.map} +1 -1
  86. package/webapp/dist/assets/{dagre-6UL2VRFP-B94p-Dpl.js → dagre-6UL2VRFP-CGOxEM4k.js} +7 -7
  87. package/webapp/dist/assets/{dagre-6UL2VRFP-B94p-Dpl.js.map → dagre-6UL2VRFP-CGOxEM4k.js.map} +1 -1
  88. package/webapp/dist/assets/{diagram-PSM6KHXK-DP-zGmAS.js → diagram-PSM6KHXK-C4qykQr2.js} +8 -8
  89. package/webapp/dist/assets/{diagram-PSM6KHXK-DP-zGmAS.js.map → diagram-PSM6KHXK-C4qykQr2.js.map} +1 -1
  90. package/webapp/dist/assets/{diagram-QEK2KX5R-DquJirs4.js → diagram-QEK2KX5R-DcOyu6uO.js} +7 -7
  91. package/webapp/dist/assets/{diagram-QEK2KX5R-DquJirs4.js.map → diagram-QEK2KX5R-DcOyu6uO.js.map} +1 -1
  92. package/webapp/dist/assets/{diagram-S2PKOQOG-Dt5W2t6V.js → diagram-S2PKOQOG-4PZWLejv.js} +7 -7
  93. package/webapp/dist/assets/{diagram-S2PKOQOG-Dt5W2t6V.js.map → diagram-S2PKOQOG-4PZWLejv.js.map} +1 -1
  94. package/webapp/dist/assets/{erDiagram-Q2GNP2WA-Bs0-2Rfj.js → erDiagram-Q2GNP2WA-D-T72NZh.js} +5 -5
  95. package/webapp/dist/assets/{erDiagram-Q2GNP2WA-Bs0-2Rfj.js.map → erDiagram-Q2GNP2WA-D-T72NZh.js.map} +1 -1
  96. package/webapp/dist/assets/{flowDiagram-NV44I4VS-cJjXWAlK.js → flowDiagram-NV44I4VS-Dt4A3yp5.js} +6 -6
  97. package/webapp/dist/assets/{flowDiagram-NV44I4VS-cJjXWAlK.js.map → flowDiagram-NV44I4VS-Dt4A3yp5.js.map} +1 -1
  98. package/webapp/dist/assets/{ganttDiagram-JELNMOA3-Du1AUaKm.js → ganttDiagram-JELNMOA3-BBzjsK3y.js} +3 -3
  99. package/webapp/dist/assets/{ganttDiagram-JELNMOA3-Du1AUaKm.js.map → ganttDiagram-JELNMOA3-BBzjsK3y.js.map} +1 -1
  100. package/webapp/dist/assets/{gitGraphDiagram-V2S2FVAM-D_jVOYOK.js → gitGraphDiagram-V2S2FVAM-BubK7K8g.js} +8 -8
  101. package/webapp/dist/assets/{gitGraphDiagram-V2S2FVAM-D_jVOYOK.js.map → gitGraphDiagram-V2S2FVAM-BubK7K8g.js.map} +1 -1
  102. package/webapp/dist/assets/{graph-CuF_sq4r.js → graph-BnZA7q73.js} +3 -3
  103. package/webapp/dist/assets/{graph-CuF_sq4r.js.map → graph-BnZA7q73.js.map} +1 -1
  104. package/webapp/dist/assets/{index-DAShQcjb.js → index-DWOcffUL.js} +1288 -248
  105. package/webapp/dist/assets/{index-DAShQcjb.js.map → index-DWOcffUL.js.map} +1 -1
  106. package/webapp/dist/assets/{infoDiagram-HS3SLOUP-CEFlo_Hl.js → infoDiagram-HS3SLOUP-Du-AWabt.js} +6 -6
  107. package/webapp/dist/assets/{infoDiagram-HS3SLOUP-CEFlo_Hl.js.map → infoDiagram-HS3SLOUP-Du-AWabt.js.map} +1 -1
  108. package/webapp/dist/assets/{journeyDiagram-XKPGCS4Q-zc2Q4Se9.js → journeyDiagram-XKPGCS4Q-Ckq0AXof.js} +5 -5
  109. package/webapp/dist/assets/{journeyDiagram-XKPGCS4Q-zc2Q4Se9.js.map → journeyDiagram-XKPGCS4Q-Ckq0AXof.js.map} +1 -1
  110. package/webapp/dist/assets/{kanban-definition-3W4ZIXB7-oT42RM2a.js → kanban-definition-3W4ZIXB7-Buq8V-MH.js} +3 -3
  111. package/webapp/dist/assets/{kanban-definition-3W4ZIXB7-oT42RM2a.js.map → kanban-definition-3W4ZIXB7-Buq8V-MH.js.map} +1 -1
  112. package/webapp/dist/assets/{layout-BvaOu3k2.js → layout-CLWW_Um8.js} +5 -5
  113. package/webapp/dist/assets/{layout-BvaOu3k2.js.map → layout-CLWW_Um8.js.map} +1 -1
  114. package/webapp/dist/assets/{linear-Cg-CjocS.js → linear-lHd5Tlqa.js} +2 -2
  115. package/webapp/dist/assets/{linear-Cg-CjocS.js.map → linear-lHd5Tlqa.js.map} +1 -1
  116. package/webapp/dist/assets/{mindmap-definition-VGOIOE7T-CVFVrU22.js → mindmap-definition-VGOIOE7T-B0b69NGL.js} +4 -4
  117. package/webapp/dist/assets/{mindmap-definition-VGOIOE7T-CVFVrU22.js.map → mindmap-definition-VGOIOE7T-B0b69NGL.js.map} +1 -1
  118. package/webapp/dist/assets/{pieDiagram-ADFJNKIX-Bai5CMos.js → pieDiagram-ADFJNKIX-BYL1QeMo.js} +8 -8
  119. package/webapp/dist/assets/{pieDiagram-ADFJNKIX-Bai5CMos.js.map → pieDiagram-ADFJNKIX-BYL1QeMo.js.map} +1 -1
  120. package/webapp/dist/assets/{quadrantDiagram-AYHSOK5B-BPXDO_2E.js → quadrantDiagram-AYHSOK5B-tPPMCc4q.js} +3 -3
  121. package/webapp/dist/assets/{quadrantDiagram-AYHSOK5B-BPXDO_2E.js.map → quadrantDiagram-AYHSOK5B-tPPMCc4q.js.map} +1 -1
  122. package/webapp/dist/assets/{requirementDiagram-UZGBJVZJ-Dgj9X9cE.js → requirementDiagram-UZGBJVZJ-DyVxeq1s.js} +4 -4
  123. package/webapp/dist/assets/{requirementDiagram-UZGBJVZJ-Dgj9X9cE.js.map → requirementDiagram-UZGBJVZJ-DyVxeq1s.js.map} +1 -1
  124. package/webapp/dist/assets/{sankeyDiagram-TZEHDZUN-Dc0mO4OD.js → sankeyDiagram-TZEHDZUN-CX7oyOTa.js} +2 -2
  125. package/webapp/dist/assets/{sankeyDiagram-TZEHDZUN-Dc0mO4OD.js.map → sankeyDiagram-TZEHDZUN-CX7oyOTa.js.map} +1 -1
  126. package/webapp/dist/assets/{sequenceDiagram-WL72ISMW-DZJTga0d.js → sequenceDiagram-WL72ISMW-DCy2ebSq.js} +4 -4
  127. package/webapp/dist/assets/{sequenceDiagram-WL72ISMW-DZJTga0d.js.map → sequenceDiagram-WL72ISMW-DCy2ebSq.js.map} +1 -1
  128. package/webapp/dist/assets/{stateDiagram-FKZM4ZOC-RNxYatKM.js → stateDiagram-FKZM4ZOC-BparV-Ha.js} +9 -9
  129. package/webapp/dist/assets/{stateDiagram-FKZM4ZOC-RNxYatKM.js.map → stateDiagram-FKZM4ZOC-BparV-Ha.js.map} +1 -1
  130. package/webapp/dist/assets/{stateDiagram-v2-4FDKWEC3-ADxYqWzo.js → stateDiagram-v2-4FDKWEC3-feI3D8TP.js} +5 -5
  131. package/webapp/dist/assets/{stateDiagram-v2-4FDKWEC3-ADxYqWzo.js.map → stateDiagram-v2-4FDKWEC3-feI3D8TP.js.map} +1 -1
  132. package/webapp/dist/assets/{timeline-definition-IT6M3QCI-Qx_h1e-i.js → timeline-definition-IT6M3QCI-N19-5xkB.js} +3 -3
  133. package/webapp/dist/assets/{timeline-definition-IT6M3QCI-Qx_h1e-i.js.map → timeline-definition-IT6M3QCI-N19-5xkB.js.map} +1 -1
  134. package/webapp/dist/assets/{treemap-GDKQZRPO-BHzYvXGn.js → treemap-GDKQZRPO-DOQIHULF.js} +5 -5
  135. package/webapp/dist/assets/{treemap-GDKQZRPO-BHzYvXGn.js.map → treemap-GDKQZRPO-DOQIHULF.js.map} +1 -1
  136. package/webapp/dist/assets/{xychartDiagram-PRI3JC2R-DGdjkYQQ.js → xychartDiagram-PRI3JC2R-BU-Gq2qn.js} +3 -3
  137. package/webapp/dist/assets/{xychartDiagram-PRI3JC2R-DGdjkYQQ.js.map → xychartDiagram-PRI3JC2R-BU-Gq2qn.js.map} +1 -1
  138. package/webapp/dist/index.html +1 -1
@@ -115,6 +115,7 @@ function isPersistedMessageRecord(record) {
115
115
  case 'web_search_call_record':
116
116
  case 'native_tool_call_record':
117
117
  case 'tool_result_image_ingest_record':
118
+ case 'user_image_ingest_record':
118
119
  case 'quest_for_sup_record':
119
120
  case 'tellask_reply_resolution_record':
120
121
  case 'tellask_call_anchor_record':
@@ -153,7 +154,7 @@ function normalizeDraftUserText(events, targetGenseq) {
153
154
  return null;
154
155
  return texts.join('\n\n');
155
156
  }
156
- function rewriteFuncResultContentItems(items, newRootId) {
157
+ function rewriteContentItemsForFork(items, newRootId) {
157
158
  if (!items)
158
159
  return undefined;
159
160
  return items.map((item) => {
@@ -187,21 +188,26 @@ function rewriteRecordForFork(record, newRootId) {
187
188
  // not part of baseline state reconciliation and must not make forking fail.
188
189
  case 'web_search_call_record':
189
190
  case 'native_tool_call_record':
190
- case 'human_text_record':
191
191
  case 'quest_for_sup_record':
192
- case 'tellask_result_record':
193
192
  case 'tellask_reply_resolution_record':
194
193
  case 'tellask_call_anchor_record':
195
- case 'tellask_carryover_record':
196
194
  case 'gen_start_record':
197
195
  case 'gen_finish_record':
198
196
  return record;
197
+ case 'human_text_record':
198
+ case 'tellask_result_record':
199
+ case 'tellask_carryover_record':
200
+ return {
201
+ ...record,
202
+ contentItems: rewriteContentItemsForFork(record.contentItems, newRootId),
203
+ };
199
204
  case 'func_result_record':
200
205
  return {
201
206
  ...record,
202
- contentItems: rewriteFuncResultContentItems(record.contentItems, newRootId),
207
+ contentItems: rewriteContentItemsForFork(record.contentItems, newRootId),
203
208
  };
204
209
  case 'tool_result_image_ingest_record':
210
+ case 'user_image_ingest_record':
205
211
  return {
206
212
  ...record,
207
213
  artifact: {
@@ -38,24 +38,7 @@ async function resolvePendingCourseStartPromptForRestore(args) {
38
38
  }
39
39
  return { pendingCourseStartPrompt: undefined };
40
40
  }
41
- return {
42
- pendingCourseStartPrompt: {
43
- content: pending.content,
44
- msgId: pending.msgId,
45
- grammar: 'markdown',
46
- origin: 'runtime',
47
- ...(pending.userLanguageCode === undefined
48
- ? {}
49
- : { userLanguageCode: pending.userLanguageCode }),
50
- ...(pending.tellaskReplyDirective === undefined
51
- ? {}
52
- : { tellaskReplyDirective: pending.tellaskReplyDirective }),
53
- ...(pending.skipTaskdoc === undefined ? {} : { skipTaskdoc: pending.skipTaskdoc }),
54
- ...(pending.subdialogReplyTarget === undefined
55
- ? {}
56
- : { subdialogReplyTarget: pending.subdialogReplyTarget }),
57
- },
58
- };
41
+ return { pendingCourseStartPrompt: pending };
59
42
  }
60
43
  async function getOrRestoreRootDialog(rootId, status) {
61
44
  const existing = dialog_global_registry_1.globalDialogRegistry.get(rootId);
package/dist/dialog.d.ts CHANGED
@@ -14,36 +14,23 @@
14
14
  */
15
15
  import type { ContextHealthSnapshot } from '@longrun-ai/kernel/types/context-health';
16
16
  import type { DialogEvent, NativeToolCallPayload, ReminderContent, WebSearchCallAction, WebSearchCallSource } from '@longrun-ai/kernel/types/dialog';
17
- import type { DialogPrompt, DialogRunControlSpec, DialogSubdialogReplyTarget, DriveIntent } from '@longrun-ai/kernel/types/drive-intent';
17
+ import type { DialogQueuedDeferredQ4HAnswerState, DialogQueuedPromptState, DialogQueuedUserGenerationBoundaryState, DialogRunControlSpec, DialogRuntimePrompt, DialogSubdialogReplyTarget, DialogUserPrompt, DriveIntent } from '@longrun-ai/kernel/types/drive-intent';
18
18
  import type { LanguageCode } from '@longrun-ai/kernel/types/language';
19
19
  import type { CalleeCourseNumber, CalleeGenerationSeqNumber, CallingCourseNumber, CallingGenerationSeqNumber, DialogMetadataFile, HumanQuestion, ProviderData, ReasoningPayload, TellaskCallRecordName, TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
20
20
  import { ChatMessage, FuncResultMsg, TellaskCarryoverMsg, TellaskResultMsg } from './llm/client';
21
- import type { ToolResultImageIngest } from './llm/gen';
21
+ import type { ToolResultImageIngest, UserImageIngest } from './llm/gen';
22
22
  import type { JsonValue } from './tool';
23
23
  import { Reminder, ReminderOptions, ReminderOwner } from './tool';
24
24
  type NewCourseHookResult = {
25
25
  kind: 'continue';
26
- prompt: DialogPrompt;
26
+ prompt: DialogRuntimePrompt;
27
27
  } | {
28
28
  kind: 'reject';
29
29
  errorText: string;
30
30
  };
31
- type UpNextPromptState = {
32
- kind: 'user_generation_boundary' | 'deferred_q4h_answer' | 'registered_assignment_update' | 'new_course_start';
33
- prompt: string;
34
- msgId: string;
35
- grammar?: 'markdown';
36
- userLanguageCode?: LanguageCode;
37
- origin: 'user' | 'diligence_push' | 'runtime';
38
- q4hAnswerCallId?: string;
39
- tellaskReplyDirective?: TellaskReplyDirective;
40
- skipTaskdoc?: boolean;
41
- subdialogReplyTarget?: DialogSubdialogReplyTarget;
42
- runControl?: DialogRunControlSpec;
43
- };
44
31
  type NewCourseHook = (args: {
45
32
  dialog: Dialog;
46
- prompt: DialogPrompt;
33
+ prompt: DialogRuntimePrompt;
47
34
  runControl?: DialogRunControlSpec;
48
35
  }) => Promise<NewCourseHookResult>;
49
36
  export type DialogSuspensionStatusOptions = Readonly<{
@@ -106,7 +93,7 @@ export interface DialogInitParams {
106
93
  createdAt?: string;
107
94
  updatedAt?: string;
108
95
  contextHealth?: ContextHealthSnapshot;
109
- pendingCourseStartPrompt?: DialogPrompt;
96
+ pendingCourseStartPrompt?: DialogRuntimePrompt;
110
97
  };
111
98
  }
112
99
  export type VisibleReminderTarget = Readonly<{
@@ -153,7 +140,7 @@ export declare abstract class Dialog {
153
140
  protected _lastUserLanguageCode: LanguageCode;
154
141
  protected _lastContextHealth?: ContextHealthSnapshot;
155
142
  protected _lastContextHealthGenseq?: number;
156
- protected _upNextQueue: UpNextPromptState[];
143
+ protected _upNextQueue: DialogQueuedPromptState[];
157
144
  protected _driveIntents: DriveIntent[];
158
145
  protected _activeRunControlSpec?: DialogRunControlSpec;
159
146
  protected _newCourseHook?: NewCourseHook;
@@ -322,7 +309,6 @@ export declare abstract class Dialog {
322
309
  setSuspensionState(state: 'active' | 'suspended' | 'resumed'): void;
323
310
  get createdAt(): string;
324
311
  get updatedAt(): string;
325
- private buildUpNextPromptState;
326
312
  private replaceQueuedPromptState;
327
313
  private setNewCourseStartPrompt;
328
314
  private mergePromptQ4HAnswerCallId;
@@ -330,31 +316,32 @@ export declare abstract class Dialog {
330
316
  private peekLatestUpNext;
331
317
  queueUserPromptAtGenerationBoundary(options: {
332
318
  prompt: string;
319
+ contentItems?: DialogQueuedUserGenerationBoundaryState['contentItems'];
333
320
  msgId: string;
334
321
  grammar: 'markdown';
335
322
  userLanguageCode?: LanguageCode;
336
323
  q4hAnswerCallId?: string;
337
- }): UpNextPromptState;
324
+ }): DialogQueuedPromptState;
338
325
  queueDeferredQ4HAnswerPrompt(options: {
339
326
  prompt: string;
327
+ contentItems?: DialogQueuedDeferredQ4HAnswerState['contentItems'];
340
328
  msgId: string;
341
329
  grammar: 'markdown';
342
330
  userLanguageCode?: LanguageCode;
343
331
  q4hAnswerCallId?: string;
344
- }): UpNextPromptState;
332
+ }): DialogQueuedPromptState;
345
333
  queueRegisteredAssignmentUpdatePrompt(options: {
346
334
  prompt: string;
347
335
  msgId: string;
348
336
  grammar: 'markdown';
349
337
  userLanguageCode?: LanguageCode;
350
- q4hAnswerCallId?: string;
351
- tellaskReplyDirective?: TellaskReplyDirective;
338
+ tellaskReplyDirective: TellaskReplyDirective;
352
339
  skipTaskdoc?: boolean;
353
- subdialogReplyTarget?: DialogSubdialogReplyTarget;
354
- }): UpNextPromptState;
340
+ subdialogReplyTarget: DialogSubdialogReplyTarget;
341
+ }): DialogQueuedPromptState;
355
342
  hasUpNext(): boolean;
356
- peekUpNext(): UpNextPromptState | undefined;
357
- takeUpNext(): UpNextPromptState | undefined;
343
+ peekUpNext(): DialogQueuedPromptState | undefined;
344
+ takeUpNext(): DialogQueuedPromptState | undefined;
358
345
  setActiveRunControlSpec(spec?: DialogRunControlSpec): void;
359
346
  getActiveRunControlSpec(): DialogRunControlSpec | undefined;
360
347
  setNewCourseHook(hook?: NewCourseHook): void;
@@ -388,6 +375,7 @@ export declare abstract class Dialog {
388
375
  originCourse?: CallingCourseNumber;
389
376
  calling_genseq?: CallingGenerationSeqNumber;
390
377
  carryoverContent?: string;
378
+ contentItems?: DialogUserPrompt['contentItems'];
391
379
  sessionSlug?: string;
392
380
  calleeCourse?: CalleeCourseNumber;
393
381
  calleeGenseq?: CalleeGenerationSeqNumber;
@@ -414,6 +402,7 @@ export declare abstract class Dialog {
414
402
  }): Promise<void>;
415
403
  nativeToolCall(payload: NativeToolCallPayload): Promise<void>;
416
404
  toolResultImageIngest(payload: ToolResultImageIngest): Promise<void>;
405
+ userImageIngest(payload: UserImageIngest): Promise<void>;
417
406
  callingStart(payload: {
418
407
  callName: 'tellaskBack' | 'tellask' | 'tellaskSessionless' | 'askHuman' | 'freshBootsReasoning';
419
408
  callId: string;
@@ -422,7 +411,7 @@ export declare abstract class Dialog {
422
411
  tellaskContent: string;
423
412
  }): Promise<void>;
424
413
  updateQuestions4Human(questions: HumanQuestion[]): Promise<void>;
425
- persistUserMessage(content: string, msgId: string, grammar: 'markdown', origin: 'user' | 'diligence_push' | 'runtime' | undefined, userLanguageCode?: LanguageCode, q4hAnswerCallId?: string, tellaskReplyDirective?: TellaskReplyDirective): Promise<void>;
414
+ persistUserMessage(content: string, msgId: string, grammar: 'markdown', origin: 'user' | 'diligence_push' | 'runtime' | undefined, userLanguageCode?: LanguageCode, q4hAnswerCallId?: string, tellaskReplyDirective?: TellaskReplyDirective, contentItems?: DialogUserPrompt['contentItems']): Promise<void>;
426
415
  receiveHumanReply(args: {
427
416
  content: string;
428
417
  userLanguageCode?: LanguageCode;
@@ -633,6 +622,7 @@ export declare abstract class DialogStore {
633
622
  }): Promise<void>;
634
623
  nativeToolCall(_dialog: Dialog, _payload: NativeToolCallPayload): Promise<void>;
635
624
  toolResultImageIngest(_dialog: Dialog, _payload: ToolResultImageIngest): Promise<void>;
625
+ userImageIngest(_dialog: Dialog, _payload: UserImageIngest): Promise<void>;
636
626
  /**
637
627
  * Load current course number from persisted metadata
638
628
  * This method should be implemented by subclasses to read from storage
@@ -650,7 +640,7 @@ export declare abstract class DialogStore {
650
640
  /**
651
641
  * Persist a user message to storage
652
642
  */
653
- persistUserMessage(_dialog: Dialog, _content: string, _msgId: string, _grammar: 'markdown', _origin: 'user' | 'diligence_push' | 'runtime' | undefined, _userLanguageCode?: LanguageCode, _q4hAnswerCallId?: string, _tellaskReplyDirective?: TellaskReplyDirective): Promise<void>;
643
+ persistUserMessage(_dialog: Dialog, _content: string, _msgId: string, _grammar: 'markdown', _origin: 'user' | 'diligence_push' | 'runtime' | undefined, _userLanguageCode?: LanguageCode, _q4hAnswerCallId?: string, _tellaskReplyDirective?: TellaskReplyDirective, _contentItems?: DialogUserPrompt['contentItems']): Promise<void>;
654
644
  appendTellaskReplyResolution(_dialog: Dialog, _payload: {
655
645
  callId: string;
656
646
  replyCallName: 'replyTellask' | 'replyTellaskSessionless' | 'replyTellaskBack';
@@ -684,7 +674,7 @@ export declare abstract class DialogStore {
684
674
  /**
685
675
  * Start a new course in storage
686
676
  */
687
- startNewCourse(_dialog: Dialog, _newCoursePrompt: DialogPrompt): Promise<void>;
677
+ startNewCourse(_dialog: Dialog, _newCoursePrompt: DialogRuntimePrompt): Promise<void>;
688
678
  /**
689
679
  * Handle stream error
690
680
  */
package/dist/dialog.js CHANGED
@@ -632,21 +632,6 @@ class Dialog {
632
632
  get updatedAt() {
633
633
  return this._updatedAt;
634
634
  }
635
- buildUpNextPromptState(prompt, kind, runControl) {
636
- return {
637
- kind,
638
- prompt: prompt.content,
639
- msgId: prompt.msgId,
640
- grammar: prompt.grammar,
641
- userLanguageCode: prompt.userLanguageCode,
642
- origin: prompt.origin,
643
- q4hAnswerCallId: prompt.q4hAnswerCallId,
644
- tellaskReplyDirective: prompt.tellaskReplyDirective,
645
- skipTaskdoc: prompt.skipTaskdoc,
646
- subdialogReplyTarget: prompt.subdialogReplyTarget,
647
- runControl,
648
- };
649
- }
650
635
  replaceQueuedPromptState(existingMsgId, nextPrompt) {
651
636
  const queueIndex = this._upNextQueue.findIndex((prompt) => prompt.msgId === existingMsgId);
652
637
  if (queueIndex < 0) {
@@ -657,19 +642,68 @@ class Dialog {
657
642
  const intent = this._driveIntents[index];
658
643
  if (intent.kind !== 'prompt' || intent.prompt.msgId !== existingMsgId)
659
644
  continue;
645
+ const promptCommon = {
646
+ content: nextPrompt.prompt,
647
+ ...(nextPrompt.contentItems === undefined ? {} : { contentItems: nextPrompt.contentItems }),
648
+ msgId: nextPrompt.msgId,
649
+ grammar: nextPrompt.grammar ?? 'markdown',
650
+ userLanguageCode: nextPrompt.userLanguageCode ?? this._lastUserLanguageCode,
651
+ };
660
652
  this._driveIntents[index] = {
661
653
  ...intent,
662
- prompt: {
663
- ...intent.prompt,
664
- content: nextPrompt.prompt,
665
- msgId: nextPrompt.msgId,
666
- grammar: nextPrompt.grammar ?? 'markdown',
667
- userLanguageCode: nextPrompt.userLanguageCode,
668
- q4hAnswerCallId: nextPrompt.q4hAnswerCallId,
669
- tellaskReplyDirective: nextPrompt.tellaskReplyDirective,
670
- skipTaskdoc: nextPrompt.skipTaskdoc,
671
- subdialogReplyTarget: nextPrompt.subdialogReplyTarget,
672
- },
654
+ prompt: (() => {
655
+ switch (nextPrompt.kind) {
656
+ case 'user_generation_boundary':
657
+ case 'deferred_q4h_answer': {
658
+ const prompt = {
659
+ ...promptCommon,
660
+ origin: 'user',
661
+ ...(nextPrompt.q4hAnswerCallId === undefined
662
+ ? {}
663
+ : { q4hAnswerCallId: nextPrompt.q4hAnswerCallId }),
664
+ };
665
+ return prompt;
666
+ }
667
+ case 'registered_assignment_update':
668
+ case 'new_course_runtime_subdialog': {
669
+ const prompt = {
670
+ ...promptCommon,
671
+ origin: 'runtime',
672
+ ...(nextPrompt.skipTaskdoc === undefined
673
+ ? {}
674
+ : { skipTaskdoc: nextPrompt.skipTaskdoc }),
675
+ tellaskReplyDirective: nextPrompt.tellaskReplyDirective,
676
+ subdialogReplyTarget: nextPrompt.subdialogReplyTarget,
677
+ };
678
+ return prompt;
679
+ }
680
+ case 'new_course_runtime_reply': {
681
+ const prompt = {
682
+ ...promptCommon,
683
+ origin: 'runtime',
684
+ ...(nextPrompt.skipTaskdoc === undefined
685
+ ? {}
686
+ : { skipTaskdoc: nextPrompt.skipTaskdoc }),
687
+ tellaskReplyDirective: nextPrompt.tellaskReplyDirective,
688
+ };
689
+ return prompt;
690
+ }
691
+ case 'new_course_runtime_guide': {
692
+ const prompt = {
693
+ ...promptCommon,
694
+ origin: 'runtime',
695
+ ...(nextPrompt.skipTaskdoc === undefined
696
+ ? {}
697
+ : { skipTaskdoc: nextPrompt.skipTaskdoc }),
698
+ };
699
+ return prompt;
700
+ }
701
+ default: {
702
+ const _exhaustive = nextPrompt;
703
+ throw new Error(`UpNext prompt replacement invariant violation: unsupported queued prompt`);
704
+ }
705
+ }
706
+ })(),
673
707
  runControl: nextPrompt.runControl,
674
708
  };
675
709
  return nextPrompt;
@@ -690,14 +724,69 @@ class Dialog {
690
724
  if (!trimmed) {
691
725
  throw new Error('Prompt is required to start a new course');
692
726
  }
693
- const normalized = {
694
- ...prepared,
727
+ const runtimeCommon = {
695
728
  content: trimmed,
696
729
  msgId: prepared.msgId.trim() || (0, id_1.generateShortId)(),
697
730
  grammar: 'markdown',
698
731
  userLanguageCode: prepared.userLanguageCode ?? this._lastUserLanguageCode,
732
+ origin: 'runtime',
733
+ ...(prepared.skipTaskdoc === undefined ? {} : { skipTaskdoc: prepared.skipTaskdoc }),
699
734
  };
700
- this._upNextQueue = [this.buildUpNextPromptState(normalized, 'new_course_start')];
735
+ const normalized = prepared.subdialogReplyTarget !== undefined
736
+ ? (() => {
737
+ const prompt = {
738
+ ...runtimeCommon,
739
+ tellaskReplyDirective: prepared.tellaskReplyDirective,
740
+ subdialogReplyTarget: prepared.subdialogReplyTarget,
741
+ };
742
+ return prompt;
743
+ })()
744
+ : prepared.tellaskReplyDirective !== undefined
745
+ ? (() => {
746
+ const prompt = {
747
+ ...runtimeCommon,
748
+ tellaskReplyDirective: prepared.tellaskReplyDirective,
749
+ };
750
+ return prompt;
751
+ })()
752
+ : (() => {
753
+ const prompt = runtimeCommon;
754
+ return prompt;
755
+ })();
756
+ this._upNextQueue = [
757
+ normalized.subdialogReplyTarget !== undefined
758
+ ? {
759
+ kind: 'new_course_runtime_subdialog',
760
+ prompt: normalized.content,
761
+ msgId: normalized.msgId,
762
+ grammar: normalized.grammar,
763
+ userLanguageCode: normalized.userLanguageCode,
764
+ origin: 'runtime',
765
+ tellaskReplyDirective: normalized.tellaskReplyDirective,
766
+ skipTaskdoc: normalized.skipTaskdoc,
767
+ subdialogReplyTarget: normalized.subdialogReplyTarget,
768
+ }
769
+ : normalized.tellaskReplyDirective !== undefined
770
+ ? {
771
+ kind: 'new_course_runtime_reply',
772
+ prompt: normalized.content,
773
+ msgId: normalized.msgId,
774
+ grammar: normalized.grammar,
775
+ userLanguageCode: normalized.userLanguageCode,
776
+ origin: 'runtime',
777
+ tellaskReplyDirective: normalized.tellaskReplyDirective,
778
+ skipTaskdoc: normalized.skipTaskdoc,
779
+ }
780
+ : {
781
+ kind: 'new_course_runtime_guide',
782
+ prompt: normalized.content,
783
+ msgId: normalized.msgId,
784
+ grammar: normalized.grammar,
785
+ userLanguageCode: normalized.userLanguageCode,
786
+ origin: 'runtime',
787
+ skipTaskdoc: normalized.skipTaskdoc,
788
+ },
789
+ ];
701
790
  return normalized;
702
791
  }
703
792
  mergePromptQ4HAnswerCallId(existing, incoming) {
@@ -717,19 +806,62 @@ class Dialog {
717
806
  }
718
807
  enqueueQueuedPromptState(state) {
719
808
  this._upNextQueue.push(state);
809
+ const promptCommon = {
810
+ content: state.prompt,
811
+ ...(state.contentItems === undefined ? {} : { contentItems: state.contentItems }),
812
+ msgId: state.msgId,
813
+ grammar: state.grammar ?? 'markdown',
814
+ userLanguageCode: state.userLanguageCode ?? this._lastUserLanguageCode,
815
+ };
720
816
  this._driveIntents.push({
721
817
  kind: 'prompt',
722
- prompt: {
723
- content: state.prompt,
724
- msgId: state.msgId,
725
- grammar: state.grammar ?? 'markdown',
726
- userLanguageCode: state.userLanguageCode ?? this._lastUserLanguageCode,
727
- origin: state.origin,
728
- q4hAnswerCallId: state.q4hAnswerCallId,
729
- tellaskReplyDirective: state.tellaskReplyDirective,
730
- skipTaskdoc: state.skipTaskdoc,
731
- subdialogReplyTarget: state.subdialogReplyTarget,
732
- },
818
+ prompt: (() => {
819
+ switch (state.kind) {
820
+ case 'user_generation_boundary':
821
+ case 'deferred_q4h_answer': {
822
+ const prompt = {
823
+ ...promptCommon,
824
+ origin: 'user',
825
+ ...(state.q4hAnswerCallId === undefined
826
+ ? {}
827
+ : { q4hAnswerCallId: state.q4hAnswerCallId }),
828
+ };
829
+ return prompt;
830
+ }
831
+ case 'registered_assignment_update':
832
+ case 'new_course_runtime_subdialog': {
833
+ const prompt = {
834
+ ...promptCommon,
835
+ origin: 'runtime',
836
+ ...(state.skipTaskdoc === undefined ? {} : { skipTaskdoc: state.skipTaskdoc }),
837
+ tellaskReplyDirective: state.tellaskReplyDirective,
838
+ subdialogReplyTarget: state.subdialogReplyTarget,
839
+ };
840
+ return prompt;
841
+ }
842
+ case 'new_course_runtime_reply': {
843
+ const prompt = {
844
+ ...promptCommon,
845
+ origin: 'runtime',
846
+ ...(state.skipTaskdoc === undefined ? {} : { skipTaskdoc: state.skipTaskdoc }),
847
+ tellaskReplyDirective: state.tellaskReplyDirective,
848
+ };
849
+ return prompt;
850
+ }
851
+ case 'new_course_runtime_guide': {
852
+ const prompt = {
853
+ ...promptCommon,
854
+ origin: 'runtime',
855
+ ...(state.skipTaskdoc === undefined ? {} : { skipTaskdoc: state.skipTaskdoc }),
856
+ };
857
+ return prompt;
858
+ }
859
+ default: {
860
+ const _exhaustive = state;
861
+ throw new Error(`UpNext enqueue invariant violation: unsupported queued prompt`);
862
+ }
863
+ }
864
+ })(),
733
865
  runControl: state.runControl,
734
866
  });
735
867
  this._updatedAt = (0, time_1.formatUnifiedTimestamp)(new Date());
@@ -746,7 +878,7 @@ class Dialog {
746
878
  if (!trimmed) {
747
879
  throw new Error('Prompt is required to queue generation-boundary user prompt');
748
880
  }
749
- if (existing?.kind !== 'user_generation_boundary' || existing.origin !== 'user') {
881
+ if (existing?.kind !== 'user_generation_boundary') {
750
882
  const created = {
751
883
  kind: 'user_generation_boundary',
752
884
  prompt: trimmed,
@@ -754,6 +886,7 @@ class Dialog {
754
886
  grammar: options.grammar,
755
887
  userLanguageCode: options.userLanguageCode ?? this._lastUserLanguageCode,
756
888
  origin: 'user',
889
+ contentItems: options.contentItems,
757
890
  q4hAnswerCallId: options.q4hAnswerCallId,
758
891
  };
759
892
  this.enqueueQueuedPromptState(created);
@@ -762,6 +895,9 @@ class Dialog {
762
895
  const merged = {
763
896
  ...existing,
764
897
  prompt: `${existing.prompt}\n\n---\n\n${trimmed}`,
898
+ contentItems: existing.contentItems || options.contentItems
899
+ ? [...(existing.contentItems ?? []), ...(options.contentItems ?? [])]
900
+ : undefined,
765
901
  grammar: options.grammar,
766
902
  userLanguageCode: options.userLanguageCode ?? existing.userLanguageCode ?? this._lastUserLanguageCode,
767
903
  q4hAnswerCallId: this.mergePromptQ4HAnswerCallId(existing.q4hAnswerCallId, options.q4hAnswerCallId),
@@ -780,6 +916,7 @@ class Dialog {
780
916
  const created = {
781
917
  kind: 'deferred_q4h_answer',
782
918
  prompt: trimmed,
919
+ contentItems: options.contentItems,
783
920
  msgId: options.msgId,
784
921
  grammar: options.grammar,
785
922
  userLanguageCode: options.userLanguageCode ?? this._lastUserLanguageCode,
@@ -804,7 +941,6 @@ class Dialog {
804
941
  grammar: options.grammar,
805
942
  userLanguageCode: options.userLanguageCode ?? this._lastUserLanguageCode,
806
943
  origin: 'runtime',
807
- q4hAnswerCallId: options.q4hAnswerCallId,
808
944
  tellaskReplyDirective: options.tellaskReplyDirective,
809
945
  skipTaskdoc: options.skipTaskdoc,
810
946
  subdialogReplyTarget: options.subdialogReplyTarget,
@@ -819,10 +955,9 @@ class Dialog {
819
955
  msgId: options.msgId,
820
956
  grammar: options.grammar,
821
957
  userLanguageCode: options.userLanguageCode ?? existing.userLanguageCode ?? this._lastUserLanguageCode,
822
- q4hAnswerCallId: this.mergePromptQ4HAnswerCallId(existing.q4hAnswerCallId, options.q4hAnswerCallId),
823
- tellaskReplyDirective: options.tellaskReplyDirective ?? existing.tellaskReplyDirective,
958
+ tellaskReplyDirective: options.tellaskReplyDirective,
824
959
  skipTaskdoc: options.skipTaskdoc ?? existing.skipTaskdoc,
825
- subdialogReplyTarget: options.subdialogReplyTarget ?? existing.subdialogReplyTarget,
960
+ subdialogReplyTarget: options.subdialogReplyTarget,
826
961
  runControl: undefined,
827
962
  };
828
963
  this.replaceQueuedPromptState(existing.msgId, merged);
@@ -881,14 +1016,22 @@ class Dialog {
881
1016
  collectiveTargets: this.assignmentFromSup.collectiveTargets ?? [this.agentId],
882
1017
  })}\n---\n${trimmedPrompt}`
883
1018
  : trimmedPrompt;
884
- const basePrompt = {
885
- content: combinedPrompt,
886
- msgId: (0, id_1.generateShortId)(),
887
- grammar: 'markdown',
888
- userLanguageCode: this._lastUserLanguageCode,
889
- origin: 'runtime',
890
- ...(this instanceof SubDialog ? buildSubdialogAssignmentPromptMeta(this) : {}),
891
- };
1019
+ const basePrompt = this instanceof SubDialog
1020
+ ? {
1021
+ content: combinedPrompt,
1022
+ msgId: (0, id_1.generateShortId)(),
1023
+ grammar: 'markdown',
1024
+ userLanguageCode: this._lastUserLanguageCode,
1025
+ origin: 'runtime',
1026
+ ...buildSubdialogAssignmentPromptMeta(this),
1027
+ }
1028
+ : {
1029
+ content: combinedPrompt,
1030
+ msgId: (0, id_1.generateShortId)(),
1031
+ grammar: 'markdown',
1032
+ userLanguageCode: this._lastUserLanguageCode,
1033
+ origin: 'runtime',
1034
+ };
892
1035
  const runControlSpec = options?.runControl ?? this._activeRunControlSpec;
893
1036
  let nextPrompt = basePrompt;
894
1037
  if (this._newCourseHook && options?.skipRunControlHook !== true) {
@@ -1034,6 +1177,7 @@ class Dialog {
1034
1177
  role: 'user',
1035
1178
  genseq: this.activeGenSeqOrUndefined ?? 1,
1036
1179
  content: options.carryoverContent,
1180
+ ...(options.contentItems === undefined ? {} : { contentItems: options.contentItems }),
1037
1181
  originCourse: carryoverOriginCourse,
1038
1182
  carryoverCourse: currentCourse,
1039
1183
  responderId,
@@ -1067,6 +1211,7 @@ class Dialog {
1067
1211
  callName,
1068
1212
  status,
1069
1213
  content: options.response,
1214
+ ...(options.contentItems === undefined ? {} : { contentItems: options.contentItems }),
1070
1215
  ...(options.originCourse !== undefined ? { originCourse: options.originCourse } : {}),
1071
1216
  ...(options.calling_genseq !== undefined
1072
1217
  ? { calling_genseq: options.calling_genseq }
@@ -1091,6 +1236,7 @@ class Dialog {
1091
1236
  callName,
1092
1237
  status,
1093
1238
  content: options.response,
1239
+ ...(options.contentItems === undefined ? {} : { contentItems: options.contentItems }),
1094
1240
  ...(options.originCourse !== undefined ? { originCourse: options.originCourse } : {}),
1095
1241
  ...(options.calling_genseq !== undefined
1096
1242
  ? { calling_genseq: options.calling_genseq }
@@ -1113,6 +1259,7 @@ class Dialog {
1113
1259
  callName,
1114
1260
  status,
1115
1261
  content: options.response,
1262
+ ...(options.contentItems === undefined ? {} : { contentItems: options.contentItems }),
1116
1263
  ...(options.originCourse !== undefined ? { originCourse: options.originCourse } : {}),
1117
1264
  ...(options.calling_genseq !== undefined
1118
1265
  ? { calling_genseq: options.calling_genseq }
@@ -1213,6 +1360,9 @@ class Dialog {
1213
1360
  async toolResultImageIngest(payload) {
1214
1361
  await this.dlgStore.toolResultImageIngest(this, payload);
1215
1362
  }
1363
+ async userImageIngest(payload) {
1364
+ await this.dlgStore.userImageIngest(this, payload);
1365
+ }
1216
1366
  // Tellask-special call lifecycle events
1217
1367
  async callingStart(payload) {
1218
1368
  // Store callId for inline call-result correlation
@@ -1222,8 +1372,8 @@ class Dialog {
1222
1372
  async updateQuestions4Human(questions) {
1223
1373
  return await this.dlgStore.updateQuestions4Human(this, questions);
1224
1374
  }
1225
- async persistUserMessage(content, msgId, grammar, origin, userLanguageCode, q4hAnswerCallId, tellaskReplyDirective) {
1226
- return await this.dlgStore.persistUserMessage(this, content, msgId, grammar, origin, userLanguageCode, q4hAnswerCallId, tellaskReplyDirective);
1375
+ async persistUserMessage(content, msgId, grammar, origin, userLanguageCode, q4hAnswerCallId, tellaskReplyDirective, contentItems) {
1376
+ return await this.dlgStore.persistUserMessage(this, content, msgId, grammar, origin, userLanguageCode, q4hAnswerCallId, tellaskReplyDirective, contentItems);
1227
1377
  }
1228
1378
  async receiveHumanReply(args) {
1229
1379
  if (args.content.trim() === '') {
@@ -1645,6 +1795,7 @@ class DialogStore {
1645
1795
  async webSearchCall(_dialog, _payload) { }
1646
1796
  async nativeToolCall(_dialog, _payload) { }
1647
1797
  async toolResultImageIngest(_dialog, _payload) { }
1798
+ async userImageIngest(_dialog, _payload) { }
1648
1799
  /**
1649
1800
  * Load current course number from persisted metadata
1650
1801
  * This method should be implemented by subclasses to read from storage
@@ -1668,7 +1819,7 @@ class DialogStore {
1668
1819
  /**
1669
1820
  * Persist a user message to storage
1670
1821
  */
1671
- async persistUserMessage(_dialog, _content, _msgId, _grammar, _origin, _userLanguageCode, _q4hAnswerCallId, _tellaskReplyDirective) { }
1822
+ async persistUserMessage(_dialog, _content, _msgId, _grammar, _origin, _userLanguageCode, _q4hAnswerCallId, _tellaskReplyDirective, _contentItems) { }
1672
1823
  async appendTellaskReplyResolution(_dialog, _payload) { }
1673
1824
  /**
1674
1825
  * Persist an assistant message to storage
@@ -247,7 +247,8 @@ flowchart TD
247
247
 
248
248
  - If a sideline dialog has completed all assigned goals and can deliver the final result, it MUST reply directly with the response body; do not use `tellaskBack` to send final delivery.
249
249
  - Runtime treats that direct reply as the completion delivery to the tellasker dialog and injects the work-language marker automatically (`【Completed】` in English work language, `【最终完成】` in Chinese work language).
250
- - If any goal is incomplete, the dialog is blocked, or critical context is missing, it MUST issue `tellaskBack({ tellaskContent: "..." })` to request clarification or next-step confirmation before proceeding.
250
+ - If the work is unfinished, do not default to `tellaskBack`; first use team SOP / role ownership to judge whether a responsible owner is already clear, and if yes for execution work, directly use `tellask` / `tellaskSessionless` for that owner.
251
+ - Use `tellaskBack({ tellaskContent: "..." })` only when the upstream requester must clarify the request, decide a tradeoff, confirm acceptance criteria, provide missing input, or current SOP cannot determine ownership.
251
252
  - **FBR exception**: FBR sideline dialogs forbid all tellask calls (including `tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman`); they must list missing context and return.
252
253
 
253
254
  **Inter-dialog transfer and markers (normative)**:
@@ -268,7 +269,7 @@ flowchart TD
268
269
 
269
270
  **Protocol clarification**:
270
271
 
271
- - Ask-back must be emitted via `tellaskBack({ tellaskContent: "..." })`; do not post plain-text intermediate status updates while unfinished.
272
+ - When you truly need to ask upstream back, emit it via `tellaskBack({ tellaskContent: "..." })`; first judge whether team SOP already identifies another responsible owner. Do not post plain-text intermediate status updates while unfinished.
272
273
  - A direct plain-text reply is correct when the sideline is already complete and is delivering the final result upstream.
273
274
 
274
275
  Note: no extra "Status: ..." line is required; the first-line marker is the stage reminder.