@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.
Files changed (76) hide show
  1. package/package.descriptor.mjs +346 -142
  2. package/package.json +3 -19
  3. package/src/server/buildTemplateContext.js +107 -0
  4. package/templates/migrations/assistant_config_initial.cjs +25 -0
  5. package/templates/migrations/assistant_transcripts_initial.cjs +21 -14
  6. package/templates/src/local-package/client/components/AssistantSettingsClientElement.vue +88 -0
  7. package/templates/src/local-package/client/components/AssistantSurfaceClientElement.vue +10 -0
  8. package/{src/client/composables/useAssistantWorkspaceRuntime.js → templates/src/local-package/client/composables/useAssistantRuntime.js} +91 -114
  9. package/templates/src/local-package/client/index.js +3 -0
  10. package/templates/src/local-package/client/providers/AssistantClientProvider.js +16 -0
  11. package/templates/src/local-package/package.descriptor.mjs +85 -0
  12. package/templates/src/local-package/package.json +11 -0
  13. package/{src/server/AssistantServiceProvider.js → templates/src/local-package/server/AssistantProvider.js} +37 -61
  14. package/templates/src/local-package/server/actionIds.js +9 -0
  15. package/templates/src/local-package/server/actions.js +190 -0
  16. package/templates/src/local-package/server/registerRoutes.js +296 -0
  17. package/templates/src/local-package/server/repositories/assistantConfigRepository.js +141 -0
  18. package/{src → templates/src/local-package}/server/repositories/conversationsRepository.js +44 -45
  19. package/{src → templates/src/local-package}/server/repositories/messagesRepository.js +49 -34
  20. package/templates/src/local-package/server/services/assistantConfigService.js +90 -0
  21. package/{src → templates/src/local-package}/server/services/chatService.js +45 -37
  22. package/{src → templates/src/local-package}/server/services/transcriptService.js +61 -82
  23. package/templates/src/local-package/shared/assistantRuntimeConfig.js +13 -0
  24. package/templates/src/local-package/shared/index.js +1 -0
  25. package/templates/src/pages/assistant/index.vue +7 -0
  26. package/test/buildTemplateContext.test.js +112 -0
  27. package/test/packageDescriptor.test.js +69 -0
  28. package/src/client/components/AssistantClientElement.vue +0 -1316
  29. package/src/client/components/AssistantConsoleSettingsClientElement.vue +0 -70
  30. package/src/client/components/AssistantSettingsFormCard.vue +0 -76
  31. package/src/client/components/AssistantWorkspaceClientElement.vue +0 -15
  32. package/src/client/components/AssistantWorkspaceSettingsClientElement.vue +0 -72
  33. package/src/client/index.js +0 -10
  34. package/src/client/lib/assistantApi.js +0 -137
  35. package/src/client/lib/assistantHttpClient.js +0 -10
  36. package/src/client/lib/markdownRenderer.js +0 -31
  37. package/src/client/providers/AssistantWebClientProvider.js +0 -20
  38. package/src/server/actionIds.js +0 -11
  39. package/src/server/actions.js +0 -191
  40. package/src/server/lib/aiClient.js +0 -43
  41. package/src/server/lib/ndjson.js +0 -47
  42. package/src/server/lib/providers/anthropicClient.js +0 -375
  43. package/src/server/lib/providers/common.js +0 -150
  44. package/src/server/lib/providers/deepSeekClient.js +0 -22
  45. package/src/server/lib/providers/openAiClient.js +0 -13
  46. package/src/server/lib/providers/openAiCompatibleClient.js +0 -69
  47. package/src/server/lib/resolveWorkspaceSlug.js +0 -24
  48. package/src/server/lib/serviceToolCatalog.js +0 -459
  49. package/src/server/registerRoutes.js +0 -383
  50. package/src/server/repositories/assistantSettingsRepository.js +0 -100
  51. package/src/server/repositories/repositoryPersistenceUtils.js +0 -48
  52. package/src/server/services/assistantSettingsService.js +0 -149
  53. package/src/shared/assistantPaths.js +0 -50
  54. package/src/shared/assistantResource.js +0 -317
  55. package/src/shared/assistantSettingsResource.js +0 -197
  56. package/src/shared/index.js +0 -43
  57. package/src/shared/queryKeys.js +0 -69
  58. package/src/shared/settingsEvents.js +0 -6
  59. package/src/shared/streamEvents.js +0 -29
  60. package/src/shared/support/conversationStatus.js +0 -18
  61. package/src/shared/support/jsonObject.js +0 -18
  62. package/src/shared/support/positiveInteger.js +0 -9
  63. package/templates/migrations/assistant_settings_initial.cjs +0 -37
  64. package/templates/src/pages/admin/workspace/assistant/index.vue +0 -7
  65. package/test/aiConfigValidation.test.js +0 -15
  66. package/test/assistantApiSurfaceHeader.test.js +0 -64
  67. package/test/assistantResource.test.js +0 -53
  68. package/test/assistantSettingsResource.test.js +0 -48
  69. package/test/assistantSettingsService.test.js +0 -133
  70. package/test/chatService.test.js +0 -841
  71. package/test/descriptorSurfaceOption.test.js +0 -35
  72. package/test/queryKeys.test.js +0 -41
  73. package/test/resolveWorkspaceSlug.test.js +0 -83
  74. package/test/routeInputContracts.test.js +0 -286
  75. package/test/serviceToolCatalog.test.js +0 -1235
  76. package/test/transcriptService.test.js +0 -175
@@ -1,50 +0,0 @@
1
- import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
2
- import { normalizePathname } from "@jskit-ai/kernel/shared/surface/paths";
3
- import { checkRouteVisibility } from "@jskit-ai/users-core/shared/support/usersVisibility";
4
-
5
- const ASSISTANT_API_RELATIVE_PATH = "/assistant";
6
- const ASSISTANT_WORKSPACE_API_BASE_PATH_TEMPLATE = "/api/w/:workspaceSlug/assistant";
7
- const ASSISTANT_PUBLIC_API_BASE_PATH = `/api${ASSISTANT_API_RELATIVE_PATH}`;
8
-
9
- function resolveAssistantApiBasePath({ visibility = "workspace" } = {}) {
10
- const normalizedVisibility = checkRouteVisibility(normalizeText(visibility).toLowerCase() || "workspace", {
11
- context: "resolveAssistantApiBasePath visibility"
12
- });
13
- if (normalizedVisibility === "workspace" || normalizedVisibility === "workspace_user") {
14
- return ASSISTANT_WORKSPACE_API_BASE_PATH_TEMPLATE;
15
- }
16
-
17
- return ASSISTANT_PUBLIC_API_BASE_PATH;
18
- }
19
-
20
- function resolveAssistantWorkspaceApiBasePath(workspaceSlug = "") {
21
- const normalizedWorkspaceSlug = normalizeText(workspaceSlug).toLowerCase();
22
- if (!normalizedWorkspaceSlug) {
23
- return "";
24
- }
25
-
26
- return `/api/w/${encodeURIComponent(normalizedWorkspaceSlug)}${ASSISTANT_API_RELATIVE_PATH}`;
27
- }
28
-
29
- function buildAssistantWorkspaceApiPath(workspaceSlug = "", suffix = "/") {
30
- const basePath = resolveAssistantWorkspaceApiBasePath(workspaceSlug);
31
- if (!basePath) {
32
- return "";
33
- }
34
-
35
- const normalizedSuffix = normalizePathname(suffix);
36
- if (normalizedSuffix === "/") {
37
- return basePath;
38
- }
39
-
40
- return `${basePath}${normalizedSuffix}`;
41
- }
42
-
43
- export {
44
- ASSISTANT_API_RELATIVE_PATH,
45
- ASSISTANT_WORKSPACE_API_BASE_PATH_TEMPLATE,
46
- ASSISTANT_PUBLIC_API_BASE_PATH,
47
- resolveAssistantApiBasePath,
48
- resolveAssistantWorkspaceApiBasePath,
49
- buildAssistantWorkspaceApiPath
50
- };
@@ -1,317 +0,0 @@
1
- import { Type } from "typebox";
2
- import {
3
- normalizeObjectInput,
4
- createCursorListValidator
5
- } from "@jskit-ai/kernel/shared/validators";
6
- import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
7
- import { normalizeConversationStatus } from "./support/conversationStatus.js";
8
- import { toPositiveInteger } from "./support/positiveInteger.js";
9
-
10
- const MAX_INPUT_CHARS = 8000;
11
- const MAX_HISTORY_MESSAGES = 20;
12
- const MAX_PAGE_SIZE = 200;
13
- const MAX_MESSAGE_PAGE_SIZE = 500;
14
-
15
- function normalizePaginationValue(value, fallback, max) {
16
- const parsed = toPositiveInteger(value, fallback);
17
- return Math.max(1, Math.min(max, parsed));
18
- }
19
-
20
- function normalizeChatStreamBody(payload = {}) {
21
- const source = normalizeObjectInput(payload);
22
- const normalized = {
23
- messageId: normalizeText(source.messageId),
24
- input: normalizeText(source.input)
25
- };
26
-
27
- const conversationId = toPositiveInteger(source.conversationId, 0);
28
- if (conversationId > 0) {
29
- normalized.conversationId = conversationId;
30
- }
31
-
32
- const history = Array.isArray(source.history) ? source.history : [];
33
- normalized.history = history
34
- .slice(0, MAX_HISTORY_MESSAGES)
35
- .map((entry) => {
36
- const item = normalizeObjectInput(entry);
37
- const role = normalizeText(item.role).toLowerCase();
38
- if (role !== "user" && role !== "assistant") {
39
- return null;
40
- }
41
-
42
- const content = normalizeText(item.content);
43
- if (!content) {
44
- return null;
45
- }
46
-
47
- return {
48
- role,
49
- content: content.slice(0, MAX_INPUT_CHARS)
50
- };
51
- })
52
- .filter(Boolean);
53
-
54
- const clientContext = normalizeObjectInput(source.clientContext);
55
- if (Object.keys(clientContext).length > 0) {
56
- normalized.clientContext = {
57
- locale: normalizeText(clientContext.locale),
58
- timezone: normalizeText(clientContext.timezone)
59
- };
60
- }
61
-
62
- return normalized;
63
- }
64
-
65
- function normalizeConversationsListQuery(payload = {}) {
66
- const source = normalizeObjectInput(payload);
67
- const status = normalizeConversationStatus(source.status, {
68
- fallback: ""
69
- });
70
- const normalized = {};
71
-
72
- if (Object.hasOwn(source, "cursor")) {
73
- normalized.cursor = toPositiveInteger(source.cursor, 0);
74
- }
75
- if (Object.hasOwn(source, "limit")) {
76
- normalized.limit = toPositiveInteger(source.limit, 0);
77
- }
78
- if (status) {
79
- normalized.status = status;
80
- }
81
-
82
- return normalized;
83
- }
84
-
85
- function normalizeConversationMessagesQuery(payload = {}) {
86
- const source = normalizeObjectInput(payload);
87
-
88
- return {
89
- page: normalizePaginationValue(source.page, 1, MAX_MESSAGE_PAGE_SIZE),
90
- pageSize: normalizePaginationValue(source.pageSize, 200, MAX_MESSAGE_PAGE_SIZE)
91
- };
92
- }
93
-
94
- function normalizeConversationMessagesParams(payload = {}) {
95
- const source = normalizeObjectInput(payload);
96
- return {
97
- conversationId: toPositiveInteger(source.conversationId, 0)
98
- };
99
- }
100
-
101
- function createOptionalPositiveIntegerQuerySchema(max = null) {
102
- const numericSchema = max == null
103
- ? Type.Integer({ minimum: 1 })
104
- : Type.Integer({ minimum: 1, maximum: max });
105
-
106
- return Type.Optional(
107
- Type.Union([
108
- numericSchema,
109
- Type.String({ pattern: "^[1-9][0-9]*$" })
110
- ])
111
- );
112
- }
113
-
114
- function normalizeConversationRecord(payload = {}) {
115
- const source = normalizeObjectInput(payload);
116
-
117
- return {
118
- id: toPositiveInteger(source.id, 0),
119
- workspaceId: toPositiveInteger(source.workspaceId, 0),
120
- workspaceSlug: normalizeText(source.workspaceSlug),
121
- workspaceName: normalizeText(source.workspaceName),
122
- title: normalizeText(source.title),
123
- createdByUserId: toPositiveInteger(source.createdByUserId, 0) || null,
124
- createdByUserDisplayName: normalizeText(source.createdByUserDisplayName),
125
- createdByUserEmail: normalizeText(source.createdByUserEmail),
126
- status: normalizeText(source.status),
127
- provider: normalizeText(source.provider),
128
- model: normalizeText(source.model),
129
- surfaceSid: normalizeText(source.surfaceSid),
130
- startedAt: normalizeText(source.startedAt),
131
- endedAt: normalizeText(source.endedAt) || null,
132
- messageCount: Math.max(0, Number(source.messageCount || 0)),
133
- metadata: normalizeObjectInput(source.metadata),
134
- createdAt: normalizeText(source.createdAt),
135
- updatedAt: normalizeText(source.updatedAt)
136
- };
137
- }
138
-
139
- function normalizeConversationMessageRecord(payload = {}) {
140
- const source = normalizeObjectInput(payload);
141
-
142
- return {
143
- id: toPositiveInteger(source.id, 0),
144
- conversationId: toPositiveInteger(source.conversationId, 0),
145
- workspaceId: toPositiveInteger(source.workspaceId, 0),
146
- seq: toPositiveInteger(source.seq, 0),
147
- role: normalizeText(source.role),
148
- kind: normalizeText(source.kind),
149
- clientMessageSid: normalizeText(source.clientMessageSid),
150
- actorUserId: toPositiveInteger(source.actorUserId, 0) || null,
151
- contentText: source.contentText == null ? null : String(source.contentText),
152
- metadata: normalizeObjectInput(source.metadata),
153
- createdAt: normalizeText(source.createdAt)
154
- };
155
- }
156
-
157
- const historyMessageSchema = Type.Object(
158
- {
159
- role: Type.Union([Type.Literal("user"), Type.Literal("assistant")]),
160
- content: Type.String({ minLength: 1, maxLength: MAX_INPUT_CHARS })
161
- },
162
- { additionalProperties: false }
163
- );
164
-
165
- const chatStreamBodySchema = Type.Object(
166
- {
167
- messageId: Type.String({ minLength: 1, maxLength: 128 }),
168
- conversationId: Type.Optional(Type.Integer({ minimum: 1 })),
169
- input: Type.String({ minLength: 1, maxLength: MAX_INPUT_CHARS }),
170
- history: Type.Optional(Type.Array(historyMessageSchema, { maxItems: MAX_HISTORY_MESSAGES })),
171
- clientContext: Type.Optional(
172
- Type.Object(
173
- {
174
- locale: Type.Optional(Type.String({ maxLength: 64 })),
175
- timezone: Type.Optional(Type.String({ maxLength: 64 }))
176
- },
177
- { additionalProperties: false }
178
- )
179
- )
180
- },
181
- {
182
- additionalProperties: false
183
- }
184
- );
185
-
186
- const conversationRecordSchema = Type.Object(
187
- {
188
- id: Type.Integer({ minimum: 1 }),
189
- workspaceId: Type.Integer({ minimum: 1 }),
190
- workspaceSlug: Type.String(),
191
- workspaceName: Type.String(),
192
- title: Type.String(),
193
- createdByUserId: Type.Union([Type.Integer({ minimum: 1 }), Type.Null()]),
194
- createdByUserDisplayName: Type.String(),
195
- createdByUserEmail: Type.String(),
196
- status: Type.String(),
197
- provider: Type.String(),
198
- model: Type.String(),
199
- surfaceSid: Type.String(),
200
- startedAt: Type.String({ minLength: 1 }),
201
- endedAt: Type.Union([Type.String({ minLength: 1 }), Type.Null()]),
202
- messageCount: Type.Integer({ minimum: 0 }),
203
- metadata: Type.Record(Type.String(), Type.Unknown()),
204
- createdAt: Type.String({ minLength: 1 }),
205
- updatedAt: Type.String({ minLength: 1 })
206
- },
207
- { additionalProperties: false }
208
- );
209
-
210
- const conversationRecordValidator = Object.freeze({
211
- schema: conversationRecordSchema,
212
- normalize: normalizeConversationRecord
213
- });
214
-
215
- const messageRecordSchema = Type.Object(
216
- {
217
- id: Type.Integer({ minimum: 1 }),
218
- conversationId: Type.Integer({ minimum: 1 }),
219
- workspaceId: Type.Integer({ minimum: 1 }),
220
- seq: Type.Integer({ minimum: 1 }),
221
- role: Type.String({ minLength: 1 }),
222
- kind: Type.String({ minLength: 1 }),
223
- clientMessageSid: Type.String(),
224
- actorUserId: Type.Union([Type.Integer({ minimum: 1 }), Type.Null()]),
225
- contentText: Type.Union([Type.String(), Type.Null()]),
226
- metadata: Type.Record(Type.String(), Type.Unknown()),
227
- createdAt: Type.String({ minLength: 1 })
228
- },
229
- { additionalProperties: false }
230
- );
231
-
232
- const paginationProperties = Object.freeze({
233
- page: Type.Integer({ minimum: 1 }),
234
- pageSize: Type.Integer({ minimum: 1 }),
235
- total: Type.Integer({ minimum: 0 }),
236
- totalPages: Type.Integer({ minimum: 1 })
237
- });
238
-
239
- const assistantResource = Object.freeze({
240
- resource: "assistant",
241
- operations: {
242
- chatStream: {
243
- method: "POST",
244
- bodyValidator: Object.freeze({
245
- schema: chatStreamBodySchema,
246
- normalize: normalizeChatStreamBody
247
- })
248
- },
249
- conversationsList: {
250
- method: "GET",
251
- queryValidator: Object.freeze({
252
- schema: Type.Object(
253
- {
254
- cursor: createOptionalPositiveIntegerQuerySchema(),
255
- limit: createOptionalPositiveIntegerQuerySchema(MAX_PAGE_SIZE),
256
- status: Type.Optional(Type.String({ minLength: 1, maxLength: 32 }))
257
- },
258
- { additionalProperties: false }
259
- ),
260
- normalize: normalizeConversationsListQuery
261
- }),
262
- outputValidator: createCursorListValidator(conversationRecordValidator)
263
- },
264
- conversationMessagesList: {
265
- method: "GET",
266
- paramsValidator: Object.freeze({
267
- schema: Type.Object(
268
- {
269
- conversationId: Type.Union([
270
- Type.Integer({ minimum: 1 }),
271
- Type.String({ pattern: "^[1-9][0-9]*$" })
272
- ])
273
- },
274
- { additionalProperties: false }
275
- ),
276
- normalize: normalizeConversationMessagesParams
277
- }),
278
- queryValidator: Object.freeze({
279
- schema: Type.Object(
280
- {
281
- page: createOptionalPositiveIntegerQuerySchema(),
282
- pageSize: createOptionalPositiveIntegerQuerySchema(MAX_MESSAGE_PAGE_SIZE)
283
- },
284
- { additionalProperties: false }
285
- ),
286
- normalize: normalizeConversationMessagesQuery
287
- }),
288
- outputValidator: Object.freeze({
289
- schema: Type.Object(
290
- {
291
- ...paginationProperties,
292
- conversation: conversationRecordSchema,
293
- entries: Type.Array(messageRecordSchema)
294
- },
295
- { additionalProperties: false }
296
- ),
297
- normalize(payload = {}) {
298
- const source = normalizeObjectInput(payload);
299
- return {
300
- conversation: normalizeConversationRecord(source.conversation),
301
- entries: (Array.isArray(source.entries) ? source.entries : []).map(normalizeConversationMessageRecord),
302
- page: normalizePaginationValue(source.page, 1, MAX_MESSAGE_PAGE_SIZE),
303
- pageSize: normalizePaginationValue(source.pageSize, 200, MAX_MESSAGE_PAGE_SIZE),
304
- total: Math.max(0, Number(source.total || 0)),
305
- totalPages: Math.max(1, Number(source.totalPages || 1))
306
- };
307
- }
308
- })
309
- }
310
- }
311
- });
312
-
313
- export {
314
- MAX_INPUT_CHARS,
315
- MAX_HISTORY_MESSAGES,
316
- assistantResource
317
- };
@@ -1,197 +0,0 @@
1
- import { Type } from "typebox";
2
- import {
3
- normalizeObjectInput,
4
- normalizeSettingsFieldInput,
5
- normalizeSettingsFieldOutput
6
- } from "@jskit-ai/kernel/shared/validators";
7
- import { normalizeText } from "@jskit-ai/kernel/shared/actions/textNormalization";
8
-
9
- const MAX_SYSTEM_PROMPT_CHARS = 12_000;
10
-
11
- function createPromptSchema(promptLabel) {
12
- return Type.String({
13
- maxLength: MAX_SYSTEM_PROMPT_CHARS,
14
- messages: {
15
- maxLength: `${promptLabel} must be at most ${MAX_SYSTEM_PROMPT_CHARS} characters.`,
16
- default: `${promptLabel} must be valid text.`
17
- }
18
- });
19
- }
20
-
21
- function createPromptSettingsResource({
22
- resourceId = "",
23
- fields = [],
24
- validationMessage = "Fix invalid values and try again.",
25
- saveSuccessMessage = "Saved.",
26
- saveErrorMessage = "Unable to save settings."
27
- } = {}) {
28
- const settingsOutputProperties = {};
29
- const settingsCreateProperties = {};
30
- for (const field of fields) {
31
- settingsOutputProperties[field.key] = field.outputSchema;
32
- settingsCreateProperties[field.key] =
33
- field.required === false ? Type.Optional(field.inputSchema) : field.inputSchema;
34
- }
35
-
36
- const settingsOutputSchema = Type.Object(settingsOutputProperties, { additionalProperties: false });
37
- const settingsCreateSchema = Type.Object(settingsCreateProperties, { additionalProperties: false });
38
- const settingsPatchSchema = Type.Partial(settingsCreateSchema, {
39
- additionalProperties: false
40
- });
41
- const recordSchema = Type.Object(
42
- {
43
- settings: settingsOutputSchema
44
- },
45
- { additionalProperties: false }
46
- );
47
-
48
- function normalizeInput(payload = {}) {
49
- return normalizeSettingsFieldInput(payload, fields);
50
- }
51
-
52
- function normalizeOutput(payload = {}) {
53
- const source = normalizeObjectInput(payload);
54
- const settingsSource = normalizeObjectInput(source.settings);
55
- return {
56
- settings: normalizeSettingsFieldOutput(settingsSource, fields)
57
- };
58
- }
59
-
60
- const outputValidator = Object.freeze({
61
- schema: recordSchema,
62
- normalize: normalizeOutput
63
- });
64
-
65
- return Object.freeze({
66
- resource: resourceId,
67
- messages: {
68
- validation: validationMessage,
69
- saveSuccess: saveSuccessMessage,
70
- saveError: saveErrorMessage
71
- },
72
- operations: Object.freeze({
73
- view: Object.freeze({
74
- method: "GET",
75
- outputValidator
76
- }),
77
- create: Object.freeze({
78
- method: "POST",
79
- bodyValidator: Object.freeze({
80
- schema: settingsCreateSchema,
81
- normalize: normalizeInput
82
- }),
83
- outputValidator
84
- }),
85
- replace: Object.freeze({
86
- method: "PUT",
87
- bodyValidator: Object.freeze({
88
- schema: settingsCreateSchema,
89
- normalize: normalizeInput
90
- }),
91
- outputValidator
92
- }),
93
- patch: Object.freeze({
94
- method: "PATCH",
95
- bodyValidator: Object.freeze({
96
- schema: settingsPatchSchema,
97
- normalize: normalizeInput
98
- }),
99
- outputValidator
100
- })
101
- })
102
- });
103
- }
104
-
105
- function createFieldRegistry(scopeLabel) {
106
- const fields = [];
107
-
108
- function defineField(field = {}) {
109
- const key = normalizeText(field.key);
110
- if (!key) {
111
- throw new TypeError(`${scopeLabel}.defineField requires field.key.`);
112
- }
113
- if (fields.some((entry) => entry.key === key)) {
114
- throw new Error(`${scopeLabel}.defineField duplicate key: ${key}`);
115
- }
116
- if (!field.inputSchema || typeof field.inputSchema !== "object") {
117
- throw new TypeError(`${scopeLabel}.defineField("${key}") requires inputSchema.`);
118
- }
119
- if (!field.outputSchema || typeof field.outputSchema !== "object") {
120
- throw new TypeError(`${scopeLabel}.defineField("${key}") requires outputSchema.`);
121
- }
122
- if (typeof field.normalizeInput !== "function") {
123
- throw new TypeError(`${scopeLabel}.defineField("${key}") requires normalizeInput.`);
124
- }
125
- if (typeof field.normalizeOutput !== "function") {
126
- throw new TypeError(`${scopeLabel}.defineField("${key}") requires normalizeOutput.`);
127
- }
128
- if (typeof field.resolveDefault !== "function") {
129
- throw new TypeError(`${scopeLabel}.defineField("${key}") requires resolveDefault.`);
130
- }
131
-
132
- fields.push({
133
- key,
134
- required: field.required !== false,
135
- inputSchema: field.inputSchema,
136
- outputSchema: field.outputSchema,
137
- normalizeInput: field.normalizeInput,
138
- normalizeOutput: field.normalizeOutput,
139
- resolveDefault: field.resolveDefault
140
- });
141
- }
142
-
143
- return {
144
- fields,
145
- defineField
146
- };
147
- }
148
-
149
- const assistantConsoleSettingsFields = (() => {
150
- const registry = createFieldRegistry("assistantConsoleSettingsFields");
151
- const { fields, defineField } = registry;
152
- defineField({
153
- key: "workspaceSurfacePrompt",
154
- required: true,
155
- inputSchema: createPromptSchema("Workspace surface system prompt"),
156
- outputSchema: Type.String({ maxLength: MAX_SYSTEM_PROMPT_CHARS }),
157
- normalizeInput: (value) => String(value || ""),
158
- normalizeOutput: (value) => String(value || ""),
159
- resolveDefault: () => ""
160
- });
161
- return fields;
162
- })();
163
-
164
- const assistantWorkspaceSettingsFields = (() => {
165
- const registry = createFieldRegistry("assistantWorkspaceSettingsFields");
166
- const { fields, defineField } = registry;
167
- defineField({
168
- key: "appSurfacePrompt",
169
- required: true,
170
- inputSchema: createPromptSchema("App surface system prompt"),
171
- outputSchema: Type.String({ maxLength: MAX_SYSTEM_PROMPT_CHARS }),
172
- normalizeInput: (value) => String(value || ""),
173
- normalizeOutput: (value) => String(value || ""),
174
- resolveDefault: () => ""
175
- });
176
- return fields;
177
- })();
178
-
179
- const assistantConsoleSettingsResource = createPromptSettingsResource({
180
- resourceId: "assistantConsoleSettings",
181
- fields: assistantConsoleSettingsFields,
182
- saveSuccessMessage: "Assistant console settings updated.",
183
- saveErrorMessage: "Unable to update assistant console settings."
184
- });
185
-
186
- const assistantWorkspaceSettingsResource = createPromptSettingsResource({
187
- resourceId: "assistantWorkspaceSettings",
188
- fields: assistantWorkspaceSettingsFields,
189
- saveSuccessMessage: "Assistant workspace settings updated.",
190
- saveErrorMessage: "Unable to update assistant workspace settings."
191
- });
192
-
193
- export {
194
- MAX_SYSTEM_PROMPT_CHARS,
195
- assistantConsoleSettingsResource,
196
- assistantWorkspaceSettingsResource
197
- };
@@ -1,43 +0,0 @@
1
- export {
2
- ASSISTANT_API_RELATIVE_PATH,
3
- resolveAssistantApiBasePath,
4
- resolveAssistantWorkspaceApiBasePath,
5
- buildAssistantWorkspaceApiPath
6
- } from "./assistantPaths.js";
7
-
8
- export {
9
- ASSISTANT_QUERY_KEY_PREFIX,
10
- assistantRootQueryKey,
11
- assistantWorkspaceScopeQueryKey,
12
- assistantConversationsListQueryKey,
13
- assistantConversationMessagesQueryKey
14
- } from "./queryKeys.js";
15
-
16
- export {
17
- ASSISTANT_STREAM_EVENT_TYPES,
18
- normalizeAssistantStreamEventType
19
- } from "./streamEvents.js";
20
-
21
- export {
22
- MAX_INPUT_CHARS,
23
- MAX_HISTORY_MESSAGES,
24
- assistantResource
25
- } from "./assistantResource.js";
26
-
27
- export {
28
- MAX_SYSTEM_PROMPT_CHARS,
29
- assistantConsoleSettingsResource,
30
- assistantWorkspaceSettingsResource
31
- } from "./assistantSettingsResource.js";
32
-
33
- export {
34
- assistantSettingsEvents
35
- } from "./settingsEvents.js";
36
-
37
- export {
38
- ASSISTANT_CONVERSATION_STATUSES,
39
- normalizeConversationStatus
40
- } from "./support/conversationStatus.js";
41
-
42
- export { parseJsonObject } from "./support/jsonObject.js";
43
- export { toPositiveInteger } from "./support/positiveInteger.js";
@@ -1,69 +0,0 @@
1
- const ASSISTANT_QUERY_KEY_PREFIX = Object.freeze(["assistant"]);
2
-
3
- function normalizeWorkspaceSlug(value) {
4
- return String(value || "").trim() || "none";
5
- }
6
-
7
- function normalizePositiveInteger(value, fallback) {
8
- const parsed = Number(value);
9
- if (!Number.isInteger(parsed) || parsed < 1) {
10
- return fallback;
11
- }
12
-
13
- return parsed;
14
- }
15
-
16
- function normalizeWorkspaceScope({ workspaceSlug = "", workspaceId = 0 } = {}) {
17
- const normalizedWorkspaceId = normalizePositiveInteger(workspaceId, 0);
18
- if (normalizedWorkspaceId > 0) {
19
- return `id:${normalizedWorkspaceId}`;
20
- }
21
-
22
- return `slug:${normalizeWorkspaceSlug(workspaceSlug)}`;
23
- }
24
-
25
- function normalizeStatus(value) {
26
- const normalized = String(value || "").trim().toLowerCase();
27
- return normalized || "all";
28
- }
29
-
30
- function normalizeConversationId(value) {
31
- return String(normalizePositiveInteger(value, 0) || "none");
32
- }
33
-
34
- function assistantRootQueryKey() {
35
- return [...ASSISTANT_QUERY_KEY_PREFIX];
36
- }
37
-
38
- function assistantWorkspaceScopeQueryKey(workspaceScope = {}) {
39
- return [...assistantRootQueryKey(), normalizeWorkspaceScope(workspaceScope)];
40
- }
41
-
42
- function assistantConversationsListQueryKey(workspaceScope = {}, { limit = 20, status = "" } = {}) {
43
- return [
44
- ...assistantWorkspaceScopeQueryKey(workspaceScope),
45
- "conversations",
46
- "list",
47
- normalizePositiveInteger(limit, 20),
48
- normalizeStatus(status)
49
- ];
50
- }
51
-
52
- function assistantConversationMessagesQueryKey(workspaceScope = {}, conversationId, { page = 1, pageSize = 200 } = {}) {
53
- return [
54
- ...assistantWorkspaceScopeQueryKey(workspaceScope),
55
- "conversations",
56
- normalizeConversationId(conversationId),
57
- "messages",
58
- normalizePositiveInteger(page, 1),
59
- normalizePositiveInteger(pageSize, 200)
60
- ];
61
- }
62
-
63
- export {
64
- ASSISTANT_QUERY_KEY_PREFIX,
65
- assistantRootQueryKey,
66
- assistantWorkspaceScopeQueryKey,
67
- assistantConversationsListQueryKey,
68
- assistantConversationMessagesQueryKey
69
- };
@@ -1,6 +0,0 @@
1
- const assistantSettingsEvents = Object.freeze({
2
- consoleSettingsChanged: "assistant.console.settings.changed",
3
- workspaceSettingsChanged: "assistant.workspace.settings.changed"
4
- });
5
-
6
- export { assistantSettingsEvents };