@jskit-ai/assistant-runtime 0.1.29 → 0.1.30
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 +8 -8
- package/package.json +8 -8
- package/src/server/actions.js +13 -12
- package/src/server/registerRoutes.js +48 -18
- package/test/lazyAppConfig.test.js +48 -10
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-runtime",
|
|
4
|
-
version: "0.1.
|
|
4
|
+
version: "0.1.30",
|
|
5
5
|
kind: "runtime",
|
|
6
6
|
description: "Shared assistant runtime with per-surface assistant registration.",
|
|
7
7
|
dependsOn: [
|
|
@@ -74,13 +74,13 @@ export default Object.freeze({
|
|
|
74
74
|
mutations: {
|
|
75
75
|
dependencies: {
|
|
76
76
|
runtime: {
|
|
77
|
-
"@jskit-ai/assistant-core": "0.1.
|
|
78
|
-
"@jskit-ai/database-runtime": "0.1.
|
|
79
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
80
|
-
"@jskit-ai/kernel": "0.1.
|
|
81
|
-
"@jskit-ai/shell-web": "0.1.
|
|
82
|
-
"@jskit-ai/users-core": "0.1.
|
|
83
|
-
"@jskit-ai/users-web": "0.1.
|
|
77
|
+
"@jskit-ai/assistant-core": "0.1.35",
|
|
78
|
+
"@jskit-ai/database-runtime": "0.1.59",
|
|
79
|
+
"@jskit-ai/http-runtime": "0.1.58",
|
|
80
|
+
"@jskit-ai/kernel": "0.1.59",
|
|
81
|
+
"@jskit-ai/shell-web": "0.1.58",
|
|
82
|
+
"@jskit-ai/users-core": "0.1.69",
|
|
83
|
+
"@jskit-ai/users-web": "0.1.74",
|
|
84
84
|
"@tanstack/vue-query": "^5.90.5",
|
|
85
85
|
"vuetify": "^4.0.0"
|
|
86
86
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/assistant-runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.30",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./client": "./src/client/index.js",
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
"./server/actionIds": "./src/server/actionIds.js"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@jskit-ai/assistant-core": "0.1.
|
|
12
|
-
"@jskit-ai/database-runtime": "0.1.
|
|
13
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
14
|
-
"@jskit-ai/kernel": "0.1.
|
|
15
|
-
"@jskit-ai/shell-web": "0.1.
|
|
16
|
-
"@jskit-ai/users-core": "0.1.
|
|
17
|
-
"@jskit-ai/users-web": "0.1.
|
|
11
|
+
"@jskit-ai/assistant-core": "0.1.35",
|
|
12
|
+
"@jskit-ai/database-runtime": "0.1.59",
|
|
13
|
+
"@jskit-ai/http-runtime": "0.1.58",
|
|
14
|
+
"@jskit-ai/kernel": "0.1.59",
|
|
15
|
+
"@jskit-ai/shell-web": "0.1.58",
|
|
16
|
+
"@jskit-ai/users-core": "0.1.69",
|
|
17
|
+
"@jskit-ai/users-web": "0.1.74",
|
|
18
18
|
"json-rest-schema": "1.x.x",
|
|
19
19
|
"@tanstack/vue-query": "^5.90.5",
|
|
20
20
|
"vuetify": "^4.0.0"
|
package/src/server/actions.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
deepFreeze
|
|
7
7
|
} from "@jskit-ai/kernel/shared/support/deepFreeze";
|
|
8
|
+
import { returnJsonApiData } from "@jskit-ai/http-runtime/shared";
|
|
8
9
|
import {
|
|
9
10
|
assistantConfigResource,
|
|
10
11
|
assistantResource
|
|
@@ -120,17 +121,17 @@ const assistantActions = Object.freeze([
|
|
|
120
121
|
require: "authenticated"
|
|
121
122
|
},
|
|
122
123
|
input: runtimeConversationsListInputValidator,
|
|
123
|
-
output:
|
|
124
|
+
output: null,
|
|
124
125
|
idempotency: "none",
|
|
125
126
|
audit: {
|
|
126
127
|
actionName: actionIds.conversationsList
|
|
127
128
|
},
|
|
128
129
|
observability: {},
|
|
129
130
|
async execute(input, context, deps) {
|
|
130
|
-
return deps.chatService.listConversations(input.query, {
|
|
131
|
+
return returnJsonApiData(await deps.chatService.listConversations(input.query, {
|
|
131
132
|
context,
|
|
132
133
|
input
|
|
133
|
-
});
|
|
134
|
+
}));
|
|
134
135
|
}
|
|
135
136
|
},
|
|
136
137
|
{
|
|
@@ -143,17 +144,17 @@ const assistantActions = Object.freeze([
|
|
|
143
144
|
require: "authenticated"
|
|
144
145
|
},
|
|
145
146
|
input: runtimeConversationMessagesListInputValidator,
|
|
146
|
-
output:
|
|
147
|
+
output: null,
|
|
147
148
|
idempotency: "none",
|
|
148
149
|
audit: {
|
|
149
150
|
actionName: actionIds.conversationMessagesList
|
|
150
151
|
},
|
|
151
152
|
observability: {},
|
|
152
153
|
async execute(input, context, deps) {
|
|
153
|
-
return deps.chatService.getConversationMessages(input.conversationId, input.query, {
|
|
154
|
+
return returnJsonApiData(await deps.chatService.getConversationMessages(input.conversationId, input.query, {
|
|
154
155
|
context,
|
|
155
156
|
input
|
|
156
|
-
});
|
|
157
|
+
}));
|
|
157
158
|
}
|
|
158
159
|
},
|
|
159
160
|
{
|
|
@@ -166,16 +167,16 @@ const assistantActions = Object.freeze([
|
|
|
166
167
|
require: "authenticated"
|
|
167
168
|
},
|
|
168
169
|
input: settingsReadInputValidator,
|
|
169
|
-
output:
|
|
170
|
+
output: null,
|
|
170
171
|
idempotency: "none",
|
|
171
172
|
audit: {
|
|
172
173
|
actionName: actionIds.settingsRead
|
|
173
174
|
},
|
|
174
175
|
observability: {},
|
|
175
176
|
async execute(input, context, deps) {
|
|
176
|
-
return deps.assistantConfigService.getSettings(input, {
|
|
177
|
+
return returnJsonApiData(await deps.assistantConfigService.getSettings(input, {
|
|
177
178
|
context
|
|
178
|
-
});
|
|
179
|
+
}));
|
|
179
180
|
}
|
|
180
181
|
},
|
|
181
182
|
{
|
|
@@ -188,16 +189,16 @@ const assistantActions = Object.freeze([
|
|
|
188
189
|
require: "authenticated"
|
|
189
190
|
},
|
|
190
191
|
input: settingsUpdateInputValidator,
|
|
191
|
-
output:
|
|
192
|
+
output: null,
|
|
192
193
|
idempotency: "optional",
|
|
193
194
|
audit: {
|
|
194
195
|
actionName: actionIds.settingsUpdate
|
|
195
196
|
},
|
|
196
197
|
observability: {},
|
|
197
198
|
async execute(input, context, deps) {
|
|
198
|
-
return deps.assistantConfigService.updateSettings(input, input.patch, {
|
|
199
|
+
return returnJsonApiData(await deps.assistantConfigService.updateSettings(input, input.patch, {
|
|
199
200
|
context
|
|
200
|
-
});
|
|
201
|
+
}));
|
|
201
202
|
}
|
|
202
203
|
}
|
|
203
204
|
]);
|
|
@@ -2,8 +2,13 @@ import { AppError } from "@jskit-ai/kernel/server/runtime";
|
|
|
2
2
|
import { resolveAppConfig } from "@jskit-ai/kernel/server/support";
|
|
3
3
|
import { composeSchemaDefinitions } from "@jskit-ai/kernel/shared/validators";
|
|
4
4
|
import { normalizeSurfaceId } from "@jskit-ai/kernel/shared/surface/registry";
|
|
5
|
-
import {
|
|
5
|
+
import { createJsonApiResourceRouteContract } from "@jskit-ai/http-runtime/shared/validators/jsonApiRouteTransport";
|
|
6
6
|
import {
|
|
7
|
+
ASSISTANT_CONVERSATIONS_TRANSPORT,
|
|
8
|
+
ASSISTANT_CONVERSATION_MESSAGES_TRANSPORT,
|
|
9
|
+
ASSISTANT_SETTINGS_UPDATE_TRANSPORT,
|
|
10
|
+
ASSISTANT_SETTINGS_TRANSPORT,
|
|
11
|
+
assistantConversationOutputValidator,
|
|
7
12
|
assistantConfigResource,
|
|
8
13
|
assistantResource,
|
|
9
14
|
resolveAssistantApiBasePath
|
|
@@ -156,6 +161,24 @@ function buildChatStreamActionInput(routeInput = {}, requestBody = {}) {
|
|
|
156
161
|
return actionInput;
|
|
157
162
|
}
|
|
158
163
|
|
|
164
|
+
function resolveAssistantSettingsRecordId(record = {}) {
|
|
165
|
+
const scopeKey = String(record?.scopeKey || "").trim();
|
|
166
|
+
if (!scopeKey) {
|
|
167
|
+
throw new Error("Assistant settings JSON:API response requires scopeKey.");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return scopeKey;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function resolveAssistantConversationMessagesRecordId(record = {}) {
|
|
174
|
+
const conversationId = String(record?.conversation?.id || "").trim();
|
|
175
|
+
if (!conversationId) {
|
|
176
|
+
throw new Error("Assistant conversation messages JSON:API response requires conversation.id.");
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return conversationId;
|
|
180
|
+
}
|
|
181
|
+
|
|
159
182
|
function registerSettingsRoutes(
|
|
160
183
|
router,
|
|
161
184
|
resolveCurrentAppConfig,
|
|
@@ -181,8 +204,11 @@ function registerSettingsRoutes(
|
|
|
181
204
|
tags: ["assistant", "settings"],
|
|
182
205
|
summary: "Get assistant settings."
|
|
183
206
|
},
|
|
184
|
-
|
|
185
|
-
|
|
207
|
+
...createJsonApiResourceRouteContract({
|
|
208
|
+
...ASSISTANT_SETTINGS_TRANSPORT,
|
|
209
|
+
output: assistantConfigResource.operations.view.output,
|
|
210
|
+
outputKind: "record",
|
|
211
|
+
getRecordId: resolveAssistantSettingsRecordId
|
|
186
212
|
})
|
|
187
213
|
},
|
|
188
214
|
async function assistantSettingsReadRoute(request, reply) {
|
|
@@ -216,15 +242,14 @@ function registerSettingsRoutes(
|
|
|
216
242
|
tags: ["assistant", "settings"],
|
|
217
243
|
summary: "Update assistant settings."
|
|
218
244
|
},
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
)
|
|
245
|
+
...createJsonApiResourceRouteContract({
|
|
246
|
+
...ASSISTANT_SETTINGS_UPDATE_TRANSPORT,
|
|
247
|
+
body: assistantConfigResource.operations.patch.body,
|
|
248
|
+
output: assistantConfigResource.operations.patch.output,
|
|
249
|
+
outputKind: "record",
|
|
250
|
+
getRecordId: resolveAssistantSettingsRecordId,
|
|
251
|
+
includeValidation400: true
|
|
252
|
+
})
|
|
228
253
|
},
|
|
229
254
|
async function assistantSettingsPatchRoute(request, reply) {
|
|
230
255
|
const routeState = resolveRouteRequestState(request, {
|
|
@@ -400,9 +425,11 @@ function registerRuntimeRoutes(
|
|
|
400
425
|
tags: ["assistant"],
|
|
401
426
|
summary: "List assistant conversations."
|
|
402
427
|
},
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
428
|
+
...createJsonApiResourceRouteContract({
|
|
429
|
+
...ASSISTANT_CONVERSATIONS_TRANSPORT,
|
|
430
|
+
query: assistantResource.operations.conversationsList.query,
|
|
431
|
+
output: assistantConversationOutputValidator,
|
|
432
|
+
outputKind: "collection"
|
|
406
433
|
})
|
|
407
434
|
},
|
|
408
435
|
async function assistantConversationsRoute(request, reply) {
|
|
@@ -439,9 +466,12 @@ function registerRuntimeRoutes(
|
|
|
439
466
|
tags: ["assistant"],
|
|
440
467
|
summary: "List assistant conversation messages."
|
|
441
468
|
},
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
469
|
+
...createJsonApiResourceRouteContract({
|
|
470
|
+
...ASSISTANT_CONVERSATION_MESSAGES_TRANSPORT,
|
|
471
|
+
query: assistantResource.operations.conversationMessagesList.query,
|
|
472
|
+
output: assistantResource.operations.conversationMessagesList.output,
|
|
473
|
+
outputKind: "record",
|
|
474
|
+
getRecordId: resolveAssistantConversationMessagesRecordId
|
|
445
475
|
})
|
|
446
476
|
},
|
|
447
477
|
async function assistantConversationMessagesRoute(request, reply) {
|
|
@@ -85,6 +85,46 @@ function createAssistantTestApp({
|
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
function findRoute(routes, { method, path }) {
|
|
89
|
+
return routes.find((entry) => entry.method === method && entry.path === path) || null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
test("registerRoutes exposes JSON:API contracts for assistant settings and transcript endpoints", () => {
|
|
93
|
+
const testApp = createAssistantTestApp({
|
|
94
|
+
workspaceScopeSupport: createWorkspaceServerScopeSupport(),
|
|
95
|
+
resolveCurrentAppConfig: () => createAssistantAppConfig()
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
registerRoutes(testApp.app);
|
|
99
|
+
const routes = testApp.router.list();
|
|
100
|
+
const publicSettingsReadRoute = findRoute(routes, {
|
|
101
|
+
method: "GET",
|
|
102
|
+
path: "/api/assistant/:surfaceId/settings"
|
|
103
|
+
});
|
|
104
|
+
const publicSettingsUpdateRoute = findRoute(routes, {
|
|
105
|
+
method: "PATCH",
|
|
106
|
+
path: "/api/assistant/:surfaceId/settings"
|
|
107
|
+
});
|
|
108
|
+
const publicConversationsRoute = findRoute(routes, {
|
|
109
|
+
method: "GET",
|
|
110
|
+
path: "/api/assistant/:surfaceId/conversations"
|
|
111
|
+
});
|
|
112
|
+
const publicConversationMessagesRoute = findRoute(routes, {
|
|
113
|
+
method: "GET",
|
|
114
|
+
path: "/api/assistant/:surfaceId/conversations/:conversationId/messages"
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
assert.equal(publicSettingsReadRoute?.transport?.kind, "jsonapi-resource");
|
|
118
|
+
assert.equal(publicSettingsUpdateRoute?.transport?.kind, "jsonapi-resource");
|
|
119
|
+
assert.equal(publicConversationsRoute?.transport?.kind, "jsonapi-resource");
|
|
120
|
+
assert.equal(publicConversationMessagesRoute?.transport?.kind, "jsonapi-resource");
|
|
121
|
+
assert.equal(publicSettingsReadRoute?.schema?.response?.[200]?.required?.[0], "data");
|
|
122
|
+
assert.equal(publicSettingsUpdateRoute?.schema?.body?.required?.[0], "data");
|
|
123
|
+
assert.equal(publicSettingsUpdateRoute?.schema?.response?.[200]?.required?.[0], "data");
|
|
124
|
+
assert.equal(publicConversationsRoute?.schema?.response?.[200]?.required?.[0], "data");
|
|
125
|
+
assert.equal(publicConversationMessagesRoute?.schema?.response?.[200]?.required?.[0], "data");
|
|
126
|
+
});
|
|
127
|
+
|
|
88
128
|
test("registerRoutes resolves appConfig lazily when handlers run", async () => {
|
|
89
129
|
let currentAppConfig = null;
|
|
90
130
|
const workspaceScopeSupport = createWorkspaceServerScopeSupport();
|
|
@@ -97,11 +137,10 @@ test("registerRoutes resolves appConfig lazily when handlers run", async () => {
|
|
|
97
137
|
currentAppConfig = createAssistantAppConfig();
|
|
98
138
|
const routes = testApp.router.list();
|
|
99
139
|
|
|
100
|
-
const route = routes
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
);
|
|
140
|
+
const route = findRoute(routes, {
|
|
141
|
+
method: "GET",
|
|
142
|
+
path: "/api/w/:workspaceSlug/assistant/:surfaceId/conversations"
|
|
143
|
+
});
|
|
105
144
|
|
|
106
145
|
assert.ok(route, "Expected workspace assistant conversations route to be registered.");
|
|
107
146
|
|
|
@@ -167,11 +206,10 @@ test("registerRoutes returns clear AppError payload for pre-stream assistant fai
|
|
|
167
206
|
currentAppConfig = createAssistantAppConfig();
|
|
168
207
|
const routes = testApp.router.list();
|
|
169
208
|
|
|
170
|
-
const route = routes
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
);
|
|
209
|
+
const route = findRoute(routes, {
|
|
210
|
+
method: "POST",
|
|
211
|
+
path: "/api/w/:workspaceSlug/assistant/:surfaceId/chat/stream"
|
|
212
|
+
});
|
|
175
213
|
|
|
176
214
|
assert.ok(route, "Expected workspace assistant chat stream route to be registered.");
|
|
177
215
|
|