@jskit-ai/assistant 0.1.30 → 0.1.31
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/package.descriptor.mjs +9 -9
- package/package.json +9 -9
- package/src/server/repositories/conversationsRepository.js +4 -4
- package/src/server/repositories/messagesRepository.js +2 -2
- package/src/server/services/chatService.js +3 -3
- package/src/server/services/transcriptService.js +2 -2
- package/src/shared/assistantResource.js +4 -4
- package/templates/migrations/assistant_transcripts_initial.cjs +6 -6
- package/test/assistantResource.test.js +1 -1
- package/test/transcriptService.test.js +1 -1
package/package.descriptor.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export default Object.freeze({
|
|
2
2
|
packageVersion: 1,
|
|
3
3
|
packageId: "@jskit-ai/assistant",
|
|
4
|
-
version: "0.1.
|
|
4
|
+
version: "0.1.31",
|
|
5
5
|
kind: "runtime",
|
|
6
6
|
description: "Unified assistant module with streaming chat, transcript persistence, service-aware tool execution, and workspace UI.",
|
|
7
7
|
options: {
|
|
@@ -110,14 +110,14 @@ export default Object.freeze({
|
|
|
110
110
|
mutations: {
|
|
111
111
|
dependencies: {
|
|
112
112
|
runtime: {
|
|
113
|
-
"@jskit-ai/assistant": "0.1.
|
|
114
|
-
"@jskit-ai/auth-core": "0.1.
|
|
115
|
-
"@jskit-ai/database-runtime": "0.1.
|
|
116
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
117
|
-
"@jskit-ai/kernel": "0.1.
|
|
118
|
-
"@jskit-ai/realtime": "0.1.
|
|
119
|
-
"@jskit-ai/users-core": "0.1.
|
|
120
|
-
"@jskit-ai/users-web": "0.1.
|
|
113
|
+
"@jskit-ai/assistant": "0.1.31",
|
|
114
|
+
"@jskit-ai/auth-core": "0.1.22",
|
|
115
|
+
"@jskit-ai/database-runtime": "0.1.23",
|
|
116
|
+
"@jskit-ai/http-runtime": "0.1.22",
|
|
117
|
+
"@jskit-ai/kernel": "0.1.23",
|
|
118
|
+
"@jskit-ai/realtime": "0.1.22",
|
|
119
|
+
"@jskit-ai/users-core": "0.1.32",
|
|
120
|
+
"@jskit-ai/users-web": "0.1.37",
|
|
121
121
|
"@tanstack/vue-query": "^5.90.5",
|
|
122
122
|
"dompurify": "^3.3.3",
|
|
123
123
|
"marked": "^17.0.4",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/assistant",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
"./shared": "./src/shared/index.js"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@jskit-ai/auth-core": "0.1.
|
|
16
|
-
"@jskit-ai/database-runtime": "0.1.
|
|
17
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
18
|
-
"@jskit-ai/kernel": "0.1.
|
|
19
|
-
"@jskit-ai/realtime": "0.1.
|
|
20
|
-
"@jskit-ai/shell-web": "0.1.
|
|
21
|
-
"@jskit-ai/users-core": "0.1.
|
|
22
|
-
"@jskit-ai/users-web": "0.1.
|
|
15
|
+
"@jskit-ai/auth-core": "0.1.22",
|
|
16
|
+
"@jskit-ai/database-runtime": "0.1.23",
|
|
17
|
+
"@jskit-ai/http-runtime": "0.1.22",
|
|
18
|
+
"@jskit-ai/kernel": "0.1.23",
|
|
19
|
+
"@jskit-ai/realtime": "0.1.22",
|
|
20
|
+
"@jskit-ai/shell-web": "0.1.22",
|
|
21
|
+
"@jskit-ai/users-core": "0.1.32",
|
|
22
|
+
"@jskit-ai/users-web": "0.1.37",
|
|
23
23
|
"@tanstack/vue-query": "^5.90.5",
|
|
24
24
|
"dompurify": "^3.3.3",
|
|
25
25
|
"marked": "^17.0.4",
|
|
@@ -21,7 +21,7 @@ function mapConversationRow(row = {}) {
|
|
|
21
21
|
status: String(row.status || "active"),
|
|
22
22
|
provider: String(row.provider || ""),
|
|
23
23
|
model: String(row.model || ""),
|
|
24
|
-
|
|
24
|
+
surfaceSid: String(row.surface_sid || ""),
|
|
25
25
|
startedAt: toIso(row.started_at),
|
|
26
26
|
endedAt: row.ended_at ? toIso(row.ended_at) : null,
|
|
27
27
|
messageCount: Number(row.message_count || 0),
|
|
@@ -101,7 +101,7 @@ function createConversationsRepository(knex) {
|
|
|
101
101
|
status: normalizeText(payload.status).toLowerCase() || "active",
|
|
102
102
|
provider: normalizeText(payload.provider),
|
|
103
103
|
model: normalizeText(payload.model),
|
|
104
|
-
|
|
104
|
+
surface_sid: normalizeText(payload.surfaceSid).toLowerCase() || "admin",
|
|
105
105
|
message_count: parsePositiveInteger(payload.messageCount) || 0,
|
|
106
106
|
metadata_json: stringifyJsonObject(payload.metadata),
|
|
107
107
|
started_at: payload.startedAt ? new Date(payload.startedAt) : now,
|
|
@@ -140,8 +140,8 @@ function createConversationsRepository(knex) {
|
|
|
140
140
|
if (Object.hasOwn(patch, "model")) {
|
|
141
141
|
updatePatch.model = normalizeText(patch.model);
|
|
142
142
|
}
|
|
143
|
-
if (Object.hasOwn(patch, "
|
|
144
|
-
updatePatch.
|
|
143
|
+
if (Object.hasOwn(patch, "surfaceSid")) {
|
|
144
|
+
updatePatch.surface_sid = normalizeText(patch.surfaceSid).toLowerCase() || "admin";
|
|
145
145
|
}
|
|
146
146
|
if (Object.hasOwn(patch, "messageCount")) {
|
|
147
147
|
updatePatch.message_count = Math.max(0, Number(patch.messageCount || 0));
|
|
@@ -16,7 +16,7 @@ function mapMessageRow(row = {}) {
|
|
|
16
16
|
seq: Number(row.seq),
|
|
17
17
|
role: String(row.role || ""),
|
|
18
18
|
kind: String(row.kind || "chat"),
|
|
19
|
-
|
|
19
|
+
clientMessageSid: String(row.client_message_sid || ""),
|
|
20
20
|
actorUserId: row.actor_user_id == null ? null : Number(row.actor_user_id),
|
|
21
21
|
contentText: row.content_text == null ? null : String(row.content_text),
|
|
22
22
|
metadata: parseJsonObject(row.metadata_json),
|
|
@@ -75,7 +75,7 @@ function createMessagesRepository(knex) {
|
|
|
75
75
|
seq,
|
|
76
76
|
role: normalizeText(payload.role).toLowerCase(),
|
|
77
77
|
kind: normalizeText(payload.kind).toLowerCase() || "chat",
|
|
78
|
-
|
|
78
|
+
client_message_sid: normalizeText(payload.clientMessageSid),
|
|
79
79
|
actor_user_id: parsePositiveInteger(payload.actorUserId) || null,
|
|
80
80
|
content_text: payload.contentText == null ? null : String(payload.contentText),
|
|
81
81
|
metadata_json: stringifyJsonObject(payload.metadata),
|
|
@@ -561,7 +561,7 @@ function createChatService({ aiClient, transcriptService, serviceToolCatalog, as
|
|
|
561
561
|
conversationId: source.conversationId,
|
|
562
562
|
provider: aiClient.provider,
|
|
563
563
|
model: aiClient.defaultModel,
|
|
564
|
-
|
|
564
|
+
surfaceSid: context.surface,
|
|
565
565
|
messageId: source.messageId
|
|
566
566
|
},
|
|
567
567
|
{
|
|
@@ -580,10 +580,10 @@ function createChatService({ aiClient, transcriptService, serviceToolCatalog, as
|
|
|
580
580
|
{
|
|
581
581
|
role: "user",
|
|
582
582
|
kind: "chat",
|
|
583
|
-
|
|
583
|
+
clientMessageSid: source.messageId,
|
|
584
584
|
contentText: source.input,
|
|
585
585
|
metadata: {
|
|
586
|
-
|
|
586
|
+
surfaceSid: normalizeText(context.surface)
|
|
587
587
|
}
|
|
588
588
|
},
|
|
589
589
|
{
|
|
@@ -155,7 +155,7 @@ function createTranscriptService({ conversationsRepository, messagesRepository }
|
|
|
155
155
|
status: "active",
|
|
156
156
|
provider: normalizeText(source.provider),
|
|
157
157
|
model: normalizeText(source.model),
|
|
158
|
-
|
|
158
|
+
surfaceSid: normalizeText(source.surfaceSid).toLowerCase() || "admin",
|
|
159
159
|
metadata: {
|
|
160
160
|
firstMessageId: normalizeText(source.messageId)
|
|
161
161
|
}
|
|
@@ -186,7 +186,7 @@ function createTranscriptService({ conversationsRepository, messagesRepository }
|
|
|
186
186
|
workspaceId: conversation.workspaceId,
|
|
187
187
|
role: normalizeText(source.role).toLowerCase(),
|
|
188
188
|
kind: normalizeText(source.kind).toLowerCase() || "chat",
|
|
189
|
-
|
|
189
|
+
clientMessageSid: normalizeText(source.clientMessageSid),
|
|
190
190
|
actorUserId,
|
|
191
191
|
contentText: source.contentText == null ? null : String(source.contentText),
|
|
192
192
|
metadata: normalizeObject(source.metadata)
|
|
@@ -126,7 +126,7 @@ function normalizeConversationRecord(payload = {}) {
|
|
|
126
126
|
status: normalizeText(source.status),
|
|
127
127
|
provider: normalizeText(source.provider),
|
|
128
128
|
model: normalizeText(source.model),
|
|
129
|
-
|
|
129
|
+
surfaceSid: normalizeText(source.surfaceSid),
|
|
130
130
|
startedAt: normalizeText(source.startedAt),
|
|
131
131
|
endedAt: normalizeText(source.endedAt) || null,
|
|
132
132
|
messageCount: Math.max(0, Number(source.messageCount || 0)),
|
|
@@ -146,7 +146,7 @@ function normalizeConversationMessageRecord(payload = {}) {
|
|
|
146
146
|
seq: toPositiveInteger(source.seq, 0),
|
|
147
147
|
role: normalizeText(source.role),
|
|
148
148
|
kind: normalizeText(source.kind),
|
|
149
|
-
|
|
149
|
+
clientMessageSid: normalizeText(source.clientMessageSid),
|
|
150
150
|
actorUserId: toPositiveInteger(source.actorUserId, 0) || null,
|
|
151
151
|
contentText: source.contentText == null ? null : String(source.contentText),
|
|
152
152
|
metadata: normalizeObjectInput(source.metadata),
|
|
@@ -196,7 +196,7 @@ const conversationRecordSchema = Type.Object(
|
|
|
196
196
|
status: Type.String(),
|
|
197
197
|
provider: Type.String(),
|
|
198
198
|
model: Type.String(),
|
|
199
|
-
|
|
199
|
+
surfaceSid: Type.String(),
|
|
200
200
|
startedAt: Type.String({ minLength: 1 }),
|
|
201
201
|
endedAt: Type.Union([Type.String({ minLength: 1 }), Type.Null()]),
|
|
202
202
|
messageCount: Type.Integer({ minimum: 0 }),
|
|
@@ -220,7 +220,7 @@ const messageRecordSchema = Type.Object(
|
|
|
220
220
|
seq: Type.Integer({ minimum: 1 }),
|
|
221
221
|
role: Type.String({ minLength: 1 }),
|
|
222
222
|
kind: Type.String({ minLength: 1 }),
|
|
223
|
-
|
|
223
|
+
clientMessageSid: Type.String(),
|
|
224
224
|
actorUserId: Type.Union([Type.Integer({ minimum: 1 }), Type.Null()]),
|
|
225
225
|
contentText: Type.Union([Type.String(), Type.Null()]),
|
|
226
226
|
metadata: Type.Record(Type.String(), Type.Unknown()),
|
|
@@ -3,13 +3,13 @@ exports.up = async function up(knex) {
|
|
|
3
3
|
if (!hasConversationsTable) {
|
|
4
4
|
await knex.schema.createTable("ai_conversations", (table) => {
|
|
5
5
|
table.increments("id").unsigned().primary();
|
|
6
|
-
table.integer("workspace_id").unsigned().notNullable().index();
|
|
7
|
-
table.integer("created_by_user_id").unsigned().nullable().index();
|
|
6
|
+
table.integer("workspace_id").unsigned().notNullable().references("id").inTable("workspaces").onDelete("CASCADE").index();
|
|
7
|
+
table.integer("created_by_user_id").unsigned().nullable().references("id").inTable("users").onDelete("SET NULL").index();
|
|
8
8
|
table.string("title", 160).notNullable().defaultTo("New conversation");
|
|
9
9
|
table.string("status", 32).notNullable().defaultTo("active");
|
|
10
10
|
table.string("provider", 64).notNullable().defaultTo("");
|
|
11
11
|
table.string("model", 128).notNullable().defaultTo("");
|
|
12
|
-
table.string("
|
|
12
|
+
table.string("surface_sid", 32).notNullable().defaultTo("admin");
|
|
13
13
|
table.integer("message_count").unsigned().notNullable().defaultTo(0);
|
|
14
14
|
table.text("metadata_json").nullable();
|
|
15
15
|
table.timestamp("started_at").notNullable().defaultTo(knex.fn.now());
|
|
@@ -27,12 +27,12 @@ exports.up = async function up(knex) {
|
|
|
27
27
|
await knex.schema.createTable("ai_messages", (table) => {
|
|
28
28
|
table.increments("id").unsigned().primary();
|
|
29
29
|
table.integer("conversation_id").unsigned().notNullable().references("id").inTable("ai_conversations").onDelete("CASCADE");
|
|
30
|
-
table.integer("workspace_id").unsigned().notNullable().index();
|
|
30
|
+
table.integer("workspace_id").unsigned().notNullable().references("id").inTable("workspaces").onDelete("CASCADE").index();
|
|
31
31
|
table.integer("seq").unsigned().notNullable();
|
|
32
32
|
table.string("role", 32).notNullable();
|
|
33
33
|
table.string("kind", 32).notNullable().defaultTo("chat");
|
|
34
|
-
table.string("
|
|
35
|
-
table.integer("actor_user_id").unsigned().nullable().index();
|
|
34
|
+
table.string("client_message_sid", 128).notNullable().defaultTo("");
|
|
35
|
+
table.integer("actor_user_id").unsigned().nullable().references("id").inTable("users").onDelete("SET NULL").index();
|
|
36
36
|
table.text("content_text").nullable();
|
|
37
37
|
table.text("metadata_json").nullable();
|
|
38
38
|
table.timestamp("created_at").notNullable().defaultTo(knex.fn.now());
|
|
@@ -25,7 +25,7 @@ test("assistant output schemas accept normalized paginated payloads", () => {
|
|
|
25
25
|
status: "active",
|
|
26
26
|
provider: "openai",
|
|
27
27
|
model: "gpt-4.1",
|
|
28
|
-
|
|
28
|
+
surfaceSid: "admin",
|
|
29
29
|
startedAt: "2026-03-16T10:00:00.000Z",
|
|
30
30
|
endedAt: null,
|
|
31
31
|
messageCount: 2,
|
|
@@ -40,7 +40,7 @@ function createInMemoryTranscriptRepos({
|
|
|
40
40
|
status: String(payload.status || "active"),
|
|
41
41
|
provider: String(payload.provider || ""),
|
|
42
42
|
model: String(payload.model || ""),
|
|
43
|
-
|
|
43
|
+
surfaceSid: String(payload.surfaceSid || "admin"),
|
|
44
44
|
messageCount: Number(payload.messageCount || 0),
|
|
45
45
|
metadata: payload.metadata || {}
|
|
46
46
|
};
|