@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.
Files changed (29) hide show
  1. package/package.descriptor.mjs +84 -319
  2. package/package.json +2 -2
  3. package/src/server/buildTemplateContext.js +39 -14
  4. package/templates/src/pages/assistant/index.vue +2 -2
  5. package/templates/src/pages/settings/assistant/index.vue +7 -0
  6. package/test/buildTemplateContext.test.js +42 -27
  7. package/test/packageDescriptor.test.js +26 -55
  8. package/test/templateContracts.test.js +8 -6
  9. package/templates/migrations/assistant_config_initial.cjs +0 -25
  10. package/templates/migrations/assistant_transcripts_initial.cjs +0 -56
  11. package/templates/src/local-package/client/components/AssistantSettingsClientElement.vue +0 -88
  12. package/templates/src/local-package/client/components/AssistantSurfaceClientElement.vue +0 -10
  13. package/templates/src/local-package/client/composables/useAssistantRuntime.js +0 -754
  14. package/templates/src/local-package/client/index.js +0 -4
  15. package/templates/src/local-package/client/providers/AssistantClientProvider.js +0 -16
  16. package/templates/src/local-package/package.descriptor.mjs +0 -85
  17. package/templates/src/local-package/package.json +0 -11
  18. package/templates/src/local-package/server/AssistantProvider.js +0 -143
  19. package/templates/src/local-package/server/actionIds.js +0 -9
  20. package/templates/src/local-package/server/actions.js +0 -183
  21. package/templates/src/local-package/server/registerRoutes.js +0 -296
  22. package/templates/src/local-package/server/repositories/assistantConfigRepository.js +0 -141
  23. package/templates/src/local-package/server/repositories/conversationsRepository.js +0 -240
  24. package/templates/src/local-package/server/repositories/messagesRepository.js +0 -166
  25. package/templates/src/local-package/server/services/assistantConfigService.js +0 -90
  26. package/templates/src/local-package/server/services/chatService.js +0 -995
  27. package/templates/src/local-package/server/services/transcriptService.js +0 -308
  28. package/templates/src/local-package/shared/assistantRuntimeConfig.js +0 -13
  29. 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 };