@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,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
|
-
};
|
package/src/shared/index.js
DELETED
|
@@ -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";
|
package/src/shared/queryKeys.js
DELETED
|
@@ -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
|
-
};
|