@jskit-ai/assistant 0.1.32 → 0.1.35
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 +346 -142
- package/package.json +3 -19
- package/src/server/buildTemplateContext.js +107 -0
- package/templates/migrations/assistant_config_initial.cjs +25 -0
- package/templates/migrations/assistant_transcripts_initial.cjs +21 -14
- package/templates/src/local-package/client/components/AssistantSettingsClientElement.vue +88 -0
- package/templates/src/local-package/client/components/AssistantSurfaceClientElement.vue +10 -0
- package/{src/client/composables/useAssistantWorkspaceRuntime.js → templates/src/local-package/client/composables/useAssistantRuntime.js} +91 -114
- package/templates/src/local-package/client/index.js +3 -0
- package/templates/src/local-package/client/providers/AssistantClientProvider.js +16 -0
- package/templates/src/local-package/package.descriptor.mjs +85 -0
- package/templates/src/local-package/package.json +11 -0
- package/{src/server/AssistantServiceProvider.js → templates/src/local-package/server/AssistantProvider.js} +37 -61
- package/templates/src/local-package/server/actionIds.js +9 -0
- package/templates/src/local-package/server/actions.js +190 -0
- package/templates/src/local-package/server/registerRoutes.js +296 -0
- package/templates/src/local-package/server/repositories/assistantConfigRepository.js +141 -0
- package/{src → templates/src/local-package}/server/repositories/conversationsRepository.js +44 -45
- package/{src → templates/src/local-package}/server/repositories/messagesRepository.js +49 -34
- package/templates/src/local-package/server/services/assistantConfigService.js +90 -0
- package/{src → templates/src/local-package}/server/services/chatService.js +45 -37
- package/{src → templates/src/local-package}/server/services/transcriptService.js +61 -82
- package/templates/src/local-package/shared/assistantRuntimeConfig.js +13 -0
- package/templates/src/local-package/shared/index.js +1 -0
- package/templates/src/pages/assistant/index.vue +7 -0
- package/test/buildTemplateContext.test.js +112 -0
- package/test/packageDescriptor.test.js +69 -0
- package/src/client/components/AssistantClientElement.vue +0 -1316
- package/src/client/components/AssistantConsoleSettingsClientElement.vue +0 -70
- package/src/client/components/AssistantSettingsFormCard.vue +0 -76
- package/src/client/components/AssistantWorkspaceClientElement.vue +0 -15
- package/src/client/components/AssistantWorkspaceSettingsClientElement.vue +0 -72
- package/src/client/index.js +0 -10
- package/src/client/lib/assistantApi.js +0 -137
- package/src/client/lib/assistantHttpClient.js +0 -10
- package/src/client/lib/markdownRenderer.js +0 -31
- package/src/client/providers/AssistantWebClientProvider.js +0 -20
- package/src/server/actionIds.js +0 -11
- package/src/server/actions.js +0 -191
- package/src/server/lib/aiClient.js +0 -43
- package/src/server/lib/ndjson.js +0 -47
- package/src/server/lib/providers/anthropicClient.js +0 -375
- package/src/server/lib/providers/common.js +0 -150
- package/src/server/lib/providers/deepSeekClient.js +0 -22
- package/src/server/lib/providers/openAiClient.js +0 -13
- package/src/server/lib/providers/openAiCompatibleClient.js +0 -69
- package/src/server/lib/resolveWorkspaceSlug.js +0 -24
- package/src/server/lib/serviceToolCatalog.js +0 -459
- package/src/server/registerRoutes.js +0 -383
- package/src/server/repositories/assistantSettingsRepository.js +0 -100
- package/src/server/repositories/repositoryPersistenceUtils.js +0 -48
- package/src/server/services/assistantSettingsService.js +0 -149
- package/src/shared/assistantPaths.js +0 -50
- package/src/shared/assistantResource.js +0 -317
- package/src/shared/assistantSettingsResource.js +0 -197
- package/src/shared/index.js +0 -43
- package/src/shared/queryKeys.js +0 -69
- package/src/shared/settingsEvents.js +0 -6
- package/src/shared/streamEvents.js +0 -29
- package/src/shared/support/conversationStatus.js +0 -18
- package/src/shared/support/jsonObject.js +0 -18
- package/src/shared/support/positiveInteger.js +0 -9
- package/templates/migrations/assistant_settings_initial.cjs +0 -37
- package/templates/src/pages/admin/workspace/assistant/index.vue +0 -7
- package/test/aiConfigValidation.test.js +0 -15
- package/test/assistantApiSurfaceHeader.test.js +0 -64
- package/test/assistantResource.test.js +0 -53
- package/test/assistantSettingsResource.test.js +0 -48
- package/test/assistantSettingsService.test.js +0 -133
- package/test/chatService.test.js +0 -841
- package/test/descriptorSurfaceOption.test.js +0 -35
- package/test/queryKeys.test.js +0 -41
- package/test/resolveWorkspaceSlug.test.js +0 -83
- package/test/routeInputContracts.test.js +0 -286
- package/test/serviceToolCatalog.test.js +0 -1235
- package/test/transcriptService.test.js +0 -175
|
@@ -1,383 +0,0 @@
|
|
|
1
|
-
import { withStandardErrorResponses } from "@jskit-ai/http-runtime/shared/validators/errorResponses";
|
|
2
|
-
import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
3
|
-
import {
|
|
4
|
-
workspaceSlugParamsValidator
|
|
5
|
-
} from "@jskit-ai/users-core/server/validators/routeParamsValidator";
|
|
6
|
-
import {
|
|
7
|
-
resolveDefaultWorkspaceRouteSurfaceIdFromAppConfig,
|
|
8
|
-
resolveWorkspaceSurfaceIdsFromAppConfig
|
|
9
|
-
} from "@jskit-ai/users-core/server/support/workspaceActionSurfaces";
|
|
10
|
-
import { resolveAssistantApiBasePath } from "../shared/assistantPaths.js";
|
|
11
|
-
import { assistantResource } from "../shared/assistantResource.js";
|
|
12
|
-
import {
|
|
13
|
-
assistantConsoleSettingsResource,
|
|
14
|
-
assistantWorkspaceSettingsResource
|
|
15
|
-
} from "../shared/assistantSettingsResource.js";
|
|
16
|
-
import { actionIds } from "./actionIds.js";
|
|
17
|
-
import { endNdjson, mapStreamError, setNdjsonHeaders, writeNdjson } from "./lib/ndjson.js";
|
|
18
|
-
|
|
19
|
-
function resolveAssistantWorkspaceRouteSurfaceConfig(app) {
|
|
20
|
-
const appConfig = typeof app?.has === "function" && app.has("appConfig") ? app.make("appConfig") : {};
|
|
21
|
-
const workspaceSurfaceIds = resolveWorkspaceSurfaceIdsFromAppConfig(appConfig);
|
|
22
|
-
const fallbackSurfaceId = resolveDefaultWorkspaceRouteSurfaceIdFromAppConfig(appConfig);
|
|
23
|
-
return Object.freeze({
|
|
24
|
-
fallbackSurfaceId,
|
|
25
|
-
allowedSurfaceIds: new Set(workspaceSurfaceIds)
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function resolveAssistantWorkspaceRequestSurfaceId(request, workspaceRouteSurfaceConfig = {}) {
|
|
30
|
-
const headerValue = request?.headers?.["x-jskit-surface"];
|
|
31
|
-
const headerCandidate = Array.isArray(headerValue) ? headerValue[0] : headerValue;
|
|
32
|
-
const requestedSurfaceId = normalizeText(headerCandidate).toLowerCase();
|
|
33
|
-
const fallbackSurfaceId = normalizeText(workspaceRouteSurfaceConfig?.fallbackSurfaceId).toLowerCase() || "app";
|
|
34
|
-
const allowedSurfaceIds = workspaceRouteSurfaceConfig?.allowedSurfaceIds instanceof Set
|
|
35
|
-
? workspaceRouteSurfaceConfig.allowedSurfaceIds
|
|
36
|
-
: new Set();
|
|
37
|
-
|
|
38
|
-
if (!requestedSurfaceId) {
|
|
39
|
-
return fallbackSurfaceId;
|
|
40
|
-
}
|
|
41
|
-
if (allowedSurfaceIds.size > 0 && !allowedSurfaceIds.has(requestedSurfaceId)) {
|
|
42
|
-
return fallbackSurfaceId;
|
|
43
|
-
}
|
|
44
|
-
return requestedSurfaceId;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function registerRoutes(app) {
|
|
48
|
-
if (!app || typeof app.make !== "function") {
|
|
49
|
-
throw new Error("registerRoutes requires application make().");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const router = app.make("jskit.http.router");
|
|
53
|
-
const visibility = "workspace";
|
|
54
|
-
const workspaceRouteSurfaceConfig = resolveAssistantWorkspaceRouteSurfaceConfig(app);
|
|
55
|
-
const workspaceRouteSurfaceId = workspaceRouteSurfaceConfig.fallbackSurfaceId;
|
|
56
|
-
const routeBase = resolveAssistantApiBasePath({
|
|
57
|
-
visibility
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
router.register(
|
|
61
|
-
"GET",
|
|
62
|
-
"/api/console/settings/assistant",
|
|
63
|
-
{
|
|
64
|
-
auth: "required",
|
|
65
|
-
surface: "console",
|
|
66
|
-
meta: {
|
|
67
|
-
tags: ["assistant", "settings"],
|
|
68
|
-
summary: "Get assistant console settings."
|
|
69
|
-
},
|
|
70
|
-
responseValidators: withStandardErrorResponses({
|
|
71
|
-
200: assistantConsoleSettingsResource.operations.view.outputValidator
|
|
72
|
-
})
|
|
73
|
-
},
|
|
74
|
-
async function assistantConsoleSettingsReadRoute(request, reply) {
|
|
75
|
-
const response = await request.executeAction({
|
|
76
|
-
actionId: actionIds.consoleSettingsRead
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
reply.code(200).send(response);
|
|
80
|
-
}
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
router.register(
|
|
84
|
-
"PATCH",
|
|
85
|
-
"/api/console/settings/assistant",
|
|
86
|
-
{
|
|
87
|
-
auth: "required",
|
|
88
|
-
surface: "console",
|
|
89
|
-
meta: {
|
|
90
|
-
tags: ["assistant", "settings"],
|
|
91
|
-
summary: "Update assistant console settings."
|
|
92
|
-
},
|
|
93
|
-
bodyValidator: assistantConsoleSettingsResource.operations.patch.bodyValidator,
|
|
94
|
-
responseValidators: withStandardErrorResponses(
|
|
95
|
-
{
|
|
96
|
-
200: assistantConsoleSettingsResource.operations.patch.outputValidator
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
includeValidation400: true
|
|
100
|
-
}
|
|
101
|
-
)
|
|
102
|
-
},
|
|
103
|
-
async function assistantConsoleSettingsPatchRoute(request, reply) {
|
|
104
|
-
const response = await request.executeAction({
|
|
105
|
-
actionId: actionIds.consoleSettingsUpdate,
|
|
106
|
-
input: {
|
|
107
|
-
payload: request.input.body
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
reply.code(200).send(response);
|
|
112
|
-
}
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
router.register(
|
|
116
|
-
"GET",
|
|
117
|
-
"/api/w/:workspaceSlug/settings/assistant",
|
|
118
|
-
{
|
|
119
|
-
auth: "required",
|
|
120
|
-
surface: workspaceRouteSurfaceId,
|
|
121
|
-
visibility,
|
|
122
|
-
meta: {
|
|
123
|
-
tags: ["assistant", "settings"],
|
|
124
|
-
summary: "Get assistant workspace settings."
|
|
125
|
-
},
|
|
126
|
-
paramsValidator: workspaceSlugParamsValidator,
|
|
127
|
-
responseValidators: withStandardErrorResponses({
|
|
128
|
-
200: assistantWorkspaceSettingsResource.operations.view.outputValidator
|
|
129
|
-
})
|
|
130
|
-
},
|
|
131
|
-
async function assistantWorkspaceSettingsReadRoute(request, reply) {
|
|
132
|
-
const response = await request.executeAction({
|
|
133
|
-
actionId: actionIds.workspaceSettingsRead,
|
|
134
|
-
context: {
|
|
135
|
-
surface: resolveAssistantWorkspaceRequestSurfaceId(request, workspaceRouteSurfaceConfig)
|
|
136
|
-
},
|
|
137
|
-
input: {
|
|
138
|
-
workspaceSlug: request.input.params.workspaceSlug
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
reply.code(200).send(response);
|
|
143
|
-
}
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
router.register(
|
|
147
|
-
"PATCH",
|
|
148
|
-
"/api/w/:workspaceSlug/settings/assistant",
|
|
149
|
-
{
|
|
150
|
-
auth: "required",
|
|
151
|
-
surface: workspaceRouteSurfaceId,
|
|
152
|
-
visibility,
|
|
153
|
-
meta: {
|
|
154
|
-
tags: ["assistant", "settings"],
|
|
155
|
-
summary: "Update assistant workspace settings."
|
|
156
|
-
},
|
|
157
|
-
paramsValidator: workspaceSlugParamsValidator,
|
|
158
|
-
bodyValidator: assistantWorkspaceSettingsResource.operations.patch.bodyValidator,
|
|
159
|
-
responseValidators: withStandardErrorResponses(
|
|
160
|
-
{
|
|
161
|
-
200: assistantWorkspaceSettingsResource.operations.patch.outputValidator
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
includeValidation400: true
|
|
165
|
-
}
|
|
166
|
-
)
|
|
167
|
-
},
|
|
168
|
-
async function assistantWorkspaceSettingsPatchRoute(request, reply) {
|
|
169
|
-
const response = await request.executeAction({
|
|
170
|
-
actionId: actionIds.workspaceSettingsUpdate,
|
|
171
|
-
context: {
|
|
172
|
-
surface: resolveAssistantWorkspaceRequestSurfaceId(request, workspaceRouteSurfaceConfig)
|
|
173
|
-
},
|
|
174
|
-
input: {
|
|
175
|
-
workspaceSlug: request.input.params.workspaceSlug,
|
|
176
|
-
patch: request.input.body
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
reply.code(200).send(response);
|
|
181
|
-
}
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
router.register(
|
|
185
|
-
"POST",
|
|
186
|
-
`${routeBase}/chat/stream`,
|
|
187
|
-
{
|
|
188
|
-
auth: "required",
|
|
189
|
-
surface: workspaceRouteSurfaceId,
|
|
190
|
-
visibility,
|
|
191
|
-
meta: {
|
|
192
|
-
tags: ["assistant"],
|
|
193
|
-
summary: "Stream assistant response for workspace user."
|
|
194
|
-
},
|
|
195
|
-
paramsValidator: workspaceSlugParamsValidator,
|
|
196
|
-
bodyValidator: assistantResource.operations.chatStream.bodyValidator
|
|
197
|
-
},
|
|
198
|
-
async function assistantChatStreamRoute(request, reply) {
|
|
199
|
-
const abortController = new AbortController();
|
|
200
|
-
const closeListener = () => {
|
|
201
|
-
abortController.abort();
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
let streamStarted = false;
|
|
205
|
-
|
|
206
|
-
function ensureStreamStarted() {
|
|
207
|
-
if (streamStarted) {
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
setNdjsonHeaders(reply);
|
|
212
|
-
reply.code(200);
|
|
213
|
-
reply.hijack();
|
|
214
|
-
if (typeof reply.raw.flushHeaders === "function") {
|
|
215
|
-
reply.raw.flushHeaders();
|
|
216
|
-
}
|
|
217
|
-
streamStarted = true;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const streamWriter = Object.freeze({
|
|
221
|
-
sendMeta(payload = {}) {
|
|
222
|
-
ensureStreamStarted();
|
|
223
|
-
writeNdjson(reply, payload);
|
|
224
|
-
},
|
|
225
|
-
sendAssistantDelta(payload = {}) {
|
|
226
|
-
ensureStreamStarted();
|
|
227
|
-
writeNdjson(reply, payload);
|
|
228
|
-
},
|
|
229
|
-
sendAssistantMessage(payload = {}) {
|
|
230
|
-
ensureStreamStarted();
|
|
231
|
-
writeNdjson(reply, payload);
|
|
232
|
-
},
|
|
233
|
-
sendToolCall(payload = {}) {
|
|
234
|
-
ensureStreamStarted();
|
|
235
|
-
writeNdjson(reply, payload);
|
|
236
|
-
},
|
|
237
|
-
sendToolResult(payload = {}) {
|
|
238
|
-
ensureStreamStarted();
|
|
239
|
-
writeNdjson(reply, payload);
|
|
240
|
-
},
|
|
241
|
-
sendError(payload = {}) {
|
|
242
|
-
ensureStreamStarted();
|
|
243
|
-
writeNdjson(reply, payload);
|
|
244
|
-
},
|
|
245
|
-
sendDone(payload = {}) {
|
|
246
|
-
ensureStreamStarted();
|
|
247
|
-
writeNdjson(reply, payload);
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
try {
|
|
252
|
-
request.raw.on("close", closeListener);
|
|
253
|
-
|
|
254
|
-
await request.executeAction({
|
|
255
|
-
actionId: actionIds.chatStream,
|
|
256
|
-
context: {
|
|
257
|
-
surface: resolveAssistantWorkspaceRequestSurfaceId(request, workspaceRouteSurfaceConfig)
|
|
258
|
-
},
|
|
259
|
-
input: (() => {
|
|
260
|
-
const body = request.input.body;
|
|
261
|
-
const input = {
|
|
262
|
-
workspaceSlug: request.input.params.workspaceSlug,
|
|
263
|
-
messageId: body.messageId,
|
|
264
|
-
input: body.input
|
|
265
|
-
};
|
|
266
|
-
if (Object.hasOwn(body, "conversationId")) {
|
|
267
|
-
input.conversationId = body.conversationId;
|
|
268
|
-
}
|
|
269
|
-
if (Object.hasOwn(body, "history")) {
|
|
270
|
-
input.history = body.history;
|
|
271
|
-
}
|
|
272
|
-
if (Object.hasOwn(body, "clientContext")) {
|
|
273
|
-
input.clientContext = body.clientContext;
|
|
274
|
-
}
|
|
275
|
-
return input;
|
|
276
|
-
})(),
|
|
277
|
-
deps: {
|
|
278
|
-
streamWriter,
|
|
279
|
-
abortSignal: abortController.signal
|
|
280
|
-
}
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
if (streamStarted) {
|
|
284
|
-
endNdjson(reply);
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
reply.code(204).send();
|
|
289
|
-
} catch (error) {
|
|
290
|
-
if (!streamStarted) {
|
|
291
|
-
const statusCode = Number(error?.status || error?.statusCode || 500);
|
|
292
|
-
const safeStatusCode = Number.isInteger(statusCode) && statusCode >= 400 && statusCode <= 599 ? statusCode : 500;
|
|
293
|
-
reply.code(safeStatusCode).send({
|
|
294
|
-
error: safeStatusCode >= 500 ? "Internal server error." : String(error?.message || "Request failed.")
|
|
295
|
-
});
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
const streamError = mapStreamError(error);
|
|
300
|
-
writeNdjson(reply, {
|
|
301
|
-
type: "error",
|
|
302
|
-
...streamError
|
|
303
|
-
});
|
|
304
|
-
writeNdjson(reply, {
|
|
305
|
-
type: "done",
|
|
306
|
-
status: "failed"
|
|
307
|
-
});
|
|
308
|
-
endNdjson(reply);
|
|
309
|
-
} finally {
|
|
310
|
-
request.raw.off("close", closeListener);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
);
|
|
314
|
-
|
|
315
|
-
router.register(
|
|
316
|
-
"GET",
|
|
317
|
-
`${routeBase}/conversations`,
|
|
318
|
-
{
|
|
319
|
-
auth: "required",
|
|
320
|
-
surface: workspaceRouteSurfaceId,
|
|
321
|
-
visibility,
|
|
322
|
-
meta: {
|
|
323
|
-
tags: ["assistant"],
|
|
324
|
-
summary: "List assistant conversations for current workspace user."
|
|
325
|
-
},
|
|
326
|
-
paramsValidator: workspaceSlugParamsValidator,
|
|
327
|
-
queryValidator: assistantResource.operations.conversationsList.queryValidator,
|
|
328
|
-
responseValidators: withStandardErrorResponses({
|
|
329
|
-
200: assistantResource.operations.conversationsList.outputValidator
|
|
330
|
-
})
|
|
331
|
-
},
|
|
332
|
-
async function assistantConversationsRoute(request, reply) {
|
|
333
|
-
const response = await request.executeAction({
|
|
334
|
-
actionId: actionIds.conversationsList,
|
|
335
|
-
context: {
|
|
336
|
-
surface: resolveAssistantWorkspaceRequestSurfaceId(request, workspaceRouteSurfaceConfig)
|
|
337
|
-
},
|
|
338
|
-
input: {
|
|
339
|
-
workspaceSlug: request.input.params.workspaceSlug,
|
|
340
|
-
query: request.input.query
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
reply.code(200).send(response);
|
|
345
|
-
}
|
|
346
|
-
);
|
|
347
|
-
|
|
348
|
-
router.register(
|
|
349
|
-
"GET",
|
|
350
|
-
`${routeBase}/conversations/:conversationId/messages`,
|
|
351
|
-
{
|
|
352
|
-
auth: "required",
|
|
353
|
-
surface: workspaceRouteSurfaceId,
|
|
354
|
-
visibility,
|
|
355
|
-
meta: {
|
|
356
|
-
tags: ["assistant"],
|
|
357
|
-
summary: "List messages for one assistant conversation."
|
|
358
|
-
},
|
|
359
|
-
paramsValidator: [workspaceSlugParamsValidator, assistantResource.operations.conversationMessagesList.paramsValidator],
|
|
360
|
-
queryValidator: assistantResource.operations.conversationMessagesList.queryValidator,
|
|
361
|
-
responseValidators: withStandardErrorResponses({
|
|
362
|
-
200: assistantResource.operations.conversationMessagesList.outputValidator
|
|
363
|
-
})
|
|
364
|
-
},
|
|
365
|
-
async function assistantConversationMessagesRoute(request, reply) {
|
|
366
|
-
const response = await request.executeAction({
|
|
367
|
-
actionId: actionIds.conversationMessagesList,
|
|
368
|
-
context: {
|
|
369
|
-
surface: resolveAssistantWorkspaceRequestSurfaceId(request, workspaceRouteSurfaceConfig)
|
|
370
|
-
},
|
|
371
|
-
input: {
|
|
372
|
-
workspaceSlug: request.input.params.workspaceSlug,
|
|
373
|
-
conversationId: request.input.params.conversationId,
|
|
374
|
-
query: request.input.query
|
|
375
|
-
}
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
reply.code(200).send(response);
|
|
379
|
-
}
|
|
380
|
-
);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
export { registerRoutes };
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { parsePositiveInteger } from "@jskit-ai/kernel/server/runtime";
|
|
2
|
-
import { toIso } from "./repositoryPersistenceUtils.js";
|
|
3
|
-
|
|
4
|
-
function mapConsoleRow(row = {}) {
|
|
5
|
-
return {
|
|
6
|
-
workspaceSurfacePrompt: String(row.assistant_workspace_surface_prompt || ""),
|
|
7
|
-
createdAt: toIso(row.created_at),
|
|
8
|
-
updatedAt: toIso(row.updated_at)
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function mapWorkspaceRow(row = {}) {
|
|
13
|
-
return {
|
|
14
|
-
workspaceId: Number(row.workspace_id),
|
|
15
|
-
appSurfacePrompt: String(row.assistant_app_surface_prompt || ""),
|
|
16
|
-
createdAt: toIso(row.created_at),
|
|
17
|
-
updatedAt: toIso(row.updated_at)
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function createRepository(knex) {
|
|
22
|
-
if (typeof knex !== "function") {
|
|
23
|
-
throw new TypeError("assistantSettingsRepository requires knex.");
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async function ensureConsoleSettings(options = {}) {
|
|
27
|
-
const client = options?.trx || knex;
|
|
28
|
-
const row = await client("console_settings").where({ id: 1 }).first();
|
|
29
|
-
if (!row) {
|
|
30
|
-
throw new Error("console_settings row missing.");
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return mapConsoleRow(row);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async function updateConsoleSettings(patch = {}, options = {}) {
|
|
37
|
-
const client = options?.trx || knex;
|
|
38
|
-
const nextWorkspaceSurfacePrompt = String(patch.workspaceSurfacePrompt || "");
|
|
39
|
-
|
|
40
|
-
await client("console_settings")
|
|
41
|
-
.where({ id: 1 })
|
|
42
|
-
.update({
|
|
43
|
-
assistant_workspace_surface_prompt: nextWorkspaceSurfacePrompt,
|
|
44
|
-
updated_at: new Date()
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
return ensureConsoleSettings({
|
|
48
|
-
trx: client
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async function ensureWorkspaceSettings(workspaceId, options = {}) {
|
|
53
|
-
const numericWorkspaceId = parsePositiveInteger(workspaceId);
|
|
54
|
-
if (!numericWorkspaceId) {
|
|
55
|
-
throw new TypeError("assistantSettingsRepository.ensureWorkspaceSettings requires workspace id.");
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const client = options?.trx || knex;
|
|
59
|
-
const row = await client("workspace_settings").where({ workspace_id: numericWorkspaceId }).first();
|
|
60
|
-
if (!row) {
|
|
61
|
-
throw new Error("workspace_settings row missing.");
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return mapWorkspaceRow(row);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
async function updateWorkspaceSettings(workspaceId, patch = {}, options = {}) {
|
|
68
|
-
const numericWorkspaceId = parsePositiveInteger(workspaceId);
|
|
69
|
-
if (!numericWorkspaceId) {
|
|
70
|
-
throw new TypeError("assistantSettingsRepository.updateWorkspaceSettings requires workspace id.");
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const client = options?.trx || knex;
|
|
74
|
-
const nextAppSurfacePrompt = String(patch.appSurfacePrompt || "");
|
|
75
|
-
|
|
76
|
-
await ensureWorkspaceSettings(numericWorkspaceId, {
|
|
77
|
-
trx: client
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
await client("workspace_settings")
|
|
81
|
-
.where({ workspace_id: numericWorkspaceId })
|
|
82
|
-
.update({
|
|
83
|
-
assistant_app_surface_prompt: nextAppSurfacePrompt,
|
|
84
|
-
updated_at: new Date()
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
return ensureWorkspaceSettings(numericWorkspaceId, {
|
|
88
|
-
trx: client
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return Object.freeze({
|
|
93
|
-
ensureConsoleSettings,
|
|
94
|
-
updateConsoleSettings,
|
|
95
|
-
ensureWorkspaceSettings,
|
|
96
|
-
updateWorkspaceSettings
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export { createRepository };
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { parseJsonObject } from "../../shared/support/jsonObject.js";
|
|
2
|
-
|
|
3
|
-
function stringifyJsonObject(value) {
|
|
4
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5
|
-
return null;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
return JSON.stringify(value);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function toIso(value) {
|
|
12
|
-
if (!value) {
|
|
13
|
-
return "";
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const date = value instanceof Date ? value : new Date(value);
|
|
17
|
-
if (Number.isNaN(date.getTime())) {
|
|
18
|
-
return "";
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return date.toISOString();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function resolveInsertedId(insertResult) {
|
|
25
|
-
if (Array.isArray(insertResult) && insertResult.length > 0) {
|
|
26
|
-
const first = insertResult[0];
|
|
27
|
-
if (first && typeof first === "object" && !Array.isArray(first)) {
|
|
28
|
-
const objectId = Number(first.id);
|
|
29
|
-
if (Number.isInteger(objectId) && objectId > 0) {
|
|
30
|
-
return objectId;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const scalarId = Number(first);
|
|
35
|
-
if (Number.isInteger(scalarId) && scalarId > 0) {
|
|
36
|
-
return scalarId;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const directId = Number(insertResult);
|
|
41
|
-
if (Number.isInteger(directId) && directId > 0) {
|
|
42
|
-
return directId;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return 0;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export { parseJsonObject, stringifyJsonObject, toIso, resolveInsertedId };
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { parsePositiveInteger } from "@jskit-ai/kernel/server/runtime";
|
|
2
|
-
import { normalizeObjectInput } from "@jskit-ai/kernel/shared/validators";
|
|
3
|
-
import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
4
|
-
import { pickOwnProperties } from "@jskit-ai/kernel/shared/support";
|
|
5
|
-
|
|
6
|
-
const serviceEvents = Object.freeze({
|
|
7
|
-
updateConsoleSettings: Object.freeze([
|
|
8
|
-
Object.freeze({
|
|
9
|
-
type: "entity.changed",
|
|
10
|
-
source: "assistant",
|
|
11
|
-
entity: "console.settings",
|
|
12
|
-
operation: "updated",
|
|
13
|
-
entityId: 1,
|
|
14
|
-
realtime: Object.freeze({
|
|
15
|
-
event: "assistant.console.settings.changed",
|
|
16
|
-
audience: "all_users"
|
|
17
|
-
})
|
|
18
|
-
})
|
|
19
|
-
]),
|
|
20
|
-
updateWorkspaceSettings: Object.freeze([
|
|
21
|
-
Object.freeze({
|
|
22
|
-
type: "entity.changed",
|
|
23
|
-
source: "assistant",
|
|
24
|
-
entity: "workspace.settings",
|
|
25
|
-
operation: "updated",
|
|
26
|
-
entityId: ({ args }) => args?.[0]?.id || null,
|
|
27
|
-
realtime: Object.freeze({
|
|
28
|
-
event: "assistant.workspace.settings.changed",
|
|
29
|
-
audience: "event_scope",
|
|
30
|
-
payload: ({ args }) => ({
|
|
31
|
-
workspaceSlug: String(args?.[0]?.slug || "").trim()
|
|
32
|
-
})
|
|
33
|
-
})
|
|
34
|
-
})
|
|
35
|
-
])
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
function normalizeSurface(value) {
|
|
39
|
-
return normalizeText(value).toLowerCase();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function mapConsoleResponse(record = {}) {
|
|
43
|
-
return {
|
|
44
|
-
settings: {
|
|
45
|
-
workspaceSurfacePrompt: String(record.workspaceSurfacePrompt || "")
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function mapWorkspaceResponse(record = {}) {
|
|
51
|
-
return {
|
|
52
|
-
settings: {
|
|
53
|
-
appSurfacePrompt: String(record.appSurfacePrompt || "")
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function createService({ assistantSettingsRepository, consoleService } = {}) {
|
|
59
|
-
if (!assistantSettingsRepository || typeof assistantSettingsRepository.ensureConsoleSettings !== "function") {
|
|
60
|
-
throw new Error("assistantSettingsService requires assistantSettingsRepository.ensureConsoleSettings().");
|
|
61
|
-
}
|
|
62
|
-
if (!assistantSettingsRepository || typeof assistantSettingsRepository.ensureWorkspaceSettings !== "function") {
|
|
63
|
-
throw new Error("assistantSettingsService requires assistantSettingsRepository.ensureWorkspaceSettings().");
|
|
64
|
-
}
|
|
65
|
-
if (!assistantSettingsRepository || typeof assistantSettingsRepository.updateConsoleSettings !== "function") {
|
|
66
|
-
throw new Error("assistantSettingsService requires assistantSettingsRepository.updateConsoleSettings().");
|
|
67
|
-
}
|
|
68
|
-
if (!assistantSettingsRepository || typeof assistantSettingsRepository.updateWorkspaceSettings !== "function") {
|
|
69
|
-
throw new Error("assistantSettingsService requires assistantSettingsRepository.updateWorkspaceSettings().");
|
|
70
|
-
}
|
|
71
|
-
if (!consoleService || typeof consoleService.requireConsoleOwner !== "function") {
|
|
72
|
-
throw new Error("assistantSettingsService requires consoleService.requireConsoleOwner().");
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async function getConsoleSettings(options = {}) {
|
|
76
|
-
await consoleService.requireConsoleOwner(options?.context, options);
|
|
77
|
-
const settings = await assistantSettingsRepository.ensureConsoleSettings(options);
|
|
78
|
-
return mapConsoleResponse(settings);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
async function updateConsoleSettings(payload = {}, options = {}) {
|
|
82
|
-
await consoleService.requireConsoleOwner(options?.context, options);
|
|
83
|
-
const source = normalizeObjectInput(payload);
|
|
84
|
-
const patch = pickOwnProperties(source, ["workspaceSurfacePrompt"]);
|
|
85
|
-
if (Object.keys(patch).length < 1) {
|
|
86
|
-
const settings = await assistantSettingsRepository.ensureConsoleSettings(options);
|
|
87
|
-
return mapConsoleResponse(settings);
|
|
88
|
-
}
|
|
89
|
-
const settings = await assistantSettingsRepository.updateConsoleSettings({
|
|
90
|
-
workspaceSurfacePrompt: String(patch.workspaceSurfacePrompt || "")
|
|
91
|
-
}, options);
|
|
92
|
-
return mapConsoleResponse(settings);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
async function getWorkspaceSettings(workspace, options = {}) {
|
|
96
|
-
const workspaceId = parsePositiveInteger(workspace?.id);
|
|
97
|
-
if (!workspaceId) {
|
|
98
|
-
throw new Error("assistantSettingsService.getWorkspaceSettings requires workspace.id.");
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const settings = await assistantSettingsRepository.ensureWorkspaceSettings(workspaceId, options);
|
|
102
|
-
return mapWorkspaceResponse(settings);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
async function updateWorkspaceSettings(workspace, payload = {}, options = {}) {
|
|
106
|
-
const workspaceId = parsePositiveInteger(workspace?.id);
|
|
107
|
-
if (!workspaceId) {
|
|
108
|
-
throw new Error("assistantSettingsService.updateWorkspaceSettings requires workspace.id.");
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const source = normalizeObjectInput(payload);
|
|
112
|
-
const patch = pickOwnProperties(source, ["appSurfacePrompt"]);
|
|
113
|
-
if (Object.keys(patch).length < 1) {
|
|
114
|
-
const settings = await assistantSettingsRepository.ensureWorkspaceSettings(workspaceId, options);
|
|
115
|
-
return mapWorkspaceResponse(settings);
|
|
116
|
-
}
|
|
117
|
-
const settings = await assistantSettingsRepository.updateWorkspaceSettings(
|
|
118
|
-
workspaceId,
|
|
119
|
-
{
|
|
120
|
-
appSurfacePrompt: String(patch.appSurfacePrompt || "")
|
|
121
|
-
},
|
|
122
|
-
options
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
return mapWorkspaceResponse(settings);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
async function resolveSystemPrompt(workspace, { surface = "" } = {}, options = {}) {
|
|
129
|
-
const normalizedSurface = normalizeSurface(surface);
|
|
130
|
-
|
|
131
|
-
if (normalizedSurface === "app") {
|
|
132
|
-
const workspaceSettings = await getWorkspaceSettings(workspace, options);
|
|
133
|
-
return String(workspaceSettings?.settings?.appSurfacePrompt || "");
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const consoleSettings = await assistantSettingsRepository.ensureConsoleSettings(options);
|
|
137
|
-
return String(consoleSettings.workspaceSurfacePrompt || "");
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return Object.freeze({
|
|
141
|
-
getConsoleSettings,
|
|
142
|
-
updateConsoleSettings,
|
|
143
|
-
getWorkspaceSettings,
|
|
144
|
-
updateWorkspaceSettings,
|
|
145
|
-
resolveSystemPrompt
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export { createService, serviceEvents };
|