@jini-ai/chat 0.3.11 → 0.5.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 (205) hide show
  1. package/CHANGELOG.md +126 -0
  2. package/README.md +152 -6
  3. package/dist/core/ag-ui/entry.d.ts +53 -0
  4. package/dist/core/ag-ui/entry.js +135 -0
  5. package/dist/core/agentic/chat-capabilities.d.ts +1 -1
  6. package/dist/core/agentic/index.d.ts +1 -1
  7. package/dist/core/agentic/index.js +1 -1
  8. package/dist/core/assistant-content.d.ts +6 -2
  9. package/dist/core/assistant-content.js +2 -2
  10. package/dist/core/compact-events.d.ts +3 -1
  11. package/dist/core/compact-events.js +1 -1
  12. package/dist/core/events.d.ts +1 -1
  13. package/dist/core/events.js +1 -1
  14. package/dist/core/index.d.ts +3 -3
  15. package/dist/core/index.js +3 -3
  16. package/dist/core/messages.d.ts +4 -2
  17. package/dist/core/messages.js +2 -2
  18. package/dist/core/partial-json.d.ts +6 -2
  19. package/dist/core/partial-json.js +3 -3
  20. package/dist/core/persistence/index.d.ts +1 -1
  21. package/dist/core/persistence/index.js +1 -1
  22. package/dist/core/persistence/ports.d.ts +2 -123
  23. package/dist/core/persistence/title.d.ts +3 -1
  24. package/dist/core/persistence/title.js +1 -1
  25. package/dist/core/question-form/format.d.ts +16 -7
  26. package/dist/core/question-form/format.js +3 -3
  27. package/dist/core/question-form/normalize.d.ts +7 -2
  28. package/dist/core/question-form/normalize.js +5 -5
  29. package/dist/core/question-form/scan.d.ts +18 -6
  30. package/dist/core/question-form/scan.js +14 -14
  31. package/dist/core/run-activity.d.ts +16 -4
  32. package/dist/core/run-activity.js +11 -11
  33. package/dist/core/run-events/entry.d.ts +121 -0
  34. package/dist/core/run-events/entry.js +290 -0
  35. package/dist/core/todos.d.ts +20 -8
  36. package/dist/core/todos.js +11 -11
  37. package/dist/core/tool-events.d.ts +3 -1
  38. package/dist/core/tool-events.js +1 -1
  39. package/dist/core/tool-output.d.ts +3 -1
  40. package/dist/core/tool-output.js +1 -1
  41. package/dist/core/tools.d.ts +14 -3
  42. package/dist/core/tools.js +3 -3
  43. package/dist/core/transcript.d.ts +13 -5
  44. package/dist/core/transcript.js +5 -5
  45. package/dist/core/util/manifest.d.ts +9 -3
  46. package/dist/core/util/manifest.js +3 -3
  47. package/dist/core/util/markdown-context.d.ts +11 -3
  48. package/dist/core/util/markdown-context.js +3 -3
  49. package/dist/core/util/markup-attributes.d.ts +3 -1
  50. package/dist/core/util/markup-attributes.js +1 -1
  51. package/dist/core/util/parser.d.ts +9 -5
  52. package/dist/core/util/parser.js +13 -13
  53. package/dist/core/util/recover.d.ts +6 -2
  54. package/dist/core/util/recover.js +6 -6
  55. package/dist/core/util/strip.d.ts +19 -5
  56. package/dist/core/util/strip.js +17 -17
  57. package/dist/core/util/validate.d.ts +3 -1
  58. package/dist/core/util/validate.js +1 -1
  59. package/dist/embed-widget/browser/page-actions.d.ts +121 -0
  60. package/dist/embed-widget/browser/page-actions.js +113 -0
  61. package/dist/embed-widget/browser/session-store.d.ts +44 -0
  62. package/dist/embed-widget/browser/session-store.js +103 -0
  63. package/dist/embed-widget/react/embed.d.ts +45 -0
  64. package/dist/embed-widget/react/embed.js +87 -0
  65. package/dist/embed-widget/react/header.d.ts +21 -0
  66. package/dist/embed-widget/react/header.js +18 -0
  67. package/dist/embed-widget/transports/fetch-sse.d.ts +75 -0
  68. package/dist/embed-widget/transports/fetch-sse.js +175 -0
  69. package/dist/react/agent-bridge/frontend-session-bridge.d.ts +15 -3
  70. package/dist/react/agent-bridge/frontend-session-bridge.js +13 -6
  71. package/dist/react/artifact-types.d.ts +3 -3
  72. package/dist/react/artifact-types.js +3 -3
  73. package/dist/react/components/A2uiSurfaceCard.js +34 -13
  74. package/dist/react/components/AttachmentPreviewModal.hooks.d.ts +7 -2
  75. package/dist/react/components/AttachmentPreviewModal.hooks.js +5 -5
  76. package/dist/react/components/AttachmentPreviewModal.js +2 -2
  77. package/dist/react/components/AttachmentTray.d.ts +3 -1
  78. package/dist/react/components/AttachmentTray.js +2 -2
  79. package/dist/react/components/ChatFab.js +1 -1
  80. package/dist/react/components/Composer.js +9 -9
  81. package/dist/react/components/ConversationList.js +1 -1
  82. package/dist/react/components/McpUiSurfaceCard.d.ts +4 -2
  83. package/dist/react/components/McpUiSurfaceCard.js +5 -5
  84. package/dist/react/components/MessageList.js +1 -1
  85. package/dist/react/components/MessageRow.js +9 -9
  86. package/dist/react/components/QuestionForm.js +5 -5
  87. package/dist/react/components/ToolCard.js +9 -9
  88. package/dist/react/components/composer-discovery.d.ts +29 -8
  89. package/dist/react/components/composer-discovery.js +10 -10
  90. package/dist/react/ext-event-renderer-registry.d.ts +15 -5
  91. package/dist/react/ext-event-renderer-registry.js +4 -4
  92. package/dist/react/features/chat-pane/components/AgentRuntimePicker.d.ts +3 -1
  93. package/dist/react/features/chat-pane/components/AgentRuntimePicker.js +3 -3
  94. package/dist/react/features/chat-pane/components/ChatPane.js +43 -43
  95. package/dist/react/features/chat-pane/create-daemon-attachment-uploader.d.ts +4 -1
  96. package/dist/react/features/chat-pane/create-daemon-attachment-uploader.js +5 -35
  97. package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.d.ts +5 -2
  98. package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.js +1 -1
  99. package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.d.ts +38 -10
  100. package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.js +15 -15
  101. package/dist/react/features/chat-pane/hooks/useChatPane.hooks.js +31 -31
  102. package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.d.ts +3 -1
  103. package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.js +3 -3
  104. package/dist/react/features/chat-pane/hooks/useChatPaneComposerPlaceholder.hooks.d.ts +4 -1
  105. package/dist/react/features/chat-pane/hooks/useChatPaneComposerPlaceholder.hooks.js +1 -1
  106. package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.js +30 -30
  107. package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.js +57 -57
  108. package/dist/react/features/chat-pane/rules.d.ts +13 -4
  109. package/dist/react/features/chat-pane/rules.js +5 -5
  110. package/dist/react/features/chat-pane/types.d.ts +1 -1
  111. package/dist/react/hooks/attachment-preview-cache.d.ts +7 -2
  112. package/dist/react/hooks/attachment-preview-cache.js +2 -2
  113. package/dist/react/hooks/composer-draft-cache.d.ts +17 -5
  114. package/dist/react/hooks/composer-draft-cache.js +6 -6
  115. package/dist/react/hooks/useArtifactStream.d.ts +5 -1
  116. package/dist/react/hooks/useArtifactStream.js +3 -3
  117. package/dist/react/hooks/useChatFabDrag.d.ts +9 -4
  118. package/dist/react/hooks/useChatFabDrag.js +4 -4
  119. package/dist/react/hooks/useComposer.js +8 -8
  120. package/dist/react/hooks/useConversation.js +56 -4
  121. package/dist/react/hooks/useExtEventGroups.d.ts +5 -1
  122. package/dist/react/hooks/useExtEventGroups.js +1 -1
  123. package/dist/react/hooks/useLatestOperation.d.ts +8 -3
  124. package/dist/react/hooks/useLatestOperation.js +4 -4
  125. package/dist/react/hooks/usePinnedTodos.d.ts +3 -1
  126. package/dist/react/hooks/usePinnedTodos.js +3 -3
  127. package/dist/react/hooks/useQuestionForms.d.ts +7 -2
  128. package/dist/react/hooks/useQuestionForms.js +7 -7
  129. package/dist/react/hooks/useRunActivity.d.ts +6 -1
  130. package/dist/react/hooks/useRunActivity.js +3 -3
  131. package/dist/react/hooks/useRunStream.d.ts +3 -1
  132. package/dist/react/hooks/useRunStream.js +1 -1
  133. package/dist/react/hooks/useToolTimeline.d.ts +3 -1
  134. package/dist/react/hooks/useToolTimeline.js +3 -3
  135. package/dist/react/index.d.ts +4 -4
  136. package/dist/react/index.js +6 -6
  137. package/dist/react/message-blocks.d.ts +10 -4
  138. package/dist/react/message-blocks.js +2 -2
  139. package/dist/react/styles/reference.css +3 -3
  140. package/dist/react/tool-renderer-registry.d.ts +8 -3
  141. package/dist/react/tool-renderer-registry.js +3 -3
  142. package/dist/react/util/defined-props.d.ts +3 -1
  143. package/dist/react/util/defined-props.js +1 -1
  144. package/dist/server/run-finalizer/entry.d.ts +47 -0
  145. package/dist/server/run-finalizer/entry.js +156 -0
  146. package/dist/server/run-finalizer/ports.d.ts +52 -0
  147. package/dist/store/contracts/index.d.ts +5 -0
  148. package/dist/store/contracts/index.js +5 -0
  149. package/dist/store/errors.d.ts +12 -0
  150. package/dist/store/errors.js +18 -0
  151. package/dist/store/index.d.ts +4 -0
  152. package/dist/store/index.js +2 -0
  153. package/dist/store/legacy/index.d.ts +3 -0
  154. package/dist/store/legacy/index.js +2 -0
  155. package/dist/store/legacy/sqlite/conversations.d.ts +129 -0
  156. package/dist/store/legacy/sqlite/conversations.js +274 -0
  157. package/dist/store/legacy/sqlite/index.d.ts +6 -0
  158. package/dist/store/legacy/sqlite/index.js +5 -0
  159. package/dist/store/legacy/sqlite/messages.d.ts +156 -0
  160. package/dist/store/legacy/sqlite/messages.js +246 -0
  161. package/dist/store/legacy/sqlite/schema.d.ts +3 -0
  162. package/dist/store/legacy/sqlite/schema.js +40 -0
  163. package/dist/store/pglite/index.d.ts +21 -0
  164. package/dist/store/pglite/index.js +17 -0
  165. package/dist/store/ports.d.ts +121 -0
  166. package/dist/store/ports.js +2 -0
  167. package/dist/store/postgres/index.d.ts +21 -0
  168. package/dist/store/postgres/index.js +17 -0
  169. package/dist/store/sql/boundary.d.ts +28 -0
  170. package/dist/store/sql/boundary.js +32 -0
  171. package/dist/store/sql/cursor.d.ts +24 -0
  172. package/dist/store/sql/cursor.js +49 -0
  173. package/dist/store/sql/maintenance.d.ts +9 -0
  174. package/dist/store/sql/maintenance.js +16 -0
  175. package/dist/store/sql/store.d.ts +22 -0
  176. package/dist/store/sql/store.js +340 -0
  177. package/dist/store/sql/tables.d.ts +34 -0
  178. package/dist/store/sql/tables.js +2 -0
  179. package/dist/store/sqlite/index.d.ts +36 -0
  180. package/dist/store/sqlite/index.js +29 -0
  181. package/dist/store/sqlite/schema.d.ts +49 -0
  182. package/dist/store/sqlite/schema.js +80 -0
  183. package/package.json +211 -14
  184. package/dist/react/features/model-picker/components/CredentialStatusBadge.d.ts +0 -7
  185. package/dist/react/features/model-picker/components/CredentialStatusBadge.js +0 -20
  186. package/dist/react/features/model-picker/components/ModelPicker.d.ts +0 -9
  187. package/dist/react/features/model-picker/components/ModelPicker.js +0 -34
  188. package/dist/react/features/model-picker/constants.d.ts +0 -6
  189. package/dist/react/features/model-picker/constants.js +0 -9
  190. package/dist/react/features/model-picker/dependencies.d.ts +0 -11
  191. package/dist/react/features/model-picker/dependencies.js +0 -10
  192. package/dist/react/features/model-picker/hooks/useModelPicker.hooks.d.ts +0 -27
  193. package/dist/react/features/model-picker/hooks/useModelPicker.hooks.js +0 -62
  194. package/dist/react/features/model-picker/index.d.ts +0 -32
  195. package/dist/react/features/model-picker/index.js +0 -29
  196. package/dist/react/features/model-picker/ports.d.ts +0 -11
  197. package/dist/react/features/model-picker/rules.d.ts +0 -26
  198. package/dist/react/features/model-picker/rules.js +0 -84
  199. package/dist/react/features/model-picker/types.d.ts +0 -38
  200. package/dist/react/features/model-picker/types.js +0 -2
  201. package/dist/react/poc-mcp-ui-official/PocMcpUiCard.d.ts +0 -9
  202. package/dist/react/poc-mcp-ui-official/PocMcpUiCard.js +0 -29
  203. package/dist/react/poc-mcp-ui-official/create-poc-resource.d.ts +0 -30
  204. package/dist/react/poc-mcp-ui-official/create-poc-resource.js +0 -44
  205. /package/dist/{react/features/model-picker → server/run-finalizer}/ports.js +0 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,126 @@
1
+ ## Unreleased
2
+
3
+ - Type store fixtures with the shared storage kernel and chat contracts, including host-owned tables;
4
+ align construction, reopening, paging and message fixtures with current API shapes.
5
+ - Declare jsdom and better-sqlite3 development types for package-wide test compilation.
6
+
7
+ - Update the A2UI chat renderer and its catalog fixture to the agentic/UI object-argument APIs.
8
+ Supply the shared system clock and preserve the existing action-ID sequence and timestamp format;
9
+ adapt interpreter unsubscribe to React cleanup without type assertions.
10
+ - Include tests in package typechecking; align capability/barrel calls, run-event fixtures and the
11
+ finalizer's asynchronous daemon mock with their current contracts.
12
+
13
+ - Remove the unexported MCP-UI proof of concept, its fixtures and tests, and the unused internal
14
+ model picker with its tests. Neither directory was reachable from a public entry point.
15
+ - Exclude both directories' stale compiled output from distribution when rebuilding over an old dist.
16
+ - Drop chat's direct `@mcp-ui/client` and `@mcp-ui/server` dependencies; the live MCP-UI surface
17
+ continues to use the shared UI implementation. Public exports and runtime behavior are unchanged.
18
+
19
+ ## 0.5.0 — 2026-10-02
20
+
21
+ ### BREAKING
22
+
23
+ - Browser fetch is injected; run activity/finalization use canonical ports and embed/browser surfaces are isolated. CSS imports remain side effects for bundlers.
24
+ - Distribution includes runtime output, release documentation and required assets only. Process records and per-job neutrality checks are no longer part of the package surface.
25
+
26
+ - Browser bridge/uploader fetch ports default to global fetch. Partial-upload cleanup now uses the injected uploader fetch; quick deadlines stay 15 seconds. Remove platform dependency and retain native timeout reasons.
27
+
28
+ - Adopt shared kernel contracts and preserve the module rationale in neutral documentation.
29
+ - Add run-event folding, injected run settlement and the optional AG-UI projection on isolated subpaths.
30
+ - Add opt-in embeddable chat composition, injected fetch/SSE transport, bounded browser session storage and host-controlled page actions on isolated subpaths.
31
+ - Convert public helper and compatibility factory argument shapes to required and optional objects while preserving transcript storage, ownership checks and renderer priority.
32
+ - Correct renderer priority and opt-in stylesheet documentation; retain the layout rationale with neutral provenance.
33
+ - BREAKING: replace the local finalizer Clock with core Clock.nowMs(); core/React helpers and ext-event slot-key callbacks take required objects.
34
+
35
+
36
+ - BREAKING: ChatStore methods use required argument objects; paging options move to the second bag. ChatHistoryMaintenance and ChatStoreFactory follow the same convention.
37
+ - BREAKING: SQLite/Postgres/PGlite factories use core `Clock` through `{ clock }` rather than `{ now }`; system-time defaults and SQL behavior are preserved.
38
+
39
+ ## 0.4.0 (unpublished release candidate)
40
+
41
+ - Owner-scoped transcript adapters and paging live on store subpaths; the host supplies the migrated kernel.
42
+
43
+ ## Unreleased
44
+
45
+ - Add neutral owner-scoped ChatStore, structured errors and bounded keyset pages.
46
+ - Add SQLite, embedded/socket PGlite and Postgres adapters over the same borrowed kernel SQL body.
47
+ - Preserve the eight-method ChatHistoryStore contract and existing stored schema/projection.
48
+
49
+ # @jini-ai/chat-core
50
+
51
+ ## @jini-ai/chat 0.3.11
52
+
53
+ ### Patch Changes
54
+
55
+ - `useChatPaneRuntimeInventory` polls daemon health only while the tab is visible. Hiding the
56
+ tab clears the interval; showing it checks status once and restarts the interval. A tick is
57
+ skipped while the previous status call is still in flight. Hosts no longer need their own
58
+ hidden-tab probe gate for this hook.
59
+
60
+ ## 0.1.2
61
+
62
+ ### Patch Changes
63
+
64
+ - Add top-level `main`/`types` fields alongside the existing `exports` map. A consumer on
65
+ TypeScript's classic `moduleResolution: "node"` (node10) — which ignores `package.json#exports`
66
+ entirely — could not resolve this package's types at all (`TS2307: Cannot find module`) even
67
+ after the previous exports-map fix restored `require()` at runtime; type resolution and runtime
68
+ resolution are separate algorithms. Verified against a real external consumer (whose
69
+ tsconfig uses this legacy resolution mode): adding these two fields, with its tsconfig completely
70
+ unchanged, made the error disappear. Also fixes absolute-path `require()` (distinct from a bare
71
+ specifier, which already worked) for the same reason — `main` was previously absent.
72
+
73
+ Purely additive: every modern resolver (Node's own runtime `exports` resolution, TypeScript's
74
+ `bundler`/`node16`/`nodenext`) prefers `exports` over `main`/`types` when both are present, so
75
+ this changes nothing for a consumer already on a modern resolver.
76
+
77
+ - Updated dependencies
78
+ - @jini-ai/agentic@0.1.2
79
+
80
+ ## 0.1.1
81
+
82
+ ### Patch Changes
83
+
84
+ - Add a `"default"` export condition to every published package's `exports` map — every one of
85
+ them lacked it, which meant `require()` failed with `ERR_PACKAGE_PATH_NOT_EXPORTED` for any
86
+ CommonJS consumer (found via a real external integration attempt; Node needs `require(esm)`
87
+ support, i.e. Node >=22.12, for this to resolve).
88
+
89
+ `@jini-ai/agent-runtime`:
90
+
91
+ - **New**: `RuntimeBuildOptions.permissionMode` (`'bypass' | 'restricted'`) lets a caller opt a
92
+ run OUT of the auto-approve-every-permission-prompt flag every def with one
93
+ (`bypassPermissions` / `--yolo` / `--dangerously-skip-permissions`) previously pushed
94
+ unconditionally, with no way to turn it off. Omitting it keeps today's default (bypass)
95
+ behavior unchanged.
96
+ - **New**: `ClaudeStreamEvent`, `CopilotStreamEvent`, and `QoderEvent` are now real exported
97
+ discriminated unions instead of `Record<string, unknown>` — a real external consumer guessed a
98
+ nonexistent field name (`event.text` instead of the actual `event.delta`) against the old
99
+ untyped sink and silently lost every streamed token with no compile or runtime error.
100
+ - Fixed a doc/implementation mismatch in `claude-stream.ts`: the module doc claimed `tool_result`
101
+ events carry `{ tool_use_id, content, is_error }`; the actual emitted shape is
102
+ `{ toolUseId, content, isError }`.
103
+
104
+ `@jini-ai/daemon`: `AgentExecutorRunInput.permissionMode` forwards the new
105
+ `RuntimeBuildOptions.permissionMode` through to `buildArgs`, so a host can actually reach the new
106
+ opt-out from the daemon's real run-input surface, not just from `@jini-ai/agent-runtime` in
107
+ isolation.
108
+
109
+ `@jini-ai/agentic`: `setAtPointer` no longer throws on a malformed (e.g. missing leading `/`)
110
+ `updateDataModel` path — degrades to a no-op like its sibling `getAtPointer`, matching this
111
+ package's own "a bad binding must not crash the renderer" contract. That path is agent-authored
112
+ wire data with no error boundary above it in any host, so the uncaught throw could unmount an
113
+ entire chat UI from ~40 bytes of malformed input.
114
+
115
+ `@jini-ai/chat-react`: a local (client-resolved) A2UI button action is no longer a silent no-op —
116
+ `A2uiSurfaceCard` now surfaces the resolved value. New `ExtEventErrorBoundary` confines a
117
+ `kind: 'ext'` event group's renderer to its own card instead of letting a render/effect-phase
118
+ throw from agent-controlled content unmount the whole chat root (there was no error boundary
119
+ anywhere in this package or its hosts before this).
120
+
121
+ - Updated dependencies
122
+ - @jini-ai/agentic@0.1.1
123
+
124
+ ### C2 storage ownership
125
+ - Added `./store/legacy` and `./store/legacy/sqlite`; preserved sync local project chat CRUD and schema.
126
+ - Retained the original owner-isolation suite on the concern adapter after draining the old package.
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > This README currently documents only the `./core` subpath — chat-core's own content, moved here
4
4
  > verbatim. `./react` (formerly `@jini-ai/ui`'s `./chat` export) is landing in the same 2026-08-03
5
5
  > consolidation; this file will be extended to cover it once that move is complete rather than
6
- > rewritten twice. See `packages/chat/src/core/source-map.md` for `./core`'s own provenance.
6
+ > rewritten twice. See the archived provenance ledger for `./core`'s own provenance.
7
7
 
8
8
  Framework-free chat vocabulary and pure parsers for a chat/artifact frontend: the message and
9
9
  run-event types, the `ChatTransport` port a host implements to reach a real agent runtime, and a
@@ -25,7 +25,7 @@ npm install @jini-ai/chat
25
25
  import { ChatMessage } from '@jini-ai/chat/core'; // or the bare '@jini-ai/chat' alias
26
26
  ```
27
27
 
28
- No peer dependencies. `@jini-ai/agentic` is a regular dependency, pulled in for the
28
+ Core needs no optional peers. `@jini-ai/agentic` is a regular dependency, pulled in for the
29
29
  `CapabilityDef` vocabulary this package's `CHAT_CAPABILITIES` manifest is built from.
30
30
 
31
31
  ## What you get
@@ -78,11 +78,11 @@ const history: ChatMessage[] = [
78
78
  { id: '2', role: 'assistant', content: '', runStatus: 'running', events: [] },
79
79
  ];
80
80
 
81
- const transcript = buildTranscript(history);
81
+ const transcript = buildTranscript({ history });
82
82
 
83
83
  function onDone(finalEvents: ChatMessage['events'] = []) {
84
- const toolEvents = dedupeToolUsesById(finalEvents);
85
- console.log(toolEvents.length, 'tool calls,', isTerminalRunStatus('succeeded'));
84
+ const toolEvents = dedupeToolUsesById({ events: finalEvents });
85
+ console.log(toolEvents.length, 'tool calls,', isTerminalRunStatus({ status: 'succeeded' }));
86
86
  }
87
87
 
88
88
  // Implement once per host — a fetch/SSE adapter, a WebSocket adapter, or a test fake.
@@ -105,5 +105,151 @@ ESM only — ships `"type": "module"` with no CommonJS `require` build.
105
105
 
106
106
  ## Provenance
107
107
 
108
- See [source-map.md](./source-map.md) for per-file provenance and scope decisions. Apache-2.0,
108
+ See the archived provenance ledger for per-file provenance and scope decisions. Apache-2.0,
109
109
  inherited from Open Design — see the repo `NOTICE`.
110
+
111
+ ## Durable transcript store
112
+
113
+ `@jini-ai/chat/store` exports the async `ChatStore`, its immutable owner scope, pages,
114
+ optional search capability contract, and `ChatStoreError`. It loads without SQL, drivers,
115
+ Node builtins or React. The existing eight-method `ChatHistoryStore` remains available
116
+ from core; existing hosts and fakes need no paging methods.
117
+
118
+ SQL adapters are explicit Node entries: `store/sqlite`, `store/pglite`, `store/postgres`.
119
+ They borrow the host's already-opened, migrated `@jini-ai/db` kernel. They do not open,
120
+ close, migrate or configure it. PGlite accepts embedded and socket transports. PostgreSQL
121
+ requires the node-postgres transport. Each entry rejects mismatched transport/dialect.
122
+ Install db and Kysely for these entries, and inject your own selected driver into db.
123
+ Core supplies the shared `Clock` contract. Pass `{ clock }` as the second factory argument
124
+ (`clock.nowMs()`); omitting it keeps system wall time. All three SQL dialects share the
125
+ same object-method contract. `list()` is a zero-argument read. `pageConversations({},
126
+ { limit, cursor })` keeps paging in the optional bag; maintenance uses
127
+ `sweepExpired({ now }, { limit })`. Existing hosts and fakes must update positional methods.
128
+ All database and React peers are optional; Kysely dev tests pin 0.29.6 and PGlite 0.5.8.
129
+
130
+ ```ts
131
+ import { createSqliteChatStore } from '@jini-ai/chat/store/sqlite';
132
+ const store = createSqliteChatStore({ kernel, scope: {
133
+ scopeId: 'workspace', ownerKind: 'user', ownerId: 'account',
134
+ } });
135
+ const page = await store.pageConversations({}, { limit: 50 });
136
+ const conversation = await store.get({ id: 'conversation' });
137
+ await store.appendMessage({ conversationId: 'conversation', message });
138
+ await store.rename({ id: 'conversation', title: 'Title' }, { source: 'manual' });
139
+ ```
140
+
141
+ The host authenticates and binds the scope; guest IDs must already be hashed. Every read
142
+ and mutation enforces all three scope fields, including paging. Missing and foreign IDs
143
+ have identical results. Duplicate creates throw a generic `conflict` without disclosing
144
+ ownership. Driver failures become `unavailable`, retaining the original cause.
145
+
146
+ Pages default to 50 and accept integer limits 1..200; invalid bounds and continuations
147
+ are structured errors. Conversation pages use `(updatedAt DESC, id ASC)`, message pages
148
+ `(position ASC, id ASC)`. ID ties use UTF-8 byte ordinal ordering (SQLite BINARY / PG C),
149
+ independent of locale. Opaque versioned cursors bind the owner, read kind and conversation;
150
+ validation happens before reading. Deleted anchors remain usable. Pages are live views:
151
+ activity can reorder conversations between calls, so a cursor does not promise a snapshot.
152
+ Each page selects at most limit+1 rows. Compatibility `list` and `messages` return all rows
153
+ and can cost O(N); new consumers should page.
154
+
155
+ Message upserts keep the original parent, position, role, agent identity and creation time.
156
+ They only persist existing ai_* columns; `resumable` and `lastRunEventId` remain absent.
157
+ Malformed optional JSON leaves text readable and the damaged value absent. No search
158
+ implementation is shipped: the optional capability is absent on every SQL adapter.
159
+
160
+ Appends join transactions on the exact injected kernel and acquire the conversation lock
161
+ before position allocation. A host ledger must share that kernel and take its run lock
162
+ before calling append; a second kernel for the same file cannot substitute for that context.
163
+
164
+ Separate privileged `createSqliteChatMaintenance` / PGlite / Postgres factories delete at
165
+ most 500 expired conversations per call (limits 1..500). The host schema supplies cascades;
166
+ SQLite borrowers must have foreign keys enabled. Stores never expose cross-owner maintenance.
167
+
168
+ SQLite also retains positional `createChatHistoryStore(db, scope, now?)` and
169
+ `createChatHistoryMaintenance(db)` wrappers over db's memoized borrowed kernel. The explicit
170
+ `ensureChatHistoryTables(db)` helper uses the unchanged DDL and is never called by a factory.
171
+ The temporary sqlite-chat entry delegates here; its richer local legacy model stays separate.
172
+
173
+ Postgres contract tests require `JINI_CHAT_TEST_POSTGRES_URL` naming a disposable
174
+ `jini_chat_test_*` database and fail if it is unavailable; use `pnpm run test:postgres`.
175
+ PGlite socket tests bind a local socket and must run on a host permitting that operation.
176
+
177
+ ## Legacy local-project SQLite API
178
+
179
+ `@jini-ai/chat/store/legacy` exports the old `ChatSessionMode` vocabulary. `./store/legacy/sqlite`
180
+ exports the unchanged synchronous conversation/message CRUD and `LEGACY_CHAT_DDL`, receiving a
181
+ borrowed structural `SqliteDb`. This is the local single-user `conversations`/`messages` model,
182
+ separate from the owner-scoped `ai_chats`/`ai_chat_messages` ChatStore. Server storage composes its
183
+ schema with projects and rich daemon sessions. No chat constructor opens a driver or migrates a host DB.
184
+
185
+ ## Design decisions
186
+
187
+ - [Queued page actions are consumed before execution](docs/decisions/DR-001-single-shot-page-actions.md).
188
+ - [Streaming adapters close message boundaries on interruption](docs/decisions/DR-002-stream-interruption-boundaries.md).
189
+ - [Human surfaces survive reconnect with honest status](docs/decisions/DR-003-human-surface-rehydration.md).
190
+
191
+ ## Kernel contracts
192
+
193
+ Run finalization receives `Clock` from `@jini-ai/core/primitives` and reads `nowMs()`;
194
+ `RunActivityClock` remains a separate activity value object. Public core/React helpers receive
195
+ required argument objects: e.g. `isTerminalRunStatus({ status })`,
196
+ `assistantContentFromEvents({ events })`, `useRunStream({ transport })`, and
197
+ `registerExtEventRenderer({ name, renderer }, { slotKey })`. A slot-key callback receives `{ data }`.
198
+ `interleaveMessageBlocks({ events, content, rows }, { slotOf })` retains its reconstruction checks.
199
+ The isolated `core/run-events`, `core/ag-ui`, `server/run-finalizer`, `react/embed`,
200
+ `transports/fetch-sse`, `browser/session-store` and `browser/page-actions` subpaths are published.
201
+ `FrontendSessionBridgeArgs` is exported from `react`; hosts pass baseUrl and openStream, optionally request or native fetch.
202
+ The SSE transport takes an injected decoder; browser hosts must supply a browser-safe module.
203
+
204
+ ## React integration boundaries
205
+
206
+ Model/provider selection belongs to the host-injected `ModelAgentPickerSlot`, because choosing
207
+ an LLM or agent is a provider concern rather than a chat-domain concern. The unused internal
208
+ picker was removed after a fresh caller check confirmed that only its own tests reached it.
209
+ It had already been removed from the public React barrel in August 2026; no public export changes.
210
+
211
+ The retired picker combined provider grouping, credential badges and a searchable trigger/popover
212
+ from earlier UI implementations. Its rules were independent of chat state and React; the hook
213
+ owned open/query state and outside-click/Escape subscriptions. Static host-supplied lists needed
214
+ no transport, while a host could inject a live-catalogue fetch. The popover rendered inline for
215
+ testability because chat had no positioning/collision primitive; hosts handled clipping with CSS.
216
+ Credential ordering preferred configured providers, preserving model order on ties. Unknown
217
+ providers received a fallback label rather than disappearing; unknown selected IDs remained custom
218
+ values, and auto-selection was opt-in. Search was omitted below eight options, blank search kept
219
+ all groups, and subtitles avoided repeating the provider label. Badge labels used host i18n;
220
+ the protocol catalogue type had a local alias to avoid an unrelated runtime model-type collision.
221
+
222
+ The unexported official MCP-UI proof of concept and its fixtures were also removed. It evaluated
223
+ the upstream resource builder and client through ESM: client 7.1.1's CommonJS entry failed in
224
+ the original experiment. Its pre-fetched HTML bypassed resource fetching; delivery still required
225
+ a sandbox proxy's readiness handshake. The jsdom probe checked iframe creation, sandboxing and
226
+ sizing rather than a live handshake, and jsdom dropped the client's `border: none` shorthand.
227
+ The live `McpUiSurfaceCard` delegates to `@jini-ai/ui/mcp-ui`, whose official client integration
228
+ owns the sandbox lifecycle. Chat therefore no longer declares either MCP-UI vendor dependency.
229
+ The distribution excludes both removed directories' compiled output, including stale files left
230
+ by a build over an existing `dist` directory.
231
+
232
+ ## A2UI renderer integration
233
+
234
+ `A2uiSurfaceCard` composes the agentic interpreter with the shared core system clock and an
235
+ action-ID sequence. It preserves wall-clock timestamps and the existing
236
+ `a2ui-action-<sequence>-<base36 timestamp>` IDs. Catalog, registry and interpreter calls use
237
+ their required argument objects; React cleanup wraps the interpreter's object-argument
238
+ unsubscribe. Text values retain the catalog's validated wire shape through `DynamicValueSchema`.
239
+
240
+ Package typechecking includes `src/**/__tests__/**` so fixture API drift is reported alongside
241
+ production errors. Store contract fixtures use the typed chat store and storage kernel,
242
+ including fixture-owned host tables. Paging fixtures require a continuation before reusing it,
243
+ and stored message fixtures conform to the current event and attachment contracts. Development
244
+ declarations for jsdom and better-sqlite3 are provided by their `@types` dependencies.
245
+
246
+ ## Browser fetch defaults
247
+
248
+ `createFrontendSessionBridge({ baseUrl, openStream, fetch?, request? }, options)`
249
+ uses native fetch by default, with a 15-second deadline. An explicit `request`
250
+ continues to take precedence. `createDaemonAttachmentUploader({ baseUrl, fetch? }, options)`
251
+ uses the same fetch for upload and partial-upload cleanup; omission uses
252
+ `globalThis.fetch`. Cleanup has its own 15-second abort deadline and does not
253
+ inherit the failed upload's cancellation. Upload quotas and its 30-second batch
254
+ deadline are unchanged. Browser timeout reasons remain native; platform is no
255
+ longer a dependency of this package.
@@ -0,0 +1,53 @@
1
+ /** Pure chat-event to AG-UI projection; lifecycle state belongs to one run.
2
+ * This legacy wire reducer is independent of saved-chat reduction: partial tool input remains
3
+ * a CUSTOM extension, while media stays in run-event vocabulary and is absent from TOOL_CALL_RESULT.
4
+ * Strict interruption ordering closes a message before a tool starts. IDs and custom event names
5
+ * are injected, with official AG-UI types authoritative; auth, routes and encoder stay with the host.
6
+ * The host emits RUN_STARTED and terminal RUN_FINISHED/RUN_ERROR outside this pure projection. */
7
+ import { EventType, type AGUIEvent } from '@ag-ui/core';
8
+ import type { AgentEvent } from '../events.js';
9
+ export interface EventIdGenerator {
10
+ next(args: {
11
+ prefix: string;
12
+ ordinal: number;
13
+ }): string;
14
+ }
15
+ export interface CustomEventNames {
16
+ readonly usage: string;
17
+ readonly status: string;
18
+ readonly extensionPrefix: string;
19
+ }
20
+ export interface RunAgentWirePayload {
21
+ readonly type: string;
22
+ readonly [key: string]: unknown;
23
+ }
24
+ /** Preserve the legacy AG-UI wire reduction, including partial input as extension events.
25
+ * Unlike the saved-chat reducer, this projection carries partial tool-input extensions. */
26
+ export declare function reduceAgentWirePayload({ payload }: {
27
+ payload: RunAgentWirePayload;
28
+ }): AgentEvent | null;
29
+ export type AgUiEvent = Extract<AGUIEvent, {
30
+ type: EventType.RUN_STARTED | EventType.RUN_FINISHED | EventType.RUN_ERROR | EventType.TEXT_MESSAGE_START | EventType.TEXT_MESSAGE_CONTENT | EventType.TEXT_MESSAGE_END | EventType.REASONING_START | EventType.REASONING_MESSAGE_START | EventType.REASONING_MESSAGE_CONTENT | EventType.REASONING_MESSAGE_END | EventType.REASONING_END | EventType.TOOL_CALL_START | EventType.TOOL_CALL_ARGS | EventType.TOOL_CALL_END | EventType.TOOL_CALL_RESULT | EventType.RAW | EventType.CUSTOM;
31
+ }>;
32
+ export interface AgUiTranslationState {
33
+ openTextMessageId: string | null;
34
+ openReasoningMessageId: string | null;
35
+ nextId: number;
36
+ readonly ids: EventIdGenerator;
37
+ readonly customEventNames: CustomEventNames;
38
+ }
39
+ /** Create isolated per-run translation state with explicit IDs and custom-event wire names. */
40
+ export declare function createAgUiTranslationState({ ids, customEventNames }: {
41
+ ids: EventIdGenerator;
42
+ customEventNames: CustomEventNames;
43
+ }): AgUiTranslationState;
44
+ /** Emit ordered message/tool lifecycles; a tool call closes the preceding message first. */
45
+ export declare function translateAgentEventToAgUi({ event, state }: {
46
+ event: AgentEvent;
47
+ state: AgUiTranslationState;
48
+ }): AgUiEvent[];
49
+ /** Close open text/reasoning before the host emits RUN_FINISHED or RUN_ERROR. */
50
+ export declare function closeAgUiRun({ state }: {
51
+ state: AgUiTranslationState;
52
+ }): AgUiEvent[];
53
+ //# sourceMappingURL=entry.d.ts.map
@@ -0,0 +1,135 @@
1
+ /** Pure chat-event to AG-UI projection; lifecycle state belongs to one run.
2
+ * This legacy wire reducer is independent of saved-chat reduction: partial tool input remains
3
+ * a CUSTOM extension, while media stays in run-event vocabulary and is absent from TOOL_CALL_RESULT.
4
+ * Strict interruption ordering closes a message before a tool starts. IDs and custom event names
5
+ * are injected, with official AG-UI types authoritative; auth, routes and encoder stay with the host.
6
+ * The host emits RUN_STARTED and terminal RUN_FINISHED/RUN_ERROR outside this pure projection. */
7
+ import { EventType } from '@ag-ui/core';
8
+ function asString(v) {
9
+ return typeof v === "string" ? v : v == null ? "" : JSON.stringify(v);
10
+ }
11
+ function reduceUsagePayload(payload) {
12
+ const usage = (payload.usage ?? {});
13
+ return {
14
+ kind: "usage",
15
+ ...(typeof usage.input_tokens === "number" ? { inputTokens: usage.input_tokens } : {}),
16
+ ...(typeof usage.output_tokens === "number" ? { outputTokens: usage.output_tokens } : {}),
17
+ ...(typeof payload.costUsd === "number" ? { costUsd: payload.costUsd } : {}),
18
+ ...(typeof payload.durationMs === "number" ? { durationMs: payload.durationMs } : {}),
19
+ };
20
+ }
21
+ const WIRE_PAYLOAD_REDUCERS = {
22
+ status: (payload) => ({ kind: "status", label: asString(payload.label), ...(payload.detail ? { detail: asString(payload.detail) } : {}) }),
23
+ text_delta: (payload) => ({ kind: "text", text: asString(payload.delta) }),
24
+ thinking_delta: (payload) => ({ kind: "thinking", text: asString(payload.delta) }),
25
+ tool_use: (payload) => ({ kind: "tool_use", id: asString(payload.id), name: asString(payload.name), input: payload.input }),
26
+ tool_result: (payload) => ({
27
+ kind: "tool_result",
28
+ toolUseId: asString(payload.toolUseId),
29
+ content: asString(payload.content),
30
+ isError: Boolean(payload.isError),
31
+ }),
32
+ usage: reduceUsagePayload,
33
+ raw: (payload) => ({ kind: "raw", line: asString(payload.line) }),
34
+ "mcp-ui": (payload) => ({ kind: "ext", name: "mcp-ui", data: payload.resource }),
35
+ a2ui: (payload) => ({ kind: "ext", name: "a2ui", data: payload.message }),
36
+ thinking_start: () => null,
37
+ };
38
+ /** Preserve the legacy AG-UI wire reduction, including partial input as extension events.
39
+ * Unlike the saved-chat reducer, this projection carries partial tool-input extensions. */
40
+ export function reduceAgentWirePayload({ payload }) {
41
+ const reducer = Object.hasOwn(WIRE_PAYLOAD_REDUCERS, payload.type) ? WIRE_PAYLOAD_REDUCERS[payload.type] : undefined;
42
+ return reducer ? reducer(payload) : { kind: "ext", name: payload.type, data: payload };
43
+ }
44
+ /** Create isolated per-run translation state with explicit IDs and custom-event wire names. */
45
+ export function createAgUiTranslationState({ ids, customEventNames }) {
46
+ return { openTextMessageId: null, openReasoningMessageId: null, nextId: 0, ids, customEventNames: { ...customEventNames } };
47
+ }
48
+ function mintId(state, prefix) {
49
+ state.nextId += 1;
50
+ return state.ids.next({ prefix, ordinal: state.nextId });
51
+ }
52
+ function closeOpenMessages(state) {
53
+ const events = [];
54
+ if (state.openTextMessageId) {
55
+ events.push({ type: EventType.TEXT_MESSAGE_END, messageId: state.openTextMessageId });
56
+ state.openTextMessageId = null;
57
+ }
58
+ if (state.openReasoningMessageId) {
59
+ const messageId = state.openReasoningMessageId;
60
+ events.push({ type: EventType.REASONING_MESSAGE_END, messageId });
61
+ events.push({ type: EventType.REASONING_END, messageId });
62
+ state.openReasoningMessageId = null;
63
+ }
64
+ return events;
65
+ }
66
+ function handleTextAgentEvent(event, state) {
67
+ const events = [];
68
+ if (state.openReasoningMessageId)
69
+ events.push(...closeOpenMessages(state));
70
+ if (!state.openTextMessageId) {
71
+ state.openTextMessageId = mintId(state, "msg");
72
+ events.push({ type: EventType.TEXT_MESSAGE_START, messageId: state.openTextMessageId, role: "assistant" });
73
+ }
74
+ events.push({ type: EventType.TEXT_MESSAGE_CONTENT, messageId: state.openTextMessageId, delta: event.text });
75
+ return events;
76
+ }
77
+ function handleThinkingAgentEvent(event, state) {
78
+ const events = [];
79
+ if (state.openTextMessageId)
80
+ events.push(...closeOpenMessages(state));
81
+ if (!state.openReasoningMessageId) {
82
+ state.openReasoningMessageId = mintId(state, "reasoning");
83
+ events.push({ type: EventType.REASONING_START, messageId: state.openReasoningMessageId });
84
+ events.push({ type: EventType.REASONING_MESSAGE_START, messageId: state.openReasoningMessageId, role: "reasoning" });
85
+ }
86
+ events.push({ type: EventType.REASONING_MESSAGE_CONTENT, messageId: state.openReasoningMessageId, delta: event.text });
87
+ return events;
88
+ }
89
+ function handleToolUseAgentEvent(event, state) {
90
+ const events = [];
91
+ if (state.openTextMessageId || state.openReasoningMessageId)
92
+ events.push(...closeOpenMessages(state));
93
+ events.push({ type: EventType.TOOL_CALL_START, toolCallId: event.id, toolCallName: event.name });
94
+ events.push({ type: EventType.TOOL_CALL_ARGS, toolCallId: event.id, delta: JSON.stringify(event.input ?? {}) });
95
+ events.push({ type: EventType.TOOL_CALL_END, toolCallId: event.id });
96
+ return events;
97
+ }
98
+ /** Emit ordered message/tool lifecycles; a tool call closes the preceding message first. */
99
+ export function translateAgentEventToAgUi({ event, state }) {
100
+ switch (event.kind) {
101
+ case "text":
102
+ return handleTextAgentEvent(event, state);
103
+ case "thinking":
104
+ return handleThinkingAgentEvent(event, state);
105
+ case "tool_use":
106
+ return handleToolUseAgentEvent(event, state);
107
+ case "tool_result":
108
+ return [
109
+ {
110
+ type: EventType.TOOL_CALL_RESULT,
111
+ messageId: mintId(state, "tool_result_msg"),
112
+ toolCallId: event.toolUseId,
113
+ content: event.content,
114
+ role: "tool",
115
+ },
116
+ ];
117
+ case "usage":
118
+ return [{ type: EventType.CUSTOM, name: state.customEventNames.usage, value: event }];
119
+ case "status":
120
+ return [{ type: EventType.CUSTOM, name: state.customEventNames.status, value: event }];
121
+ case "raw":
122
+ return [{ type: EventType.RAW, event: event.line }];
123
+ case "ext":
124
+ return [{ type: EventType.CUSTOM, name: `${state.customEventNames.extensionPrefix}${event.name}`, value: event.data }];
125
+ default: {
126
+ const neverEvent = event;
127
+ throw new Error(`translateAgentEventToAgUi: unhandled AgentEvent.kind ${JSON.stringify(neverEvent)}`);
128
+ }
129
+ }
130
+ }
131
+ /** Close open text/reasoning before the host emits RUN_FINISHED or RUN_ERROR. */
132
+ export function closeAgUiRun({ state }) {
133
+ return closeOpenMessages(state);
134
+ }
135
+ //# sourceMappingURL=entry.js.map
@@ -11,7 +11,7 @@
11
11
  * This is a genuine chat product surface, not vocabulary — unlike its former siblings here
12
12
  * (capability.ts, page-capabilities.ts, …), which moved to `@jini-ai/agentic` on 2026-07-26 so a
13
13
  * non-chat consumer could depend on the vocabulary without depending on chat. This file stayed
14
- * behind on purpose: it's the proof the split is real (see `@jini-ai/agentic`'s source-map.md).
14
+ * behind on purpose: it's the proof the split is real (see `@jini-ai/agentic`'s archived provenance ledger).
15
15
  */
16
16
  import type { CapabilityDef } from '@jini-ai/agentic';
17
17
  /** The bounded, explicit set of chat-pane capabilities every transport surface hosts. */
@@ -6,7 +6,7 @@
6
6
  * Everything that used to live here besides `chat-capabilities.ts` (the framework-free
7
7
  * `CapabilityDef` vocabulary, the two shipped manifests' shared machinery, the `data-agent-*`
8
8
  * markup convention, and the protocol projections) moved to `@jini-ai/agentic` on 2026-07-26 — see
9
- * `packages/agentic/source-map.md` for the extraction and why. This barrel now only exports
9
+ * `packages/agentic/archived provenance ledger` for the extraction and why. This barrel now only exports
10
10
  * `CHAT_CAPABILITIES`, the seven `chat.*` verbs that are a genuine chat product surface rather
11
11
  * than generic vocabulary.
12
12
  *
@@ -6,7 +6,7 @@
6
6
  * Everything that used to live here besides `chat-capabilities.ts` (the framework-free
7
7
  * `CapabilityDef` vocabulary, the two shipped manifests' shared machinery, the `data-agent-*`
8
8
  * markup convention, and the protocol projections) moved to `@jini-ai/agentic` on 2026-07-26 — see
9
- * `packages/agentic/source-map.md` for the extraction and why. This barrel now only exports
9
+ * `packages/agentic/archived provenance ledger` for the extraction and why. This barrel now only exports
10
10
  * `CHAT_CAPABILITIES`, the seven `chat.*` verbs that are a genuine chat product surface rather
11
11
  * than generic vocabulary.
12
12
  *
@@ -23,7 +23,11 @@ export declare const ASSISTANT_STEP_SEPARATOR = "\n\n";
23
23
  * @param events - The turn's events, in arrival order.
24
24
  * @complexity O(total text length).
25
25
  */
26
- export declare function assistantContentFromEvents(events: readonly AgentEvent[] | undefined): string;
26
+ export declare function assistantContentFromEvents({ events }: {
27
+ events: readonly AgentEvent[] | undefined;
28
+ }): string;
27
29
  /** The pre-2026-09-27 rule (plain concatenation), kept only so older saved rows still match. */
28
- export declare function legacyAssistantContentFromEvents(events: readonly AgentEvent[] | undefined): string;
30
+ export declare function legacyAssistantContentFromEvents({ events }: {
31
+ events: readonly AgentEvent[] | undefined;
32
+ }): string;
29
33
  //# sourceMappingURL=assistant-content.d.ts.map
@@ -11,7 +11,7 @@ function separatorBefore(out, text) {
11
11
  * @param events - The turn's events, in arrival order.
12
12
  * @complexity O(total text length).
13
13
  */
14
- export function assistantContentFromEvents(events) {
14
+ export function assistantContentFromEvents({ events }) {
15
15
  let out = '';
16
16
  let stepBoundary = false;
17
17
  for (const ev of events ?? []) {
@@ -30,7 +30,7 @@ export function assistantContentFromEvents(events) {
30
30
  return out;
31
31
  }
32
32
  /** The pre-2026-09-27 rule (plain concatenation), kept only so older saved rows still match. */
33
- export function legacyAssistantContentFromEvents(events) {
33
+ export function legacyAssistantContentFromEvents({ events }) {
34
34
  let out = '';
35
35
  for (const ev of events ?? []) {
36
36
  if (ev.kind === 'text')
@@ -19,5 +19,7 @@ import type { AgentEvent } from './events.js';
19
19
  * @param events - A turn's events, in arrival order.
20
20
  * @complexity O(number of events + total text length).
21
21
  */
22
- export declare function mergeAdjacentTextEvents(events: readonly AgentEvent[] | undefined): AgentEvent[];
22
+ export declare function mergeAdjacentTextEvents({ events }: {
23
+ events: readonly AgentEvent[] | undefined;
24
+ }): AgentEvent[];
23
25
  //# sourceMappingURL=compact-events.d.ts.map
@@ -8,7 +8,7 @@ function isDelta(event) {
8
8
  * @param events - A turn's events, in arrival order.
9
9
  * @complexity O(number of events + total text length).
10
10
  */
11
- export function mergeAdjacentTextEvents(events) {
11
+ export function mergeAdjacentTextEvents({ events }) {
12
12
  const out = [];
13
13
  for (const event of events ?? []) {
14
14
  const last = out[out.length - 1];
@@ -7,7 +7,7 @@
7
7
  * decoupled from it: a host's transport adapter is responsible for reducing
8
8
  * wire deltas (`text_delta`, `thinking_delta`, `tool_input_delta`, ...) into
9
9
  * the persisted/renderable `AgentEvent` items below before handing them to
10
- * chat-core's pure helpers. See source-map.md for the provenance of this
10
+ * chat-core's pure helpers. See archived provenance ledger for the provenance of this
11
11
  * split and why chat-core does not itself depend on `@jini-ai/protocol`.
12
12
  */
13
13
  /**
@@ -7,7 +7,7 @@
7
7
  * decoupled from it: a host's transport adapter is responsible for reducing
8
8
  * wire deltas (`text_delta`, `thinking_delta`, `tool_input_delta`, ...) into
9
9
  * the persisted/renderable `AgentEvent` items below before handing them to
10
- * chat-core's pure helpers. See source-map.md for the provenance of this
10
+ * chat-core's pure helpers. See archived provenance ledger for the provenance of this
11
11
  * split and why chat-core does not itself depend on `@jini-ai/protocol`.
12
12
  */
13
13
  export {};
@@ -4,7 +4,7 @@
4
4
  * Zero React, zero DOM/browser globals, zero Node built-ins, zero imports
5
5
  * from any product package's scope. See ADS-memory/reports/jini-port/extraction-plan.md
6
6
  * §12 C2/C3 and ADS-memory/reports/jini-port/recon/r4b-webui-design.md §1 for the design
7
- * this package targets, and source-map.md for exact provenance.
7
+ * this package targets, and archived provenance ledger for exact provenance.
8
8
  *
9
9
  * Was `@jini-ai/chat-core` (its own top-level package, one entry point) through npm 0.1.2 —
10
10
  * consolidated 2026-08-03 into `@jini-ai/chat`'s `./core` subpath alongside `./react` (formerly
@@ -31,13 +31,13 @@ export * from './compact-events.js';
31
31
  * vocabulary this used to sit alongside — `CapabilityDef`, `PAGE_CAPABILITIES`, the
32
32
  * `data-agent-*` convention, the policy gate, the protocol projections — moved to `@jini-ai/agentic`
33
33
  * on 2026-07-26; import it directly rather than through this package. See
34
- * `packages/agentic/source-map.md` and this package's own source-map.md for the extraction.
34
+ * `packages/agentic/archived provenance ledger` and this package's own archived provenance ledger for the extraction.
35
35
  */
36
36
  export * from './agentic/index.js';
37
37
  /**
38
38
  * Durable chat history — the storage-neutral `ChatHistoryStore` port and the local title
39
39
  * heuristic. Types and pure functions only, so this package stays framework-free and
40
- * `runtime: universal`; the SQLite implementation lives in `@jini-ai/sqlite`'s `chat-history`
40
+ * `runtime: universal`; the SQLite implementation lives in `@jini-ai/sqlite-chat`'s `chat-history`
41
41
  * module, and a host binds it to its own authentication.
42
42
  */
43
43
  export * from './persistence/index.js';