@jini-ai/chat 0.6.15-rc.1 → 0.6.15
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.
- package/dist/core/accepted-input.js +29 -14
- package/dist/core/ag-ui/entry.js +3 -1
- package/dist/core/agent-plugin-chat-state.js +3 -1
- package/dist/core/assistant-client/ag-ui-transport.js +1 -1
- package/dist/core/assistant-client/attachment-liveness.js +1 -1
- package/dist/core/assistant-client/durable-run-subscription.js +2 -1
- package/dist/core/assistant-client/transport.js +13 -7
- package/dist/core/assistant-content.js +2 -1
- package/dist/core/composer-history.js +2 -1
- package/dist/core/durable-projection.js +2 -1
- package/dist/core/durable-runs/continuation.js +2 -1
- package/dist/core/messages.d.ts +5 -1
- package/dist/core/partial-json.js +18 -9
- package/dist/core/persistence/title.d.ts +1 -1
- package/dist/core/persistence/title.js +25 -7
- package/dist/core/question-answer.js +9 -4
- package/dist/core/question-form/normalize.js +1 -1
- package/dist/core/question-form/scan.js +25 -15
- package/dist/core/question-form/secret-answers.js +2 -1
- package/dist/core/run-activity.js +8 -4
- package/dist/core/run-events/entry.js +6 -2
- package/dist/core/transcript.js +13 -6
- package/dist/core/turn-usage.js +12 -4
- package/dist/core/user-text-redaction.d.ts +2 -5
- package/dist/core/user-text-redaction.js +3 -3
- package/dist/core/util/manifest.js +13 -11
- package/dist/core/util/markdown-context.d.ts +14 -0
- package/dist/core/util/markdown-context.js +42 -4
- package/dist/core/util/markup-attributes.js +1 -1
- package/dist/core/util/parser.js +7 -7
- package/dist/core/util/pointer.js +22 -6
- package/dist/core/util/recover.js +5 -8
- package/dist/core/util/strip.js +12 -15
- package/dist/core/util/validate.js +30 -18
- package/dist/embed-widget/browser/lazy-loader.js +16 -12
- package/dist/embed-widget/react/dialog.hooks.js +2 -2
- package/dist/embed-widget/react/embed.js +1 -1
- package/dist/embed-widget/react/header.hooks.js +1 -1
- package/dist/embed-widget/transports/fetch-sse.js +2 -1
- package/dist/embed-widget/vanilla/index.js +19 -12
- package/dist/embed-widget/vanilla/state.js +4 -2
- package/dist/react/components/AttachmentPreviewModal.hooks.js +2 -1
- package/dist/react/components/ChatSettingsDialog.js +18 -9
- package/dist/react/components/Composer.js +5 -4
- package/dist/react/components/ConversationList.js +5 -4
- package/dist/react/components/Markdown.js +29 -26
- package/dist/react/components/McpUiSurfaceCard.js +2 -1
- package/dist/react/components/MessageList.hooks.js +3 -2
- package/dist/react/components/MessageRow.js +23 -7
- package/dist/react/components/MessageRow.usage.js +7 -2
- package/dist/react/components/QuestionForm.js +4 -5
- package/dist/react/components/SentAttachment.js +4 -1
- package/dist/react/components/TodoCard.js +9 -1
- package/dist/react/components/ToolCard.js +8 -7
- package/dist/react/components/composer-discovery.js +8 -8
- package/dist/react/features/chat-pane/components/AgentPluginUsage.js +1 -2
- package/dist/react/features/chat-pane/components/AgentRuntimePicker.d.ts +1 -1
- package/dist/react/features/chat-pane/components/AgentRuntimePicker.js +15 -5
- package/dist/react/features/chat-pane/components/ChatPane.js +5 -8
- package/dist/react/features/chat-pane/components/RuntimeDropUp.js +1 -1
- package/dist/react/features/chat-pane/create-daemon-attachment-uploader.js +1 -1
- package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.js +2 -2
- package/dist/react/features/chat-pane/hooks/useChatPane.hooks.js +12 -7
- package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.js +18 -22
- package/dist/react/features/chat-pane/hooks/useChatPaneControlsHeight.hooks.js +1 -1
- package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.js +2 -2
- package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.js +2 -2
- package/dist/react/features/chat-pane/hooks/useRuntimeDropUp.hooks.js +2 -2
- package/dist/react/features/chat-pane/model-options.js +4 -2
- package/dist/react/features/chat-pane/styles.d.ts +1 -1
- package/dist/react/features/chat-pane/styles.js +26 -3
- package/dist/react/features/chat-pane/types.d.ts +8 -0
- package/dist/react/hooks/assistant-chats.js +22 -8
- package/dist/react/hooks/useArtifactStream.js +2 -1
- package/dist/react/hooks/useComposer.js +2 -2
- package/dist/react/hooks/useComposerHistoryKeys.hooks.js +2 -2
- package/dist/react/hooks/useConversation.js +9 -4
- package/dist/react/hooks/useExtEventGroups.js +4 -2
- package/dist/react/hooks/useLatestOperation.js +2 -1
- package/dist/react/hooks/useQuestionForms.js +32 -22
- package/dist/react/hooks/useRunStream.js +4 -2
- package/dist/react/message-blocks.js +4 -2
- package/dist/react/styles/reference.css +9 -0
- package/dist/react/tool-call-display.js +1 -2
- package/dist/server/durable-runs/recover.js +13 -5
- package/dist/server/run-finalizer/entry.js +1 -0
- package/dist/store/runtime/chat-history-store.js +9 -3
- package/dist/store/runtime/durable-run-store.js +34 -24
- package/dist/store/runtime/run-ledger.js +7 -4
- package/dist/store/sql/boundary.js +3 -1
- package/dist/store/sql/cursor.js +8 -3
- package/dist/store/sql/store.js +36 -28
- package/package.json +15 -15
package/dist/store/sql/store.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const MESSAGE_POSITION = 'm.position';
|
|
2
|
+
const CONVERSATION_UPDATED_AT = 'c.updated_at';
|
|
1
3
|
/** One SQL query body upstreamed from the existing host adapter; no resource/schema ownership. */
|
|
2
4
|
// Legacy project/conversation CRUD trusts access to a local database file; this owner-bound store
|
|
3
5
|
// serves shared databases instead. Choose by trust model: borrowing a handle must not grant access
|
|
@@ -96,7 +98,9 @@ function runFields(row) {
|
|
|
96
98
|
}
|
|
97
99
|
/** Reject an unbounded or malformed history read before any query runs. */
|
|
98
100
|
function assertHistoryReadBounds({ limit, fromPosition }) {
|
|
99
|
-
if (!Number.isInteger(limit) || limit < 1 || limit > 100
|
|
101
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > 100)
|
|
102
|
+
throw new ChatStoreError({ code: 'invalid-input' });
|
|
103
|
+
if (fromPosition !== undefined && (!Number.isSafeInteger(fromPosition) || fromPosition < 0)) {
|
|
100
104
|
throw new ChatStoreError({ code: 'invalid-input' });
|
|
101
105
|
}
|
|
102
106
|
}
|
|
@@ -139,7 +143,7 @@ export function createSqlChatStore({ kernel, scope: inputScope }, { clock = crea
|
|
|
139
143
|
"c.title",
|
|
140
144
|
"c.title_source",
|
|
141
145
|
"c.created_at",
|
|
142
|
-
|
|
146
|
+
CONVERSATION_UPDATED_AT,
|
|
143
147
|
"c.expires_at",
|
|
144
148
|
eb
|
|
145
149
|
.selectFrom("ai_chat_messages as m")
|
|
@@ -182,7 +186,7 @@ export function createSqlChatStore({ kernel, scope: inputScope }, { clock = crea
|
|
|
182
186
|
}
|
|
183
187
|
/** Read owned messages in persisted position order; foreign IDs produce no rows. */
|
|
184
188
|
async function messages({ conversationId }, _optional = {}) {
|
|
185
|
-
const rows = await run(db => ownedMessages(db, conversationId).orderBy(
|
|
189
|
+
const rows = await run(db => ownedMessages(db, conversationId).orderBy(MESSAGE_POSITION).execute());
|
|
186
190
|
return rows.map(toMessage);
|
|
187
191
|
}
|
|
188
192
|
/** Writes and projects one message inside the borrowed transaction; null for absent/foreign IDs. */
|
|
@@ -226,18 +230,7 @@ export function createSqlChatStore({ kernel, scope: inputScope }, { clock = crea
|
|
|
226
230
|
started_at: m.startedAt ?? null,
|
|
227
231
|
ended_at: m.endedAt ?? null,
|
|
228
232
|
})
|
|
229
|
-
.onConflict(
|
|
230
|
-
.column("id")
|
|
231
|
-
.doUpdateSet((eb) => ({
|
|
232
|
-
content: eb.ref("excluded.content"),
|
|
233
|
-
events_json: eb.ref("excluded.events_json"),
|
|
234
|
-
attachments_json: eb.ref("excluded.attachments_json"),
|
|
235
|
-
run_id: eb.ref("excluded.run_id"),
|
|
236
|
-
run_status: eb.ref("excluded.run_status"),
|
|
237
|
-
started_at: eb.ref("excluded.started_at"),
|
|
238
|
-
ended_at: eb.ref("excluded.ended_at"),
|
|
239
|
-
}))
|
|
240
|
-
.where((eb) => eb("ai_chat_messages.conversation_id", "=", eb.ref("excluded.conversation_id"))))
|
|
233
|
+
.onConflict(updateOwnedMessageConflict)
|
|
241
234
|
.execute());
|
|
242
235
|
// A new message is activity: the list orders by `updated_at`.
|
|
243
236
|
await run((db) => db.updateTable("ai_chats").set({ updated_at: clock.nowMs() }).where("id", "=", conversationId).execute());
|
|
@@ -260,7 +253,9 @@ export function createSqlChatStore({ kernel, scope: inputScope }, { clock = crea
|
|
|
260
253
|
* @complexity The database scans owned content for search; only limit rows cross the port.
|
|
261
254
|
*/
|
|
262
255
|
async list(_required, { query, limit = 20 } = {}) {
|
|
263
|
-
if (!Number.isInteger(limit) || limit < 1 || limit > 50
|
|
256
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > 50)
|
|
257
|
+
throw new ChatStoreError({ code: 'invalid-input' });
|
|
258
|
+
if (query !== undefined && (typeof query !== 'string' || query.length > 200)) {
|
|
264
259
|
throw new ChatStoreError({ code: 'invalid-input' });
|
|
265
260
|
}
|
|
266
261
|
const rows = await run(db => {
|
|
@@ -277,7 +272,7 @@ export function createSqlChatStore({ kernel, scope: inputScope }, { clock = crea
|
|
|
277
272
|
.where(sql `lower(found.content) like ${pattern} escape '!'`)),
|
|
278
273
|
]));
|
|
279
274
|
}
|
|
280
|
-
return statement.orderBy(
|
|
275
|
+
return statement.orderBy(CONVERSATION_UPDATED_AT, 'desc').orderBy(ordinalId(kernel.dialect, 'c.id')).limit(limit).execute();
|
|
281
276
|
});
|
|
282
277
|
return rows.map(row => ({ ...toConversation(row), firstUserLine: row.first_user_line ?? '' }));
|
|
283
278
|
},
|
|
@@ -286,12 +281,12 @@ export function createSqlChatStore({ kernel, scope: inputScope }, { clock = crea
|
|
|
286
281
|
assertHistoryReadBounds({ limit, fromPosition });
|
|
287
282
|
const rows = await run(db => {
|
|
288
283
|
let statement = ownedMessages(db, chatId).clearSelect().select([
|
|
289
|
-
'm.id', 'm.role', 'm.content',
|
|
284
|
+
'm.id', 'm.role', 'm.content', MESSAGE_POSITION, 'm.created_at',
|
|
290
285
|
]);
|
|
291
286
|
if (fromPosition !== undefined)
|
|
292
|
-
statement = statement.where(
|
|
287
|
+
statement = statement.where(MESSAGE_POSITION, '>=', fromPosition);
|
|
293
288
|
return statement.select(includeToolEvents ? sql `m.events_json`.as('events_json') : sql `null`.as('events_json'))
|
|
294
|
-
.orderBy(
|
|
289
|
+
.orderBy(MESSAGE_POSITION, fromPosition === undefined ? 'desc' : 'asc').limit(limit + 1).execute();
|
|
295
290
|
});
|
|
296
291
|
const page = rows.slice(0, limit);
|
|
297
292
|
if (fromPosition === undefined)
|
|
@@ -300,7 +295,7 @@ export function createSqlChatStore({ kernel, scope: inputScope }, { clock = crea
|
|
|
300
295
|
},
|
|
301
296
|
},
|
|
302
297
|
async list() {
|
|
303
|
-
const rows = await run((db) => ownedConversations(db).orderBy(
|
|
298
|
+
const rows = await run((db) => ownedConversations(db).orderBy(CONVERSATION_UPDATED_AT, "desc").execute());
|
|
304
299
|
return rows.map((row) => toConversation(row));
|
|
305
300
|
},
|
|
306
301
|
get,
|
|
@@ -387,10 +382,10 @@ export function createSqlChatStore({ kernel, scope: inputScope }, { clock = crea
|
|
|
387
382
|
let query = ownedConversations(db);
|
|
388
383
|
if (anchor)
|
|
389
384
|
query = query.where(eb => eb.or([
|
|
390
|
-
eb(
|
|
391
|
-
eb.and([eb(
|
|
385
|
+
eb(CONVERSATION_UPDATED_AT, '<', anchor[0]),
|
|
386
|
+
eb.and([eb(CONVERSATION_UPDATED_AT, '=', anchor[0]), eb(id, '>', anchor[1])]),
|
|
392
387
|
]));
|
|
393
|
-
return query.orderBy(
|
|
388
|
+
return query.orderBy(CONVERSATION_UPDATED_AT, 'desc').orderBy(id, 'asc').limit(limit + 1).execute();
|
|
394
389
|
});
|
|
395
390
|
const items = rows.slice(0, limit).map(row => toConversation(row));
|
|
396
391
|
const last = items.at(-1);
|
|
@@ -404,13 +399,13 @@ export function createSqlChatStore({ kernel, scope: inputScope }, { clock = crea
|
|
|
404
399
|
const id = ordinalId(kernel.dialect, 'm.id');
|
|
405
400
|
// One join, at most limit+1 rows, including the ownership check; no parent pre-read.
|
|
406
401
|
const rows = await run(db => {
|
|
407
|
-
let query = ownedMessages(db, input.conversationId).select(
|
|
402
|
+
let query = ownedMessages(db, input.conversationId).select(MESSAGE_POSITION);
|
|
408
403
|
if (anchor)
|
|
409
404
|
query = query.where(eb => eb.or([
|
|
410
|
-
eb(
|
|
411
|
-
eb.and([eb(
|
|
405
|
+
eb(MESSAGE_POSITION, '>', anchor[0]),
|
|
406
|
+
eb.and([eb(MESSAGE_POSITION, '=', anchor[0]), eb(id, '>', anchor[1])]),
|
|
412
407
|
]));
|
|
413
|
-
return query.orderBy(
|
|
408
|
+
return query.orderBy(MESSAGE_POSITION, 'asc').orderBy(id, 'asc').limit(limit + 1).execute();
|
|
414
409
|
});
|
|
415
410
|
const page = rows.slice(0, limit), last = page.at(-1);
|
|
416
411
|
return { items: page.map(toMessage), ...(rows.length > limit && last ? {
|
|
@@ -435,4 +430,17 @@ export function createSqlChatStore({ kernel, scope: inputScope }, { clock = crea
|
|
|
435
430
|
pageMessages: (required, optional = {}) => atStoreBoundary({ operation: () => store.pageMessages(required, optional) }),
|
|
436
431
|
};
|
|
437
432
|
}
|
|
433
|
+
function updateOwnedMessageConflict(oc) {
|
|
434
|
+
return oc.column("id")
|
|
435
|
+
.doUpdateSet((eb) => ({
|
|
436
|
+
content: eb.ref("excluded.content"),
|
|
437
|
+
events_json: eb.ref("excluded.events_json"),
|
|
438
|
+
attachments_json: eb.ref("excluded.attachments_json"),
|
|
439
|
+
run_id: eb.ref("excluded.run_id"),
|
|
440
|
+
run_status: eb.ref("excluded.run_status"),
|
|
441
|
+
started_at: eb.ref("excluded.started_at"),
|
|
442
|
+
ended_at: eb.ref("excluded.ended_at"),
|
|
443
|
+
}))
|
|
444
|
+
.where((eb) => eb("ai_chat_messages.conversation_id", "=", eb.ref("excluded.conversation_id")));
|
|
445
|
+
}
|
|
438
446
|
//# sourceMappingURL=store.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jini-ai/chat",
|
|
3
|
-
"version": "0.6.15
|
|
3
|
+
"version": "0.6.15",
|
|
4
4
|
"description": "Jini's chat/artifact frontend, consolidated into one package with two subpaths: framework-free chat vocabulary and pure parsers in `/core`, headless hooks + presentational components + slots in `/react`. Import only the layer you need.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -196,12 +196,12 @@
|
|
|
196
196
|
"registry": "https://registry.npmjs.org"
|
|
197
197
|
},
|
|
198
198
|
"dependencies": {
|
|
199
|
-
"@jini-ai/core": "^0.6.15
|
|
199
|
+
"@jini-ai/core": "^0.6.15"
|
|
200
200
|
},
|
|
201
201
|
"peerDependencies": {
|
|
202
202
|
"react": "^18.3.0 || ^19.0.0",
|
|
203
203
|
"react-dom": "^18.3.0 || ^19.0.0",
|
|
204
|
-
"@jini-ai/db": "^0.6.
|
|
204
|
+
"@jini-ai/db": "^0.6.10",
|
|
205
205
|
"kysely": "^0.29.6",
|
|
206
206
|
"better-sqlite3": "^13.0.0",
|
|
207
207
|
"@electric-sql/pglite": "0.5.8",
|
|
@@ -213,11 +213,11 @@
|
|
|
213
213
|
"@radix-ui/react-radio-group": "^1.4.7",
|
|
214
214
|
"@radix-ui/react-select": "^2.3.7",
|
|
215
215
|
"@radix-ui/react-slot": "^1.3.3",
|
|
216
|
-
"@jini-ai/agent-runtime": "^0.6.
|
|
217
|
-
"@jini-ai/agentic": "^0.6.
|
|
218
|
-
"@jini-ai/protocol": "^0.6.
|
|
219
|
-
"@jini-ai/ui": "^0.6.
|
|
220
|
-
"@jini-ai/diagnostics": "^0.6.
|
|
216
|
+
"@jini-ai/agent-runtime": "^0.6.10",
|
|
217
|
+
"@jini-ai/agentic": "^0.6.10",
|
|
218
|
+
"@jini-ai/protocol": "^0.6.10",
|
|
219
|
+
"@jini-ai/ui": "^0.6.10",
|
|
220
|
+
"@jini-ai/diagnostics": "^0.6.10"
|
|
221
221
|
},
|
|
222
222
|
"peerDependenciesMeta": {
|
|
223
223
|
"react": {
|
|
@@ -303,13 +303,13 @@
|
|
|
303
303
|
"pg": "8.23.0",
|
|
304
304
|
"@ag-ui/core": "0.0.58",
|
|
305
305
|
"fast-check": "4.3.0",
|
|
306
|
-
"@jini-ai/db": "0.6.15
|
|
307
|
-
"@jini-ai/
|
|
308
|
-
"@jini-ai/
|
|
309
|
-
"@jini-ai/
|
|
310
|
-
"@jini-ai/core": "^0.6.15
|
|
311
|
-
"@jini-ai/
|
|
312
|
-
"@jini-ai/
|
|
306
|
+
"@jini-ai/db": "0.6.15",
|
|
307
|
+
"@jini-ai/agent-runtime": "0.6.15",
|
|
308
|
+
"@jini-ai/protocol": "^0.6.15",
|
|
309
|
+
"@jini-ai/agentic": "^0.6.15",
|
|
310
|
+
"@jini-ai/core": "^0.6.15",
|
|
311
|
+
"@jini-ai/diagnostics": "^0.6.15",
|
|
312
|
+
"@jini-ai/ui": "^0.6.15"
|
|
313
313
|
},
|
|
314
314
|
"typesVersions": {
|
|
315
315
|
"*": {
|