@jskit-ai/assistant 0.1.38 → 0.1.40
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 +84 -319
- package/package.json +2 -2
- package/src/server/buildTemplateContext.js +39 -14
- package/templates/src/pages/assistant/index.vue +2 -2
- package/templates/src/pages/settings/assistant/index.vue +7 -0
- package/test/buildTemplateContext.test.js +42 -27
- package/test/packageDescriptor.test.js +26 -55
- package/test/templateContracts.test.js +8 -6
- package/templates/migrations/assistant_config_initial.cjs +0 -25
- package/templates/migrations/assistant_transcripts_initial.cjs +0 -56
- package/templates/src/local-package/client/components/AssistantSettingsClientElement.vue +0 -88
- package/templates/src/local-package/client/components/AssistantSurfaceClientElement.vue +0 -10
- package/templates/src/local-package/client/composables/useAssistantRuntime.js +0 -754
- package/templates/src/local-package/client/index.js +0 -4
- package/templates/src/local-package/client/providers/AssistantClientProvider.js +0 -16
- package/templates/src/local-package/package.descriptor.mjs +0 -85
- package/templates/src/local-package/package.json +0 -11
- package/templates/src/local-package/server/AssistantProvider.js +0 -143
- package/templates/src/local-package/server/actionIds.js +0 -9
- package/templates/src/local-package/server/actions.js +0 -183
- package/templates/src/local-package/server/registerRoutes.js +0 -296
- package/templates/src/local-package/server/repositories/assistantConfigRepository.js +0 -141
- package/templates/src/local-package/server/repositories/conversationsRepository.js +0 -240
- package/templates/src/local-package/server/repositories/messagesRepository.js +0 -166
- package/templates/src/local-package/server/services/assistantConfigService.js +0 -90
- package/templates/src/local-package/server/services/chatService.js +0 -995
- package/templates/src/local-package/server/services/transcriptService.js +0 -308
- package/templates/src/local-package/shared/assistantRuntimeConfig.js +0 -13
- package/templates/src/local-package/shared/index.js +0 -1
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { runInTransaction } from "@jskit-ai/database-runtime/shared/repositoryOptions";
|
|
2
|
-
import { parsePositiveInteger } from "@jskit-ai/kernel/server/runtime";
|
|
3
|
-
import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
4
|
-
import {
|
|
5
|
-
parseJsonObject,
|
|
6
|
-
resolveInsertedId,
|
|
7
|
-
stringifyJsonObject,
|
|
8
|
-
toIso
|
|
9
|
-
} from "@jskit-ai/assistant-core/server";
|
|
10
|
-
import { assistantRuntimeConfig } from "../../shared/assistantRuntimeConfig.js";
|
|
11
|
-
|
|
12
|
-
function normalizeWorkspaceId(value) {
|
|
13
|
-
return parsePositiveInteger(value) || null;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function applyWorkspaceScope(query, columnName, workspaceId) {
|
|
17
|
-
const normalizedWorkspaceId = normalizeWorkspaceId(workspaceId);
|
|
18
|
-
if (normalizedWorkspaceId) {
|
|
19
|
-
return query.where(columnName, normalizedWorkspaceId);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return query.whereNull(columnName);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function mapMessageRow(row = {}) {
|
|
26
|
-
return {
|
|
27
|
-
id: Number(row.id),
|
|
28
|
-
conversationId: Number(row.conversation_id),
|
|
29
|
-
workspaceId: normalizeWorkspaceId(row.workspace_id),
|
|
30
|
-
seq: Number(row.seq),
|
|
31
|
-
role: String(row.role || ""),
|
|
32
|
-
kind: String(row.kind || "chat"),
|
|
33
|
-
clientMessageSid: String(row.client_message_sid || ""),
|
|
34
|
-
actorUserId: row.actor_user_id == null ? null : Number(row.actor_user_id),
|
|
35
|
-
contentText: row.content_text == null ? null : String(row.content_text),
|
|
36
|
-
metadata: parseJsonObject(row.metadata_json),
|
|
37
|
-
createdAt: toIso(row.created_at)
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function normalizePagination(pagination = {}, { defaultPage = 1, defaultPageSize = 200, maxPageSize = 500 } = {}) {
|
|
42
|
-
const page = Math.max(1, parsePositiveInteger(pagination.page) || defaultPage);
|
|
43
|
-
const pageSize = Math.max(1, Math.min(maxPageSize, parsePositiveInteger(pagination.pageSize) || defaultPageSize));
|
|
44
|
-
|
|
45
|
-
return {
|
|
46
|
-
page,
|
|
47
|
-
pageSize
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function resolveNextSequence(client, conversationId) {
|
|
52
|
-
const row = await client(assistantRuntimeConfig.messagesTable)
|
|
53
|
-
.where({ conversation_id: conversationId })
|
|
54
|
-
.max({ maxSeq: "seq" })
|
|
55
|
-
.first();
|
|
56
|
-
const maxSeq = Number(row?.maxSeq || 0);
|
|
57
|
-
if (!Number.isInteger(maxSeq) || maxSeq < 0) {
|
|
58
|
-
return 1;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return maxSeq + 1;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function createRepository(knex) {
|
|
65
|
-
if (!knex || typeof knex !== "function") {
|
|
66
|
-
throw new Error("createMessagesRepository requires knex client.");
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async function findById(messageId, options = {}) {
|
|
70
|
-
const numericMessageId = parsePositiveInteger(messageId);
|
|
71
|
-
if (!numericMessageId) {
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const client = options?.trx || knex;
|
|
76
|
-
const row = await client(assistantRuntimeConfig.messagesTable)
|
|
77
|
-
.where({ id: numericMessageId })
|
|
78
|
-
.first();
|
|
79
|
-
|
|
80
|
-
return row ? mapMessageRow(row) : null;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
async function create(payload = {}, options = {}) {
|
|
84
|
-
const client = options?.trx || knex;
|
|
85
|
-
const conversationId = parsePositiveInteger(payload.conversationId);
|
|
86
|
-
if (!conversationId) {
|
|
87
|
-
throw new TypeError("messagesRepository.create requires conversationId.");
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const seq = parsePositiveInteger(payload.seq) || (await resolveNextSequence(client, conversationId));
|
|
91
|
-
const insertResult = await client(assistantRuntimeConfig.messagesTable).insert({
|
|
92
|
-
conversation_id: conversationId,
|
|
93
|
-
workspace_id: normalizeWorkspaceId(payload.workspaceId),
|
|
94
|
-
seq,
|
|
95
|
-
role: normalizeText(payload.role).toLowerCase(),
|
|
96
|
-
kind: normalizeText(payload.kind).toLowerCase() || "chat",
|
|
97
|
-
client_message_sid: normalizeText(payload.clientMessageSid),
|
|
98
|
-
actor_user_id: parsePositiveInteger(payload.actorUserId) || null,
|
|
99
|
-
content_text: payload.contentText == null ? null : String(payload.contentText),
|
|
100
|
-
metadata_json: stringifyJsonObject(payload.metadata),
|
|
101
|
-
created_at: payload.createdAt ? new Date(payload.createdAt) : new Date()
|
|
102
|
-
});
|
|
103
|
-
const id = resolveInsertedId(insertResult);
|
|
104
|
-
if (!id) {
|
|
105
|
-
throw new Error("messagesRepository.create could not resolve inserted id.");
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return findById(id, {
|
|
109
|
-
trx: client
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async function countByConversationScope(conversationId, { workspaceId = null } = {}, options = {}) {
|
|
114
|
-
const numericConversationId = parsePositiveInteger(conversationId);
|
|
115
|
-
if (!numericConversationId) {
|
|
116
|
-
return 0;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const client = options?.trx || knex;
|
|
120
|
-
const query = client(assistantRuntimeConfig.messagesTable).where({
|
|
121
|
-
conversation_id: numericConversationId
|
|
122
|
-
});
|
|
123
|
-
applyWorkspaceScope(query, "workspace_id", workspaceId);
|
|
124
|
-
const row = await query.count({ total: "*" }).first();
|
|
125
|
-
|
|
126
|
-
const total = Number(row?.total || 0);
|
|
127
|
-
return Number.isFinite(total) && total > 0 ? total : 0;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
async function listByConversationScope(conversationId, { workspaceId = null } = {}, pagination = {}, options = {}) {
|
|
131
|
-
const numericConversationId = parsePositiveInteger(conversationId);
|
|
132
|
-
if (!numericConversationId) {
|
|
133
|
-
return [];
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const client = options?.trx || knex;
|
|
137
|
-
const { page, pageSize } = normalizePagination(pagination);
|
|
138
|
-
const offset = (page - 1) * pageSize;
|
|
139
|
-
|
|
140
|
-
const query = client(assistantRuntimeConfig.messagesTable).where({
|
|
141
|
-
conversation_id: numericConversationId
|
|
142
|
-
});
|
|
143
|
-
applyWorkspaceScope(query, "workspace_id", workspaceId);
|
|
144
|
-
const rows = await query
|
|
145
|
-
.orderBy("seq", "asc")
|
|
146
|
-
.orderBy("id", "asc")
|
|
147
|
-
.limit(pageSize)
|
|
148
|
-
.offset(offset);
|
|
149
|
-
|
|
150
|
-
return rows.map(mapMessageRow);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async function transaction(callback) {
|
|
154
|
-
return runInTransaction(knex, callback);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return Object.freeze({
|
|
158
|
-
findById,
|
|
159
|
-
create,
|
|
160
|
-
countByConversationScope,
|
|
161
|
-
listByConversationScope,
|
|
162
|
-
transaction
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
export { createRepository };
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { AppError, parsePositiveInteger } from "@jskit-ai/kernel/server/runtime";
|
|
2
|
-
import { normalizeObject } from "@jskit-ai/kernel/shared/support/normalize";
|
|
3
|
-
import { resolveWorkspace } from "@jskit-ai/users-core/server/support/resolveWorkspace";
|
|
4
|
-
import { assistantRuntimeConfig } from "../../shared/assistantRuntimeConfig.js";
|
|
5
|
-
|
|
6
|
-
function createService({ assistantConfigRepository, consoleService = null } = {}) {
|
|
7
|
-
if (!assistantConfigRepository || typeof assistantConfigRepository.findByScope !== "function") {
|
|
8
|
-
throw new Error("assistantConfigService requires assistantConfigRepository.findByScope().");
|
|
9
|
-
}
|
|
10
|
-
if (typeof assistantConfigRepository.upsertByScope !== "function") {
|
|
11
|
-
throw new Error("assistantConfigService requires assistantConfigRepository.upsertByScope().");
|
|
12
|
-
}
|
|
13
|
-
if (typeof assistantConfigRepository.createDefaultRecord !== "function") {
|
|
14
|
-
throw new Error("assistantConfigService requires assistantConfigRepository.createDefaultRecord().");
|
|
15
|
-
}
|
|
16
|
-
if (
|
|
17
|
-
assistantRuntimeConfig.settingsSurfaceRequiresConsoleOwner &&
|
|
18
|
-
(!consoleService || typeof consoleService.requireConsoleOwner !== "function")
|
|
19
|
-
) {
|
|
20
|
-
throw new Error("assistantConfigService requires consoleService.requireConsoleOwner() for console-owner settings surfaces.");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async function requireSettingsAccess(context = {}, options = {}) {
|
|
24
|
-
if (assistantRuntimeConfig.settingsSurfaceRequiresConsoleOwner !== true) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
await consoleService.requireConsoleOwner(context, options);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function resolveConfigWorkspaceId(workspace = null, input = {}, context = {}) {
|
|
32
|
-
if (assistantRuntimeConfig.configScope !== "workspace") {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const resolvedWorkspace = workspace || resolveWorkspace(context, input);
|
|
37
|
-
const workspaceId = parsePositiveInteger(resolvedWorkspace?.id);
|
|
38
|
-
if (!workspaceId) {
|
|
39
|
-
throw new AppError(409, "Workspace selection required.");
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return workspaceId;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async function getSettings(input = {}, options = {}) {
|
|
46
|
-
await requireSettingsAccess(options?.context, options);
|
|
47
|
-
|
|
48
|
-
const workspaceId = resolveConfigWorkspaceId(null, input, options?.context);
|
|
49
|
-
const existing = await assistantConfigRepository.findByScope({
|
|
50
|
-
targetSurfaceId: assistantRuntimeConfig.runtimeSurfaceId,
|
|
51
|
-
workspaceId
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
return existing || assistantConfigRepository.createDefaultRecord({
|
|
55
|
-
targetSurfaceId: assistantRuntimeConfig.runtimeSurfaceId,
|
|
56
|
-
workspaceId
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async function updateSettings(input = {}, patch = {}, options = {}) {
|
|
61
|
-
await requireSettingsAccess(options?.context, options);
|
|
62
|
-
|
|
63
|
-
const workspaceId = resolveConfigWorkspaceId(null, input, options?.context);
|
|
64
|
-
const normalizedPatch = normalizeObject(patch);
|
|
65
|
-
|
|
66
|
-
return assistantConfigRepository.upsertByScope({
|
|
67
|
-
targetSurfaceId: assistantRuntimeConfig.runtimeSurfaceId,
|
|
68
|
-
workspaceId,
|
|
69
|
-
patch: normalizedPatch
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async function resolveSystemPrompt(workspace = null, _options = {}, serviceOptions = {}) {
|
|
74
|
-
const workspaceId = resolveConfigWorkspaceId(workspace, serviceOptions?.input || {}, serviceOptions?.context);
|
|
75
|
-
const existing = await assistantConfigRepository.findByScope({
|
|
76
|
-
targetSurfaceId: assistantRuntimeConfig.runtimeSurfaceId,
|
|
77
|
-
workspaceId
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
return String(existing?.settings?.systemPrompt || "");
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return Object.freeze({
|
|
84
|
-
getSettings,
|
|
85
|
-
updateSettings,
|
|
86
|
-
resolveSystemPrompt
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export { createService };
|