@jskit-ai/assistant 0.1.4

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 (57) hide show
  1. package/package.descriptor.mjs +284 -0
  2. package/package.json +31 -0
  3. package/src/client/components/AssistantClientElement.vue +1316 -0
  4. package/src/client/components/AssistantConsoleSettingsClientElement.vue +71 -0
  5. package/src/client/components/AssistantSettingsFormCard.vue +76 -0
  6. package/src/client/components/AssistantWorkspaceClientElement.vue +15 -0
  7. package/src/client/components/AssistantWorkspaceSettingsClientElement.vue +73 -0
  8. package/src/client/composables/useAssistantWorkspaceRuntime.js +789 -0
  9. package/src/client/index.js +12 -0
  10. package/src/client/lib/assistantApi.js +137 -0
  11. package/src/client/lib/assistantHttpClient.js +10 -0
  12. package/src/client/lib/markdownRenderer.js +31 -0
  13. package/src/client/providers/AssistantWebClientProvider.js +25 -0
  14. package/src/server/AssistantServiceProvider.js +179 -0
  15. package/src/server/actionIds.js +11 -0
  16. package/src/server/actions.js +191 -0
  17. package/src/server/diTokens.js +19 -0
  18. package/src/server/lib/aiClient.js +43 -0
  19. package/src/server/lib/ndjson.js +47 -0
  20. package/src/server/lib/providers/anthropicClient.js +375 -0
  21. package/src/server/lib/providers/common.js +158 -0
  22. package/src/server/lib/providers/deepSeekClient.js +22 -0
  23. package/src/server/lib/providers/openAiClient.js +13 -0
  24. package/src/server/lib/providers/openAiCompatibleClient.js +69 -0
  25. package/src/server/lib/resolveWorkspaceSlug.js +24 -0
  26. package/src/server/lib/serviceToolCatalog.js +459 -0
  27. package/src/server/registerRoutes.js +384 -0
  28. package/src/server/repositories/assistantSettingsRepository.js +100 -0
  29. package/src/server/repositories/conversationsRepository.js +244 -0
  30. package/src/server/repositories/messagesRepository.js +154 -0
  31. package/src/server/repositories/repositoryPersistenceUtils.js +63 -0
  32. package/src/server/services/assistantSettingsService.js +153 -0
  33. package/src/server/services/chatService.js +987 -0
  34. package/src/server/services/transcriptService.js +334 -0
  35. package/src/shared/assistantPaths.js +50 -0
  36. package/src/shared/assistantResource.js +323 -0
  37. package/src/shared/assistantSettingsResource.js +214 -0
  38. package/src/shared/index.js +39 -0
  39. package/src/shared/queryKeys.js +69 -0
  40. package/src/shared/settingsEvents.js +7 -0
  41. package/src/shared/streamEvents.js +31 -0
  42. package/src/shared/support/positiveInteger.js +9 -0
  43. package/templates/migrations/assistant_settings_initial.cjs +39 -0
  44. package/templates/migrations/assistant_transcripts_initial.cjs +51 -0
  45. package/templates/src/pages/admin/workspace/assistant/index.vue +7 -0
  46. package/test/aiConfigValidation.test.js +15 -0
  47. package/test/assistantApiSurfaceHeader.test.js +64 -0
  48. package/test/assistantResource.test.js +53 -0
  49. package/test/assistantSettingsResource.test.js +48 -0
  50. package/test/assistantSettingsService.test.js +133 -0
  51. package/test/chatService.test.js +841 -0
  52. package/test/descriptorSurfaceOption.test.js +35 -0
  53. package/test/queryKeys.test.js +41 -0
  54. package/test/resolveWorkspaceSlug.test.js +83 -0
  55. package/test/routeInputContracts.test.js +287 -0
  56. package/test/serviceToolCatalog.test.js +1235 -0
  57. package/test/transcriptService.test.js +175 -0
@@ -0,0 +1,71 @@
1
+ <template>
2
+ <AssistantSettingsFormCard
3
+ root-class="assistant-console-settings-client-element"
4
+ title="Assistant console settings"
5
+ subtitle="Configure the prompt used on workspace/admin assistant surfaces."
6
+ no-permission-message="You do not have permission to view assistant console settings."
7
+ save-label="Save assistant console settings"
8
+ :add-edit="addEdit"
9
+ :show-form-skeleton="showFormSkeleton"
10
+ >
11
+ <v-textarea
12
+ v-model="form.workspaceSurfacePrompt"
13
+ label="Workspace/Admin surface prompt"
14
+ variant="outlined"
15
+ density="comfortable"
16
+ rows="6"
17
+ auto-grow
18
+ :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
19
+ :error-messages="addEdit.fieldErrors.workspaceSurfacePrompt ? [addEdit.fieldErrors.workspaceSurfacePrompt] : []"
20
+ />
21
+ </AssistantSettingsFormCard>
22
+ </template>
23
+
24
+ <script setup>
25
+ import { computed, reactive } from "vue";
26
+ import { validateOperationSection } from "@jskit-ai/http-runtime/shared/validators/operationValidation";
27
+ import { useAddEdit } from "@jskit-ai/users-web/client/composables/useAddEdit";
28
+ import AssistantSettingsFormCard from "./AssistantSettingsFormCard.vue";
29
+ import { assistantConsoleSettingsResource } from "../../shared/assistantSettingsResource.js";
30
+ import { ASSISTANT_CONSOLE_SETTINGS_CHANGED_EVENT } from "../../shared/settingsEvents.js";
31
+
32
+ const form = reactive({
33
+ workspaceSurfacePrompt: ""
34
+ });
35
+
36
+ const addEdit = useAddEdit({
37
+ visibility: "public",
38
+ access: "never",
39
+ resource: assistantConsoleSettingsResource,
40
+ apiSuffix: "/console/settings/assistant",
41
+ queryKeyFactory: () => ["assistant", "settings", "console"],
42
+ viewPermissions: [],
43
+ savePermissions: [],
44
+ writeMethod: "PATCH",
45
+ placementSource: "assistant.console-settings-view",
46
+ fallbackLoadError: "Unable to load assistant console settings.",
47
+ fallbackSaveError: "Unable to update assistant console settings.",
48
+ fieldErrorKeys: ["workspaceSurfacePrompt"],
49
+ realtime: {
50
+ event: ASSISTANT_CONSOLE_SETTINGS_CHANGED_EVENT
51
+ },
52
+ model: form,
53
+ parseInput: (rawPayload) =>
54
+ validateOperationSection({
55
+ operation: assistantConsoleSettingsResource.operations.patch,
56
+ section: "bodyValidator",
57
+ value: rawPayload
58
+ }),
59
+ mapLoadedToModel(model, payload = {}) {
60
+ const settings = payload?.settings && typeof payload.settings === "object" ? payload.settings : {};
61
+ model.workspaceSurfacePrompt = String(settings.workspaceSurfacePrompt || "");
62
+ },
63
+ buildRawPayload(model) {
64
+ return {
65
+ workspaceSurfacePrompt: model.workspaceSurfacePrompt
66
+ };
67
+ }
68
+ });
69
+
70
+ const showFormSkeleton = computed(() => Boolean(addEdit.isInitialLoading));
71
+ </script>
@@ -0,0 +1,76 @@
1
+ <template>
2
+ <section :class="props.rootClass">
3
+ <v-card rounded="lg" elevation="1" border>
4
+ <v-card-item>
5
+ <v-card-title class="text-h6">{{ props.title }}</v-card-title>
6
+ <v-card-subtitle>{{ props.subtitle }}</v-card-subtitle>
7
+ </v-card-item>
8
+ <v-divider />
9
+ <v-card-text class="pt-4">
10
+ <template v-if="props.showFormSkeleton">
11
+ <v-skeleton-loader type="text@2, list-item-two-line@4, button" />
12
+ </template>
13
+
14
+ <p v-else-if="props.addEdit.loadError" class="text-body-2 text-medium-emphasis mb-4">
15
+ {{ props.addEdit.loadError }}
16
+ </p>
17
+
18
+ <p v-else-if="!props.addEdit.canView" class="text-body-2 text-medium-emphasis mb-4">
19
+ {{ props.noPermissionMessage }}
20
+ </p>
21
+
22
+ <template v-else>
23
+ <v-form @submit.prevent="props.addEdit.submit" novalidate>
24
+ <v-progress-linear v-if="props.addEdit.isRefetching" indeterminate class="mb-4" />
25
+ <slot />
26
+ <div class="d-flex align-center justify-end ga-3 mt-2">
27
+ <v-btn
28
+ v-if="props.addEdit.canSave"
29
+ type="submit"
30
+ color="primary"
31
+ :loading="props.addEdit.isSaving"
32
+ :disabled="props.addEdit.isInitialLoading || props.addEdit.isRefetching"
33
+ >
34
+ {{ props.saveLabel }}
35
+ </v-btn>
36
+ <v-chip v-else color="secondary" label>Read-only</v-chip>
37
+ </div>
38
+ </v-form>
39
+ </template>
40
+ </v-card-text>
41
+ </v-card>
42
+ </section>
43
+ </template>
44
+
45
+ <script setup>
46
+ const props = defineProps({
47
+ rootClass: {
48
+ type: String,
49
+ required: true
50
+ },
51
+ title: {
52
+ type: String,
53
+ required: true
54
+ },
55
+ subtitle: {
56
+ type: String,
57
+ required: true
58
+ },
59
+ noPermissionMessage: {
60
+ type: String,
61
+ required: true
62
+ },
63
+ saveLabel: {
64
+ type: String,
65
+ required: true
66
+ },
67
+ addEdit: {
68
+ type: Object,
69
+ required: true
70
+ },
71
+ showFormSkeleton: {
72
+ type: Boolean,
73
+ default: false
74
+ }
75
+ });
76
+ </script>
@@ -0,0 +1,15 @@
1
+ <template>
2
+ <AssistantClientElement
3
+ :meta="runtime.meta"
4
+ :state="runtime.state"
5
+ :actions="runtime.actions"
6
+ :viewer="runtime.viewer.value"
7
+ />
8
+ </template>
9
+
10
+ <script setup>
11
+ import AssistantClientElement from "./AssistantClientElement.vue";
12
+ import { useAssistantWorkspaceRuntime } from "../composables/useAssistantWorkspaceRuntime.js";
13
+
14
+ const runtime = useAssistantWorkspaceRuntime();
15
+ </script>
@@ -0,0 +1,73 @@
1
+ <template>
2
+ <AssistantSettingsFormCard
3
+ root-class="assistant-workspace-settings-client-element"
4
+ title="Assistant workspace settings"
5
+ subtitle="Configure the prompt used on the app surface for this workspace."
6
+ no-permission-message="You do not have permission to view assistant workspace settings."
7
+ save-label="Save assistant workspace settings"
8
+ :add-edit="addEdit"
9
+ :show-form-skeleton="showFormSkeleton"
10
+ >
11
+ <v-textarea
12
+ v-model="form.appSurfacePrompt"
13
+ label="App surface prompt"
14
+ variant="outlined"
15
+ density="comfortable"
16
+ rows="6"
17
+ auto-grow
18
+ :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
19
+ :error-messages="addEdit.fieldErrors.appSurfacePrompt ? [addEdit.fieldErrors.appSurfacePrompt] : []"
20
+ />
21
+ </AssistantSettingsFormCard>
22
+ </template>
23
+
24
+ <script setup>
25
+ import { computed, reactive } from "vue";
26
+ import { validateOperationSection } from "@jskit-ai/http-runtime/shared/validators/operationValidation";
27
+ import { useAddEdit } from "@jskit-ai/users-web/client/composables/useAddEdit";
28
+ import { matchesCurrentWorkspaceEvent } from "@jskit-ai/users-web/client/support/realtimeWorkspace";
29
+ import AssistantSettingsFormCard from "./AssistantSettingsFormCard.vue";
30
+ import { assistantWorkspaceSettingsResource } from "../../shared/assistantSettingsResource.js";
31
+ import { ASSISTANT_WORKSPACE_SETTINGS_CHANGED_EVENT } from "../../shared/settingsEvents.js";
32
+
33
+ const form = reactive({
34
+ appSurfacePrompt: ""
35
+ });
36
+
37
+ const addEdit = useAddEdit({
38
+ visibility: "workspace",
39
+ resource: assistantWorkspaceSettingsResource,
40
+ apiSuffix: "/settings/assistant",
41
+ queryKeyFactory: (surfaceId = "", workspaceSlug = "") => ["assistant", "settings", "workspace", surfaceId, workspaceSlug],
42
+ viewPermissions: ["workspace.settings.view", "workspace.settings.update"],
43
+ savePermissions: ["workspace.settings.update"],
44
+ writeMethod: "PATCH",
45
+ placementSource: "assistant.workspace-settings-view",
46
+ fallbackLoadError: "Unable to load assistant workspace settings.",
47
+ fallbackSaveError: "Unable to update assistant workspace settings.",
48
+ fieldErrorKeys: ["appSurfacePrompt"],
49
+ realtime: {
50
+ event: ASSISTANT_WORKSPACE_SETTINGS_CHANGED_EVENT,
51
+ matches: ({ payload = {}, routeContext = {} } = {}) =>
52
+ matchesCurrentWorkspaceEvent(payload, routeContext?.workspaceSlugFromRoute?.value)
53
+ },
54
+ model: form,
55
+ parseInput: (rawPayload) =>
56
+ validateOperationSection({
57
+ operation: assistantWorkspaceSettingsResource.operations.patch,
58
+ section: "bodyValidator",
59
+ value: rawPayload
60
+ }),
61
+ mapLoadedToModel(model, payload = {}) {
62
+ const settings = payload?.settings && typeof payload.settings === "object" ? payload.settings : {};
63
+ model.appSurfacePrompt = String(settings.appSurfacePrompt || "");
64
+ },
65
+ buildRawPayload(model) {
66
+ return {
67
+ appSurfacePrompt: model.appSurfacePrompt
68
+ };
69
+ }
70
+ });
71
+
72
+ const showFormSkeleton = computed(() => Boolean(addEdit.isInitialLoading));
73
+ </script>