@abot-ai/runtime 1.1.0 → 1.2.0

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 (268) hide show
  1. package/README.md +6 -3
  2. package/dist/src/capabilities/tool-types.d.ts +1 -1
  3. package/dist/src/model-gateway/providers/ollama/generation-options.d.ts +1 -3
  4. package/dist/src/model-gateway/providers/ollama/generation-options.js +1 -5
  5. package/dist/src/model-gateway/providers/ollama/payload.js +0 -8
  6. package/dist/src/model-gateway/server/request-body.js +1 -0
  7. package/dist/src/plugin-sdk/index.d.ts +2 -0
  8. package/dist/src/plugin-sdk/index.js +2 -0
  9. package/dist/src/plugin-sdk/tool-availability-brief.d.ts +9 -0
  10. package/dist/src/plugin-sdk/tool-availability-brief.js +48 -0
  11. package/dist/src/plugin-sdk/tool-availability-overview.d.ts +9 -0
  12. package/dist/src/plugin-sdk/tool-availability-overview.js +62 -0
  13. package/dist/src/runtime/adapters/registered-tool-payload-plan.d.ts +0 -9
  14. package/dist/src/runtime/adapters/registered-tool-payload-plan.js +0 -67
  15. package/dist/src/runtime/adapters/registered-tool-payload-related-artifacts.d.ts +13 -0
  16. package/dist/src/runtime/adapters/registered-tool-payload-related-artifacts.js +84 -0
  17. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/catalog.js +4 -0
  18. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/execution.js +3 -0
  19. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-lifecycle.d.ts +1 -0
  20. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-lifecycle.js +11 -1
  21. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-stages.d.ts +1 -0
  22. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-stages.js +9 -1
  23. package/dist/src/runtime/capabilities/request-bound-tool-registry.js +1 -24
  24. package/dist/src/runtime/capabilities/tool-availability.d.ts +6 -0
  25. package/dist/src/runtime/capabilities/tool-availability.js +28 -0
  26. package/dist/src/runtime/context/capability-brief.d.ts +25 -0
  27. package/dist/src/runtime/context/capability-brief.js +106 -0
  28. package/dist/src/runtime/context/request-tool-results-message-binding.d.ts +6 -0
  29. package/dist/src/runtime/context/request-tool-results-message-binding.js +30 -0
  30. package/dist/src/runtime/context/request-tool-results-scope.d.ts +3 -0
  31. package/dist/src/runtime/context/request-tool-results-scope.js +8 -0
  32. package/dist/src/runtime/context/request-tool-results.d.ts +8 -4
  33. package/dist/src/runtime/context/request-tool-results.js +49 -38
  34. package/dist/src/runtime/orchestration/role-calls/candidate-validation.js +8 -1
  35. package/dist/src/runtime/orchestration/role-calls/child-return.d.ts +4 -0
  36. package/dist/src/runtime/orchestration/role-calls/child-return.js +25 -5
  37. package/dist/src/runtime/orchestration/role-calls/command-decoder.js +8 -3
  38. package/dist/src/runtime/orchestration/role-calls/command-dispatch/child-transitions.d.ts +1 -1
  39. package/dist/src/runtime/orchestration/role-calls/command-dispatch/child-transitions.js +17 -2
  40. package/dist/src/runtime/orchestration/role-calls/command-dispatch.d.ts +1 -1
  41. package/dist/src/runtime/orchestration/role-calls/command-dispatch.js +2 -2
  42. package/dist/src/runtime/orchestration/role-calls/contracts.d.ts +5 -2
  43. package/dist/src/runtime/orchestration/role-calls/contracts.js +4 -4
  44. package/dist/src/runtime/orchestration/role-calls/dependency-results.d.ts +1 -1
  45. package/dist/src/runtime/orchestration/role-calls/dependency-results.js +1 -0
  46. package/dist/src/runtime/orchestration/role-calls/index.d.ts +5 -1
  47. package/dist/src/runtime/orchestration/role-calls/index.js +5 -1
  48. package/dist/src/runtime/orchestration/role-calls/ledger.d.ts +3 -1
  49. package/dist/src/runtime/orchestration/role-calls/ledger.js +9 -2
  50. package/dist/src/runtime/orchestration/role-calls/reducer.d.ts +1 -1
  51. package/dist/src/runtime/orchestration/role-calls/reducer.js +2 -2
  52. package/dist/src/runtime/orchestration/role-calls/result-receipt.d.ts +49 -0
  53. package/dist/src/runtime/orchestration/role-calls/result-receipt.js +188 -0
  54. package/dist/src/runtime/orchestration/role-calls/return-result-receipt.d.ts +19 -0
  55. package/dist/src/runtime/orchestration/role-calls/return-result-receipt.js +52 -0
  56. package/dist/src/runtime/orchestration/role-calls/transactions.js +1 -0
  57. package/dist/src/runtime/orchestration/role-calls/work-result-lineage.d.ts +34 -0
  58. package/dist/src/runtime/orchestration/role-calls/work-result-lineage.js +185 -0
  59. package/dist/src/runtime/orchestration/role-calls/work-result-receipt.d.ts +36 -0
  60. package/dist/src/runtime/orchestration/role-calls/work-result-receipt.js +187 -0
  61. package/dist/src/runtime/orchestration/role-executors/activation/result-normalization.js +6 -3
  62. package/dist/src/runtime/orchestration/role-executors/child-invocation/transaction.js +1 -0
  63. package/dist/src/runtime/orchestration/role-executors/contracts.d.ts +2 -1
  64. package/dist/src/runtime/orchestration/worker-capabilities/assignment-provenance.d.ts +36 -0
  65. package/dist/src/runtime/orchestration/worker-capabilities/assignment-provenance.js +171 -0
  66. package/dist/src/runtime/orchestration/worker-capabilities/contracts.d.ts +32 -1
  67. package/dist/src/runtime/orchestration/worker-capabilities/execution/invocation-preparation.d.ts +2 -1
  68. package/dist/src/runtime/orchestration/worker-capabilities/execution/invocation-preparation.js +3 -0
  69. package/dist/src/runtime/orchestration/worker-capabilities/execution.js +42 -19
  70. package/dist/src/runtime/orchestration/worker-capabilities/index.d.ts +2 -0
  71. package/dist/src/runtime/orchestration/worker-capabilities/index.js +2 -0
  72. package/dist/src/runtime/orchestration/worker-capabilities/payload-assignment-validation.d.ts +3 -0
  73. package/dist/src/runtime/orchestration/worker-capabilities/payload-assignment-validation.js +30 -0
  74. package/dist/src/runtime/orchestration/worker-capabilities/payload-author.js +8 -19
  75. package/dist/src/runtime/orchestration/worker-capabilities/payload-contracts.d.ts +5 -1
  76. package/dist/src/runtime/orchestration/worker-capabilities/payload-instructions.js +1 -1
  77. package/dist/src/runtime/orchestration/worker-capabilities/payload-source-provenance.d.ts +14 -0
  78. package/dist/src/runtime/orchestration/worker-capabilities/payload-source-provenance.js +132 -0
  79. package/dist/src/runtime/request/capability-brief.d.ts +5 -0
  80. package/dist/src/runtime/request/capability-brief.js +24 -0
  81. package/dist/src/runtime/request/execution-scope.d.ts +2 -1
  82. package/dist/src/runtime/request/role-executor-composition.js +1 -1
  83. package/dist/src/runtime/request/worker-capability-composition.d.ts +2 -1
  84. package/dist/src/runtime/request/worker-capability-composition.js +6 -1
  85. package/dist/src/runtime/request/worker-capability-payload.js +11 -8
  86. package/dist/src/runtime/steps/execution-agent/prompt.js +4 -3
  87. package/dist/src/runtime/steps/planner-decision/capability-catalog-context.d.ts +14 -0
  88. package/dist/src/runtime/steps/planner-decision/capability-catalog-context.js +87 -0
  89. package/dist/src/runtime/steps/planner-decision/contracts.d.ts +3 -5
  90. package/dist/src/runtime/steps/planner-decision/contracts.js +3 -3
  91. package/dist/src/runtime/steps/planner-decision/format.d.ts +3 -2
  92. package/dist/src/runtime/steps/planner-decision/format.js +73 -76
  93. package/dist/src/runtime/steps/planner-decision/input.d.ts +4 -3
  94. package/dist/src/runtime/steps/planner-decision/input.js +10 -7
  95. package/dist/src/runtime/steps/planner-decision/parser.d.ts +3 -2
  96. package/dist/src/runtime/steps/planner-decision/parser.js +10 -19
  97. package/dist/src/runtime/steps/planner-decision/plan-parser.js +18 -12
  98. package/dist/src/runtime/steps/planner-decision/prompt.js +33 -28
  99. package/dist/src/runtime/steps/planner-decision/resume.d.ts +1 -1
  100. package/dist/src/runtime/steps/planner-decision/resume.js +38 -1
  101. package/dist/src/runtime/steps/planner-decision/run.d.ts +3 -2
  102. package/dist/src/runtime/steps/reviewer-decision/audit-coverage.d.ts +10 -0
  103. package/dist/src/runtime/steps/reviewer-decision/audit-coverage.js +186 -0
  104. package/dist/src/runtime/steps/reviewer-decision/contracts.d.ts +3 -8
  105. package/dist/src/runtime/steps/reviewer-decision/contracts.js +12 -6
  106. package/dist/src/runtime/steps/reviewer-decision/delegated-context.d.ts +24 -0
  107. package/dist/src/runtime/steps/reviewer-decision/delegated-context.js +70 -0
  108. package/dist/src/runtime/steps/reviewer-decision/diagnostics.js +1 -1
  109. package/dist/src/runtime/steps/reviewer-decision/format.js +37 -24
  110. package/dist/src/runtime/steps/reviewer-decision/input.js +1 -1
  111. package/dist/src/runtime/steps/reviewer-decision/model-context.d.ts +4 -3
  112. package/dist/src/runtime/steps/reviewer-decision/model-context.js +92 -10
  113. package/dist/src/runtime/steps/reviewer-decision/parser.js +19 -1
  114. package/dist/src/runtime/steps/reviewer-decision/projection.js +42 -68
  115. package/dist/src/runtime/steps/reviewer-decision/prompt.js +10 -5
  116. package/dist/src/runtime/steps/reviewer-decision/run.js +12 -3
  117. package/dist/src/runtime/steps/reviewer-decision/verification-coverage.d.ts +14 -0
  118. package/dist/src/runtime/steps/reviewer-decision/verification-coverage.js +52 -0
  119. package/dist/src/runtime/steps/supervisor-decision/capability-brief.d.ts +14 -0
  120. package/dist/src/runtime/steps/supervisor-decision/capability-brief.js +38 -0
  121. package/dist/src/runtime/steps/supervisor-decision/contracts.d.ts +7 -3
  122. package/dist/src/runtime/steps/supervisor-decision/diagnostics.d.ts +2 -0
  123. package/dist/src/runtime/steps/supervisor-decision/diagnostics.js +8 -2
  124. package/dist/src/runtime/steps/supervisor-decision/format.js +32 -20
  125. package/dist/src/runtime/steps/supervisor-decision/input.d.ts +4 -1
  126. package/dist/src/runtime/steps/supervisor-decision/input.js +19 -1
  127. package/dist/src/runtime/steps/supervisor-decision/parser.js +62 -59
  128. package/dist/src/runtime/steps/supervisor-decision/prompt.js +6 -7
  129. package/dist/src/runtime/steps/supervisor-decision/resume.js +47 -1
  130. package/dist/src/runtime/steps/supervisor-decision/run.js +10 -0
  131. package/dist/src/runtime/steps/supervisor-decision/working-directory.js +2 -1
  132. package/dist/src/runtime/steps/worker-decision/contracts.d.ts +2 -1
  133. package/dist/src/runtime/steps/worker-decision/input/canonical-state.js +8 -1
  134. package/dist/src/runtime/steps/worker-decision/input/diagnostic-projection.js +2 -2
  135. package/dist/src/runtime/steps/worker-decision/input/prompt-context.d.ts +1 -0
  136. package/dist/src/runtime/steps/worker-decision/input/prompt-context.js +4 -1
  137. package/dist/src/runtime/steps/worker-decision/input/reference-context.js +34 -14
  138. package/dist/src/runtime/steps/worker-decision/input/types.d.ts +2 -1
  139. package/dist/src/runtime/steps/worker-decision/input.d.ts +1 -0
  140. package/dist/src/runtime/steps/worker-decision/input.js +1 -0
  141. package/dist/src/runtime/steps/worker-decision/payload-dependency-results.d.ts +8 -0
  142. package/dist/src/runtime/steps/worker-decision/payload-dependency-results.js +19 -0
  143. package/dist/src/runtime/steps/worker-decision/prompt.js +8 -8
  144. package/dist/src/runtime/steps/worker-decision/result-author.js +18 -11
  145. package/dist/src/runtime/steps/worker-decision/run.js +2 -2
  146. package/dist/src/web-ui/app/ARCHITECTURE.md +19 -6
  147. package/dist/src/web-ui/app/app.js +6 -7
  148. package/dist/src/web-ui/app/components/composer-context-window.d.ts +25 -0
  149. package/dist/src/web-ui/app/components/composer-context-window.js +155 -0
  150. package/dist/src/web-ui/app/components/composer-plan.d.ts +9 -0
  151. package/dist/src/web-ui/app/components/composer-plan.js +128 -0
  152. package/dist/src/web-ui/app/components/conversation-activity.d.ts +5 -6
  153. package/dist/src/web-ui/app/components/conversation-activity.js +64 -157
  154. package/dist/src/web-ui/app/components/conversation-role-cards.d.ts +23 -0
  155. package/dist/src/web-ui/app/components/conversation-role-cards.js +181 -0
  156. package/dist/src/web-ui/app/components/conversation-sidebar-layout.js +12 -0
  157. package/dist/src/web-ui/app/components/conversation-sources.d.ts +7 -0
  158. package/dist/src/web-ui/app/components/conversation-sources.js +182 -0
  159. package/dist/src/web-ui/app/components/conversation-view.js +34 -6
  160. package/dist/src/web-ui/app/components/model-selector.js +4 -1
  161. package/dist/src/web-ui/app/components/operations-section.js +46 -0
  162. package/dist/src/web-ui/app/components/workspace-shell.js +86 -78
  163. package/dist/src/web-ui/app/controllers/realtime-event-controller.d.ts +1 -0
  164. package/dist/src/web-ui/app/controllers/realtime-event-controller.js +55 -90
  165. package/dist/src/web-ui/app/controllers/runtime-selection-controller.js +2 -0
  166. package/dist/src/web-ui/app/controllers/session-controller.js +17 -12
  167. package/dist/src/web-ui/app/index.html +209 -210
  168. package/dist/src/web-ui/app/lib/composer-plan-model.d.ts +32 -0
  169. package/dist/src/web-ui/app/lib/composer-plan-model.js +108 -0
  170. package/dist/src/web-ui/app/lib/conversation-role-model.d.ts +19 -0
  171. package/dist/src/web-ui/app/lib/conversation-role-model.js +193 -0
  172. package/dist/src/web-ui/app/lib/event-presentation.js +30 -9
  173. package/dist/src/web-ui/app/lib/source-url-policy.d.ts +2 -0
  174. package/dist/src/web-ui/app/lib/source-url-policy.js +31 -0
  175. package/dist/src/web-ui/app/lib/task-progress.d.ts +53 -0
  176. package/dist/src/web-ui/app/lib/task-progress.js +233 -0
  177. package/dist/src/web-ui/app/lib/tool-invocation-count.d.ts +5 -0
  178. package/dist/src/web-ui/app/lib/tool-invocation-count.js +21 -0
  179. package/dist/src/web-ui/app/lib/web-source-event.d.ts +8 -0
  180. package/dist/src/web-ui/app/lib/web-source-event.js +21 -0
  181. package/dist/src/web-ui/app/lib/web-sources.d.ts +36 -0
  182. package/dist/src/web-ui/app/lib/web-sources.js +177 -0
  183. package/dist/src/web-ui/app/styles/00-tokens-base.css +15 -3
  184. package/dist/src/web-ui/app/styles/10-shell-sessions.css +24 -34
  185. package/dist/src/web-ui/app/styles/12-conversation-sidebar.css +93 -0
  186. package/dist/src/web-ui/app/styles/20-chat-composer.css +55 -472
  187. package/dist/src/web-ui/app/styles/21-composer-controls.css +368 -0
  188. package/dist/src/web-ui/app/styles/22-composer-context-window.css +90 -0
  189. package/dist/src/web-ui/app/styles/23-composer-plan.css +171 -0
  190. package/dist/src/web-ui/app/styles/24-conversation-role-cards.css +205 -0
  191. package/dist/src/web-ui/app/styles/25-conversation-sources.css +141 -0
  192. package/dist/src/web-ui/app/styles/30-inspector-config.css +21 -209
  193. package/dist/src/web-ui/app/styles/35-memory-onboarding.css +8 -8
  194. package/dist/src/web-ui/app/styles/36-memory-management.css +13 -13
  195. package/dist/src/web-ui/app/styles/37-config-operations.css +197 -0
  196. package/dist/src/web-ui/app/styles/40-config-workspace.css +36 -36
  197. package/dist/src/web-ui/app/styles/90-responsive.css +14 -77
  198. package/dist/src/web-ui/app/styles/foundation.css +2 -2
  199. package/dist/src/web-ui/app/styles.css +7 -0
  200. package/dist/src/web-ui/app/ui-behavior.d.ts +1 -1
  201. package/dist/src/web-ui/app/ui-behavior.js +1 -1
  202. package/docs/configuration.md +15 -8
  203. package/docs/installation.md +7 -4
  204. package/docs/known-limitations.md +21 -0
  205. package/docs/plugins.md +28 -13
  206. package/docs/runtime-invariant-coverage.md +18 -17
  207. package/docs/runtime-prompt-policy-contracts.md +27 -17
  208. package/package.json +4 -3
  209. package/plugins/capability-brief/source/index.ts +5 -48
  210. package/plugins/capability-brief/src/index.cjs +46 -33
  211. package/plugins/system-probe/plugin.json +1 -0
  212. package/plugins/web/README.md +125 -0
  213. package/plugins/web/plugin.json +1 -1
  214. package/plugins/web/skills/web_fetch_skill/SKILL.md +2 -2
  215. package/plugins/web/skills/web_search_skill/SKILL.md +8 -4
  216. package/plugins/web/source/errors.ts +5 -1
  217. package/plugins/web/source/fetch-presentation.ts +61 -0
  218. package/plugins/web/source/fetch-service.ts +2 -31
  219. package/plugins/web/source/light/config.ts +196 -0
  220. package/plugins/web/source/light/crawl/origin-gate.ts +134 -0
  221. package/plugins/web/source/light/crawl/robots-cache.ts +71 -0
  222. package/plugins/web/source/light/crawl/robots-parser.ts +132 -0
  223. package/plugins/web/source/light/crawl/robots-policy.ts +154 -0
  224. package/plugins/web/source/light/crawl/session-budget.ts +141 -0
  225. package/plugins/web/source/light/crawl/transport.ts +216 -0
  226. package/plugins/web/source/light/discovery/candidate-values.ts +63 -0
  227. package/plugins/web/source/light/discovery/feed-document.ts +127 -0
  228. package/plugins/web/source/light/discovery/html-links.ts +80 -0
  229. package/plugins/web/source/light/discovery/html-robots-directives.ts +29 -0
  230. package/plugins/web/source/light/discovery/markup-tree.ts +145 -0
  231. package/plugins/web/source/light/discovery/origin-dates.ts +71 -0
  232. package/plugins/web/source/light/discovery/sitemap-document.ts +63 -0
  233. package/plugins/web/source/light/documents/cache-policy.ts +28 -0
  234. package/plugins/web/source/light/documents/document-cache.ts +99 -0
  235. package/plugins/web/source/light/documents/document-charset.ts +89 -0
  236. package/plugins/web/source/light/documents/document-contract.ts +20 -0
  237. package/plugins/web/source/light/documents/document-reader.ts +75 -0
  238. package/plugins/web/source/light/documents/extract-document.ts +124 -0
  239. package/plugins/web/source/light/documents/http-cache-freshness.ts +68 -0
  240. package/plugins/web/source/light/documents/response-decoding.ts +120 -0
  241. package/plugins/web/source/light/ranking/document-ranking.ts +114 -0
  242. package/plugins/web/source/light/ranking/query-normalization.ts +69 -0
  243. package/plugins/web/source/light/search-collection.ts +136 -0
  244. package/plugins/web/source/light/search-frontier.ts +246 -0
  245. package/plugins/web/source/light/search-metadata.ts +84 -0
  246. package/plugins/web/source/light/search-service.ts +154 -0
  247. package/plugins/web/source/light/search-unavailable.ts +33 -0
  248. package/plugins/web/source/light/sources/catalog.ts +312 -0
  249. package/plugins/web/source/light/sources/source-definition.ts +9 -0
  250. package/plugins/web/source/light/sources/source-selection.ts +35 -0
  251. package/plugins/web/source/plugin.ts +70 -56
  252. package/plugins/web/source/public-http.ts +10 -1
  253. package/plugins/web/source/search-presentation.ts +63 -63
  254. package/plugins/web/source/search-service-selector.ts +31 -0
  255. package/plugins/web/source/search-service.ts +6 -0
  256. package/plugins/web/source/search-source-presentation.ts +76 -0
  257. package/plugins/web/source/search-types.ts +4 -0
  258. package/plugins/web/source/source-output-receipts.ts +267 -0
  259. package/plugins/web/source/source-receipt-budget.ts +51 -0
  260. package/plugins/web/source/source-receipt-contract.ts +18 -0
  261. package/plugins/web/src/index.cjs +3214 -288
  262. package/src/runtime/README.md +30 -9
  263. package/dist/src/model-gateway/structured-output/budget.d.ts +0 -7
  264. package/dist/src/model-gateway/structured-output/budget.js +0 -20
  265. package/dist/src/model-gateway/structured-output/schema-character-estimator.d.ts +0 -1
  266. package/dist/src/model-gateway/structured-output/schema-character-estimator.js +0 -211
  267. package/dist/src/model-gateway/structured-output-budget.d.ts +0 -1
  268. package/dist/src/model-gateway/structured-output-budget.js +0 -1
@@ -4,25 +4,33 @@ import {
4
4
  eventTone,
5
5
  formatEventDetail,
6
6
  formatEventLabel,
7
- getPlanItemPayload,
8
- getPlanPayload,
9
- getRecord,
10
7
  isLowValueActivityEvent,
11
8
  } from "../lib/event-presentation.js";
12
9
  import { textOf } from "../lib/text-format.js";
13
10
  import { normalizeRealtimeMessage } from "../lib/realtime-message.js";
11
+ import { reduceTaskProgress } from "../lib/task-progress.js";
12
+ import { projectWebSourceEvent } from "../lib/web-source-event.js";
14
13
 
15
14
  export { normalizeRealtimeMessage } from "../lib/realtime-message.js";
15
+ export { taskStatusClass } from "../lib/task-progress.js";
16
16
 
17
- export function taskStatusClass(status) {
18
- const normalized = textOf(status).trim().toLowerCase();
19
- if (normalized === "done" || normalized === "completed") return "done";
20
- if (normalized === "in_progress" || normalized === "active") {
21
- return "active";
22
- }
23
- if (normalized === "blocked" || normalized === "failed") return "failed";
24
- if (normalized === "superseded") return "muted";
25
- return "pending";
17
+ function hasOriginalEventSequence(value) {
18
+ return Number.isSafeInteger(value) && value > 0;
19
+ }
20
+
21
+ function hasRecordedOriginalEvent(events, requestId, eventSequence) {
22
+ if (eventSequence === undefined) return false;
23
+ return events.some(
24
+ (event) =>
25
+ event.requestId === requestId && event.eventSequence === eventSequence,
26
+ );
27
+ }
28
+
29
+ function canMergeUnsequencedActivity(previous, key, eventSequence, webSources) {
30
+ if (eventSequence !== undefined) return false;
31
+ if (webSources || previous?.webSources) return false;
32
+ if (!previous?.key || previous.key !== key) return false;
33
+ return !hasOriginalEventSequence(previous.eventSequence);
26
34
  }
27
35
 
28
36
  export function createRealtimeEventController({
@@ -36,6 +44,7 @@ export function createRealtimeEventController({
36
44
  addOrMergeMessage,
37
45
  normalizeChatMessage,
38
46
  renderMessages,
47
+ renderContextWindow = () => {},
39
48
  scheduleMessageRender,
40
49
  scheduleThinkingRender,
41
50
  cancelScheduledMessageRender,
@@ -54,76 +63,12 @@ export function createRealtimeEventController({
54
63
  }
55
64
  }
56
65
 
57
- function mergeTaskProgressItem(items, nextItem) {
58
- const normalizedTitle = nextItem.title.trim().toLowerCase();
59
- const normalizedId = nextItem.id.trim();
60
- const existingIndex = items.findIndex((item) => {
61
- if (normalizedId && item.id === normalizedId) return true;
62
- return item.title.trim().toLowerCase() === normalizedTitle;
63
- });
64
- if (existingIndex < 0) {
65
- items.push(nextItem);
66
- return;
67
- }
68
- items[existingIndex] = {
69
- ...items[existingIndex],
70
- ...nextItem,
71
- id: nextItem.id || items[existingIndex].id,
72
- title: nextItem.title || items[existingIndex].title,
73
- status: nextItem.status || items[existingIndex].status,
74
- };
75
- }
76
-
77
66
  function updateTaskProgress(message) {
78
- const plan = getPlanPayload(message);
79
- const item = getPlanItemPayload(message);
80
- const snapshot = getRecord(message.progressSnapshot);
81
- const planningSignal =
82
- Boolean(plan || item || snapshot) ||
83
- textOf(message.name).startsWith("Planner ") ||
84
- textOf(message.name).startsWith("Development progress:");
85
- if (!planningSignal) return;
86
- const requestId = textOf(message.requestId) || state.activeRequestId;
87
- if (!requestId) return;
88
- const current = state.taskProgressByRequest.get(requestId) || {
89
- requestId,
90
- summary: "",
91
- total: 0,
92
- completed: 0,
93
- requestSatisfaction: "",
94
- items: [],
95
- hasSignal: false,
96
- };
97
- const next = {
98
- ...current,
99
- requestId,
100
- summary:
101
- plan?.summary || textOf(snapshot?.summary) || current.summary || "",
102
- total: plan?.total ?? current.total,
103
- completed: plan?.completed ?? current.completed,
104
- requestSatisfaction:
105
- textOf(snapshot?.requestSatisfaction) || current.requestSatisfaction,
106
- items: [...current.items],
107
- hasSignal: true,
108
- };
109
- for (const planItem of plan?.items || [])
110
- mergeTaskProgressItem(next.items, planItem);
111
- if (item) mergeTaskProgressItem(next.items, item);
112
- if (!next.summary && Array.isArray(snapshot?.requestedWork)) {
113
- next.summary =
114
- snapshot.requestedWork.map(textOf).filter(Boolean)[0] || "";
115
- }
116
- if (!next.total && next.items.length > 0) next.total = next.items.length;
117
- if (next.items.length > 0) {
118
- next.completed = Math.max(
119
- next.completed,
120
- next.items.filter((entry) => entry.status === "done").length,
121
- );
122
- }
123
- next.activeItem =
124
- next.items.find((entry) => taskStatusClass(entry.status) === "active")
125
- ?.title || "";
126
- state.taskProgressByRequest.set(requestId, next);
67
+ const requestId = textOf(message.requestId);
68
+ const current = state.taskProgressByRequest.get(requestId);
69
+ const next = reduceTaskProgress(current, message);
70
+ if (next && next !== current)
71
+ state.taskProgressByRequest.set(requestId, next);
127
72
  }
128
73
 
129
74
  function updateContextWindow(message) {
@@ -195,7 +140,7 @@ export function createRealtimeEventController({
195
140
  lastCompaction,
196
141
  pendingCompaction: lastCompaction ? null : current.pendingCompaction,
197
142
  });
198
- return;
143
+ return true;
199
144
  }
200
145
  if (eventName === "context.window.provider_usage") {
201
146
  state.contextWindowByRequest.set(requestId, {
@@ -211,19 +156,21 @@ export function createRealtimeEventController({
211
156
  totalTokens: Number(message.totalTokens),
212
157
  },
213
158
  });
214
- return;
159
+ return true;
215
160
  }
216
161
  if (eventName === "context.compaction.started") {
217
162
  state.contextWindowByRequest.set(requestId, {
218
163
  ...current,
219
164
  requestId,
220
165
  pendingCompaction: {
221
- beforePercent: Number.isFinite(Number(message.beforeUsedContextPercent))
166
+ beforePercent: Number.isFinite(
167
+ Number(message.beforeUsedContextPercent),
168
+ )
222
169
  ? Number(message.beforeUsedContextPercent)
223
170
  : current.snapshot?.usedContextPercent,
224
171
  },
225
172
  });
226
- return;
173
+ return true;
227
174
  }
228
175
  if (eventName === "context.compaction.completed") {
229
176
  const beforePercent = Number(message.beforeUsedContextPercent);
@@ -237,7 +184,7 @@ export function createRealtimeEventController({
237
184
  ? { beforePercent, afterPercent }
238
185
  : current.lastCompaction,
239
186
  });
240
- return;
187
+ return true;
241
188
  }
242
189
  if (eventName === "context.compaction.failed") {
243
190
  state.contextWindowByRequest.set(requestId, {
@@ -245,12 +192,22 @@ export function createRealtimeEventController({
245
192
  requestId,
246
193
  pendingCompaction: null,
247
194
  });
195
+ return true;
248
196
  }
249
197
  }
250
198
 
251
199
  function recordEvent(message) {
200
+ const requestId = textOf(message.requestId) || state.activeRequestId;
201
+ const eventSequence = hasOriginalEventSequence(message.eventSequence)
202
+ ? message.eventSequence
203
+ : undefined;
204
+ if (hasRecordedOriginalEvent(state.events, requestId, eventSequence)) {
205
+ trackSeq(message);
206
+ return;
207
+ }
252
208
  updateTaskProgress(message);
253
- updateContextWindow(message);
209
+ const contextWindowUpdated = updateContextWindow(message);
210
+ if (contextWindowUpdated) renderContextWindow();
254
211
  const eventName = textOf(message.name || message.rawType || message.type);
255
212
  if (isLowValueActivityEvent(message)) {
256
213
  trackSeq(message);
@@ -259,10 +216,14 @@ export function createRealtimeEventController({
259
216
  const name = formatEventLabel(message);
260
217
  const summary = formatEventDetail(message);
261
218
  const tone = eventTone(message);
262
- const key = eventKeyFor(message, name, tone);
263
- const requestId = textOf(message.requestId) || state.activeRequestId;
219
+ const stage = textOf(message.stage);
220
+ const phase = textOf(message.phase);
221
+ const key = eventKeyFor({ ...message, requestId }, name, tone);
222
+ const webSources = projectWebSourceEvent(message);
264
223
  const lastEvent = state.events[state.events.length - 1];
265
- if (lastEvent?.key && lastEvent.key === key) {
224
+ if (
225
+ canMergeUnsequencedActivity(lastEvent, key, eventSequence, webSources)
226
+ ) {
266
227
  lastEvent.count = (lastEvent.count || 1) + 1;
267
228
  lastEvent.summary = summary;
268
229
  lastEvent.updatedAt = Date.now();
@@ -278,15 +239,19 @@ export function createRealtimeEventController({
278
239
  count: 1,
279
240
  lastSeqNo:
280
241
  typeof message.seqNo === "number" ? message.seqNo : undefined,
242
+ eventSequence,
281
243
  updatedAt: Date.now(),
282
244
  type: message.type,
283
245
  rawType: message.rawType,
284
246
  eventName,
247
+ stage,
248
+ phase,
285
249
  name,
286
250
  summary,
287
251
  tone,
288
252
  tool: textOf(message.tool),
289
253
  approvalId: textOf(message.approvalId),
254
+ ...(webSources ? { webSources } : {}),
290
255
  payload: {
291
256
  plan: message.plan,
292
257
  item: message.item,
@@ -285,6 +285,8 @@ export function createRuntimeSelectionController({
285
285
 
286
286
  function renderAgentMode() {
287
287
  const meta = agentModeMeta(state.agentMode);
288
+ dom.agentModeButton.title = `Reasoning depth: ${meta.label}`;
289
+ dom.agentModeButton.setAttribute("aria-label", `Reasoning depth: ${meta.label}`);
288
290
  dom.agentModeButton.disabled = agentModeMutationInFlight;
289
291
  dom.agentModeButton.innerHTML = `
290
292
  <span class="agent-mode-icon">${escapeHtml(meta.icon)}</span>
@@ -1,10 +1,5 @@
1
1
  import { matchesSessionQuery } from "../ui-behavior.js";
2
- import {
3
- escapeAttribute,
4
- escapeHtml,
5
- formatTime,
6
- textOf,
7
- } from "../lib/text-format.js";
2
+ import { escapeAttribute, escapeHtml, textOf } from "../lib/text-format.js";
8
3
  import { getNumber } from "../lib/event-presentation.js";
9
4
 
10
5
  export function createSessionController({
@@ -22,6 +17,7 @@ export function createSessionController({
22
17
  onReload,
23
18
  onControlEvent,
24
19
  confirmAction = window.confirm.bind(window),
20
+ copyText = (value) => navigator.clipboard.writeText(value),
25
21
  }) {
26
22
  const titleOf = (session) =>
27
23
  textOf(session?.displayName || session?.title || session?.id);
@@ -93,7 +89,7 @@ export function createSessionController({
93
89
  hasUnread ? "unread" : ""
94
90
  }`;
95
91
  item.innerHTML = `
96
- <button class="session-open-button" type="button">
92
+ <button class="session-open-button" type="button" title="${escapeAttribute(titleOf(session))}">
97
93
  <div class="session-title-row">
98
94
  <div class="session-title" dir="auto">${escapeHtml(titleOf(session))}</div>
99
95
  ${
@@ -104,16 +100,12 @@ export function createSessionController({
104
100
  : ""
105
101
  }
106
102
  </div>
107
- <div class="session-preview" dir="auto">${escapeHtml(
108
- session.lastMessagePreview ||
109
- formatTime(session.updatedAt) ||
110
- session.id,
111
- )}</div>
112
103
  </button>
113
104
  <div class="session-actions" aria-label="Session actions">
114
105
  <button class="session-menu-button" type="button" title="Session actions" aria-label="Session actions" aria-haspopup="menu" aria-expanded="false" aria-controls="session-menu-${sessionIndex}">•••</button>
115
106
  <div id="session-menu-${sessionIndex}" class="session-menu" role="menu" hidden>
116
107
  <button class="session-action pin-action" type="button" role="menuitem" tabindex="-1" title="${pinned ? "Unpin session" : "Pin session"}">${pinned ? "Unpin" : "Pin"}</button>
108
+ <button class="session-action copy-filename-action" type="button" role="menuitem" tabindex="-1" title="Copy session filename">Copy filename</button>
117
109
  <button class="session-action clear-action" type="button" role="menuitem" tabindex="-1" title="Reset messages">Reset</button>
118
110
  <button class="session-action delete-action" type="button" role="menuitem" tabindex="-1" title="Delete session">Delete</button>
119
111
  </div>
@@ -128,6 +120,9 @@ export function createSessionController({
128
120
  item
129
121
  .querySelector(".pin-action")
130
122
  ?.addEventListener("click", () => togglePinned(sessionId));
123
+ item
124
+ .querySelector(".copy-filename-action")
125
+ ?.addEventListener("click", () => void copyFilename(sessionId));
131
126
  item
132
127
  .querySelector(".clear-action")
133
128
  ?.addEventListener("click", () => void clearMessages(sessionId));
@@ -229,6 +224,16 @@ export function createSessionController({
229
224
  render();
230
225
  }
231
226
 
227
+ async function copyFilename(sessionId) {
228
+ sessionActionsMenu.close({ restoreFocus: true });
229
+ try {
230
+ await copyText(`${sessionId}.json`);
231
+ shell.showToast("Session filename copied");
232
+ } catch {
233
+ shell.showToast("Could not copy session filename", "failed");
234
+ }
235
+ }
236
+
232
237
  async function clearMessages(sessionId) {
233
238
  if (!sessionId || state.busySessionIds.has(sessionId)) return;
234
239
  if (