@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
@@ -0,0 +1,177 @@
1
+ import { parseWebSourceUrl } from "./source-url-policy.js";
2
+
3
+ const MAX_SOURCES_PER_RECEIPT = 25;
4
+ const RETRIEVAL_STATES = new Set(["not_attempted", "retrieved", "failed"]);
5
+ const PRESENTATION_STATES = new Set([
6
+ "omitted",
7
+ "reference",
8
+ "snippet",
9
+ "content",
10
+ ]);
11
+
12
+ function record(value) {
13
+ return value && typeof value === "object" && !Array.isArray(value)
14
+ ? value
15
+ : null;
16
+ }
17
+
18
+ function operationForTool(toolName) {
19
+ if (toolName === "web_search") return "search";
20
+ if (toolName === "web_fetch") return "fetch";
21
+ return "";
22
+ }
23
+
24
+ function sourceTitle(value, hostname) {
25
+ if (typeof value !== "string" || !value.trim()) return hostname;
26
+ return value.trim().slice(0, 256);
27
+ }
28
+
29
+ function normalizeSource(value, legacy = false) {
30
+ const source = record(value);
31
+ if (!source) return null;
32
+ const url = parseWebSourceUrl(source.url);
33
+ if (!url || !RETRIEVAL_STATES.has(source.retrieval)) return null;
34
+ const hasKnownPresentation = PRESENTATION_STATES.has(source.presentation);
35
+ const hasLegacyPresentation = legacy && source.presentation === "unknown";
36
+ if (!hasKnownPresentation && !hasLegacyPresentation) return null;
37
+ const hasUnretrievedContent =
38
+ source.presentation === "content" && source.retrieval !== "retrieved";
39
+ if (hasUnretrievedContent) return null;
40
+ if (typeof source.contentTruncated !== "boolean") return null;
41
+ const requestedUrl = parseWebSourceUrl(source.requestedUrl);
42
+ return {
43
+ url: url.href,
44
+ ...(requestedUrl ? { requestedUrl: requestedUrl.href } : {}),
45
+ title: sourceTitle(source.title, url.hostname),
46
+ retrieval: source.retrieval,
47
+ presentation: source.presentation,
48
+ contentTruncated: source.contentTruncated,
49
+ };
50
+ }
51
+
52
+ function normalizeReceipt(value, toolName, legacy = false) {
53
+ const receipt = record(value);
54
+ const operation = operationForTool(toolName);
55
+ if (!receipt || !operation || receipt.operation !== operation) return null;
56
+ if (receipt.version !== (legacy ? 0 : 1)) return null;
57
+ if (!Array.isArray(receipt.sources)) return null;
58
+ if (receipt.sources.length > MAX_SOURCES_PER_RECEIPT) return null;
59
+ const omittedSourceCount = legacy ? 0 : receipt.omittedSourceCount;
60
+ const hasOmittedSourceCount =
61
+ !legacy && Object.hasOwn(receipt, "omittedSourceCount");
62
+ if (hasOmittedSourceCount && !Number.isSafeInteger(omittedSourceCount))
63
+ return null;
64
+ if (hasOmittedSourceCount && omittedSourceCount < 0) return null;
65
+ if (
66
+ hasOmittedSourceCount &&
67
+ receipt.sources.length + omittedSourceCount > MAX_SOURCES_PER_RECEIPT
68
+ )
69
+ return null;
70
+ const sources = receipt.sources
71
+ .map((source) => normalizeSource(source, legacy))
72
+ .filter(Boolean);
73
+ const provider = ["brave", "light"].includes(receipt.provider)
74
+ ? receipt.provider
75
+ : undefined;
76
+ return {
77
+ version: receipt.version,
78
+ operation,
79
+ ...(provider ? { provider } : {}),
80
+ ...(omittedSourceCount > 0 ? { omittedSourceCount } : {}),
81
+ sources,
82
+ };
83
+ }
84
+
85
+ export function normalizeWebSources(value, toolName) {
86
+ return normalizeReceipt(value, toolName);
87
+ }
88
+
89
+ function normalizedUrlSet(values) {
90
+ if (!Array.isArray(values)) return new Set();
91
+ return new Set(
92
+ values
93
+ .slice(0, MAX_SOURCES_PER_RECEIPT)
94
+ .map((value) => parseWebSourceUrl(value)?.href)
95
+ .filter(Boolean),
96
+ );
97
+ }
98
+
99
+ export function normalizeLegacyWebSources(value, toolName) {
100
+ const meta = record(value);
101
+ const operation = operationForTool(toolName);
102
+ if (!meta || !operation || !Array.isArray(meta.urls)) return null;
103
+ if (meta.urls.length > MAX_SOURCES_PER_RECEIPT) return null;
104
+ const fetched = normalizedUrlSet(meta.fetchedUrls);
105
+ const partial = normalizedUrlSet(meta.partialFetchedUrls);
106
+ const sources = meta.urls.flatMap((value) => {
107
+ const url = parseWebSourceUrl(value);
108
+ if (!url) return [];
109
+ const wasFetched =
110
+ operation === "fetch" || fetched.has(url.href) || partial.has(url.href);
111
+ return [
112
+ {
113
+ url: url.href,
114
+ title: url.hostname,
115
+ retrieval: wasFetched ? "retrieved" : "not_attempted",
116
+ presentation: "unknown",
117
+ contentTruncated: false,
118
+ },
119
+ ];
120
+ });
121
+ return {
122
+ version: 0,
123
+ operation,
124
+ ...(record(meta.lightSearch)?.provider === "light"
125
+ ? { provider: "light" }
126
+ : {}),
127
+ sources,
128
+ };
129
+ }
130
+
131
+ function eventReceipt(event) {
132
+ const toolName = event.tool;
133
+ if (event.webSources?.version === 0) {
134
+ return normalizeReceipt(event.webSources, toolName, true);
135
+ }
136
+ return normalizeWebSources(event.webSources, toolName);
137
+ }
138
+
139
+ function replayIdentity(event) {
140
+ const requestId = typeof event.requestId === "string" ? event.requestId : "";
141
+ const callId = typeof event.callId === "string" ? event.callId : "";
142
+ const originalSequence = event.eventSequence;
143
+ if (Number.isSafeInteger(originalSequence) && originalSequence > 0) {
144
+ return `${requestId}|${callId}|event:${originalSequence}`;
145
+ }
146
+ const transportSequence = event.seqNo ?? event.lastSeqNo;
147
+ if (Number.isSafeInteger(transportSequence) && transportSequence > 0) {
148
+ return `${requestId}|${callId}|transport:${transportSequence}`;
149
+ }
150
+ return callId ? `${requestId}|${callId}` : "";
151
+ }
152
+
153
+ export function buildConversationSources(events = []) {
154
+ if (!Array.isArray(events)) return [];
155
+ const groups = [];
156
+ const seen = new Set();
157
+ for (const value of events) {
158
+ const event = record(value);
159
+ if (!event || (event.eventName || event.name) !== "tool.completed")
160
+ continue;
161
+ const receipt = eventReceipt(event);
162
+ if (!receipt) continue;
163
+ const hasSourceEvidence =
164
+ receipt.sources.length > 0 || receipt.omittedSourceCount > 0;
165
+ if (!hasSourceEvidence) continue;
166
+ const identity = replayIdentity(event);
167
+ const replayKey = identity ? `${identity}|${JSON.stringify(receipt)}` : "";
168
+ if (replayKey && seen.has(replayKey)) continue;
169
+ if (replayKey) seen.add(replayKey);
170
+ groups.push({
171
+ ...receipt,
172
+ id: identity || `source-call-${groups.length + 1}`,
173
+ callId: typeof event.callId === "string" ? event.callId : "",
174
+ });
175
+ }
176
+ return groups;
177
+ }
@@ -27,7 +27,19 @@
27
27
  --font-display:
28
28
  "Segoe UI Variable Display", "Segoe UI", Inter, system-ui, sans-serif;
29
29
  --font-mono: "Cascadia Code", "SFMono-Regular", Consolas, monospace;
30
- --sessions-panel-width: 282px;
30
+ /* Readable typography shared by every workspace, including mobile. */
31
+ --font-size-xs: 0.875rem;
32
+ --font-size-sm: 0.9375rem;
33
+ --font-size-md: 1rem;
34
+ --font-size-lg: 1.0625rem;
35
+ --font-size-xl: 1.125rem;
36
+ --font-size-2xl: 1.25rem;
37
+ --font-size-3xl: 1.375rem;
38
+ --font-size-4xl: 1.5rem;
39
+ --font-size-5xl: 1.625rem;
40
+ --font-size-6xl: 1.875rem;
41
+ --font-size-7xl: 2.25rem;
42
+ --sessions-panel-width: 320px;
31
43
  --chat-content-width: 900px;
32
44
  --scrollbar-thumb: rgba(95, 127, 158, 0.34);
33
45
  --scrollbar-thumb-active: rgba(118, 157, 194, 0.54);
@@ -56,7 +68,7 @@ body {
56
68
  var(--bg);
57
69
  color: var(--text);
58
70
  font-family: var(--font-ui);
59
- font-size: 14px;
71
+ font-size: var(--font-size-xl);
60
72
  }
61
73
 
62
74
  button,
@@ -72,7 +84,7 @@ textarea {
72
84
 
73
85
  button {
74
86
  min-height: 36px;
75
- font-size: 13px;
87
+ font-size: var(--font-size-lg);
76
88
  font-weight: 620;
77
89
  transition:
78
90
  border-color 150ms ease,
@@ -40,7 +40,7 @@
40
40
  border-radius: 12px;
41
41
  background: #2c6ee8;
42
42
  color: #fff;
43
- font-size: 18px;
43
+ font-size: var(--font-size-4xl);
44
44
  font-weight: 700;
45
45
  box-shadow: none;
46
46
  }
@@ -125,7 +125,7 @@
125
125
  border-radius: 7px;
126
126
  background: #142234;
127
127
  color: var(--text);
128
- font-size: 12px;
128
+ font-size: var(--font-size-md);
129
129
  font-weight: 500;
130
130
  white-space: nowrap;
131
131
  opacity: 0;
@@ -200,7 +200,7 @@
200
200
  color: var(--muted);
201
201
  text-overflow: ellipsis;
202
202
  white-space: nowrap;
203
- font-size: 11px;
203
+ font-size: var(--font-size-sm);
204
204
  font-weight: 550;
205
205
  }
206
206
 
@@ -322,7 +322,7 @@
322
322
  border-radius: 9px;
323
323
  background: #2c6ee8;
324
324
  color: #fff;
325
- font-size: 14px;
325
+ font-size: var(--font-size-xl);
326
326
  font-weight: 700;
327
327
  box-shadow: none;
328
328
  }
@@ -334,7 +334,7 @@
334
334
  #sessionsHeading {
335
335
  margin: 0;
336
336
  color: var(--text-strong);
337
- font-size: 18px;
337
+ font-size: var(--font-size-4xl);
338
338
  font-weight: 400;
339
339
  letter-spacing: -0.02em;
340
340
  }
@@ -342,7 +342,7 @@
342
342
  .brand-row h1 {
343
343
  margin: 0;
344
344
  color: var(--text-strong);
345
- font-size: 15px;
345
+ font-size: var(--font-size-2xl);
346
346
  font-weight: 650;
347
347
  letter-spacing: -0.01em;
348
348
  }
@@ -350,7 +350,7 @@
350
350
  .brand-row p {
351
351
  margin: 2px 0 0;
352
352
  color: var(--muted-2);
353
- font-size: 12px;
353
+ font-size: var(--font-size-md);
354
354
  }
355
355
 
356
356
  .icon-button,
@@ -393,7 +393,7 @@
393
393
  border-radius: 10px;
394
394
  background: #2869dc;
395
395
  color: #f8fbff;
396
- font-size: 13px;
396
+ font-size: var(--font-size-lg);
397
397
  font-weight: 600;
398
398
  box-shadow: none;
399
399
  }
@@ -420,13 +420,13 @@
420
420
  .sessions-heading-row h2 {
421
421
  margin: 0;
422
422
  color: var(--text);
423
- font-size: 13px;
423
+ font-size: var(--font-size-lg);
424
424
  font-weight: 600;
425
425
  }
426
426
 
427
427
  .sessions-list-label {
428
428
  color: var(--muted);
429
- font-size: 12px;
429
+ font-size: var(--font-size-md);
430
430
  font-weight: 400;
431
431
  }
432
432
 
@@ -437,7 +437,7 @@
437
437
  background: rgba(105, 147, 188, 0.1);
438
438
  color: var(--muted);
439
439
  text-align: center;
440
- font-size: 11px;
440
+ font-size: var(--font-size-sm);
441
441
  font-weight: 400;
442
442
  }
443
443
 
@@ -465,7 +465,7 @@
465
465
  border-radius: 9px;
466
466
  background: rgba(92, 132, 172, 0.08);
467
467
  color: var(--text);
468
- font-size: 13px;
468
+ font-size: var(--font-size-lg);
469
469
  box-shadow: none;
470
470
  }
471
471
 
@@ -496,12 +496,12 @@
496
496
 
497
497
  .sidebar-empty-state strong {
498
498
  color: var(--text);
499
- font-size: 13px;
499
+ font-size: var(--font-size-lg);
500
500
  font-weight: 600;
501
501
  }
502
502
 
503
503
  .sidebar-empty-state span {
504
- font-size: 12px;
504
+ font-size: var(--font-size-md);
505
505
  line-height: 1.5;
506
506
  }
507
507
 
@@ -556,7 +556,7 @@
556
556
  padding: 0 30px 0 0;
557
557
  border: 0;
558
558
  background: transparent;
559
- text-align: left;
559
+ text-align: start;
560
560
  box-shadow: none;
561
561
  }
562
562
 
@@ -577,30 +577,20 @@
577
577
  color: var(--text);
578
578
  text-overflow: ellipsis;
579
579
  white-space: nowrap;
580
- font-size: 13px;
580
+ font-size: var(--font-size-lg);
581
581
  font-weight: 400;
582
582
  }
583
583
 
584
- .session-preview {
585
- display: -webkit-box;
586
- overflow: hidden;
587
- color: var(--muted-2);
588
- font-size: 12px;
589
- line-height: 1.4;
590
- -webkit-box-orient: vertical;
591
- -webkit-line-clamp: 2;
592
- }
593
-
594
584
  .session-unread-badge {
595
585
  display: inline-grid;
596
586
  place-items: center;
597
- min-width: 18px;
598
- height: 18px;
587
+ min-width: 1.5rem;
588
+ height: 1.5rem;
599
589
  padding: 0 5px;
600
590
  border-radius: 999px;
601
591
  background: rgba(87, 148, 255, 0.18);
602
592
  color: #cfe0ff;
603
- font-size: 10px;
593
+ font-size: var(--font-size-xs);
604
594
  font-weight: 650;
605
595
  }
606
596
 
@@ -630,7 +620,7 @@
630
620
  border-radius: 7px;
631
621
  background: rgba(10, 23, 37, 0.9);
632
622
  color: var(--muted);
633
- font-size: 10px;
623
+ font-size: var(--font-size-xs);
634
624
  letter-spacing: -1px;
635
625
  box-shadow: none;
636
626
  }
@@ -662,7 +652,7 @@
662
652
  background: transparent;
663
653
  color: var(--text);
664
654
  text-align: left;
665
- font-size: 12px;
655
+ font-size: var(--font-size-md);
666
656
  box-shadow: none;
667
657
  }
668
658
 
@@ -700,7 +690,7 @@
700
690
  align-items: center;
701
691
  gap: 7px;
702
692
  color: var(--muted);
703
- font-size: 12px;
693
+ font-size: var(--font-size-md);
704
694
  font-weight: 500;
705
695
  }
706
696
 
@@ -723,7 +713,7 @@
723
713
  .field-label,
724
714
  .control-label {
725
715
  color: var(--muted-2);
726
- font-size: 11px;
716
+ font-size: var(--font-size-sm);
727
717
  font-weight: 500;
728
718
  }
729
719
 
@@ -801,7 +791,7 @@
801
791
  border-radius: 6px;
802
792
  background: transparent;
803
793
  color: var(--muted);
804
- font-size: 12px;
794
+ font-size: var(--font-size-md);
805
795
  font-weight: 550;
806
796
  text-align: center;
807
797
  text-transform: capitalize;
@@ -0,0 +1,93 @@
1
+ /* Persistent conversation navigation; viewport policy lives in workspace-shell. */
2
+
3
+ .app-shell.sessions-docked {
4
+ grid-template-columns: 72px var(--sessions-panel-width) minmax(0, 1fr);
5
+ }
6
+
7
+ .app-shell.sessions-docked .sessions-panel {
8
+ position: relative;
9
+ inset: auto;
10
+ z-index: 2;
11
+ grid-column: 2;
12
+ grid-row: 1;
13
+ width: auto;
14
+ height: 100%;
15
+ opacity: 1;
16
+ pointer-events: auto;
17
+ transform: none;
18
+ transition: none;
19
+ box-shadow: none;
20
+ }
21
+
22
+ .app-shell.sessions-docked .chat-panel {
23
+ grid-column: 3;
24
+ }
25
+
26
+ .session-item {
27
+ align-items: center;
28
+ min-height: 38px;
29
+ margin-block-end: 3px;
30
+ padding: 7px 9px 7px 12px;
31
+ border-radius: 8px;
32
+ background: transparent;
33
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--line) 35%, transparent);
34
+ }
35
+
36
+ .session-item:hover,
37
+ .session-item:focus-within {
38
+ background: var(--control-bg-hover);
39
+ }
40
+
41
+ .session-item.active,
42
+ .session-item.active:hover,
43
+ .session-item.active:focus-within {
44
+ background: var(--accent-soft);
45
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent);
46
+ }
47
+
48
+ .session-open-button {
49
+ align-content: center;
50
+ min-height: 24px;
51
+ gap: 0;
52
+ padding: 0;
53
+ padding-inline-end: 30px;
54
+ border-radius: 4px;
55
+ }
56
+
57
+ .session-open-button:focus-visible {
58
+ outline: 2px solid var(--accent-strong);
59
+ outline-offset: 3px;
60
+ }
61
+
62
+ .session-title {
63
+ font-size: var(--font-size-sm);
64
+ line-height: 1.4;
65
+ text-align: start;
66
+ }
67
+
68
+ .session-item.active .session-title,
69
+ .session-item.unread .session-title {
70
+ color: var(--text-strong);
71
+ font-weight: 550;
72
+ }
73
+
74
+ .session-item.pinned::before {
75
+ top: 50%;
76
+ left: auto;
77
+ inset-inline-start: 4px;
78
+ transform: translateY(-50%);
79
+ }
80
+
81
+ .session-actions {
82
+ top: 6px;
83
+ }
84
+
85
+ .session-menu-button {
86
+ background: transparent;
87
+ }
88
+
89
+ .session-menu-button:hover,
90
+ .session-menu-button:focus-visible {
91
+ background: var(--control-bg-hover);
92
+ color: var(--text-strong);
93
+ }