dominds 0.7.6 → 0.8.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.
Files changed (155) hide show
  1. package/README.md +2 -2
  2. package/README.zh.md +2 -2
  3. package/dist/agent-priming.js +169 -200
  4. package/dist/cli/read.js +2 -7
  5. package/dist/dialog-factory.js +6 -4
  6. package/dist/dialog-instance-registry.js +2 -2
  7. package/dist/dialog.js +99 -91
  8. package/dist/docs/dialog-persistence.md +2 -2
  9. package/dist/docs/dialog-persistence.zh.md +2 -2
  10. package/dist/docs/dialog-system.md +86 -90
  11. package/dist/docs/dialog-system.zh.md +82 -83
  12. package/dist/docs/diligence-push.md +2 -2
  13. package/dist/docs/diligence-push.zh.md +2 -2
  14. package/dist/docs/dominds-agent-priming.md +11 -11
  15. package/dist/docs/dominds-agent-priming.zh.md +9 -9
  16. package/dist/docs/dominds-terminology.md +34 -34
  17. package/dist/docs/fbr-implementation.md +4 -4
  18. package/dist/docs/fbr-implementation.zh.md +4 -4
  19. package/dist/docs/fbr.md +31 -53
  20. package/dist/docs/fbr.zh.md +30 -48
  21. package/dist/docs/mottos.md +2 -3
  22. package/dist/docs/mottos.zh.md +2 -2
  23. package/dist/docs/q4h.md +6 -6
  24. package/dist/docs/q4h.zh.md +6 -6
  25. package/dist/docs/tellask-collab.md +13 -13
  26. package/dist/docs/tellask-collab.zh.md +18 -18
  27. package/dist/llm/driver-entry.js +9 -33
  28. package/dist/llm/driver-v2/core.js +413 -111
  29. package/dist/llm/driver-v2/index.js +5 -0
  30. package/dist/llm/driver-v2/orchestrator.js +4 -3
  31. package/dist/llm/driver-v2/policy.js +17 -23
  32. package/dist/llm/driver-v2/restore-dialog-hierarchy.js +73 -0
  33. package/dist/llm/driver-v2/round.js +18 -7
  34. package/dist/llm/driver-v2/runtime-utils.js +3 -5
  35. package/dist/llm/driver-v2/saying-events.js +4 -42
  36. package/dist/llm/driver-v2/supdialog-response.js +110 -23
  37. package/dist/llm/driver-v2/tellask-bridge.js +560 -458
  38. package/dist/mcp/sdk-client.js +1 -1
  39. package/dist/mcp/server-runtime.js +1 -1
  40. package/dist/mcp/stdio-client.js +6 -6
  41. package/dist/mcp/tool-names.js +1 -1
  42. package/dist/minds/builtin/fuxi/persona.en.md +10 -10
  43. package/dist/minds/builtin/fuxi/persona.zh.md +12 -12
  44. package/dist/minds/builtin/pangu/persona.en.md +7 -7
  45. package/dist/minds/builtin/pangu/persona.zh.md +6 -6
  46. package/dist/minds/minds-i18n.js +2 -2
  47. package/dist/minds/system-prompt-parts.js +15 -12
  48. package/dist/minds/system-prompt.js +58 -56
  49. package/dist/persistence.js +675 -527
  50. package/dist/server/api-routes.js +1 -1
  51. package/dist/server/websocket-handler.js +10 -20
  52. package/dist/server.js +3 -3
  53. package/dist/shared/diligence.js +12 -12
  54. package/dist/shared/i18n/driver-messages.js +28 -118
  55. package/dist/shared/utils/inter-dialog-format.js +53 -53
  56. package/dist/snippets/starting.en.md +1 -1
  57. package/dist/snippets/starting.zh.md +1 -2
  58. package/dist/static/assets/{_baseUniq-2IQvcpiv.js → _baseUniq-D4N_zVXV.js} +2 -2
  59. package/dist/static/assets/{_baseUniq-2IQvcpiv.js.map → _baseUniq-D4N_zVXV.js.map} +1 -1
  60. package/dist/static/assets/{arc-Boi4s2EY.js → arc-7bP9qomB.js} +2 -2
  61. package/dist/static/assets/{arc-Boi4s2EY.js.map → arc-7bP9qomB.js.map} +1 -1
  62. package/dist/static/assets/{architectureDiagram-VXUJARFQ-CV1IIalQ.js → architectureDiagram-VXUJARFQ-DToIiZuZ.js} +6 -6
  63. package/dist/static/assets/{architectureDiagram-VXUJARFQ-CV1IIalQ.js.map → architectureDiagram-VXUJARFQ-DToIiZuZ.js.map} +1 -1
  64. package/dist/static/assets/{blockDiagram-VD42YOAC-C66ZvUb1.js → blockDiagram-VD42YOAC-C-pRNHpf.js} +7 -7
  65. package/dist/static/assets/{blockDiagram-VD42YOAC-C66ZvUb1.js.map → blockDiagram-VD42YOAC-C-pRNHpf.js.map} +1 -1
  66. package/dist/static/assets/{c4Diagram-YG6GDRKO-2YQZQ-KQ.js → c4Diagram-YG6GDRKO-Bnp-nWKO.js} +3 -3
  67. package/dist/static/assets/{c4Diagram-YG6GDRKO-2YQZQ-KQ.js.map → c4Diagram-YG6GDRKO-Bnp-nWKO.js.map} +1 -1
  68. package/dist/static/assets/{channel-DBG_xYT_.js → channel-CTv1SsAF.js} +2 -2
  69. package/dist/static/assets/{channel-DBG_xYT_.js.map → channel-CTv1SsAF.js.map} +1 -1
  70. package/dist/static/assets/{chunk-4BX2VUAB-D92pQ5qM.js → chunk-4BX2VUAB-D_OGa3ss.js} +2 -2
  71. package/dist/static/assets/{chunk-4BX2VUAB-D92pQ5qM.js.map → chunk-4BX2VUAB-D_OGa3ss.js.map} +1 -1
  72. package/dist/static/assets/{chunk-55IACEB6-T3IKxvjm.js → chunk-55IACEB6-I4o4MCuM.js} +2 -2
  73. package/dist/static/assets/{chunk-55IACEB6-T3IKxvjm.js.map → chunk-55IACEB6-I4o4MCuM.js.map} +1 -1
  74. package/dist/static/assets/{chunk-B4BG7PRW-SKDCq7xY.js → chunk-B4BG7PRW-Bp-TIXg6.js} +5 -5
  75. package/dist/static/assets/{chunk-B4BG7PRW-SKDCq7xY.js.map → chunk-B4BG7PRW-Bp-TIXg6.js.map} +1 -1
  76. package/dist/static/assets/{chunk-DI55MBZ5-CKY9xXzj.js → chunk-DI55MBZ5-Bnph5Hmd.js} +4 -4
  77. package/dist/static/assets/{chunk-DI55MBZ5-CKY9xXzj.js.map → chunk-DI55MBZ5-Bnph5Hmd.js.map} +1 -1
  78. package/dist/static/assets/{chunk-FMBD7UC4-CzaQthG_.js → chunk-FMBD7UC4-q3UyRsNI.js} +2 -2
  79. package/dist/static/assets/{chunk-FMBD7UC4-CzaQthG_.js.map → chunk-FMBD7UC4-q3UyRsNI.js.map} +1 -1
  80. package/dist/static/assets/{chunk-QN33PNHL-8v7ASP75.js → chunk-QN33PNHL-BxUlvLXP.js} +2 -2
  81. package/dist/static/assets/{chunk-QN33PNHL-8v7ASP75.js.map → chunk-QN33PNHL-BxUlvLXP.js.map} +1 -1
  82. package/dist/static/assets/{chunk-QZHKN3VN-Cd3_mr-D.js → chunk-QZHKN3VN-DpQR9BVw.js} +2 -2
  83. package/dist/static/assets/{chunk-QZHKN3VN-Cd3_mr-D.js.map → chunk-QZHKN3VN-DpQR9BVw.js.map} +1 -1
  84. package/dist/static/assets/{chunk-TZMSLE5B-BrTyfkJK.js → chunk-TZMSLE5B-BX8vrVo0.js} +2 -2
  85. package/dist/static/assets/{chunk-TZMSLE5B-BrTyfkJK.js.map → chunk-TZMSLE5B-BX8vrVo0.js.map} +1 -1
  86. package/dist/static/assets/{classDiagram-2ON5EDUG-pLBmQ3Qa.js → classDiagram-2ON5EDUG-Ccx5_2Xq.js} +6 -6
  87. package/dist/static/assets/{classDiagram-2ON5EDUG-pLBmQ3Qa.js.map → classDiagram-2ON5EDUG-Ccx5_2Xq.js.map} +1 -1
  88. package/dist/static/assets/{classDiagram-v2-WZHVMYZB-pLBmQ3Qa.js → classDiagram-v2-WZHVMYZB-Ccx5_2Xq.js} +6 -6
  89. package/dist/static/assets/{classDiagram-v2-WZHVMYZB-pLBmQ3Qa.js.map → classDiagram-v2-WZHVMYZB-Ccx5_2Xq.js.map} +1 -1
  90. package/dist/static/assets/{clone-rjxmrDHc.js → clone-Cl5zSMrO.js} +2 -2
  91. package/dist/static/assets/{clone-rjxmrDHc.js.map → clone-Cl5zSMrO.js.map} +1 -1
  92. package/dist/static/assets/{cose-bilkent-S5V4N54A-DaW3q2vS.js → cose-bilkent-S5V4N54A-B-FUX86B.js} +2 -2
  93. package/dist/static/assets/{cose-bilkent-S5V4N54A-DaW3q2vS.js.map → cose-bilkent-S5V4N54A-B-FUX86B.js.map} +1 -1
  94. package/dist/static/assets/{dagre-6UL2VRFP-BT252775.js → dagre-6UL2VRFP-Bj8vSSpT.js} +7 -7
  95. package/dist/static/assets/{dagre-6UL2VRFP-BT252775.js.map → dagre-6UL2VRFP-Bj8vSSpT.js.map} +1 -1
  96. package/dist/static/assets/{diagram-PSM6KHXK-Cp0jEYgm.js → diagram-PSM6KHXK-BPcgy7jf.js} +7 -7
  97. package/dist/static/assets/{diagram-PSM6KHXK-Cp0jEYgm.js.map → diagram-PSM6KHXK-BPcgy7jf.js.map} +1 -1
  98. package/dist/static/assets/{diagram-QEK2KX5R-BYEiCch_.js → diagram-QEK2KX5R-DHxd6LWi.js} +6 -6
  99. package/dist/static/assets/{diagram-QEK2KX5R-BYEiCch_.js.map → diagram-QEK2KX5R-DHxd6LWi.js.map} +1 -1
  100. package/dist/static/assets/{diagram-S2PKOQOG-SNGZ1B53.js → diagram-S2PKOQOG-C4ynhhLr.js} +6 -6
  101. package/dist/static/assets/{diagram-S2PKOQOG-SNGZ1B53.js.map → diagram-S2PKOQOG-C4ynhhLr.js.map} +1 -1
  102. package/dist/static/assets/{erDiagram-Q2GNP2WA-CMdkkngT.js → erDiagram-Q2GNP2WA-CQ25uxxf.js} +5 -5
  103. package/dist/static/assets/{erDiagram-Q2GNP2WA-CMdkkngT.js.map → erDiagram-Q2GNP2WA-CQ25uxxf.js.map} +1 -1
  104. package/dist/static/assets/{flowDiagram-NV44I4VS-k203P84f.js → flowDiagram-NV44I4VS-ChkkAldk.js} +6 -6
  105. package/dist/static/assets/{flowDiagram-NV44I4VS-k203P84f.js.map → flowDiagram-NV44I4VS-ChkkAldk.js.map} +1 -1
  106. package/dist/static/assets/{ganttDiagram-JELNMOA3-CgsVe01-.js → ganttDiagram-JELNMOA3-CBt_Zorl.js} +3 -3
  107. package/dist/static/assets/{ganttDiagram-JELNMOA3-CgsVe01-.js.map → ganttDiagram-JELNMOA3-CBt_Zorl.js.map} +1 -1
  108. package/dist/static/assets/{gitGraphDiagram-NY62KEGX-BGOR_N5w.js → gitGraphDiagram-NY62KEGX-CtBc2dOO.js} +7 -7
  109. package/dist/static/assets/{gitGraphDiagram-NY62KEGX-BGOR_N5w.js.map → gitGraphDiagram-NY62KEGX-CtBc2dOO.js.map} +1 -1
  110. package/dist/static/assets/{graph-DDHIhCSW.js → graph-BGzNnzuI.js} +3 -3
  111. package/dist/static/assets/{graph-DDHIhCSW.js.map → graph-BGzNnzuI.js.map} +1 -1
  112. package/dist/static/assets/{index-CUZD-Ua6.js → index-Vrp1PT3b.js} +654 -355
  113. package/dist/static/assets/index-Vrp1PT3b.js.map +1 -0
  114. package/dist/static/assets/{infoDiagram-WHAUD3N6-D0GlWUIm.js → infoDiagram-WHAUD3N6-BYJF-Ol5.js} +5 -5
  115. package/dist/static/assets/{infoDiagram-WHAUD3N6-D0GlWUIm.js.map → infoDiagram-WHAUD3N6-BYJF-Ol5.js.map} +1 -1
  116. package/dist/static/assets/{journeyDiagram-XKPGCS4Q-I0W1fDTZ.js → journeyDiagram-XKPGCS4Q-Cl2p8ZBw.js} +5 -5
  117. package/dist/static/assets/{journeyDiagram-XKPGCS4Q-I0W1fDTZ.js.map → journeyDiagram-XKPGCS4Q-Cl2p8ZBw.js.map} +1 -1
  118. package/dist/static/assets/{kanban-definition-3W4ZIXB7-BY5xVZyl.js → kanban-definition-3W4ZIXB7-DBH-HEwY.js} +3 -3
  119. package/dist/static/assets/{kanban-definition-3W4ZIXB7-BY5xVZyl.js.map → kanban-definition-3W4ZIXB7-DBH-HEwY.js.map} +1 -1
  120. package/dist/static/assets/{layout-C7mFT1m6.js → layout-DdWO-uEo.js} +5 -5
  121. package/dist/static/assets/{layout-C7mFT1m6.js.map → layout-DdWO-uEo.js.map} +1 -1
  122. package/dist/static/assets/{linear-WSX0brRY.js → linear-BY3MovaF.js} +2 -2
  123. package/dist/static/assets/{linear-WSX0brRY.js.map → linear-BY3MovaF.js.map} +1 -1
  124. package/dist/static/assets/{min-DOTQTP4p.js → min-aHCJK1uN.js} +3 -3
  125. package/dist/static/assets/{min-DOTQTP4p.js.map → min-aHCJK1uN.js.map} +1 -1
  126. package/dist/static/assets/{mindmap-definition-VGOIOE7T-BWhHo-Hq.js → mindmap-definition-VGOIOE7T-BjJnBRtB.js} +4 -4
  127. package/dist/static/assets/{mindmap-definition-VGOIOE7T-BWhHo-Hq.js.map → mindmap-definition-VGOIOE7T-BjJnBRtB.js.map} +1 -1
  128. package/dist/static/assets/{pieDiagram-ADFJNKIX-B91oxvos.js → pieDiagram-ADFJNKIX-xAcmdymv.js} +7 -7
  129. package/dist/static/assets/{pieDiagram-ADFJNKIX-B91oxvos.js.map → pieDiagram-ADFJNKIX-xAcmdymv.js.map} +1 -1
  130. package/dist/static/assets/{quadrantDiagram-AYHSOK5B-DqMUyBPr.js → quadrantDiagram-AYHSOK5B-BPbEGCEj.js} +3 -3
  131. package/dist/static/assets/{quadrantDiagram-AYHSOK5B-DqMUyBPr.js.map → quadrantDiagram-AYHSOK5B-BPbEGCEj.js.map} +1 -1
  132. package/dist/static/assets/{requirementDiagram-UZGBJVZJ-COUayA3m.js → requirementDiagram-UZGBJVZJ--w6UfXy0.js} +4 -4
  133. package/dist/static/assets/{requirementDiagram-UZGBJVZJ-COUayA3m.js.map → requirementDiagram-UZGBJVZJ--w6UfXy0.js.map} +1 -1
  134. package/dist/static/assets/{sankeyDiagram-TZEHDZUN-Bp9r8YDi.js → sankeyDiagram-TZEHDZUN-B_T6TQwh.js} +2 -2
  135. package/dist/static/assets/{sankeyDiagram-TZEHDZUN-Bp9r8YDi.js.map → sankeyDiagram-TZEHDZUN-B_T6TQwh.js.map} +1 -1
  136. package/dist/static/assets/{sequenceDiagram-WL72ISMW-CpuTC5cG.js → sequenceDiagram-WL72ISMW-DX_oVvqA.js} +4 -4
  137. package/dist/static/assets/{sequenceDiagram-WL72ISMW-CpuTC5cG.js.map → sequenceDiagram-WL72ISMW-DX_oVvqA.js.map} +1 -1
  138. package/dist/static/assets/{stateDiagram-FKZM4ZOC-Bxoo7e6E.js → stateDiagram-FKZM4ZOC-BAybZU8l.js} +9 -9
  139. package/dist/static/assets/{stateDiagram-FKZM4ZOC-Bxoo7e6E.js.map → stateDiagram-FKZM4ZOC-BAybZU8l.js.map} +1 -1
  140. package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-Q-DL7tae.js → stateDiagram-v2-4FDKWEC3-BUsvuCdD.js} +5 -5
  141. package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-Q-DL7tae.js.map → stateDiagram-v2-4FDKWEC3-BUsvuCdD.js.map} +1 -1
  142. package/dist/static/assets/{timeline-definition-IT6M3QCI-DuOiHQPk.js → timeline-definition-IT6M3QCI-DOYN-4XM.js} +3 -3
  143. package/dist/static/assets/{timeline-definition-IT6M3QCI-DuOiHQPk.js.map → timeline-definition-IT6M3QCI-DOYN-4XM.js.map} +1 -1
  144. package/dist/static/assets/{treemap-KMMF4GRG-YbrDC0fO.js → treemap-KMMF4GRG-CQXygT0T.js} +4 -4
  145. package/dist/static/assets/{treemap-KMMF4GRG-YbrDC0fO.js.map → treemap-KMMF4GRG-CQXygT0T.js.map} +1 -1
  146. package/dist/static/assets/{xychartDiagram-PRI3JC2R-DDRlTIfV.js → xychartDiagram-PRI3JC2R-ByFAvTeN.js} +3 -3
  147. package/dist/static/assets/{xychartDiagram-PRI3JC2R-DDRlTIfV.js.map → xychartDiagram-PRI3JC2R-ByFAvTeN.js.map} +1 -1
  148. package/dist/static/index.html +1 -1
  149. package/dist/tools/builtins.js +0 -8
  150. package/dist/tools/env.js +1 -1
  151. package/dist/tools/mcp.js +31 -9
  152. package/dist/tools/pending-tellask-reminder.js +14 -17
  153. package/dist/tools/team-mgmt.js +1 -1
  154. package/package.json +1 -1
  155. package/dist/static/assets/index-CUZD-Ua6.js.map +0 -1
@@ -61,30 +61,6 @@ function getErrorCode(error) {
61
61
  function isRecord(value) {
62
62
  return typeof value === 'object' && value !== null;
63
63
  }
64
- function isAssignmentFromSup(value) {
65
- if (!isRecord(value))
66
- return false;
67
- if (typeof value.tellaskHead !== 'string')
68
- return false;
69
- if (typeof value.tellaskBody !== 'string')
70
- return false;
71
- if (typeof value.originMemberId !== 'string')
72
- return false;
73
- if (typeof value.callerDialogId !== 'string')
74
- return false;
75
- if (typeof value.callId !== 'string')
76
- return false;
77
- if ('collectiveTargets' in value) {
78
- const collectiveTargets = value.collectiveTargets;
79
- if (collectiveTargets === undefined)
80
- return true;
81
- if (!Array.isArray(collectiveTargets))
82
- return false;
83
- if (!collectiveTargets.every((item) => typeof item === 'string'))
84
- return false;
85
- }
86
- return true;
87
- }
88
64
  function isRootDialogMetadataFile(value) {
89
65
  if (!isRecord(value))
90
66
  return false;
@@ -104,7 +80,7 @@ function isRootDialogMetadataFile(value) {
104
80
  }
105
81
  if (value.supdialogId !== undefined)
106
82
  return false;
107
- if (value.tellaskSession !== undefined)
83
+ if (value.sessionSlug !== undefined)
108
84
  return false;
109
85
  if (value.assignmentFromSup !== undefined)
110
86
  return false;
@@ -123,10 +99,44 @@ function isSubdialogMetadataFile(value) {
123
99
  return false;
124
100
  if (typeof value.supdialogId !== 'string')
125
101
  return false;
126
- if (value.tellaskSession !== undefined && typeof value.tellaskSession !== 'string')
102
+ if (value.sessionSlug !== undefined && typeof value.sessionSlug !== 'string')
103
+ return false;
104
+ const assignment = value.assignmentFromSup;
105
+ if (!isRecord(assignment))
106
+ return false;
107
+ if (typeof assignment.tellaskContent !== 'string')
127
108
  return false;
128
- if (!isAssignmentFromSup(value.assignmentFromSup))
109
+ if (typeof assignment.originMemberId !== 'string')
129
110
  return false;
111
+ if (typeof assignment.callerDialogId !== 'string')
112
+ return false;
113
+ if (typeof assignment.callId !== 'string')
114
+ return false;
115
+ if (assignment.collectiveTargets !== undefined) {
116
+ if (!Array.isArray(assignment.collectiveTargets))
117
+ return false;
118
+ if (!assignment.collectiveTargets.every((item) => typeof item === 'string'))
119
+ return false;
120
+ }
121
+ switch (assignment.callName) {
122
+ case 'tellask':
123
+ case 'tellaskSessionless': {
124
+ if (!Array.isArray(assignment.mentionList))
125
+ return false;
126
+ if (assignment.mentionList.length < 1)
127
+ return false;
128
+ if (!assignment.mentionList.every((item) => typeof item === 'string'))
129
+ return false;
130
+ break;
131
+ }
132
+ case 'freshBootsReasoning': {
133
+ if (assignment.mentionList !== undefined)
134
+ return false;
135
+ break;
136
+ }
137
+ default:
138
+ return false;
139
+ }
130
140
  return true;
131
141
  }
132
142
  function isDialogMetadataFile(value) {
@@ -268,7 +278,29 @@ function isSubdialogResponseRecord(value) {
268
278
  return false;
269
279
  if (value.callType !== 'A' && value.callType !== 'B' && value.callType !== 'C')
270
280
  return false;
271
- if (typeof value.tellaskHead !== 'string')
281
+ if (value.callName !== 'tellaskBack' &&
282
+ value.callName !== 'tellask' &&
283
+ value.callName !== 'tellaskSessionless' &&
284
+ value.callName !== 'freshBootsReasoning') {
285
+ return false;
286
+ }
287
+ switch (value.callName) {
288
+ case 'tellask':
289
+ case 'tellaskSessionless':
290
+ if (!Array.isArray(value.mentionList))
291
+ return false;
292
+ if (!value.mentionList.every((item) => typeof item === 'string'))
293
+ return false;
294
+ if (value.mentionList.length < 1)
295
+ return false;
296
+ break;
297
+ case 'tellaskBack':
298
+ case 'freshBootsReasoning':
299
+ if (value.mentionList !== undefined)
300
+ return false;
301
+ break;
302
+ }
303
+ if (typeof value.tellaskContent !== 'string')
272
304
  return false;
273
305
  if (typeof value.responderId !== 'string')
274
306
  return false;
@@ -279,8 +311,95 @@ function isSubdialogResponseRecord(value) {
279
311
  return true;
280
312
  }
281
313
  // Remove old type definitions - now using shared/types/storage.ts
282
- const tellask_1 = require("./tellask");
283
314
  const id_1 = require("./utils/id");
315
+ const TELLASK_SPECIAL_FUNCTION_NAMES = new Set([
316
+ 'tellaskBack',
317
+ 'tellask',
318
+ 'tellaskSessionless',
319
+ 'askHuman',
320
+ 'freshBootsReasoning',
321
+ ]);
322
+ function isTellaskSpecialFunctionName(name) {
323
+ return TELLASK_SPECIAL_FUNCTION_NAMES.has(name);
324
+ }
325
+ function readRequiredStringArgument(args, field) {
326
+ const value = args[field];
327
+ if (typeof value !== 'string') {
328
+ return null;
329
+ }
330
+ const trimmed = value.trim();
331
+ return trimmed === '' ? null : trimmed;
332
+ }
333
+ function readOptionalStringArgument(args, field) {
334
+ const value = args[field];
335
+ if (value === undefined) {
336
+ return null;
337
+ }
338
+ if (typeof value !== 'string') {
339
+ return null;
340
+ }
341
+ const trimmed = value.trim();
342
+ return trimmed === '' ? null : trimmed;
343
+ }
344
+ function parseReplayTellaskSpecialCall(record) {
345
+ if (!isTellaskSpecialFunctionName(record.name)) {
346
+ return null;
347
+ }
348
+ const tellaskContent = readRequiredStringArgument(record.arguments, 'tellaskContent');
349
+ if (!tellaskContent) {
350
+ return null;
351
+ }
352
+ switch (record.name) {
353
+ case 'tellaskBack': {
354
+ return {
355
+ callName: 'tellaskBack',
356
+ tellaskContent,
357
+ callId: record.id,
358
+ };
359
+ }
360
+ case 'askHuman': {
361
+ return {
362
+ callName: 'askHuman',
363
+ tellaskContent,
364
+ callId: record.id,
365
+ };
366
+ }
367
+ case 'freshBootsReasoning': {
368
+ return {
369
+ callName: 'freshBootsReasoning',
370
+ tellaskContent,
371
+ callId: record.id,
372
+ };
373
+ }
374
+ case 'tellask': {
375
+ const targetAgentId = readRequiredStringArgument(record.arguments, 'targetAgentId');
376
+ const sessionSlug = readRequiredStringArgument(record.arguments, 'sessionSlug');
377
+ if (!targetAgentId || !sessionSlug) {
378
+ return null;
379
+ }
380
+ return {
381
+ callName: 'tellask',
382
+ mentionList: [`@${targetAgentId}`],
383
+ tellaskContent,
384
+ callId: record.id,
385
+ };
386
+ }
387
+ case 'tellaskSessionless': {
388
+ const targetAgentId = readRequiredStringArgument(record.arguments, 'targetAgentId');
389
+ if (!targetAgentId) {
390
+ return null;
391
+ }
392
+ return {
393
+ callName: 'tellaskSessionless',
394
+ mentionList: [`@${targetAgentId}`],
395
+ tellaskContent,
396
+ callId: record.id,
397
+ };
398
+ }
399
+ default:
400
+ return null;
401
+ }
402
+ }
284
403
  /**
285
404
  * Uses append-only pattern for events, exceptional overwrite for reminders
286
405
  */
@@ -296,7 +415,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
296
415
  /**
297
416
  * Create subdialog with automatic persistence
298
417
  */
299
- async createSubDialog(supdialog, targetAgentId, tellaskHead, tellaskBody, options) {
418
+ async createSubDialog(supdialog, targetAgentId, mentionList, tellaskContent, options) {
300
419
  const generatedId = (0, id_1.generateDialogID)();
301
420
  const nowTs = (0, time_1.formatUnifiedTimestamp)(new Date());
302
421
  // For subdialogs, use the supdialog's root dialog ID as the root
@@ -304,12 +423,14 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
304
423
  // Prepare subdialog store
305
424
  const subdialogStore = new DiskFileDialogStore(subdialogId);
306
425
  const subdialog = new dialog_1.SubDialog(subdialogStore, supdialog, supdialog.taskDocPath, subdialogId, targetAgentId, {
307
- tellaskHead,
308
- tellaskBody,
426
+ callName: options.callName,
427
+ mentionList,
428
+ tellaskContent,
309
429
  originMemberId: options.originMemberId,
310
430
  callerDialogId: options.callerDialogId,
311
431
  callId: options.callId,
312
- }, options.tellaskSession);
432
+ collectiveTargets: options.collectiveTargets,
433
+ }, options.sessionSlug);
313
434
  // Initial subdialog user prompt is now persisted at first drive (driver.ts)
314
435
  // Ensure subdialog directory and persist metadata under supdialog/.subdialogs/
315
436
  await this.ensureSubdialogDirectory(subdialogId);
@@ -319,13 +440,15 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
319
440
  taskDocPath: supdialog.taskDocPath,
320
441
  createdAt: nowTs,
321
442
  supdialogId: supdialog.id.selfId,
322
- tellaskSession: options.tellaskSession,
443
+ sessionSlug: options.sessionSlug,
323
444
  assignmentFromSup: {
324
- tellaskHead,
325
- tellaskBody,
445
+ callName: options.callName,
446
+ mentionList,
447
+ tellaskContent,
326
448
  originMemberId: options.originMemberId,
327
449
  callerDialogId: options.callerDialogId,
328
450
  callId: options.callId,
451
+ collectiveTargets: options.collectiveTargets,
329
452
  },
330
453
  };
331
454
  await DialogPersistence.saveSubdialogMetadata(subdialogId, metadata);
@@ -363,8 +486,9 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
363
486
  rootId: subdialogId.rootId,
364
487
  },
365
488
  targetAgentId,
366
- tellaskHead,
367
- tellaskBody,
489
+ callName: options.callName,
490
+ mentionList,
491
+ tellaskContent,
368
492
  subDialogNode: {
369
493
  selfId: subdialogId.selfId,
370
494
  rootId: subdialogId.rootId,
@@ -376,10 +500,11 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
376
500
  createdAt: nowTs,
377
501
  lastModified: nowTs,
378
502
  runState: { kind: 'idle_waiting_user' },
379
- tellaskSession: options.tellaskSession,
503
+ sessionSlug: options.sessionSlug,
380
504
  assignmentFromSup: {
381
- tellaskHead,
382
- tellaskBody,
505
+ callName: options.callName,
506
+ mentionList,
507
+ tellaskContent,
383
508
  originMemberId: options.originMemberId,
384
509
  callerDialogId: options.callerDialogId,
385
510
  callId: options.callId,
@@ -422,67 +547,113 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
422
547
  * Receive and handle tellask call results with callId for inline result display
423
548
  *
424
549
  * Call Types:
425
- * - Tellask Call (inline bubble): !?@<mention-id>
550
+ * - tellask-special function call (inline bubble)
426
551
  * - Result displays INLINE in the same bubble
427
552
  * - Uses callId for correlation between call_start and response
428
553
  * - Uses receiveTeammateCallResult() + callId parameter
429
554
  *
430
- * - Teammate Tellask: !?@agentName (e.g., !?@coder, !?@tester)
555
+ * - Teammate Tellask (subdialog response bubble)
431
556
  * - Result displays in SEPARATE bubble (subdialog response)
432
557
  * - Uses calleeDialogId for correlation
433
558
  * - Uses receiveTeammateResponse() instead
434
559
  *
435
560
  * @param dialog - The dialog receiving the response
436
561
  * @param responderId - ID of the tool/agent that responded (e.g., "add_reminder")
437
- * @param tellaskHead - Headline of the original call
562
+ * @param mentionList - Mention list of the original call
563
+ * @param tellaskContent - Tellask content of the original call
438
564
  * @param result - The result content to display
439
565
  * @param status - Response status ('completed' | 'failed')
440
566
  * @param callId - Correlation ID from call_start_evt (REQUIRED for inline display)
441
567
  */
442
- async receiveTeammateCallResult(dialog, responderId, tellaskHead, result, status, callId) {
568
+ async receiveTeammateCallResult(dialog, responderId, callName, mentionList, tellaskContent, result, status, callId) {
443
569
  const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
444
570
  const calling_genseq = dialog.activeGenSeqOrUndefined;
445
571
  // Persist record WITH callId for replay correlation
446
- const ev = {
447
- ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
448
- type: 'teammate_call_result_record',
449
- responderId,
450
- tellaskHead,
451
- status,
452
- result,
453
- calling_genseq,
454
- callId,
455
- };
572
+ const ev = (() => {
573
+ switch (callName) {
574
+ case 'tellask':
575
+ case 'tellaskSessionless':
576
+ return {
577
+ ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
578
+ type: 'teammate_call_result_record',
579
+ responderId,
580
+ callName,
581
+ mentionList: mentionList ?? [],
582
+ tellaskContent,
583
+ status,
584
+ result,
585
+ calling_genseq,
586
+ callId,
587
+ };
588
+ case 'tellaskBack':
589
+ case 'askHuman':
590
+ case 'freshBootsReasoning':
591
+ return {
592
+ ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
593
+ type: 'teammate_call_result_record',
594
+ responderId,
595
+ callName,
596
+ tellaskContent,
597
+ status,
598
+ result,
599
+ calling_genseq,
600
+ callId,
601
+ };
602
+ }
603
+ })();
456
604
  await this.appendEvent(course, ev);
457
605
  // Emit TeammateCallResponseEvent WITH callId for UI correlation
458
- const toolResponseEvt = {
459
- type: 'teammate_call_response_evt',
460
- responderId,
461
- tellaskHead,
462
- status,
463
- result,
464
- course,
465
- calling_genseq,
466
- callId,
467
- };
606
+ const toolResponseEvt = (() => {
607
+ switch (callName) {
608
+ case 'tellask':
609
+ case 'tellaskSessionless':
610
+ return {
611
+ type: 'teammate_call_response_evt',
612
+ responderId,
613
+ callName,
614
+ mentionList: mentionList ?? [],
615
+ tellaskContent,
616
+ status,
617
+ result,
618
+ course,
619
+ calling_genseq,
620
+ callId,
621
+ };
622
+ case 'tellaskBack':
623
+ case 'askHuman':
624
+ case 'freshBootsReasoning':
625
+ return {
626
+ type: 'teammate_call_response_evt',
627
+ responderId,
628
+ callName,
629
+ tellaskContent,
630
+ status,
631
+ result,
632
+ course,
633
+ calling_genseq,
634
+ callId,
635
+ };
636
+ }
637
+ })();
468
638
  (0, evt_registry_1.postDialogEvent)(dialog, toolResponseEvt);
469
639
  }
470
640
  /**
471
- * Receive and handle TEAMMATE TELLASK responses (separate bubble for @agentName tellasks)
641
+ * Receive and handle TEAMMATE TELLASK responses (separate bubble for subdialog/supdialog replies)
472
642
  *
473
643
  * Call Types:
474
- * - Teammate Tellask: !?@agentName (e.g., !?@coder, !?@tester)
644
+ * - Teammate Tellask response
475
645
  * - Result displays in SEPARATE bubble (subdialog or supdialog response)
476
646
  * - Uses calleeDialogId for correlation (not callId)
477
647
  * - Uses this method (receiveTeammateResponse)
478
648
  *
479
649
  * @param dialog - The dialog receiving the response
480
650
  * @param responderId - ID of the teammate agent (e.g., "coder")
481
- * @param tellaskHead - Headline of the original teammate tellask
651
+ * @param mentionList - Mention list of the original teammate tellask
652
+ * @param tellaskContent - Tellask content of the original teammate tellask
482
653
  * @param status - Response status ('completed' | 'failed')
483
654
  * @param calleeDialogId - ID of the callee dialog (subdialog OR supdialog) for navigation links
484
655
  */
485
- async receiveTeammateResponse(dialog, responderId, tellaskHead, status, calleeDialogId, options) {
656
+ async receiveTeammateResponse(dialog, responderId, callName, mentionList, tellaskContent, status, calleeDialogId, options) {
486
657
  const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
487
658
  const calling_genseq = dialog.activeGenSeqOrUndefined;
488
659
  const calleeDialogSelfId = calleeDialogId ? calleeDialogId.selfId : undefined;
@@ -490,42 +661,105 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
490
661
  const agentId = options.agentId;
491
662
  const callId = options.callId;
492
663
  const originMemberId = options.originMemberId;
664
+ const calleeCourse = options.calleeCourse;
665
+ const calleeGenseq = options.calleeGenseq;
666
+ const normalizedMentionList = mentionList ?? [];
493
667
  const result = (0, inter_dialog_format_1.formatTeammateResponseContent)({
668
+ callName,
494
669
  responderId,
495
670
  requesterId: originMemberId,
496
- originalCallHeadLine: tellaskHead,
671
+ mentionList: normalizedMentionList,
672
+ tellaskContent,
497
673
  responseBody: response,
498
674
  language: (0, runtime_language_1.getWorkLanguage)(),
499
675
  });
500
- const ev = {
501
- ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
502
- type: 'teammate_response_record',
503
- responderId,
504
- calleeDialogId: calleeDialogSelfId,
505
- tellaskHead,
506
- status,
507
- result,
508
- calling_genseq,
509
- response,
510
- agentId,
511
- callId,
512
- originMemberId,
513
- };
676
+ const ev = (() => {
677
+ switch (callName) {
678
+ case 'tellask':
679
+ case 'tellaskSessionless':
680
+ return {
681
+ ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
682
+ type: 'teammate_response_record',
683
+ responderId,
684
+ callName,
685
+ calleeDialogId: calleeDialogSelfId,
686
+ calleeCourse,
687
+ calleeGenseq,
688
+ mentionList: normalizedMentionList,
689
+ tellaskContent,
690
+ status,
691
+ result,
692
+ calling_genseq,
693
+ response,
694
+ agentId,
695
+ callId,
696
+ originMemberId,
697
+ };
698
+ case 'tellaskBack':
699
+ case 'freshBootsReasoning':
700
+ return {
701
+ ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
702
+ type: 'teammate_response_record',
703
+ responderId,
704
+ callName,
705
+ calleeDialogId: calleeDialogSelfId,
706
+ calleeCourse,
707
+ calleeGenseq,
708
+ tellaskContent,
709
+ status,
710
+ result,
711
+ calling_genseq,
712
+ response,
713
+ agentId,
714
+ callId,
715
+ originMemberId,
716
+ };
717
+ }
718
+ })();
514
719
  await this.appendEvent(course, ev);
515
- const teammateResponseEvt = {
516
- type: 'teammate_response_evt',
517
- responderId,
518
- calleeDialogId: calleeDialogSelfId,
519
- tellaskHead,
520
- status,
521
- result,
522
- course,
523
- calling_genseq,
524
- response,
525
- agentId,
526
- callId,
527
- originMemberId,
528
- };
720
+ const teammateResponseEvt = (() => {
721
+ switch (callName) {
722
+ case 'tellask':
723
+ case 'tellaskSessionless':
724
+ return {
725
+ type: 'teammate_response_evt',
726
+ responderId,
727
+ callName,
728
+ calleeDialogId: calleeDialogSelfId,
729
+ calleeCourse,
730
+ calleeGenseq,
731
+ mentionList: normalizedMentionList,
732
+ tellaskContent,
733
+ status,
734
+ result,
735
+ course,
736
+ calling_genseq,
737
+ response,
738
+ agentId,
739
+ callId,
740
+ originMemberId,
741
+ };
742
+ case 'tellaskBack':
743
+ case 'freshBootsReasoning':
744
+ return {
745
+ type: 'teammate_response_evt',
746
+ responderId,
747
+ callName,
748
+ calleeDialogId: calleeDialogSelfId,
749
+ calleeCourse,
750
+ calleeGenseq,
751
+ tellaskContent,
752
+ status,
753
+ result,
754
+ course,
755
+ calling_genseq,
756
+ response,
757
+ agentId,
758
+ callId,
759
+ originMemberId,
760
+ };
761
+ }
762
+ })();
529
763
  (0, evt_registry_1.postDialogEvent)(dialog, teammateResponseEvt);
530
764
  }
531
765
  /**
@@ -713,72 +947,35 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
713
947
  };
714
948
  (0, evt_registry_1.postDialogEvent)(dialog, evt);
715
949
  }
716
- // Tellask call streaming methods
717
- async callingStart(dialog, validation) {
718
- const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
719
- const evt = {
720
- type: 'teammate_call_start_evt',
721
- validation,
722
- course,
723
- genseq: dialog.activeGenSeq,
724
- };
725
- (0, evt_registry_1.postDialogEvent)(dialog, evt);
726
- }
727
- async callingHeadlineChunk(dialog, chunk) {
950
+ // Tellask-special call lifecycle methods
951
+ async callingStart(dialog, payload) {
728
952
  const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
729
- const evt = {
730
- type: 'teammate_call_headline_chunk_evt',
731
- chunk,
732
- course,
733
- genseq: dialog.activeGenSeq,
734
- };
735
- (0, evt_registry_1.postDialogEvent)(dialog, evt);
736
- }
737
- async callingHeadlineFinish(dialog) {
738
- const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
739
- const evt = {
740
- type: 'teammate_call_headline_finish_evt',
741
- course,
742
- genseq: dialog.activeGenSeq,
743
- };
744
- (0, evt_registry_1.postDialogEvent)(dialog, evt);
745
- }
746
- async callingBodyStart(dialog) {
747
- const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
748
- const evt = {
749
- type: 'teammate_call_body_start_evt',
750
- course,
751
- genseq: dialog.activeGenSeq,
752
- };
753
- (0, evt_registry_1.postDialogEvent)(dialog, evt);
754
- }
755
- async callingBodyChunk(dialog, chunk) {
756
- const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
757
- const evt = {
758
- type: 'teammate_call_body_chunk_evt',
759
- chunk,
760
- course,
761
- genseq: dialog.activeGenSeq,
762
- };
763
- (0, evt_registry_1.postDialogEvent)(dialog, evt);
764
- }
765
- async callingBodyFinish(dialog) {
766
- const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
767
- const evt = {
768
- type: 'teammate_call_body_finish_evt',
769
- course,
770
- genseq: dialog.activeGenSeq,
771
- };
772
- (0, evt_registry_1.postDialogEvent)(dialog, evt);
773
- }
774
- async callingFinish(dialog, callId) {
775
- const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
776
- const evt = {
777
- type: 'teammate_call_finish_evt',
778
- callId,
779
- course,
780
- genseq: dialog.activeGenSeq,
781
- };
953
+ const evt = (() => {
954
+ switch (payload.callName) {
955
+ case 'tellask':
956
+ case 'tellaskSessionless':
957
+ return {
958
+ type: 'teammate_call_start_evt',
959
+ callName: payload.callName,
960
+ callId: payload.callId,
961
+ mentionList: payload.mentionList ?? [],
962
+ tellaskContent: payload.tellaskContent,
963
+ course,
964
+ genseq: dialog.activeGenSeq,
965
+ };
966
+ case 'tellaskBack':
967
+ case 'askHuman':
968
+ case 'freshBootsReasoning':
969
+ return {
970
+ type: 'teammate_call_start_evt',
971
+ callName: payload.callName,
972
+ callId: payload.callId,
973
+ tellaskContent: payload.tellaskContent,
974
+ course,
975
+ genseq: dialog.activeGenSeq,
976
+ };
977
+ }
978
+ })();
782
979
  (0, evt_registry_1.postDialogEvent)(dialog, evt);
783
980
  }
784
981
  // Function call events (non-streaming mode - single event captures entire call)
@@ -951,10 +1148,13 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
951
1148
  return records.map((record) => ({
952
1149
  subdialogId: new dialog_1.DialogID(record.subdialogId, rootDialogId.rootId),
953
1150
  createdAt: record.createdAt,
954
- tellaskHead: record.tellaskHead,
1151
+ mentionList: record.mentionList,
1152
+ tellaskContent: record.tellaskContent,
955
1153
  targetAgentId: record.targetAgentId,
1154
+ callId: record.callId,
1155
+ callingCourse: record.callingCourse,
956
1156
  callType: record.callType,
957
- tellaskSession: record.tellaskSession,
1157
+ sessionSlug: record.sessionSlug,
958
1158
  }));
959
1159
  }
960
1160
  async saveSubdialogRegistry(rootDialogId, entries, status) {
@@ -1035,7 +1235,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1035
1235
  }
1036
1236
  }
1037
1237
  const subdialogStore = new DiskFileDialogStore(subdialogId);
1038
- const subdialog = new dialog_1.SubDialog(subdialogStore, rootDialog, metadata.taskDocPath, new dialog_1.DialogID(subdialogId.selfId, rootDialog.id.rootId), metadata.agentId, assignmentFromSup, metadata.tellaskSession, {
1238
+ const subdialog = new dialog_1.SubDialog(subdialogStore, rootDialog, metadata.taskDocPath, new dialog_1.DialogID(subdialogId.selfId, rootDialog.id.rootId), metadata.agentId, assignmentFromSup, metadata.sessionSlug, {
1039
1239
  messages: subdialogState.messages,
1040
1240
  reminders: subdialogState.reminders,
1041
1241
  currentCourse: subdialogState.currentCourse,
@@ -1043,7 +1243,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1043
1243
  });
1044
1244
  const latest = await DialogPersistence.loadDialogLatest(subdialogId, status);
1045
1245
  subdialog.disableDiligencePush = latest?.disableDiligencePush ?? false;
1046
- if (subdialog.tellaskSession) {
1246
+ if (subdialog.sessionSlug) {
1047
1247
  rootDialog.registerSubdialog(subdialog);
1048
1248
  }
1049
1249
  return subdialog;
@@ -1057,32 +1257,32 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1057
1257
  }
1058
1258
  };
1059
1259
  for (const entry of entries) {
1060
- if (!entry.tellaskSession)
1260
+ if (!entry.sessionSlug)
1061
1261
  continue;
1062
1262
  if (shouldPruneDead) {
1063
1263
  const latest = await DialogPersistence.loadDialogLatest(entry.subdialogId, status);
1064
1264
  const runState = latest?.runState;
1065
1265
  if (runState && runState.kind === 'dead') {
1066
1266
  prunedDeadRegistryEntries = true;
1067
- rootDialog.unregisterSubdialog(entry.agentId, entry.tellaskSession);
1068
- log_1.log.info('Skip dead subdialog while loading Type B registry', undefined, {
1267
+ rootDialog.unregisterSubdialog(entry.agentId, entry.sessionSlug);
1268
+ log_1.log.debug('Skip dead subdialog while loading Type B registry', undefined, {
1069
1269
  rootId: rootDialog.id.rootId,
1070
1270
  subdialogId: entry.subdialogId.selfId,
1071
1271
  agentId: entry.agentId,
1072
- tellaskSession: entry.tellaskSession,
1272
+ sessionSlug: entry.sessionSlug,
1073
1273
  });
1074
1274
  continue;
1075
1275
  }
1076
1276
  }
1077
1277
  const subdialog = await ensureSubdialogLoaded(entry.subdialogId);
1078
- if (!subdialog.tellaskSession) {
1079
- throw new Error(`Subdialog registry invariant violation: missing tellaskSession on loaded subdialog ` +
1080
- `(rootId=${rootDialog.id.rootId}, selfId=${entry.subdialogId.selfId}, expectedTellaskSession=${entry.tellaskSession})`);
1278
+ if (!subdialog.sessionSlug) {
1279
+ throw new Error(`Subdialog registry invariant violation: missing sessionSlug on loaded subdialog ` +
1280
+ `(rootId=${rootDialog.id.rootId}, selfId=${entry.subdialogId.selfId}, expectedSessionSlug=${entry.sessionSlug})`);
1081
1281
  }
1082
- if (subdialog.tellaskSession !== entry.tellaskSession) {
1083
- throw new Error(`Subdialog registry invariant violation: tellaskSession mismatch ` +
1282
+ if (subdialog.sessionSlug !== entry.sessionSlug) {
1283
+ throw new Error(`Subdialog registry invariant violation: sessionSlug mismatch ` +
1084
1284
  `(rootId=${rootDialog.id.rootId}, selfId=${entry.subdialogId.selfId}, ` +
1085
- `expected=${entry.tellaskSession}, actual=${subdialog.tellaskSession})`);
1285
+ `expected=${entry.sessionSlug}, actual=${subdialog.sessionSlug})`);
1086
1286
  }
1087
1287
  if (subdialog.agentId !== entry.agentId) {
1088
1288
  throw new Error(`Subdialog registry invariant violation: agentId mismatch ` +
@@ -1185,157 +1385,32 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1185
1385
  case 'human_text_record': {
1186
1386
  const genseq = event.genseq;
1187
1387
  const content = event.content || '';
1188
- const grammar = event.grammar ?? 'tellask';
1388
+ const grammar = 'markdown';
1189
1389
  const userLanguageCode = event.userLanguageCode;
1190
1390
  if (content) {
1191
- if (grammar === 'tellask') {
1192
- const receiver = {
1193
- markdownStart: async () => {
1194
- if (ws.readyState === 1) {
1195
- ws.send(JSON.stringify({
1196
- type: 'markdown_start_evt',
1197
- course,
1198
- genseq,
1199
- dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1200
- timestamp: event.ts,
1201
- }));
1202
- }
1203
- },
1204
- markdownChunk: async (chunk) => {
1205
- if (ws.readyState === 1) {
1206
- ws.send(JSON.stringify({
1207
- type: 'markdown_chunk_evt',
1208
- chunk,
1209
- course,
1210
- genseq,
1211
- dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1212
- timestamp: event.ts,
1213
- }));
1214
- }
1215
- },
1216
- markdownFinish: async () => {
1217
- if (ws.readyState === 1) {
1218
- ws.send(JSON.stringify({
1219
- type: 'markdown_finish_evt',
1220
- course,
1221
- genseq,
1222
- dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1223
- timestamp: event.ts,
1224
- }));
1225
- }
1226
- },
1227
- callStart: async (validation) => {
1228
- if (ws.readyState === 1) {
1229
- ws.send(JSON.stringify({
1230
- type: 'teammate_call_start_evt',
1231
- validation,
1232
- course,
1233
- genseq,
1234
- dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1235
- timestamp: event.ts,
1236
- }));
1237
- }
1238
- },
1239
- callHeadLineChunk: async (chunk) => {
1240
- if (ws.readyState === 1) {
1241
- ws.send(JSON.stringify({
1242
- type: 'teammate_call_headline_chunk_evt',
1243
- chunk,
1244
- course,
1245
- genseq,
1246
- dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1247
- timestamp: event.ts,
1248
- }));
1249
- }
1250
- },
1251
- callHeadLineFinish: async () => {
1252
- if (ws.readyState === 1) {
1253
- ws.send(JSON.stringify({
1254
- type: 'teammate_call_headline_finish_evt',
1255
- course,
1256
- genseq,
1257
- dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1258
- timestamp: event.ts,
1259
- }));
1260
- }
1261
- },
1262
- tellaskBodyStart: async () => {
1263
- if (ws.readyState === 1) {
1264
- ws.send(JSON.stringify({
1265
- type: 'teammate_call_body_start_evt',
1266
- course,
1267
- genseq,
1268
- dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1269
- timestamp: event.ts,
1270
- }));
1271
- }
1272
- },
1273
- tellaskBodyChunk: async (chunk) => {
1274
- if (ws.readyState === 1) {
1275
- ws.send(JSON.stringify({
1276
- type: 'teammate_call_body_chunk_evt',
1277
- chunk,
1278
- course,
1279
- genseq,
1280
- dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1281
- timestamp: event.ts,
1282
- }));
1283
- }
1284
- },
1285
- tellaskBodyFinish: async () => {
1286
- if (ws.readyState === 1) {
1287
- ws.send(JSON.stringify({
1288
- type: 'teammate_call_body_finish_evt',
1289
- course,
1290
- genseq,
1291
- dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1292
- timestamp: event.ts,
1293
- }));
1294
- }
1295
- },
1296
- callFinish: async (call) => {
1297
- if (ws.readyState === 1) {
1298
- ws.send(JSON.stringify({
1299
- type: 'teammate_call_finish_evt',
1300
- callId: call.callId,
1301
- course,
1302
- genseq,
1303
- dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1304
- timestamp: event.ts,
1305
- }));
1306
- }
1307
- },
1308
- };
1309
- // Parse user content through TellaskStreamParser (same as live mode)
1310
- const streamingParser = new tellask_1.TellaskStreamParser(receiver);
1311
- await streamingParser.takeUpstreamChunk(content);
1312
- await streamingParser.finalize();
1313
- }
1314
- else {
1315
- if (ws.readyState === 1) {
1316
- ws.send(JSON.stringify({
1317
- type: 'markdown_start_evt',
1318
- course,
1319
- genseq,
1320
- dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1321
- timestamp: event.ts,
1322
- }));
1323
- ws.send(JSON.stringify({
1324
- type: 'markdown_chunk_evt',
1325
- chunk: content,
1326
- course,
1327
- genseq,
1328
- dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1329
- timestamp: event.ts,
1330
- }));
1331
- ws.send(JSON.stringify({
1332
- type: 'markdown_finish_evt',
1333
- course,
1334
- genseq,
1335
- dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1336
- timestamp: event.ts,
1337
- }));
1338
- }
1391
+ if (ws.readyState === 1) {
1392
+ ws.send(JSON.stringify({
1393
+ type: 'markdown_start_evt',
1394
+ course,
1395
+ genseq,
1396
+ dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1397
+ timestamp: event.ts,
1398
+ }));
1399
+ ws.send(JSON.stringify({
1400
+ type: 'markdown_chunk_evt',
1401
+ chunk: content,
1402
+ course,
1403
+ genseq,
1404
+ dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1405
+ timestamp: event.ts,
1406
+ }));
1407
+ ws.send(JSON.stringify({
1408
+ type: 'markdown_finish_evt',
1409
+ course,
1410
+ genseq,
1411
+ dialog: { selfId: dialog.id.selfId, rootId: dialog.id.rootId },
1412
+ timestamp: event.ts,
1413
+ }));
1339
1414
  }
1340
1415
  }
1341
1416
  // Emit end_of_user_saying_evt to signal frontend to render <hr/> separator
@@ -1460,162 +1535,36 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1460
1535
  break;
1461
1536
  }
1462
1537
  case 'agent_words_record': {
1463
- // Replay assistant text using ad-hoc event receiver with closure-based WebSocket access
1464
1538
  const content = event.content || '';
1465
1539
  if (content) {
1466
- // Create ad-hoc receiver similar to driver pattern with closure-based WebSocket access
1467
- const receiver = {
1468
- markdownStart: async () => {
1469
- if (ws.readyState === 1) {
1470
- ws.send(JSON.stringify({
1471
- type: 'markdown_start_evt',
1472
- course,
1473
- genseq: event.genseq,
1474
- dialog: {
1475
- selfId: dialog.id.selfId,
1476
- rootId: dialog.id.rootId,
1477
- },
1478
- timestamp: event.ts,
1479
- }));
1480
- }
1481
- },
1482
- markdownChunk: async (chunk) => {
1483
- if (ws.readyState === 1) {
1484
- ws.send(JSON.stringify({
1485
- type: 'markdown_chunk_evt',
1486
- chunk,
1487
- course,
1488
- genseq: event.genseq,
1489
- dialog: {
1490
- selfId: dialog.id.selfId,
1491
- rootId: dialog.id.rootId,
1492
- },
1493
- timestamp: event.ts,
1494
- }));
1495
- }
1496
- },
1497
- markdownFinish: async () => {
1498
- if (ws.readyState === 1) {
1499
- ws.send(JSON.stringify({
1500
- type: 'markdown_finish_evt',
1501
- course,
1502
- genseq: event.genseq,
1503
- dialog: {
1504
- selfId: dialog.id.selfId,
1505
- rootId: dialog.id.rootId,
1506
- },
1507
- timestamp: event.ts,
1508
- }));
1509
- }
1510
- },
1511
- callStart: async (validation) => {
1512
- if (ws.readyState === 1) {
1513
- ws.send(JSON.stringify({
1514
- type: 'teammate_call_start_evt',
1515
- validation,
1516
- course,
1517
- genseq: event.genseq,
1518
- dialog: {
1519
- selfId: dialog.id.selfId,
1520
- rootId: dialog.id.rootId,
1521
- },
1522
- timestamp: event.ts,
1523
- }));
1524
- }
1525
- },
1526
- callHeadLineChunk: async (chunk) => {
1527
- if (ws.readyState === 1) {
1528
- ws.send(JSON.stringify({
1529
- type: 'teammate_call_headline_chunk_evt',
1530
- chunk,
1531
- course,
1532
- genseq: event.genseq,
1533
- dialog: {
1534
- selfId: dialog.id.selfId,
1535
- rootId: dialog.id.rootId,
1536
- },
1537
- timestamp: event.ts,
1538
- }));
1539
- }
1540
- },
1541
- callHeadLineFinish: async () => {
1542
- if (ws.readyState === 1) {
1543
- ws.send(JSON.stringify({
1544
- type: 'teammate_call_headline_finish_evt',
1545
- course,
1546
- genseq: event.genseq,
1547
- dialog: {
1548
- selfId: dialog.id.selfId,
1549
- rootId: dialog.id.rootId,
1550
- },
1551
- timestamp: event.ts,
1552
- }));
1553
- }
1554
- },
1555
- tellaskBodyStart: async () => {
1556
- if (ws.readyState === 1) {
1557
- ws.send(JSON.stringify({
1558
- type: 'teammate_call_body_start_evt',
1559
- course,
1560
- genseq: event.genseq,
1561
- dialog: {
1562
- selfId: dialog.id.selfId,
1563
- rootId: dialog.id.rootId,
1564
- },
1565
- timestamp: event.ts,
1566
- }));
1567
- }
1568
- },
1569
- tellaskBodyChunk: async (chunk) => {
1570
- if (ws.readyState === 1) {
1571
- ws.send(JSON.stringify({
1572
- type: 'teammate_call_body_chunk_evt',
1573
- chunk,
1574
- course,
1575
- genseq: event.genseq,
1576
- dialog: {
1577
- selfId: dialog.id.selfId,
1578
- rootId: dialog.id.rootId,
1579
- },
1580
- timestamp: event.ts,
1581
- }));
1582
- }
1583
- },
1584
- tellaskBodyFinish: async () => {
1585
- if (ws.readyState === 1) {
1586
- ws.send(JSON.stringify({
1587
- type: 'teammate_call_body_finish_evt',
1588
- course,
1589
- genseq: event.genseq,
1590
- dialog: {
1591
- selfId: dialog.id.selfId,
1592
- rootId: dialog.id.rootId,
1593
- },
1594
- timestamp: event.ts,
1595
- }));
1596
- }
1597
- },
1598
- callFinish: async (call) => {
1599
- if (ws.readyState === 1) {
1600
- ws.send(JSON.stringify({
1601
- type: 'teammate_call_finish_evt',
1602
- callId: call.callId,
1603
- course,
1604
- genseq: event.genseq,
1605
- dialog: {
1606
- selfId: dialog.id.selfId,
1607
- rootId: dialog.id.rootId,
1608
- },
1609
- timestamp: event.ts,
1610
- }));
1611
- }
1612
- },
1540
+ const dialogIdent = {
1541
+ selfId: dialog.id.selfId,
1542
+ rootId: dialog.id.rootId,
1613
1543
  };
1614
- // Use the same TellaskStreamParser that live streaming uses
1615
- const streamingParser = new tellask_1.TellaskStreamParser(receiver);
1616
- // Stream the content through the parser to ensure consistent event emission
1617
- await streamingParser.takeUpstreamChunk(content);
1618
- await streamingParser.finalize();
1544
+ if (ws.readyState === 1) {
1545
+ ws.send(JSON.stringify({
1546
+ type: 'markdown_start_evt',
1547
+ course,
1548
+ genseq: event.genseq,
1549
+ dialog: dialogIdent,
1550
+ timestamp: event.ts,
1551
+ }));
1552
+ ws.send(JSON.stringify({
1553
+ type: 'markdown_chunk_evt',
1554
+ chunk: content,
1555
+ course,
1556
+ genseq: event.genseq,
1557
+ dialog: dialogIdent,
1558
+ timestamp: event.ts,
1559
+ }));
1560
+ ws.send(JSON.stringify({
1561
+ type: 'markdown_finish_evt',
1562
+ course,
1563
+ genseq: event.genseq,
1564
+ dialog: dialogIdent,
1565
+ timestamp: event.ts,
1566
+ }));
1567
+ }
1619
1568
  }
1620
1569
  break;
1621
1570
  }
@@ -1651,8 +1600,48 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1651
1600
  break;
1652
1601
  }
1653
1602
  case 'func_call_record': {
1654
- // Handle function call events from persistence
1655
- // NOTE: func_call_evt REMOVED - emit func_call_requested_evt for UI instead
1603
+ const specialCall = parseReplayTellaskSpecialCall(event);
1604
+ if (specialCall) {
1605
+ const dialogIdent = {
1606
+ selfId: dialog.id.selfId,
1607
+ rootId: dialog.id.rootId,
1608
+ };
1609
+ const callStartEvent = (() => {
1610
+ switch (specialCall.callName) {
1611
+ case 'tellask':
1612
+ case 'tellaskSessionless':
1613
+ return {
1614
+ type: 'teammate_call_start_evt',
1615
+ callName: specialCall.callName,
1616
+ callId: specialCall.callId,
1617
+ mentionList: specialCall.mentionList,
1618
+ tellaskContent: specialCall.tellaskContent,
1619
+ course,
1620
+ genseq: event.genseq,
1621
+ dialog: dialogIdent,
1622
+ timestamp: event.ts,
1623
+ };
1624
+ case 'tellaskBack':
1625
+ case 'askHuman':
1626
+ case 'freshBootsReasoning':
1627
+ return {
1628
+ type: 'teammate_call_start_evt',
1629
+ callName: specialCall.callName,
1630
+ callId: specialCall.callId,
1631
+ tellaskContent: specialCall.tellaskContent,
1632
+ course,
1633
+ genseq: event.genseq,
1634
+ dialog: dialogIdent,
1635
+ timestamp: event.ts,
1636
+ };
1637
+ }
1638
+ })();
1639
+ if (ws.readyState === 1) {
1640
+ ws.send(JSON.stringify(callStartEvent));
1641
+ }
1642
+ break;
1643
+ }
1644
+ // Handle normal function call events from persistence.
1656
1645
  const funcCall = {
1657
1646
  type: 'func_call_requested_evt',
1658
1647
  funcId: event.id,
@@ -1758,8 +1747,8 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1758
1747
  rootId: subdialogId.rootId,
1759
1748
  },
1760
1749
  targetAgentId: subMeta.agentId,
1761
- tellaskHead: event.tellaskHead,
1762
- tellaskBody: event.tellaskBody,
1750
+ mentionList: event.mentionList,
1751
+ tellaskContent: event.tellaskContent,
1763
1752
  subDialogNode: {
1764
1753
  selfId: subMeta.id,
1765
1754
  rootId: subdialogId.rootId,
@@ -1771,7 +1760,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1771
1760
  createdAt: subMeta.createdAt,
1772
1761
  lastModified: subLatest?.lastModified || subMeta.createdAt,
1773
1762
  runState: subLatest?.runState,
1774
- tellaskSession: subMeta.tellaskSession,
1763
+ sessionSlug: subMeta.sessionSlug,
1775
1764
  assignmentFromSup: subMeta.assignmentFromSup,
1776
1765
  },
1777
1766
  timestamp: event.ts,
@@ -1783,15 +1772,64 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1783
1772
  }
1784
1773
  case 'teammate_call_result_record': {
1785
1774
  // Handle teammate-call inline results
1786
- const responseEvent = {
1787
- type: 'teammate_call_response_evt',
1788
- responderId: event.responderId,
1789
- tellaskHead: event.tellaskHead,
1790
- status: event.status,
1791
- result: event.result,
1792
- callId: event.callId || '',
1775
+ const responseEvent = (() => {
1776
+ switch (event.callName) {
1777
+ case 'tellask':
1778
+ case 'tellaskSessionless':
1779
+ return {
1780
+ type: 'teammate_call_response_evt',
1781
+ responderId: event.responderId,
1782
+ callName: event.callName,
1783
+ mentionList: event.mentionList,
1784
+ tellaskContent: event.tellaskContent,
1785
+ status: event.status,
1786
+ result: event.result,
1787
+ callId: event.callId || '',
1788
+ course,
1789
+ calling_genseq: event.calling_genseq,
1790
+ dialog: {
1791
+ selfId: dialog.id.selfId,
1792
+ rootId: dialog.id.rootId,
1793
+ },
1794
+ timestamp: event.ts,
1795
+ };
1796
+ case 'tellaskBack':
1797
+ case 'askHuman':
1798
+ case 'freshBootsReasoning':
1799
+ return {
1800
+ type: 'teammate_call_response_evt',
1801
+ responderId: event.responderId,
1802
+ callName: event.callName,
1803
+ tellaskContent: event.tellaskContent,
1804
+ status: event.status,
1805
+ result: event.result,
1806
+ callId: event.callId || '',
1807
+ course,
1808
+ calling_genseq: event.calling_genseq,
1809
+ dialog: {
1810
+ selfId: dialog.id.selfId,
1811
+ rootId: dialog.id.rootId,
1812
+ },
1813
+ timestamp: event.ts,
1814
+ };
1815
+ }
1816
+ })();
1817
+ if (ws.readyState === 1) {
1818
+ ws.send(JSON.stringify(responseEvent));
1819
+ }
1820
+ break;
1821
+ }
1822
+ case 'teammate_call_anchor_record': {
1823
+ const anchorEvent = {
1824
+ type: 'teammate_call_anchor_evt',
1793
1825
  course,
1794
- calling_genseq: event.calling_genseq,
1826
+ genseq: event.genseq,
1827
+ anchorRole: event.anchorRole ?? 'response',
1828
+ callId: event.callId,
1829
+ assignmentCourse: event.assignmentCourse,
1830
+ assignmentGenseq: event.assignmentGenseq,
1831
+ callerDialogId: event.callerDialogId,
1832
+ callerCourse: event.callerCourse,
1795
1833
  dialog: {
1796
1834
  selfId: dialog.id.selfId,
1797
1835
  rootId: dialog.id.rootId,
@@ -1799,38 +1837,84 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1799
1837
  timestamp: event.ts,
1800
1838
  };
1801
1839
  if (ws.readyState === 1) {
1802
- ws.send(JSON.stringify(responseEvent));
1840
+ ws.send(JSON.stringify(anchorEvent));
1803
1841
  }
1804
1842
  break;
1805
1843
  }
1806
1844
  case 'teammate_response_record': {
1807
1845
  // Handle teammate response events (separate bubble for @teammate tellasks)
1846
+ const mentionList = (() => {
1847
+ switch (event.callName) {
1848
+ case 'tellask':
1849
+ case 'tellaskSessionless':
1850
+ return event.mentionList;
1851
+ case 'tellaskBack':
1852
+ case 'freshBootsReasoning':
1853
+ return undefined;
1854
+ }
1855
+ })();
1808
1856
  const formattedResult = (0, inter_dialog_format_1.formatTeammateResponseContent)({
1857
+ callName: event.callName,
1809
1858
  responderId: event.responderId,
1810
1859
  requesterId: event.originMemberId,
1811
- originalCallHeadLine: event.tellaskHead,
1860
+ mentionList,
1861
+ tellaskContent: event.tellaskContent,
1812
1862
  responseBody: event.response,
1813
1863
  language: (0, runtime_language_1.getWorkLanguage)(),
1814
1864
  });
1815
- const teammateResponseEvent = {
1816
- type: 'teammate_response_evt',
1817
- responderId: event.responderId,
1818
- calleeDialogId: event.calleeDialogId,
1819
- tellaskHead: event.tellaskHead,
1820
- status: event.status,
1821
- result: formattedResult,
1822
- response: event.response,
1823
- agentId: event.agentId,
1824
- callId: event.callId,
1825
- originMemberId: event.originMemberId,
1826
- course,
1827
- calling_genseq: event.calling_genseq,
1828
- dialog: {
1829
- selfId: dialog.id.selfId,
1830
- rootId: dialog.id.rootId,
1831
- },
1832
- timestamp: event.ts,
1833
- };
1865
+ const teammateResponseEvent = (() => {
1866
+ switch (event.callName) {
1867
+ case 'tellask':
1868
+ case 'tellaskSessionless':
1869
+ return {
1870
+ type: 'teammate_response_evt',
1871
+ responderId: event.responderId,
1872
+ callName: event.callName,
1873
+ calleeDialogId: event.calleeDialogId,
1874
+ calleeCourse: event.calleeCourse,
1875
+ calleeGenseq: event.calleeGenseq,
1876
+ mentionList,
1877
+ tellaskContent: event.tellaskContent,
1878
+ status: event.status,
1879
+ result: formattedResult,
1880
+ response: event.response,
1881
+ agentId: event.agentId,
1882
+ callId: event.callId,
1883
+ originMemberId: event.originMemberId,
1884
+ course,
1885
+ calling_genseq: event.calling_genseq,
1886
+ dialog: {
1887
+ selfId: dialog.id.selfId,
1888
+ rootId: dialog.id.rootId,
1889
+ },
1890
+ timestamp: event.ts,
1891
+ };
1892
+ case 'tellaskBack':
1893
+ case 'freshBootsReasoning':
1894
+ return {
1895
+ type: 'teammate_response_evt',
1896
+ responderId: event.responderId,
1897
+ callName: event.callName,
1898
+ calleeDialogId: event.calleeDialogId,
1899
+ calleeCourse: event.calleeCourse,
1900
+ calleeGenseq: event.calleeGenseq,
1901
+ tellaskContent: event.tellaskContent,
1902
+ status: event.status,
1903
+ result: formattedResult,
1904
+ response: event.response,
1905
+ agentId: event.agentId,
1906
+ callId: event.callId,
1907
+ originMemberId: event.originMemberId,
1908
+ course,
1909
+ calling_genseq: event.calling_genseq,
1910
+ dialog: {
1911
+ selfId: dialog.id.selfId,
1912
+ rootId: dialog.id.rootId,
1913
+ },
1914
+ timestamp: event.ts,
1915
+ };
1916
+ }
1917
+ })();
1834
1918
  if (ws.readyState === 1) {
1835
1919
  ws.send(JSON.stringify(teammateResponseEvent));
1836
1920
  }
@@ -2108,7 +2192,7 @@ class DialogPersistence {
2108
2192
  return validDialogIds;
2109
2193
  }
2110
2194
  catch (error) {
2111
- log_1.log.warn(`🔍 listDialogs: Error processing directory ${specificDir}:`, error instanceof Error ? error.message : String(error));
2195
+ log_1.log.warn(`🔍 listDialogs: Error processing directory ${specificDir}:`, error);
2112
2196
  return [];
2113
2197
  }
2114
2198
  }
@@ -2446,7 +2530,7 @@ class DialogPersistence {
2446
2530
  Array.isArray(parsed.questions)) {
2447
2531
  return parsed.questions;
2448
2532
  }
2449
- log_1.log.warn(`q4h.yaml has unexpected shape for dialog ${dialogId}`, {
2533
+ log_1.log.warn(`q4h.yaml has unexpected shape for dialog ${dialogId}`, undefined, {
2450
2534
  filePath: questionsFilePath,
2451
2535
  });
2452
2536
  return [];
@@ -2475,7 +2559,7 @@ class DialogPersistence {
2475
2559
  }
2476
2560
  }
2477
2561
  if (repairedQuestions) {
2478
- log_1.log.warn(`Repaired corrupted q4h.yaml for dialog ${dialogId}`, {
2562
+ log_1.log.warn(`Repaired corrupted q4h.yaml for dialog ${dialogId}`, undefined, {
2479
2563
  filePath: questionsFilePath,
2480
2564
  });
2481
2565
  const repairedFile = {
@@ -2494,7 +2578,7 @@ class DialogPersistence {
2494
2578
  try {
2495
2579
  const quarantinePath = `${questionsFilePath}.corrupt-${(0, node_crypto_1.randomUUID)()}`;
2496
2580
  await fs.promises.rename(questionsFilePath, quarantinePath);
2497
- log_1.log.warn(`Quarantined corrupted q4h.yaml for dialog ${dialogId}`, {
2581
+ log_1.log.warn(`Quarantined corrupted q4h.yaml for dialog ${dialogId}`, undefined, {
2498
2582
  filePath: questionsFilePath,
2499
2583
  quarantinePath,
2500
2584
  });
@@ -2810,15 +2894,48 @@ class DialogPersistence {
2810
2894
  return false;
2811
2895
  if (typeof value.createdAt !== 'string')
2812
2896
  return false;
2813
- if (typeof value.tellaskHead !== 'string')
2897
+ if (value.callName !== 'tellask' &&
2898
+ value.callName !== 'tellaskSessionless' &&
2899
+ value.callName !== 'freshBootsReasoning') {
2900
+ return false;
2901
+ }
2902
+ switch (value.callName) {
2903
+ case 'tellask':
2904
+ case 'tellaskSessionless':
2905
+ if (!Array.isArray(value.mentionList))
2906
+ return false;
2907
+ if (!value.mentionList.every((item) => typeof item === 'string'))
2908
+ return false;
2909
+ if (value.mentionList.length < 1)
2910
+ return false;
2911
+ break;
2912
+ case 'freshBootsReasoning':
2913
+ if (value.mentionList !== undefined)
2914
+ return false;
2915
+ break;
2916
+ }
2917
+ if (typeof value.tellaskContent !== 'string')
2814
2918
  return false;
2815
2919
  if (typeof value.targetAgentId !== 'string')
2816
2920
  return false;
2921
+ if (typeof value.callId !== 'string')
2922
+ return false;
2923
+ if ('callingCourse' in value) {
2924
+ const callingCourse = value.callingCourse;
2925
+ if (callingCourse !== undefined) {
2926
+ if (typeof callingCourse !== 'number')
2927
+ return false;
2928
+ if (!Number.isFinite(callingCourse))
2929
+ return false;
2930
+ if (Math.floor(callingCourse) <= 0)
2931
+ return false;
2932
+ }
2933
+ }
2817
2934
  if (value.callType !== 'A' && value.callType !== 'B' && value.callType !== 'C')
2818
2935
  return false;
2819
- if ('tellaskSession' in value) {
2820
- const tellaskSession = value.tellaskSession;
2821
- if (tellaskSession !== undefined && typeof tellaskSession !== 'string')
2936
+ if ('sessionSlug' in value) {
2937
+ const sessionSlug = value.sessionSlug;
2938
+ if (sessionSlug !== undefined && typeof sessionSlug !== 'string')
2822
2939
  return false;
2823
2940
  }
2824
2941
  return true;
@@ -3797,7 +3914,7 @@ class DialogPersistence {
3797
3914
  genseq: event.genseq,
3798
3915
  msgId: event.msgId,
3799
3916
  content: event.content,
3800
- grammar: event.grammar ?? 'tellask',
3917
+ grammar: event.grammar ?? 'markdown',
3801
3918
  });
3802
3919
  break;
3803
3920
  }
@@ -3832,12 +3949,25 @@ class DialogPersistence {
3832
3949
  }
3833
3950
  case 'teammate_call_result_record': {
3834
3951
  // Convert teammate-call inline result to ChatMessage
3952
+ const mentionList = (() => {
3953
+ switch (event.callName) {
3954
+ case 'tellask':
3955
+ case 'tellaskSessionless':
3956
+ return event.mentionList;
3957
+ case 'tellaskBack':
3958
+ case 'askHuman':
3959
+ case 'freshBootsReasoning':
3960
+ return undefined;
3961
+ }
3962
+ })();
3835
3963
  messages.push({
3836
3964
  type: 'tellask_result_msg',
3837
3965
  role: 'tool',
3838
3966
  responderId: event.responderId,
3839
- tellaskHead: event.tellaskHead,
3967
+ mentionList,
3968
+ tellaskContent: event.tellaskContent,
3840
3969
  status: event.status,
3970
+ callId: event.callId,
3841
3971
  content: event.result,
3842
3972
  });
3843
3973
  break;
@@ -3845,10 +3975,22 @@ class DialogPersistence {
3845
3975
  case 'teammate_response_record': {
3846
3976
  // Convert teammate response to ChatMessage (teammate - separate bubble)
3847
3977
  // Note: Teammate responses are stored as separate records but use same message type
3978
+ const mentionList = (() => {
3979
+ switch (event.callName) {
3980
+ case 'tellask':
3981
+ case 'tellaskSessionless':
3982
+ return event.mentionList;
3983
+ case 'tellaskBack':
3984
+ case 'freshBootsReasoning':
3985
+ return undefined;
3986
+ }
3987
+ })();
3848
3988
  const formattedResult = (0, inter_dialog_format_1.formatTeammateResponseContent)({
3989
+ callName: event.callName,
3849
3990
  responderId: event.responderId,
3850
3991
  requesterId: event.originMemberId,
3851
- originalCallHeadLine: event.tellaskHead,
3992
+ mentionList,
3993
+ tellaskContent: event.tellaskContent,
3852
3994
  responseBody: event.response,
3853
3995
  language: (0, runtime_language_1.getWorkLanguage)(),
3854
3996
  });
@@ -3856,8 +3998,10 @@ class DialogPersistence {
3856
3998
  type: 'tellask_result_msg',
3857
3999
  role: 'tool',
3858
4000
  responderId: event.responderId,
3859
- tellaskHead: event.tellaskHead,
4001
+ mentionList,
4002
+ tellaskContent: event.tellaskContent,
3860
4003
  status: event.status,
4004
+ callId: event.callId,
3861
4005
  content: formattedResult,
3862
4006
  });
3863
4007
  break;
@@ -3875,6 +4019,10 @@ class DialogPersistence {
3875
4019
  // These events are handled separately in dialog restoration
3876
4020
  // Skip them for message reconstruction
3877
4021
  break;
4022
+ case 'teammate_call_anchor_record':
4023
+ // This record is UI navigation metadata for deep links in callee dialogs.
4024
+ // It does not contribute to model context or chat transcript reconstruction.
4025
+ break;
3878
4026
  default:
3879
4027
  log_1.log.warn(`Unknown event type in rebuildFromEvents`, undefined, { event });
3880
4028
  break;
@@ -3957,7 +4105,7 @@ class DialogPersistence {
3957
4105
  key: entry.key,
3958
4106
  subdialogId: entry.subdialogId.selfId,
3959
4107
  agentId: entry.agentId,
3960
- tellaskSession: entry.tellaskSession,
4108
+ sessionSlug: entry.sessionSlug,
3961
4109
  }));
3962
4110
  const yamlContent = yaml.stringify({ entries: serializableEntries });
3963
4111
  const tempFile = path.join(dialogPath, `.${path.basename(registryFilePath)}.${process.pid}.${(0, node_crypto_1.randomUUID)()}.tmp`);
@@ -3990,7 +4138,7 @@ class DialogPersistence {
3990
4138
  key: entry.key,
3991
4139
  subdialogId: new dialog_1.DialogID(entry.subdialogId, rootDialogId.rootId),
3992
4140
  agentId: entry.agentId,
3993
- tellaskSession: entry.tellaskSession,
4141
+ sessionSlug: entry.sessionSlug,
3994
4142
  };
3995
4143
  });
3996
4144
  return entries;