@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,6 +4,11 @@ import {
4
4
  formatEventDetail,
5
5
  formatEventLabel,
6
6
  } from "../lib/event-presentation.js";
7
+ import { countToolInvocations } from "../lib/tool-invocation-count.js";
8
+ import { buildConversationRoleCards } from "../lib/conversation-role-model.js";
9
+ import { createConversationRoleCards } from "./conversation-role-cards.js";
10
+ import { buildConversationSources } from "../lib/web-sources.js";
11
+ import { createConversationSources } from "./conversation-sources.js";
7
12
 
8
13
  function textOf(value, fallback = "") {
9
14
  return typeof value === "string" ? value : fallback;
@@ -62,11 +67,16 @@ function normalizeProgress(taskProgress, requestId) {
62
67
  ];
63
68
  })
64
69
  : [];
65
- const completed = Math.max(
66
- countOf(taskProgress.completed),
67
- items.filter((item) => item.status === "done").length,
68
- );
69
- const total = Math.max(countOf(taskProgress.total), items.length);
70
+ const hasAuthoritativeCounts = taskProgress.hasSnapshot === true;
71
+ const completed = hasAuthoritativeCounts
72
+ ? countOf(taskProgress.completed)
73
+ : Math.max(
74
+ countOf(taskProgress.completed),
75
+ items.filter((item) => item.status === "done").length,
76
+ );
77
+ const total = hasAuthoritativeCounts
78
+ ? countOf(taskProgress.total)
79
+ : Math.max(countOf(taskProgress.total), items.length);
70
80
  return {
71
81
  summary: textOf(taskProgress.summary).trim(),
72
82
  activeItem: textOf(taskProgress.activeItem).trim(),
@@ -142,6 +152,8 @@ export function buildConversationActivityModel({
142
152
  return {
143
153
  requestId: "",
144
154
  events: [],
155
+ roleCards: [],
156
+ sources: [],
145
157
  progress: null,
146
158
  contextWindow: null,
147
159
  eventCount: 0,
@@ -159,6 +171,7 @@ export function buildConversationActivityModel({
159
171
  .filter((event) => eventRequestId(event) === normalizedRequestId)
160
172
  .map(presentEvent)
161
173
  : [];
174
+ const toolCount = countToolInvocations(scopedEvents);
162
175
  const timeline = buildEventTimelineEntries(scopedEvents);
163
176
  const progress = normalizeProgress(taskProgress, normalizedRequestId);
164
177
  const contextWindowModel = normalizeContextWindow(
@@ -169,12 +182,6 @@ export function buildConversationActivityModel({
169
182
  (total, event) => total + Math.max(1, countOf(event.count, 1)),
170
183
  0,
171
184
  );
172
- const toolCount = timeline.reduce((total, event) => {
173
- const eventName = textOf(event.eventName || event.rawType || event.type);
174
- return eventName.startsWith("tool.")
175
- ? total + Math.max(1, countOf(event.count, 1))
176
- : total;
177
- }, 0);
178
185
  const failureCount = timeline.reduce(
179
186
  (total, event) =>
180
187
  event.tone === "failed"
@@ -186,6 +193,12 @@ export function buildConversationActivityModel({
186
193
  return {
187
194
  requestId: normalizedRequestId,
188
195
  events: timeline,
196
+ roleCards: buildConversationRoleCards({
197
+ requestId: normalizedRequestId,
198
+ events: scopedEvents,
199
+ streaming,
200
+ }),
201
+ sources: buildConversationSources(scopedEvents),
189
202
  progress,
190
203
  contextWindow: contextWindowModel,
191
204
  eventCount,
@@ -211,135 +224,6 @@ function appendTextNode(documentRoot, parent, className, text) {
211
224
  return node;
212
225
  }
213
226
 
214
- function renderProgress(documentRoot, progress) {
215
- if (!progress) return null;
216
- const section = documentRoot.createElement("section");
217
- section.className = "conversation-activity-progress";
218
-
219
- const header = documentRoot.createElement("div");
220
- header.className = "conversation-activity-progress-header";
221
- appendTextNode(
222
- documentRoot,
223
- header,
224
- "conversation-activity-progress-title",
225
- progress.summary || progress.activeItem || "Task progress",
226
- );
227
- if (progress.total > 0) {
228
- appendTextNode(
229
- documentRoot,
230
- header,
231
- "conversation-activity-progress-count",
232
- `${Math.min(progress.completed, progress.total)}/${progress.total}`,
233
- );
234
- }
235
- section.appendChild(header);
236
-
237
- if (progress.total > 0) {
238
- const track = documentRoot.createElement("div");
239
- track.className = "conversation-activity-progress-track";
240
- const value = documentRoot.createElement("span");
241
- value.style.width = `${Math.min(100, (progress.completed / progress.total) * 100)}%`;
242
- track.appendChild(value);
243
- section.appendChild(track);
244
- }
245
-
246
- if (progress.items.length > 0) {
247
- const list = documentRoot.createElement("ol");
248
- list.className = "conversation-activity-progress-items";
249
- for (const item of progress.items) {
250
- const row = documentRoot.createElement("li");
251
- row.className = `conversation-activity-progress-item ${item.status}`;
252
- appendTextNode(
253
- documentRoot,
254
- row,
255
- "conversation-activity-progress-dot",
256
- "",
257
- );
258
- appendTextNode(
259
- documentRoot,
260
- row,
261
- "conversation-activity-progress-label",
262
- item.title,
263
- );
264
- list.appendChild(row);
265
- }
266
- section.appendChild(list);
267
- }
268
- return section;
269
- }
270
-
271
- function compactNumber(value) {
272
- return new Intl.NumberFormat("en", { notation: "compact" }).format(value);
273
- }
274
-
275
- function formatPercent(value) {
276
- return Number.isInteger(value) ? `${value}%` : `${value.toFixed(1)}%`;
277
- }
278
-
279
- function renderContextWindow(documentRoot, contextWindow) {
280
- if (!contextWindow) return null;
281
- const section = documentRoot.createElement("section");
282
- section.className = "conversation-context-window";
283
- const header = documentRoot.createElement("div");
284
- header.className = "conversation-context-window-header";
285
- appendTextNode(
286
- documentRoot,
287
- header,
288
- "conversation-context-window-title",
289
- "Context window",
290
- );
291
- appendTextNode(
292
- documentRoot,
293
- header,
294
- `conversation-context-window-value${
295
- contextWindow.admissionOutcome === "rejected" ? " rejected" : ""
296
- }`,
297
- formatPercent(contextWindow.usedContextPercent),
298
- );
299
- section.appendChild(header);
300
-
301
- const track = documentRoot.createElement("div");
302
- track.className = "conversation-context-window-track";
303
- const value = documentRoot.createElement("span");
304
- value.style.width = `${Math.min(100, contextWindow.usedContextPercent)}%`;
305
- track.appendChild(value);
306
- section.appendChild(track);
307
-
308
- appendTextNode(
309
- documentRoot,
310
- section,
311
- "conversation-context-window-detail",
312
- `${compactNumber(contextWindow.estimatedInputTokens)} / ${compactNumber(
313
- contextWindow.contextWindowTokens,
314
- )} estimated input tokens · ${formatPercent(
315
- contextWindow.remainingContextPercent,
316
- )} left · ${contextWindow.modelStep || contextWindow.profileId}`,
317
- );
318
- if (contextWindow.compaction) {
319
- appendTextNode(
320
- documentRoot,
321
- section,
322
- "conversation-context-window-compaction",
323
- `Compaction ${formatPercent(
324
- contextWindow.compaction.beforePercent,
325
- )} → ${formatPercent(contextWindow.compaction.afterPercent)}`,
326
- );
327
- }
328
- if (contextWindow.providerUsage) {
329
- appendTextNode(
330
- documentRoot,
331
- section,
332
- "conversation-context-window-provider",
333
- `Provider reported ${compactNumber(
334
- contextWindow.providerUsage.inputTokens,
335
- )} input · ${compactNumber(
336
- contextWindow.providerUsage.outputTokens,
337
- )} output tokens`,
338
- );
339
- }
340
- return section;
341
- }
342
-
343
227
  function renderTimeline(documentRoot, events) {
344
228
  const timeline = documentRoot.createElement("div");
345
229
  timeline.className = "conversation-activity-timeline";
@@ -396,6 +280,8 @@ export function pinConversationActivityToLatest({
396
280
  }
397
281
 
398
282
  export function createConversationActivity({ documentRoot = document } = {}) {
283
+ const roleCards = createConversationRoleCards({ documentRoot });
284
+ const sourceCards = createConversationSources({ documentRoot });
399
285
  const manuallyCollapsedStreamingRequests = new Set();
400
286
  const manuallyExpandedCompletedRequests = new Set();
401
287
 
@@ -422,6 +308,11 @@ export function createConversationActivity({ documentRoot = document } = {}) {
422
308
  model.failureCount > 0 ? "Activity needs attention" : "Activity",
423
309
  );
424
310
  summary.appendChild(heading);
311
+ const roleSummary = roleCards.createSummaryNode(model.roleCards);
312
+ if (roleSummary) {
313
+ details.classList.add("has-role-summary");
314
+ summary.appendChild(roleSummary);
315
+ }
425
316
 
426
317
  if (model.currentLabel) {
427
318
  appendTextNode(
@@ -441,6 +332,13 @@ export function createConversationActivity({ documentRoot = document } = {}) {
441
332
  if (model.toolCount > 0) {
442
333
  facts.push(`${model.toolCount} tool${model.toolCount === 1 ? "" : "s"}`);
443
334
  }
335
+ const sourceCount = model.sources.reduce(
336
+ (total, group) =>
337
+ total + group.sources.length + (group.omittedSourceCount || 0),
338
+ 0,
339
+ );
340
+ if (sourceCount > 0)
341
+ facts.push(`${sourceCount} source${sourceCount === 1 ? "" : "s"}`);
444
342
  if (model.failureCount > 0) facts.push(`${model.failureCount} failed`);
445
343
  if (facts.length === 0 && model.eventCount > 0) {
446
344
  facts.push(`${model.eventCount} events`);
@@ -455,19 +353,37 @@ export function createConversationActivity({ documentRoot = document } = {}) {
455
353
 
456
354
  const body = documentRoot.createElement("div");
457
355
  body.className = "conversation-activity-body";
458
- const progress = renderProgress(documentRoot, model.progress);
459
- if (progress) body.appendChild(progress);
356
+ const hasRoleCards = model.roleCards.length > 0;
357
+ const restoreCardsScroll = hasRoleCards
358
+ ? roleCards.bindScroll({ requestId: model.requestId, body, details })
359
+ : () => false;
460
360
  if (model.events.length > 0) {
461
- body.appendChild(renderTimeline(documentRoot, model.events));
361
+ body.appendChild(
362
+ roleCards.createNode({
363
+ requestId: model.requestId,
364
+ cards: model.roleCards,
365
+ timeline: renderTimeline(documentRoot, model.events),
366
+ onViewChange() {
367
+ body.scrollTop = 0;
368
+ schedulePinToLatest();
369
+ },
370
+ }),
371
+ );
462
372
  }
373
+ const sources = sourceCards.createNode(model.sources);
374
+ if (sources) body.appendChild(sources);
463
375
  details.appendChild(body);
464
376
 
465
- const pinToLatest = () =>
466
- pinConversationActivityToLatest({
377
+ const pinToLatest = () => {
378
+ const showsTimeline =
379
+ model.roleCards.length === 0 || roleCards.isTimeline(model.requestId);
380
+ if (!showsTimeline) return restoreCardsScroll();
381
+ return pinConversationActivityToLatest({
467
382
  details,
468
383
  body,
469
- streaming: model.openByDefault,
384
+ streaming: model.openByDefault && showsTimeline,
470
385
  });
386
+ };
471
387
  const schedulePinToLatest = () => {
472
388
  const animationFrame = documentRoot.defaultView?.requestAnimationFrame;
473
389
  if (typeof animationFrame === "function") {
@@ -501,23 +417,14 @@ export function createConversationActivity({ documentRoot = document } = {}) {
501
417
  const normalizedRequestId = textOf(requestId);
502
418
  manuallyCollapsedStreamingRequests.delete(normalizedRequestId);
503
419
  manuallyExpandedCompletedRequests.delete(normalizedRequestId);
420
+ roleCards.forget(normalizedRequestId);
504
421
  }
505
422
 
506
423
  function reset() {
507
424
  manuallyCollapsedStreamingRequests.clear();
508
425
  manuallyExpandedCompletedRequests.clear();
426
+ roleCards.reset();
509
427
  }
510
428
 
511
429
  return { createNode, forget, reset };
512
430
  }
513
-
514
- export function createConversationContextWindow({
515
- documentRoot = document,
516
- } = {}) {
517
- return {
518
- createNode(input = {}) {
519
- const model = buildConversationActivityModel(input);
520
- return renderContextWindow(documentRoot, model.contextWindow);
521
- },
522
- };
523
- }
@@ -0,0 +1,23 @@
1
+ import type { buildConversationRoleCards } from "../lib/conversation-role-model.js";
2
+
3
+ export declare function createConversationRoleCards(options?: {
4
+ documentRoot?: Document;
5
+ }): {
6
+ createSummaryNode(
7
+ cards: ReturnType<typeof buildConversationRoleCards>,
8
+ ): HTMLElement | null;
9
+ createNode(input: {
10
+ requestId: string;
11
+ cards: ReturnType<typeof buildConversationRoleCards>;
12
+ timeline: HTMLElement;
13
+ onViewChange?: () => void;
14
+ }): HTMLElement;
15
+ isTimeline(requestId: string): boolean;
16
+ bindScroll(input: {
17
+ requestId: string;
18
+ body: HTMLElement;
19
+ details: HTMLDetailsElement;
20
+ }): () => boolean;
21
+ forget(requestId: string): void;
22
+ reset(): void;
23
+ };
@@ -0,0 +1,181 @@
1
+ const ROLE_INITIALS = {
2
+ supervisor: "S",
3
+ planner: "P",
4
+ worker: "W",
5
+ reviewer: "R",
6
+ };
7
+
8
+ export function createConversationRoleCards({ documentRoot = document } = {}) {
9
+ const timelineRequests = new Set();
10
+ const cardsScroll = new Map();
11
+ let panelSequence = 0;
12
+
13
+ function element(tag, className, text = "") {
14
+ const node = documentRoot.createElement(tag);
15
+ node.className = className;
16
+ node.textContent = text;
17
+ return node;
18
+ }
19
+
20
+ function textElement(tag, className, text) {
21
+ const node = element(tag, className, text);
22
+ node.setAttribute("dir", "auto");
23
+ return node;
24
+ }
25
+
26
+ function roleAvatar(role) {
27
+ const avatar = element(
28
+ "span",
29
+ "conversation-role-avatar",
30
+ ROLE_INITIALS[role],
31
+ );
32
+ avatar.setAttribute("aria-hidden", "true");
33
+ return avatar;
34
+ }
35
+
36
+ function createSummaryNode(cards) {
37
+ if (cards.length === 0) return null;
38
+ const strip = element("span", "conversation-role-summary-strip");
39
+ for (const card of cards) {
40
+ const item = element(
41
+ "span",
42
+ `conversation-role-summary-item is-${card.tone}`,
43
+ );
44
+ item.dataset.role = card.role;
45
+ item.setAttribute("role", "img");
46
+ item.setAttribute("aria-label", card.title);
47
+ item.setAttribute("title", card.title);
48
+ item.appendChild(roleAvatar(card.role));
49
+ strip.appendChild(item);
50
+ }
51
+ return strip;
52
+ }
53
+
54
+ function renderCard(card) {
55
+ const row = element("li", `conversation-role-card is-${card.tone}`);
56
+ row.dataset.role = card.role;
57
+ row.dataset.cardId = card.id;
58
+ row.appendChild(roleAvatar(card.role));
59
+ const content = element("div", "conversation-role-content");
60
+ const header = element("div", "conversation-role-header");
61
+ header.appendChild(
62
+ textElement("span", "conversation-role-title", card.title),
63
+ );
64
+ if (card.active) {
65
+ const active = element("span", "conversation-role-active");
66
+ active.setAttribute("role", "img");
67
+ active.setAttribute("aria-label", "Active role");
68
+ header.appendChild(active);
69
+ }
70
+ header.appendChild(
71
+ textElement(
72
+ "span",
73
+ "conversation-role-responsibility",
74
+ card.responsibility,
75
+ ),
76
+ );
77
+ const hasActivityError = card.tone === "failed";
78
+ if (hasActivityError) {
79
+ header.appendChild(
80
+ element("span", "conversation-role-error", "Activity error"),
81
+ );
82
+ }
83
+ if (card.facts.length > 0) {
84
+ const facts = element("ul", "conversation-role-facts");
85
+ for (const fact of card.facts) {
86
+ facts.appendChild(textElement("li", "conversation-role-fact", fact));
87
+ }
88
+ header.appendChild(facts);
89
+ }
90
+ content.appendChild(header);
91
+ if (card.summary) {
92
+ const summary = element("p", "conversation-role-summary");
93
+ summary.append(
94
+ element("span", "conversation-role-action-label", "Latest: "),
95
+ textElement("bdi", "conversation-role-action", card.summary),
96
+ );
97
+ content.appendChild(summary);
98
+ }
99
+ row.appendChild(content);
100
+ return row;
101
+ }
102
+
103
+ function isTimeline(requestId) {
104
+ return timelineRequests.has(requestId);
105
+ }
106
+
107
+ function bindScroll({ requestId, body, details }) {
108
+ const position = { top: cardsScroll.get(requestId)?.top || 0 };
109
+ cardsScroll.set(requestId, position);
110
+ function ownsVisibleCards() {
111
+ if (cardsScroll.get(requestId) !== position) return false;
112
+ if (!details.open) return false;
113
+ return !isTimeline(requestId);
114
+ }
115
+ body.addEventListener("scroll", () => {
116
+ if (!ownsVisibleCards()) return;
117
+ position.top = body.scrollTop;
118
+ });
119
+ return () => {
120
+ if (!ownsVisibleCards()) return false;
121
+ body.scrollTop = position.top;
122
+ return true;
123
+ };
124
+ }
125
+
126
+ function createNode({ requestId, cards, timeline, onViewChange = () => {} }) {
127
+ if (cards.length === 0) return timeline;
128
+ const section = element("div", "conversation-role-view");
129
+ const toolbar = element("div", "conversation-role-toolbar");
130
+ toolbar.appendChild(element("span", "conversation-role-label", "Agents"));
131
+ const toggle = element("button", "conversation-role-toggle");
132
+ toggle.type = "button";
133
+ toolbar.appendChild(toggle);
134
+ const panel = element("div", "conversation-role-panel");
135
+ panel.id = `conversation-role-panel-${++panelSequence}`;
136
+ toggle.setAttribute("aria-controls", panel.id);
137
+ const list = element("ol", "conversation-role-list");
138
+ list.setAttribute("aria-label", "Request agents");
139
+ for (const card of cards) list.appendChild(renderCard(card));
140
+ panel.append(list, timeline);
141
+ section.append(toolbar, panel);
142
+
143
+ function updateView() {
144
+ const showTimeline = isTimeline(requestId);
145
+ list.hidden = showTimeline;
146
+ timeline.hidden = !showTimeline;
147
+ section.dataset.view = showTimeline ? "timeline" : "cards";
148
+ toggle.textContent = showTimeline ? "Show agents" : "Show timeline";
149
+ }
150
+
151
+ toggle.addEventListener("click", () => {
152
+ if (isTimeline(requestId)) timelineRequests.delete(requestId);
153
+ else timelineRequests.add(requestId);
154
+ const position = cardsScroll.get(requestId);
155
+ if (position) position.top = 0;
156
+ updateView();
157
+ onViewChange();
158
+ });
159
+ updateView();
160
+ return section;
161
+ }
162
+
163
+ function forget(requestId) {
164
+ timelineRequests.delete(requestId);
165
+ cardsScroll.delete(requestId);
166
+ }
167
+
168
+ function reset() {
169
+ timelineRequests.clear();
170
+ cardsScroll.clear();
171
+ }
172
+
173
+ return {
174
+ createNode,
175
+ createSummaryNode,
176
+ isTimeline,
177
+ bindScroll,
178
+ forget,
179
+ reset,
180
+ };
181
+ }
@@ -0,0 +1,12 @@
1
+ export const CONVERSATION_SIDEBAR_MEDIA_QUERY = "(min-width: 1260px)";
2
+
3
+ export function resolveConversationSidebarLayout(workspace, activeSheet, wide) {
4
+ if (workspace !== "chat") {
5
+ return { docked: false, drawerOpen: false, visible: false };
6
+ }
7
+ if (wide) {
8
+ return { docked: true, drawerOpen: false, visible: true };
9
+ }
10
+ const drawerOpen = activeSheet === "sessions";
11
+ return { docked: false, drawerOpen, visible: drawerOpen };
12
+ }
@@ -0,0 +1,7 @@
1
+ import type { ConversationSourcesGroup } from "../lib/web-sources.js";
2
+
3
+ export declare function createConversationSources(options?: {
4
+ documentRoot?: Document;
5
+ }): {
6
+ createNode(groups?: ConversationSourcesGroup[]): HTMLElement | null;
7
+ };