@jskit-ai/assistant 0.1.38 → 0.1.39

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,4 +0,0 @@
1
- export { default as AssistantSurfaceClientElement } from "./components/AssistantSurfaceClientElement.vue";
2
- export { default as AssistantSettingsClientElement } from "./components/AssistantSettingsClientElement.vue";
3
- export { AssistantClientProvider } from "./providers/AssistantClientProvider.js";
4
- export { useAssistantRuntime } from "./composables/useAssistantRuntime.js";
@@ -1,16 +0,0 @@
1
- import AssistantSettingsClientElement from "../components/AssistantSettingsClientElement.vue";
2
-
3
- class AssistantClientProvider {
4
- static id = "assistant.web.client";
5
- static dependsOn = ["users.web.client"];
6
-
7
- register(app) {
8
- if (!app || typeof app.singleton !== "function") {
9
- throw new Error("AssistantClientProvider requires application singleton().");
10
- }
11
-
12
- app.singleton("assistant.web.settings.element", () => AssistantSettingsClientElement);
13
- }
14
- }
15
-
16
- export { AssistantClientProvider };
@@ -1,85 +0,0 @@
1
- export default Object.freeze({
2
- packageVersion: 1,
3
- packageId: "@local/assistant",
4
- version: "0.1.0",
5
- kind: "runtime",
6
- description: "App-local generated assistant runtime.",
7
- dependsOn: [
8
- "@jskit-ai/assistant-core",
9
- "@jskit-ai/database-runtime",
10
- "@jskit-ai/http-runtime",
11
- "@jskit-ai/shell-web",
12
- "@jskit-ai/users-core",
13
- "@jskit-ai/users-web"
14
- ],
15
- capabilities: {
16
- provides: ["assistant.runtime"],
17
- requires: [
18
- "runtime.actions",
19
- "runtime.database",
20
- "auth.policy",
21
- "runtime.http-client",
22
- "users.core",
23
- "users.web"
24
- ]
25
- },
26
- runtime: {
27
- server: {
28
- providers: [
29
- {
30
- entrypoint: "src/server/AssistantProvider.js",
31
- export: "AssistantProvider"
32
- }
33
- ]
34
- },
35
- client: {
36
- providers: [
37
- {
38
- entrypoint: "src/client/providers/AssistantClientProvider.js",
39
- export: "AssistantClientProvider"
40
- }
41
- ]
42
- }
43
- },
44
- metadata: {
45
- apiSummary: {
46
- surfaces: [
47
- {
48
- subpath: "./server/actionIds",
49
- summary: "Generated assistant action identifiers."
50
- },
51
- {
52
- subpath: "./client",
53
- summary: "Generated assistant client wrappers."
54
- },
55
- {
56
- subpath: "./shared",
57
- summary: "Generated assistant runtime configuration."
58
- }
59
- ],
60
- containerTokens: {
61
- server: [
62
- "assistant.config.repository",
63
- "assistant.conversation.repository",
64
- "assistant.message.repository",
65
- "assistant.ai.client",
66
- "assistant.service.tool-catalog"
67
- ],
68
- client: [
69
- "assistant.web.settings.element"
70
- ]
71
- }
72
- }
73
- },
74
- mutations: {
75
- dependencies: {
76
- runtime: {},
77
- dev: {}
78
- },
79
- packageJson: {
80
- scripts: {}
81
- },
82
- procfile: {},
83
- files: []
84
- }
85
- });
@@ -1,11 +0,0 @@
1
- {
2
- "name": "@local/assistant",
3
- "version": "0.1.0",
4
- "private": true,
5
- "type": "module",
6
- "exports": {
7
- "./client": "./src/client/index.js",
8
- "./shared": "./src/shared/index.js",
9
- "./server/actionIds": "./src/server/actionIds.js"
10
- }
11
- }
@@ -1,143 +0,0 @@
1
- import { withActionDefaults } from "@jskit-ai/kernel/shared/actions";
2
- import { normalizeObject, normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
3
- import {
4
- DEFAULT_AI_TIMEOUT_MS,
5
- createAiClient,
6
- createServiceToolCatalog,
7
- normalizeOptionalHttpUrl,
8
- normalizeTimeoutMs
9
- } from "@jskit-ai/assistant-core/server";
10
- import { assistantRuntimeConfig } from "../shared/assistantRuntimeConfig.js";
11
- import { assistantActions } from "./actions.js";
12
- import { registerRoutes } from "./registerRoutes.js";
13
- import { createRepository as createAssistantConfigRepository } from "./repositories/assistantConfigRepository.js";
14
- import { createRepository as createConversationsRepository } from "./repositories/conversationsRepository.js";
15
- import { createRepository as createMessagesRepository } from "./repositories/messagesRepository.js";
16
- import { createService as createAssistantConfigService } from "./services/assistantConfigService.js";
17
- import { createChatService } from "./services/chatService.js";
18
- import { createTranscriptService } from "./services/transcriptService.js";
19
-
20
- function normalizeStringArray(value) {
21
- const source = Array.isArray(value) ? value : [value];
22
- return source.map((entry) => normalizeText(entry)).filter(Boolean);
23
- }
24
-
25
- function resolveAssistantConfig(scope) {
26
- const appConfig = scope.has("appConfig") ? normalizeObject(scope.make("appConfig")) : {};
27
- const env = scope.has("jskit.env") ? normalizeObject(scope.make("jskit.env")) : {};
28
- const assistantConfig = normalizeObject(appConfig.assistant);
29
-
30
- const provider = normalizeText(env.AI_PROVIDER || assistantConfig.provider).toLowerCase() || "openai";
31
- const apiKey = normalizeText(env.AI_API_KEY || assistantConfig.apiKey);
32
- const baseUrl = normalizeOptionalHttpUrl(env.AI_BASE_URL || assistantConfig.baseUrl, {
33
- context: "assistant AI_BASE_URL"
34
- });
35
- const model = normalizeText(assistantConfig.model);
36
- const timeoutMs = normalizeTimeoutMs(
37
- env.AI_TIMEOUT_MS || assistantConfig.timeoutMs,
38
- DEFAULT_AI_TIMEOUT_MS
39
- );
40
-
41
- return Object.freeze({
42
- ai: Object.freeze({
43
- enabled: Boolean(apiKey),
44
- provider,
45
- apiKey,
46
- baseUrl,
47
- model,
48
- timeoutMs
49
- }),
50
- barredActionIds: normalizeStringArray(assistantConfig.barredActionIds),
51
- toolSkipActionPrefixes: normalizeStringArray(assistantConfig.toolSkipActionPrefixes)
52
- });
53
- }
54
-
55
- class AssistantProvider {
56
- static id = "assistant.chat.service";
57
-
58
- static dependsOn = ["runtime.actions", "runtime.database", "auth.policy.fastify", "users.core"];
59
-
60
- register(app) {
61
- if (
62
- !app ||
63
- typeof app.singleton !== "function" ||
64
- typeof app.service !== "function" ||
65
- typeof app.actions !== "function"
66
- ) {
67
- throw new Error("AssistantProvider requires application singleton()/service()/actions().");
68
- }
69
-
70
- const config = resolveAssistantConfig(app);
71
-
72
- app.singleton("assistant.config.repository", (scope) => {
73
- const knex = scope.make("jskit.database.knex");
74
- return createAssistantConfigRepository(knex);
75
- });
76
-
77
- app.singleton("assistant.conversation.repository", (scope) => {
78
- const knex = scope.make("jskit.database.knex");
79
- return createConversationsRepository(knex);
80
- });
81
-
82
- app.singleton("assistant.message.repository", (scope) => {
83
- const knex = scope.make("jskit.database.knex");
84
- return createMessagesRepository(knex);
85
- });
86
-
87
- app.singleton("assistant.ai.client", () => {
88
- return createAiClient(config.ai);
89
- });
90
-
91
- app.singleton("assistant.service.tool-catalog", (scope) => {
92
- return createServiceToolCatalog(scope, {
93
- barredActionIds: config.barredActionIds,
94
- skipActionPrefixes: ["assistant.", ...config.toolSkipActionPrefixes]
95
- });
96
- });
97
-
98
- app.service(
99
- "assistant.config.service",
100
- (scope) =>
101
- createAssistantConfigService({
102
- assistantConfigRepository: scope.make("assistant.config.repository"),
103
- consoleService: scope.has("consoleService") ? scope.make("consoleService") : null
104
- })
105
- );
106
-
107
- app.service(
108
- "assistant.transcript.service",
109
- (scope) =>
110
- createTranscriptService({
111
- conversationsRepository: scope.make("assistant.conversation.repository"),
112
- messagesRepository: scope.make("assistant.message.repository")
113
- })
114
- );
115
-
116
- app.service(
117
- "assistant.chat.service",
118
- (scope) =>
119
- createChatService({
120
- aiClient: scope.make("assistant.ai.client"),
121
- transcriptService: scope.make("assistant.transcript.service"),
122
- serviceToolCatalog: scope.make("assistant.service.tool-catalog"),
123
- assistantConfigService: scope.make("assistant.config.service")
124
- })
125
- );
126
-
127
- app.actions(
128
- withActionDefaults(assistantActions, {
129
- domain: "assistant",
130
- dependencies: {
131
- chatService: "assistant.chat.service",
132
- assistantConfigService: "assistant.config.service"
133
- }
134
- })
135
- );
136
- }
137
-
138
- boot(app) {
139
- registerRoutes(app);
140
- }
141
- }
142
-
143
- export { AssistantProvider };
@@ -1,9 +0,0 @@
1
- const actionIds = Object.freeze({
2
- chatStream: "assistant.chat.stream",
3
- conversationsList: "assistant.conversations.list",
4
- conversationMessagesList: "assistant.conversation.messages.list",
5
- settingsRead: "assistant.settings.read",
6
- settingsUpdate: "assistant.settings.update"
7
- });
8
-
9
- export { actionIds };
@@ -1,183 +0,0 @@
1
- import {
2
- EMPTY_INPUT_VALIDATOR
3
- } from "@jskit-ai/kernel/shared/actions/actionContributorHelpers";
4
- import { workspaceSlugParamsValidator } from "@jskit-ai/users-core/server/validators/routeParamsValidator";
5
- import {
6
- assistantConfigResource,
7
- assistantResource
8
- } from "@jskit-ai/assistant-core/shared";
9
- import { assistantRuntimeConfig } from "../shared/assistantRuntimeConfig.js";
10
- import { actionIds } from "./actionIds.js";
11
-
12
- const runtimeSurfaces = Object.freeze([assistantRuntimeConfig.runtimeSurfaceId]);
13
- const settingsSurfaces = Object.freeze([assistantRuntimeConfig.settingsSurfaceId]);
14
-
15
- const runtimeQueryInputValidator = assistantRuntimeConfig.runtimeSurfaceRequiresWorkspace
16
- ? [workspaceSlugParamsValidator, { query: assistantResource.operations.conversationsList.queryValidator }]
17
- : { query: assistantResource.operations.conversationsList.queryValidator };
18
-
19
- const runtimeMessagesInputValidator = assistantRuntimeConfig.runtimeSurfaceRequiresWorkspace
20
- ? [
21
- workspaceSlugParamsValidator,
22
- assistantResource.operations.conversationMessagesList.paramsValidator,
23
- {
24
- query: assistantResource.operations.conversationMessagesList.queryValidator
25
- }
26
- ]
27
- : [
28
- assistantResource.operations.conversationMessagesList.paramsValidator,
29
- {
30
- query: assistantResource.operations.conversationMessagesList.queryValidator
31
- }
32
- ];
33
-
34
- const runtimeChatInputValidator = assistantRuntimeConfig.runtimeSurfaceRequiresWorkspace
35
- ? [workspaceSlugParamsValidator, assistantResource.operations.chatStream.bodyValidator]
36
- : assistantResource.operations.chatStream.bodyValidator;
37
-
38
- const settingsReadInputValidator = assistantRuntimeConfig.settingsSurfaceRequiresWorkspace
39
- ? workspaceSlugParamsValidator
40
- : EMPTY_INPUT_VALIDATOR;
41
-
42
- const settingsUpdateInputValidator = assistantRuntimeConfig.settingsSurfaceRequiresWorkspace
43
- ? [
44
- workspaceSlugParamsValidator,
45
- {
46
- patch: assistantConfigResource.operations.patch.bodyValidator
47
- }
48
- ]
49
- : {
50
- patch: assistantConfigResource.operations.patch.bodyValidator
51
- };
52
-
53
- const settingsReadPermission = assistantRuntimeConfig.settingsSurfaceRequiresWorkspace
54
- ? {
55
- require: "any",
56
- permissions: ["workspace.settings.view", "workspace.settings.update"]
57
- }
58
- : {
59
- require: "authenticated"
60
- };
61
-
62
- const settingsUpdatePermission = assistantRuntimeConfig.settingsSurfaceRequiresWorkspace
63
- ? {
64
- require: "all",
65
- permissions: ["workspace.settings.update"]
66
- }
67
- : {
68
- require: "authenticated"
69
- };
70
-
71
- const assistantActions = Object.freeze([
72
- {
73
- id: actionIds.chatStream,
74
- version: 1,
75
- kind: "stream",
76
- channels: ["api", "internal"],
77
- surfaces: runtimeSurfaces,
78
- permission: {
79
- require: "authenticated"
80
- },
81
- inputValidator: runtimeChatInputValidator,
82
- idempotency: "optional",
83
- audit: {
84
- actionName: actionIds.chatStream
85
- },
86
- observability: {},
87
- async execute(input, context, deps) {
88
- return deps.chatService.streamChat(input, {
89
- context,
90
- streamWriter: deps.streamWriter,
91
- abortSignal: deps.abortSignal
92
- });
93
- }
94
- },
95
- {
96
- id: actionIds.conversationsList,
97
- version: 1,
98
- kind: "query",
99
- channels: ["api", "internal"],
100
- surfaces: runtimeSurfaces,
101
- permission: {
102
- require: "authenticated"
103
- },
104
- inputValidator: runtimeQueryInputValidator,
105
- outputValidator: assistantResource.operations.conversationsList.outputValidator,
106
- idempotency: "none",
107
- audit: {
108
- actionName: actionIds.conversationsList
109
- },
110
- observability: {},
111
- async execute(input, context, deps) {
112
- return deps.chatService.listConversations(input.query, {
113
- context,
114
- input
115
- });
116
- }
117
- },
118
- {
119
- id: actionIds.conversationMessagesList,
120
- version: 1,
121
- kind: "query",
122
- channels: ["api", "internal"],
123
- surfaces: runtimeSurfaces,
124
- permission: {
125
- require: "authenticated"
126
- },
127
- inputValidator: runtimeMessagesInputValidator,
128
- outputValidator: assistantResource.operations.conversationMessagesList.outputValidator,
129
- idempotency: "none",
130
- audit: {
131
- actionName: actionIds.conversationMessagesList
132
- },
133
- observability: {},
134
- async execute(input, context, deps) {
135
- return deps.chatService.getConversationMessages(input.conversationId, input.query, {
136
- context,
137
- input
138
- });
139
- }
140
- },
141
- {
142
- id: actionIds.settingsRead,
143
- version: 1,
144
- kind: "query",
145
- channels: ["api", "automation", "internal"],
146
- surfaces: settingsSurfaces,
147
- permission: settingsReadPermission,
148
- inputValidator: settingsReadInputValidator,
149
- outputValidator: assistantConfigResource.operations.view.outputValidator,
150
- idempotency: "none",
151
- audit: {
152
- actionName: actionIds.settingsRead
153
- },
154
- observability: {},
155
- async execute(input, context, deps) {
156
- return deps.assistantConfigService.getSettings(input, {
157
- context
158
- });
159
- }
160
- },
161
- {
162
- id: actionIds.settingsUpdate,
163
- version: 1,
164
- kind: "command",
165
- channels: ["api", "automation", "internal"],
166
- surfaces: settingsSurfaces,
167
- permission: settingsUpdatePermission,
168
- inputValidator: settingsUpdateInputValidator,
169
- outputValidator: assistantConfigResource.operations.patch.outputValidator,
170
- idempotency: "optional",
171
- audit: {
172
- actionName: actionIds.settingsUpdate
173
- },
174
- observability: {},
175
- async execute(input, context, deps) {
176
- return deps.assistantConfigService.updateSettings(input, input.patch, {
177
- context
178
- });
179
- }
180
- }
181
- ]);
182
-
183
- export { assistantActions };