@jini-ai/chat 0.3.10 → 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 (206) 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.d.ts +3 -0
  107. package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.js +80 -38
  108. package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.js +57 -57
  109. package/dist/react/features/chat-pane/rules.d.ts +13 -4
  110. package/dist/react/features/chat-pane/rules.js +5 -5
  111. package/dist/react/features/chat-pane/types.d.ts +1 -1
  112. package/dist/react/hooks/attachment-preview-cache.d.ts +7 -2
  113. package/dist/react/hooks/attachment-preview-cache.js +2 -2
  114. package/dist/react/hooks/composer-draft-cache.d.ts +17 -5
  115. package/dist/react/hooks/composer-draft-cache.js +6 -6
  116. package/dist/react/hooks/useArtifactStream.d.ts +5 -1
  117. package/dist/react/hooks/useArtifactStream.js +3 -3
  118. package/dist/react/hooks/useChatFabDrag.d.ts +9 -4
  119. package/dist/react/hooks/useChatFabDrag.js +4 -4
  120. package/dist/react/hooks/useComposer.js +8 -8
  121. package/dist/react/hooks/useConversation.js +56 -4
  122. package/dist/react/hooks/useExtEventGroups.d.ts +5 -1
  123. package/dist/react/hooks/useExtEventGroups.js +1 -1
  124. package/dist/react/hooks/useLatestOperation.d.ts +8 -3
  125. package/dist/react/hooks/useLatestOperation.js +4 -4
  126. package/dist/react/hooks/usePinnedTodos.d.ts +3 -1
  127. package/dist/react/hooks/usePinnedTodos.js +3 -3
  128. package/dist/react/hooks/useQuestionForms.d.ts +7 -2
  129. package/dist/react/hooks/useQuestionForms.js +7 -7
  130. package/dist/react/hooks/useRunActivity.d.ts +6 -1
  131. package/dist/react/hooks/useRunActivity.js +3 -3
  132. package/dist/react/hooks/useRunStream.d.ts +3 -1
  133. package/dist/react/hooks/useRunStream.js +1 -1
  134. package/dist/react/hooks/useToolTimeline.d.ts +3 -1
  135. package/dist/react/hooks/useToolTimeline.js +3 -3
  136. package/dist/react/index.d.ts +4 -4
  137. package/dist/react/index.js +6 -6
  138. package/dist/react/message-blocks.d.ts +10 -4
  139. package/dist/react/message-blocks.js +2 -2
  140. package/dist/react/styles/reference.css +3 -3
  141. package/dist/react/tool-renderer-registry.d.ts +8 -3
  142. package/dist/react/tool-renderer-registry.js +3 -3
  143. package/dist/react/util/defined-props.d.ts +3 -1
  144. package/dist/react/util/defined-props.js +1 -1
  145. package/dist/server/run-finalizer/entry.d.ts +47 -0
  146. package/dist/server/run-finalizer/entry.js +156 -0
  147. package/dist/server/run-finalizer/ports.d.ts +52 -0
  148. package/dist/store/contracts/index.d.ts +5 -0
  149. package/dist/store/contracts/index.js +5 -0
  150. package/dist/store/errors.d.ts +12 -0
  151. package/dist/store/errors.js +18 -0
  152. package/dist/store/index.d.ts +4 -0
  153. package/dist/store/index.js +2 -0
  154. package/dist/store/legacy/index.d.ts +3 -0
  155. package/dist/store/legacy/index.js +2 -0
  156. package/dist/store/legacy/sqlite/conversations.d.ts +129 -0
  157. package/dist/store/legacy/sqlite/conversations.js +274 -0
  158. package/dist/store/legacy/sqlite/index.d.ts +6 -0
  159. package/dist/store/legacy/sqlite/index.js +5 -0
  160. package/dist/store/legacy/sqlite/messages.d.ts +156 -0
  161. package/dist/store/legacy/sqlite/messages.js +246 -0
  162. package/dist/store/legacy/sqlite/schema.d.ts +3 -0
  163. package/dist/store/legacy/sqlite/schema.js +40 -0
  164. package/dist/store/pglite/index.d.ts +21 -0
  165. package/dist/store/pglite/index.js +17 -0
  166. package/dist/store/ports.d.ts +121 -0
  167. package/dist/store/ports.js +2 -0
  168. package/dist/store/postgres/index.d.ts +21 -0
  169. package/dist/store/postgres/index.js +17 -0
  170. package/dist/store/sql/boundary.d.ts +28 -0
  171. package/dist/store/sql/boundary.js +32 -0
  172. package/dist/store/sql/cursor.d.ts +24 -0
  173. package/dist/store/sql/cursor.js +49 -0
  174. package/dist/store/sql/maintenance.d.ts +9 -0
  175. package/dist/store/sql/maintenance.js +16 -0
  176. package/dist/store/sql/store.d.ts +22 -0
  177. package/dist/store/sql/store.js +340 -0
  178. package/dist/store/sql/tables.d.ts +34 -0
  179. package/dist/store/sql/tables.js +2 -0
  180. package/dist/store/sqlite/index.d.ts +36 -0
  181. package/dist/store/sqlite/index.js +29 -0
  182. package/dist/store/sqlite/schema.d.ts +49 -0
  183. package/dist/store/sqlite/schema.js +80 -0
  184. package/package.json +211 -14
  185. package/dist/react/features/model-picker/components/CredentialStatusBadge.d.ts +0 -7
  186. package/dist/react/features/model-picker/components/CredentialStatusBadge.js +0 -20
  187. package/dist/react/features/model-picker/components/ModelPicker.d.ts +0 -9
  188. package/dist/react/features/model-picker/components/ModelPicker.js +0 -34
  189. package/dist/react/features/model-picker/constants.d.ts +0 -6
  190. package/dist/react/features/model-picker/constants.js +0 -9
  191. package/dist/react/features/model-picker/dependencies.d.ts +0 -11
  192. package/dist/react/features/model-picker/dependencies.js +0 -10
  193. package/dist/react/features/model-picker/hooks/useModelPicker.hooks.d.ts +0 -27
  194. package/dist/react/features/model-picker/hooks/useModelPicker.hooks.js +0 -62
  195. package/dist/react/features/model-picker/index.d.ts +0 -32
  196. package/dist/react/features/model-picker/index.js +0 -29
  197. package/dist/react/features/model-picker/ports.d.ts +0 -11
  198. package/dist/react/features/model-picker/rules.d.ts +0 -26
  199. package/dist/react/features/model-picker/rules.js +0 -84
  200. package/dist/react/features/model-picker/types.d.ts +0 -38
  201. package/dist/react/features/model-picker/types.js +0 -2
  202. package/dist/react/poc-mcp-ui-official/PocMcpUiCard.d.ts +0 -9
  203. package/dist/react/poc-mcp-ui-official/PocMcpUiCard.js +0 -29
  204. package/dist/react/poc-mcp-ui-official/create-poc-resource.d.ts +0 -30
  205. package/dist/react/poc-mcp-ui-official/create-poc-resource.js +0 -44
  206. /package/dist/{react/features/model-picker → server/run-finalizer}/ports.js +0 -0
@@ -0,0 +1,47 @@
1
+ import type { Clock } from '@jini-ai/core/primitives';
2
+ /** Saves completed run output independently of a connected client, through host ports. */
3
+ import type { ChatMessage } from '../../core/messages.js';
4
+ import { type RunNotices } from '../../core/run-events/entry.js';
5
+ import type { RunDaemonClient, RunLedger, Scheduler, RunIdClassifier } from './ports.js';
6
+ export type { RunDaemonClient, RunLedger, Scheduler, RunIdClassifier, RunRef, RunProgress, RunSettlement } from './ports.js';
7
+ /** All infrastructure and host messages are explicit; this factory opens no storage. */
8
+ export interface AssistantRunFinalizerArgs {
9
+ readonly ledger: RunLedger;
10
+ readonly daemon: RunDaemonClient;
11
+ readonly clock: Clock;
12
+ readonly scheduler: Scheduler;
13
+ readonly runIdClassifier: RunIdClassifier;
14
+ readonly notices: RunNotices;
15
+ readonly onError: (args: {
16
+ operation: 'checkpoint' | 'watch';
17
+ runId: string;
18
+ error: unknown;
19
+ }) => void;
20
+ }
21
+ /** Reconnect delay: 2000ms; retry count: 30; checkpoint interval: 1000ms. */
22
+ export interface AssistantRunFinalizerOptions {
23
+ readonly reconnectDelayMs?: number;
24
+ readonly maxReconnects?: number;
25
+ readonly checkpointIntervalMs?: number;
26
+ }
27
+ export interface AssistantRunFinalizer {
28
+ /** Ignore non-assistant, terminal, missing-status and externally held runs; deduplicate by run ID. */
29
+ watch(input: {
30
+ principalId: string;
31
+ conversationId: string;
32
+ message: ChatMessage;
33
+ }): void;
34
+ /** Wait for current watches to finish; terminal writes may overtake pending checkpoints. */
35
+ idle(args: Record<string, never>): Promise<void>;
36
+ activeCount(args: Record<string, never>): number;
37
+ }
38
+ /** Follow replayable run streams and save through atomic host ledger operations.
39
+ * The host retains authorization, owner scope, kernel transactions, boot reconciliation, HTTP
40
+ * credentials and excluded run-ID prefixes. Replay starts at zero; error-before-success and
41
+ * reconnect exhaustion must not falsely settle a run. Checkpoints are throttled with a trailing
42
+ * write, and checkpoint/settle atomically reject other runs or terminal rows: first terminal wins.
43
+ * Frame vocabulary, paragraph boundaries and compaction are shared with the run-event reducer.
44
+ * Non-success bodies are cancelled and progress scheduling stops at completion. Real database
45
+ * restart/race coverage remains a host responsibility; this factory never opens storage. */
46
+ export declare function createAssistantRunFinalizer(args: AssistantRunFinalizerArgs, options?: AssistantRunFinalizerOptions): AssistantRunFinalizer;
47
+ //# sourceMappingURL=entry.d.ts.map
@@ -0,0 +1,156 @@
1
+ import { isTerminalRunStatus } from '../../core/messages.js';
2
+ import { readSseFrames, runContentFromEvents, runEventsForSave, runInterruptedNotice, translateRunFrame } from '../../core/run-events/entry.js';
3
+ /** Follow replayable run streams and save through atomic host ledger operations.
4
+ * The host retains authorization, owner scope, kernel transactions, boot reconciliation, HTTP
5
+ * credentials and excluded run-ID prefixes. Replay starts at zero; error-before-success and
6
+ * reconnect exhaustion must not falsely settle a run. Checkpoints are throttled with a trailing
7
+ * write, and checkpoint/settle atomically reject other runs or terminal rows: first terminal wins.
8
+ * Frame vocabulary, paragraph boundaries and compaction are shared with the run-event reducer.
9
+ * Non-success bodies are cancelled and progress scheduling stops at completion. Real database
10
+ * restart/race coverage remains a host responsibility; this factory never opens storage. */
11
+ export function createAssistantRunFinalizer(args, options = {}) {
12
+ const { daemon, scheduler } = args;
13
+ const now = () => args.clock.nowMs();
14
+ const reconnectDelayMs = options.reconnectDelayMs ?? 2_000;
15
+ const maxReconnects = options.maxReconnects ?? 30;
16
+ const checkpointIntervalMs = options.checkpointIntervalMs ?? 1_000;
17
+ // Diagnostics must not change run/checkpoint behavior, even when the host callback throws.
18
+ function reportError(input) {
19
+ try {
20
+ args.onError(input);
21
+ }
22
+ catch { /* The host owns reporting failures. */ }
23
+ }
24
+ const active = new Map();
25
+ async function settle(watch, status, events) {
26
+ watch.terminal = true;
27
+ if (watch.trailing)
28
+ scheduler.cancel({ handle: watch.trailing.handle });
29
+ watch.trailing = undefined;
30
+ await args.ledger.settle({
31
+ conversationId: watch.conversationId,
32
+ messageId: watch.messageId,
33
+ runId: watch.runId,
34
+ status,
35
+ content: runContentFromEvents({ events }),
36
+ events: runEventsForSave({ events }),
37
+ endedAt: now(),
38
+ });
39
+ }
40
+ function settleInterrupted(watch) {
41
+ return settle(watch, "canceled", [...watch.events, runInterruptedNotice({ notice: args.notices.interrupted })]);
42
+ }
43
+ // Coalesce one pending write and one trailing timer. Never block frame consumption on storage.
44
+ // Growth-only checkpointing avoids shrinking a saved answer during replay from event zero.
45
+ async function checkpoint(watch) {
46
+ if (watch.terminal || watch.checkpointPending)
47
+ return;
48
+ if (watch.events.length <= watch.checkpointedEvents)
49
+ return;
50
+ const wait = checkpointIntervalMs - (now() - watch.checkpointedAt);
51
+ if (wait > 0) {
52
+ if (!watch.trailing) {
53
+ watch.trailing = { handle: scheduler.schedule({ task: () => {
54
+ watch.trailing = undefined;
55
+ void checkpoint(watch);
56
+ }, delayMs: wait }) };
57
+ }
58
+ return;
59
+ }
60
+ if (watch.trailing)
61
+ scheduler.cancel({ handle: watch.trailing.handle });
62
+ watch.trailing = undefined;
63
+ watch.checkpointedEvents = watch.events.length;
64
+ watch.checkpointedAt = now();
65
+ watch.checkpointPending = true;
66
+ await args.ledger
67
+ .checkpoint({
68
+ conversationId: watch.conversationId,
69
+ messageId: watch.messageId,
70
+ runId: watch.runId,
71
+ content: runContentFromEvents({ events: watch.events }),
72
+ events: runEventsForSave({ events: watch.events }),
73
+ })
74
+ .catch((error) => reportError({ operation: "checkpoint", runId: watch.runId, error }))
75
+ .finally(() => {
76
+ watch.checkpointPending = false;
77
+ void checkpoint(watch);
78
+ });
79
+ }
80
+ async function readStream(watch) {
81
+ const response = await daemon.openEvents({ runId: watch.runId, principalId: watch.principalId });
82
+ if (response.status === 404 || !response.ok || !response.body) {
83
+ await response.body?.cancel().catch(() => undefined);
84
+ return response.status === 404 ? { kind: "gone" } : { kind: "dropped" };
85
+ }
86
+ // Each connection replays the complete history, rather than appending duplicate deltas.
87
+ watch.events = [];
88
+ watch.failed = false;
89
+ for await (const frame of readSseFrames({ body: response.body })) {
90
+ const outcome = translateRunFrame({ kind: frame.event, raw: frame.data, notices: args.notices });
91
+ watch.events.push(...outcome.events);
92
+ if (outcome.error)
93
+ watch.failed = true;
94
+ if (outcome.terminal) {
95
+ watch.terminal = true;
96
+ return { kind: "ended", status: watch.failed && outcome.terminal === "succeeded" ? "failed" : outcome.terminal };
97
+ }
98
+ void checkpoint(watch);
99
+ }
100
+ return { kind: "dropped" };
101
+ }
102
+ async function follow(watch) {
103
+ for (let attempt = 0; attempt <= maxReconnects; attempt += 1) {
104
+ const result = await readStream(watch).catch(() => ({ kind: "dropped" }));
105
+ if (result.kind === "ended")
106
+ return settle(watch, result.status, watch.events);
107
+ if (result.kind === "gone")
108
+ return settleInterrupted(watch);
109
+ if ((await daemon.runStatus({ runId: watch.runId, principalId: watch.principalId })) === 404)
110
+ return settleInterrupted(watch);
111
+ await scheduler.sleep({ delayMs: reconnectDelayMs });
112
+ }
113
+ // Exhaustion alone is not evidence of a terminal run; the host can reattach or repair at boot.
114
+ }
115
+ return {
116
+ watch({ principalId, conversationId, message }) {
117
+ const runId = message.runId;
118
+ if (message.role !== "assistant" || !runId || !args.runIdClassifier.isDaemonRunId({ runId }))
119
+ return;
120
+ if (message.runStatus === undefined || isTerminalRunStatus({ status: message.runStatus }))
121
+ return;
122
+ if (active.has(runId))
123
+ return;
124
+ const watch = {
125
+ principalId,
126
+ conversationId,
127
+ messageId: message.id,
128
+ runId,
129
+ events: [],
130
+ failed: false,
131
+ checkpointedEvents: 0,
132
+ checkpointedAt: Number.NEGATIVE_INFINITY,
133
+ checkpointPending: false,
134
+ terminal: false,
135
+ };
136
+ const done = follow(watch)
137
+ .catch((error) => {
138
+ reportError({ operation: "watch", runId, error });
139
+ })
140
+ .finally(() => {
141
+ watch.terminal = true;
142
+ if (watch.trailing)
143
+ scheduler.cancel({ handle: watch.trailing.handle });
144
+ watch.trailing = undefined;
145
+ active.delete(runId);
146
+ });
147
+ active.set(runId, { watch, done });
148
+ },
149
+ async idle(_args) {
150
+ while (active.size > 0)
151
+ await Promise.all([...active.values()].map((entry) => entry.done));
152
+ },
153
+ activeCount: (_args) => active.size,
154
+ };
155
+ }
156
+ //# sourceMappingURL=entry.js.map
@@ -0,0 +1,52 @@
1
+ import type { AgentEvent } from '../../core/events.js';
2
+ import type { ChatRunStatus } from '../../core/messages.js';
3
+ /** Exactly which run owns the row; the host binds authorization and storage scope. */
4
+ export interface RunRef {
5
+ readonly conversationId: string;
6
+ readonly messageId: string;
7
+ readonly runId: string;
8
+ }
9
+ export interface RunProgress extends RunRef {
10
+ readonly content: string;
11
+ readonly events: readonly AgentEvent[];
12
+ }
13
+ export interface RunSettlement extends RunProgress {
14
+ readonly status: Extract<ChatRunStatus, 'succeeded' | 'failed' | 'canceled'>;
15
+ readonly endedAt: number;
16
+ }
17
+ /** Storage contract only. Both methods must atomically reject a different run or terminal row.
18
+ * First terminal write wins; a late checkpoint cannot reopen or replace that row. */
19
+ export interface RunLedger {
20
+ checkpoint(args: RunProgress): Promise<boolean>;
21
+ settle(args: RunSettlement): Promise<boolean>;
22
+ }
23
+ /** Host adapter owns URL, auth, headers and transport timeout policy. Events replay from zero. */
24
+ export interface RunDaemonClient {
25
+ openEvents(args: {
26
+ runId: string;
27
+ principalId: string;
28
+ }): Promise<Response>;
29
+ runStatus(args: {
30
+ runId: string;
31
+ principalId: string;
32
+ }): Promise<number | null>;
33
+ }
34
+ /** Scheduling returns an opaque handle; a host Node adapter can unref its timer here. */
35
+ export interface Scheduler {
36
+ schedule(args: {
37
+ task: () => void;
38
+ delayMs: number;
39
+ }): unknown;
40
+ cancel(args: {
41
+ handle: unknown;
42
+ }): void;
43
+ sleep(args: {
44
+ delayMs: number;
45
+ }): Promise<void>;
46
+ }
47
+ export interface RunIdClassifier {
48
+ isDaemonRunId(args: {
49
+ runId: string;
50
+ }): boolean;
51
+ }
52
+ //# sourceMappingURL=ports.d.ts.map
@@ -0,0 +1,5 @@
1
+ /** Closed metadata directory for the public neutral entry. Its full source closure is
2
+ * verified by store/__tests__/import-isolation.test.ts and the packed Node consumer.
3
+ */
4
+ export * from '@jini-ai/chat/store';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,5 @@
1
+ /** Closed metadata directory for the public neutral entry. Its full source closure is
2
+ * verified by store/__tests__/import-isolation.test.ts and the packed Node consumer.
3
+ */
4
+ export * from '@jini-ai/chat/store';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,12 @@
1
+ import type { ChatStoreErrorCode } from './ports.js';
2
+ /** Stable public errors; messages never expose owner IDs, cursors or driver details.
3
+ * @example new ChatStoreError({ code: 'conflict' }, { cause: originalError })
4
+ */
5
+ export declare class ChatStoreError extends Error {
6
+ readonly name: "ChatStoreError";
7
+ readonly code: ChatStoreErrorCode;
8
+ constructor({ code }: {
9
+ code: ChatStoreErrorCode;
10
+ }, options?: ErrorOptions);
11
+ }
12
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1,18 @@
1
+ const MESSAGES = {
2
+ 'invalid-input': 'Invalid chat store input.',
3
+ 'invalid-cursor': 'Invalid chat page cursor.',
4
+ conflict: 'Chat store conflict.',
5
+ unavailable: 'Chat store unavailable.',
6
+ };
7
+ /** Stable public errors; messages never expose owner IDs, cursors or driver details.
8
+ * @example new ChatStoreError({ code: 'conflict' }, { cause: originalError })
9
+ */
10
+ export class ChatStoreError extends Error {
11
+ name = 'ChatStoreError';
12
+ code;
13
+ constructor({ code }, options) {
14
+ super(MESSAGES[code], options);
15
+ this.code = code;
16
+ }
17
+ }
18
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1,4 @@
1
+ /** Neutral store contracts and errors. SQL adapters are explicit child entries. */
2
+ export type * from './ports.js';
3
+ export { ChatStoreError } from './errors.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { ChatStoreError } from './errors.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,3 @@
1
+ /** Legacy local project conversations, distinct from tenant-scoped ai_* history. */
2
+ export type ChatSessionMode = 'design' | 'chat' | 'plan';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @module db/conversations/conversations
3
+ * Owns conversation CRUD and list/get queries with per-conversation run summaries and
4
+ * total run-duration aggregation. Imports only the core/ kernel (types + rows helper).
5
+ */
6
+ import type { SqliteDb } from '@jini-ai/db/sqlite';
7
+ import type { DbRow } from '@jini-ai/db/core';
8
+ import type { ChatSessionMode } from '../index.js';
9
+ /**
10
+ * Returns all conversations for a project, newest first, each enriched with message count,
11
+ * the latest assistant run summary, and total accumulated run duration across all terminal runs.
12
+ * @param db Open SQLite database handle.
13
+ * @param projectId The project whose conversations to list.
14
+ */
15
+ export declare function listConversations({ db, projectId }: {
16
+ db: SqliteDb;
17
+ projectId: string;
18
+ }): {
19
+ latestRun: {
20
+ durationMs?: number;
21
+ endedAt?: number | undefined;
22
+ startedAt?: number | undefined;
23
+ status: string;
24
+ } | undefined;
25
+ totalDurationMs?: number;
26
+ id: any;
27
+ projectId: any;
28
+ title: any;
29
+ sessionMode: ChatSessionMode;
30
+ messageCount: number;
31
+ createdAt: number;
32
+ updatedAt: number;
33
+ }[];
34
+ /**
35
+ * Fetches a single conversation by id with its latest run summary and total run duration.
36
+ * Returns null when no matching conversation exists.
37
+ * @param db Open SQLite database handle.
38
+ * @param id Conversation id.
39
+ */
40
+ export declare function getConversation({ db, id }: {
41
+ db: SqliteDb;
42
+ id: string;
43
+ }): {
44
+ totalDurationMs?: number;
45
+ latestRun: {
46
+ durationMs?: number;
47
+ endedAt?: number | undefined;
48
+ startedAt?: number | undefined;
49
+ status: string;
50
+ } | undefined;
51
+ id: any;
52
+ projectId: any;
53
+ title: any;
54
+ sessionMode: ChatSessionMode;
55
+ messageCount: number;
56
+ createdAt: number;
57
+ updatedAt: number;
58
+ } | null;
59
+ /**
60
+ * Coerces an arbitrary database value to a valid ChatSessionMode, defaulting to 'design'.
61
+ * Upholds the invariant that no conversation ever carries an unknown session mode.
62
+ * @param value Raw value read from the session_mode column.
63
+ * @returns A valid ChatSessionMode: 'chat', 'plan', or 'design'.
64
+ */
65
+ export declare function normalizeConversationSessionMode({ value }: {
66
+ value: unknown;
67
+ }): ChatSessionMode;
68
+ /**
69
+ * Inserts a new conversation row and returns the full conversation record (including run summary).
70
+ * Normalizes sessionMode before persisting so the stored value is always a valid ChatSessionMode.
71
+ * @param db Open SQLite database handle.
72
+ * @param c Conversation fields to insert.
73
+ */
74
+ export declare function insertConversation({ db, c }: {
75
+ db: SqliteDb;
76
+ c: DbRow;
77
+ }): {
78
+ totalDurationMs?: number;
79
+ latestRun: {
80
+ durationMs?: number;
81
+ endedAt?: number | undefined;
82
+ startedAt?: number | undefined;
83
+ status: string;
84
+ } | undefined;
85
+ id: any;
86
+ projectId: any;
87
+ title: any;
88
+ sessionMode: ChatSessionMode;
89
+ messageCount: number;
90
+ createdAt: number;
91
+ updatedAt: number;
92
+ } | null;
93
+ /**
94
+ * Applies a partial patch to an existing conversation, merging with the current record.
95
+ * Returns null when the conversation does not exist; otherwise returns the updated record.
96
+ * @param db Open SQLite database handle.
97
+ * @param id Conversation id to update.
98
+ * @param patch Fields to overwrite; sessionMode and updatedAt are normalized before persisting.
99
+ */
100
+ export declare function updateConversation({ db, id, patch }: {
101
+ db: SqliteDb;
102
+ id: string;
103
+ patch: DbRow;
104
+ }): {
105
+ totalDurationMs?: number;
106
+ latestRun: {
107
+ durationMs?: number;
108
+ endedAt?: number | undefined;
109
+ startedAt?: number | undefined;
110
+ status: string;
111
+ } | undefined;
112
+ id: any;
113
+ projectId: any;
114
+ title: any;
115
+ sessionMode: ChatSessionMode;
116
+ messageCount: number;
117
+ createdAt: number;
118
+ updatedAt: number;
119
+ } | null;
120
+ /**
121
+ * Removes a conversation row by id. Cascading deletes on messages are handled by the schema.
122
+ * @param db Open SQLite database handle.
123
+ * @param id Conversation id to delete.
124
+ */
125
+ export declare function deleteConversation({ db, id }: {
126
+ db: SqliteDb;
127
+ id: string;
128
+ }): void;
129
+ //# sourceMappingURL=conversations.d.ts.map