@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
@@ -22,7 +22,8 @@ async function withTempApp(run) {
22
22
  app: { id: "app", enabled: true, requiresWorkspace: false, accessPolicyId: "authenticated" },
23
23
  admin: { id: "admin", enabled: true, requiresWorkspace: true, accessPolicyId: "workspace_member" },
24
24
  console: { id: "console", enabled: true, requiresWorkspace: false, accessPolicyId: "console_owner" }
25
- }
25
+ },
26
+ assistantSurfaces: {}
26
27
  };
27
28
  `,
28
29
  "utf8"
@@ -45,12 +46,12 @@ async function withTempApp(run) {
45
46
  }
46
47
  }
47
48
 
48
- test("buildTemplateContext derives runtime, settings, and table placeholders from explicit surfaces", async () => {
49
+ test("buildTemplateContext derives per-surface placeholders from explicit surfaces", async () => {
49
50
  await withTempApp(async (appRoot) => {
50
51
  const context = await buildTemplateContext({
51
52
  appRoot,
52
53
  options: {
53
- "runtime-surface": "app",
54
+ surface: "app",
54
55
  "settings-surface": "console",
55
56
  "config-scope": "global",
56
57
  placement: "shell-layout:primary-menu",
@@ -58,55 +59,69 @@ test("buildTemplateContext derives runtime, settings, and table placeholders fro
58
59
  }
59
60
  });
60
61
 
61
- assert.equal(context.__ASSISTANT_RUNTIME_SURFACE_ID__, "app");
62
+ assert.equal(context.__ASSISTANT_SURFACE_ID__, "app");
62
63
  assert.equal(context.__ASSISTANT_SETTINGS_SURFACE_ID__, "console");
63
- assert.equal(context.__ASSISTANT_RUNTIME_SURFACE_REQUIRES_WORKSPACE__, "false");
64
- assert.equal(context.__ASSISTANT_SETTINGS_SURFACE_REQUIRES_WORKSPACE__, "false");
65
- assert.equal(context.__ASSISTANT_SETTINGS_SURFACE_REQUIRES_CONSOLE_OWNER__, "true");
66
64
  assert.equal(context.__ASSISTANT_CONFIG_SCOPE__, "global");
67
65
  assert.equal(context.__ASSISTANT_SETTINGS_HOST__, "console-settings");
68
- assert.equal(context.__ASSISTANT_CONVERSATIONS_TABLE__, "assistant_app_conversations");
69
- assert.equal(context.__ASSISTANT_MESSAGES_TABLE__, "assistant_app_messages");
66
+ assert.equal(context.__ASSISTANT_AI_CONFIG_PREFIX__, "APP_ASSISTANT");
70
67
  assert.equal(context.__ASSISTANT_MENU_PLACEMENT_HOST__, "shell-layout");
71
68
  assert.equal(context.__ASSISTANT_MENU_PLACEMENT_POSITION__, "primary-menu");
72
69
  assert.equal(context.__ASSISTANT_MENU_LABEL__, "Copilot");
70
+ assert.equal(context.__ASSISTANT_SETTINGS_MENU_WORKSPACE_SUFFIX__, "/settings/assistant");
71
+ assert.equal(context.__ASSISTANT_SETTINGS_MENU_NON_WORKSPACE_SUFFIX__, "/settings/assistant");
73
72
  });
74
73
  });
75
74
 
76
- test("buildTemplateContext rejects workspace config scope for non-workspace surfaces", async () => {
75
+ test("buildTemplateContext rejects workspace config scope for a non-workspace assistant surface", async () => {
77
76
  await withTempApp(async (appRoot) => {
78
77
  await assert.rejects(
79
78
  () =>
80
79
  buildTemplateContext({
81
80
  appRoot,
82
81
  options: {
83
- "runtime-surface": "app",
82
+ surface: "app",
84
83
  "settings-surface": "console",
85
84
  "config-scope": "workspace",
86
85
  placement: "shell-layout:primary-menu"
87
86
  }
88
87
  }),
89
- /config-scope "workspace" requires runtime surface "app" with requiresWorkspace=true/
88
+ /config-scope "workspace" requires surface "app" with requiresWorkspace=true/
90
89
  );
91
90
  });
92
91
  });
93
92
 
94
- test("buildTemplateContext accepts workspace config scope when both surfaces require workspace", async () => {
93
+ test("buildTemplateContext rejects duplicate assistant surfaces already configured in public config", async () => {
95
94
  await withTempApp(async (appRoot) => {
96
- const context = await buildTemplateContext({
97
- appRoot,
98
- options: {
99
- "runtime-surface": "admin",
100
- "settings-surface": "admin",
101
- "config-scope": "workspace",
102
- placement: "shell-layout:top-right"
103
- }
104
- });
95
+ await writeFile(
96
+ path.join(appRoot, "config", "public.js"),
97
+ `export const config = {
98
+ surfaceDefinitions: {
99
+ app: { id: "app", enabled: true, requiresWorkspace: false, accessPolicyId: "authenticated" },
100
+ console: { id: "console", enabled: true, requiresWorkspace: false, accessPolicyId: "console_owner" }
101
+ },
102
+ assistantSurfaces: {
103
+ app: {
104
+ settingsSurfaceId: "console",
105
+ configScope: "global"
106
+ }
107
+ }
108
+ };
109
+ `,
110
+ "utf8"
111
+ );
105
112
 
106
- assert.equal(context.__ASSISTANT_RUNTIME_SURFACE_REQUIRES_WORKSPACE__, "true");
107
- assert.equal(context.__ASSISTANT_SETTINGS_SURFACE_REQUIRES_WORKSPACE__, "true");
108
- assert.equal(context.__ASSISTANT_SETTINGS_HOST__, "admin-settings");
109
- assert.equal(context.__ASSISTANT_CONVERSATIONS_TABLE__, "assistant_admin_conversations");
110
- assert.equal(context.__ASSISTANT_MESSAGES_TABLE__, "assistant_admin_messages");
113
+ await assert.rejects(
114
+ () =>
115
+ buildTemplateContext({
116
+ appRoot,
117
+ options: {
118
+ surface: "app",
119
+ "settings-surface": "console",
120
+ "config-scope": "global",
121
+ placement: "shell-layout:primary-menu"
122
+ }
123
+ }),
124
+ /already has an assistant configured/
125
+ );
111
126
  });
112
127
  });
@@ -1,6 +1,4 @@
1
1
  import assert from "node:assert/strict";
2
- import { readFile } from "node:fs/promises";
3
- import path from "node:path";
4
2
  import test from "node:test";
5
3
  import descriptor from "../package.descriptor.mjs";
6
4
 
@@ -14,69 +12,42 @@ function findTextMutation(id) {
14
12
  return mutations.find((entry) => String(entry?.id || "") === id) || null;
15
13
  }
16
14
 
17
- test("assistant descriptor exposes generator options for runtime surface, settings surface, and config scope", () => {
15
+ test("assistant descriptor exposes per-surface generation options and depends on assistant-runtime", () => {
18
16
  assert.equal(descriptor.kind, "generator");
19
- assert.equal(descriptor.metadata?.generatorPrimarySubcommand, "install");
20
- assert.equal(descriptor.options?.["runtime-surface"]?.required, true);
17
+ assert.equal(descriptor.options?.surface?.required, true);
21
18
  assert.equal(descriptor.options?.["settings-surface"]?.required, true);
22
19
  assert.equal(descriptor.options?.["config-scope"]?.defaultValue, "global");
20
+ assert.equal(descriptor.options?.["ai-config-prefix"]?.required, false);
21
+ assert.deepEqual(descriptor.dependsOn, ["@jskit-ai/assistant-runtime"]);
23
22
  });
24
23
 
25
- test("assistant descriptor publishes install examples for the supported runtime/settings shapes", () => {
26
- const installMetadata = descriptor.metadata?.generatorSubcommands?.install || {};
27
- const examples = Array.isArray(installMetadata.examples) ? installMetadata.examples : [];
28
- const labels = examples.map((entry) => String(entry?.label || ""));
29
-
30
- assert.equal(examples.length, 4);
31
- assert.deepEqual(labels, [
32
- "App runtime, console settings, global config",
33
- "App runtime, app settings, global config",
34
- "Workspace runtime, console settings, global config",
35
- "Workspace runtime, workspace settings, workspace config"
36
- ]);
37
- });
38
-
39
- test("assistant descriptor installs generated local runtime files instead of shipping a framework runtime", () => {
24
+ test("assistant descriptor generates only assistant runtime/settings pages and no local runtime package", () => {
40
25
  const runtimePage = findFileMutation("assistant-page-runtime");
41
- const localPackageDescriptor = findFileMutation("assistant-local-package-descriptor");
42
- const configMigration = findFileMutation("assistant-config-initial-schema");
43
- const transcriptMigration = findFileMutation("assistant-transcripts-initial-schema");
26
+ const settingsPageStandard = findFileMutation("assistant-page-settings-standard");
27
+ const settingsPageAdmin = findFileMutation("assistant-page-settings-admin");
28
+ const fileMutations = Array.isArray(descriptor?.mutations?.files) ? descriptor.mutations.files : [];
44
29
 
45
- assert.equal(runtimePage?.toSurface, "${option:runtime-surface|lower}");
30
+ assert.equal(runtimePage?.toSurface, "${option:surface|lower}");
46
31
  assert.equal(runtimePage?.toSurfacePath, "assistant/index.vue");
47
- assert.equal(localPackageDescriptor?.to, "packages/assistant/package.descriptor.mjs");
48
- assert.equal(configMigration?.from, "templates/migrations/assistant_config_initial.cjs");
49
- assert.equal(transcriptMigration?.from, "templates/migrations/assistant_transcripts_initial.cjs");
32
+ assert.equal(settingsPageStandard?.toSurfacePath, "settings/${option:settings-route-path|path}/index.vue");
33
+ assert.equal(settingsPageAdmin?.toSurfacePath, "workspace/settings/${option:settings-route-path|path}/index.vue");
34
+ assert.equal(fileMutations.length, 3);
50
35
  });
51
36
 
52
- test("assistant descriptor targets runtime and settings placements through explicit surface options", () => {
37
+ test("assistant descriptor appends menu placement, settings menu placement, and per-surface config entries", () => {
53
38
  const menuPlacement = findTextMutation("assistant-placement-menu");
54
- const settingsPlacement = findTextMutation("assistant-settings-form-placement");
55
-
56
- assert.match(String(menuPlacement?.value || ""), /surfaces: \["\$\{option:runtime-surface\|lower\}"\]/);
57
- assert.match(String(menuPlacement?.value || ""), /workspaceSuffix: "__ASSISTANT_MENU_WORKSPACE_SUFFIX__"/);
58
- assert.match(String(menuPlacement?.value || ""), /nonWorkspaceSuffix: "__ASSISTANT_MENU_NON_WORKSPACE_SUFFIX__"/);
39
+ const settingsPlacement = findTextMutation("assistant-settings-menu-placement");
40
+ const publicConfig = findTextMutation("assistant-public-surface-config");
41
+ const serverConfig = findTextMutation("assistant-server-surface-config");
42
+ const envBlock = findTextMutation("assistant-ai-prefixed-env");
43
+
44
+ assert.match(String(menuPlacement?.value || ""), /assistant\.generated\.menu:\$\{option:surface\|lower\}/);
45
+ assert.match(String(menuPlacement?.value || ""), /surfaces: \["\$\{option:surface\|lower\}"\]/);
46
+ assert.match(String(settingsPlacement?.value || ""), /assistant\.generated\.settings\.menu:\$\{option:surface\|lower\}/);
59
47
  assert.match(String(settingsPlacement?.value || ""), /host: "__ASSISTANT_SETTINGS_HOST__"/);
60
- assert.match(String(settingsPlacement?.value || ""), /surfaces: \["\$\{option:settings-surface\|lower\}"\]/);
61
- assert.match(String(settingsPlacement?.value || ""), /componentToken: "assistant.web.settings.element"/);
62
- });
63
-
64
- test("assistant descriptor runtime deps use assistant-core and avoid workspace package coupling", () => {
65
- const runtimeDeps = descriptor?.mutations?.dependencies?.runtime || {};
66
- const assistantCorePackageJsonPath = path.resolve(
67
- path.dirname(new URL(import.meta.url).pathname),
68
- "..",
69
- "..",
70
- "assistant-core",
71
- "package.json"
72
- );
73
-
74
- return readFile(assistantCorePackageJsonPath, "utf8").then((source) => {
75
- const assistantCorePackageJson = JSON.parse(source);
76
-
77
- assert.equal(runtimeDeps["@local/assistant"], "file:packages/assistant");
78
- assert.equal(runtimeDeps["@jskit-ai/assistant-core"], assistantCorePackageJson.version);
79
- assert.equal(Object.hasOwn(runtimeDeps, "@jskit-ai/workspaces-core"), false);
80
- assert.equal(Object.hasOwn(runtimeDeps, "@jskit-ai/workspaces-web"), false);
81
- });
48
+ assert.match(String(settingsPlacement?.value || ""), /position: "primary-menu"/);
49
+ assert.match(String(publicConfig?.value || ""), /config\.assistantSurfaces\.\$\{option:surface\|lower\} = \{/);
50
+ assert.match(String(serverConfig?.value || ""), /config\.assistantServer\.\$\{option:surface\|lower\} = \{/);
51
+ assert.match(String(serverConfig?.value || ""), /aiConfigPrefix: "__ASSISTANT_AI_CONFIG_PREFIX__"/);
52
+ assert.match(String(envBlock?.value || ""), /__ASSISTANT_AI_CONFIG_PREFIX___AI_PROVIDER=\$\{option:ai-provider\}/);
82
53
  });
@@ -9,14 +9,16 @@ async function readTemplateFile(relativePath) {
9
9
  return readFile(path.join(packageRoot, relativePath), "utf8");
10
10
  }
11
11
 
12
- test("generated assistant client index exports the descriptor-declared client provider", async () => {
13
- const source = await readTemplateFile("templates/src/local-package/client/index.js");
12
+ test("assistant page template renders the shared runtime client element with an explicit surface id", async () => {
13
+ const source = await readTemplateFile("templates/src/pages/assistant/index.vue");
14
14
 
15
- assert.match(source, /export \{ AssistantClientProvider \} from "\.\/providers\/AssistantClientProvider\.js";/);
15
+ assert.match(source, /<AssistantSurfaceClientElement surface-id="__ASSISTANT_SURFACE_ID__" \/>/);
16
+ assert.match(source, /from "@jskit-ai\/assistant-runtime\/client"/);
16
17
  });
17
18
 
18
- test("generated assistant actions do not emit legacy action visibility fields", async () => {
19
- const source = await readTemplateFile("templates/src/local-package/server/actions.js");
19
+ test("assistant settings page template renders the shared runtime settings client element with the target surface id", async () => {
20
+ const source = await readTemplateFile("templates/src/pages/settings/assistant/index.vue");
20
21
 
21
- assert.doesNotMatch(source, /\bvisibility:/);
22
+ assert.match(source, /<AssistantSettingsClientElement target-surface-id="__ASSISTANT_SURFACE_ID__" \/>/);
23
+ assert.match(source, /from "@jskit-ai\/assistant-runtime\/client"/);
22
24
  });
@@ -1,25 +0,0 @@
1
- exports.up = async function up(knex) {
2
- const hasTable = await knex.schema.hasTable("__ASSISTANT_CONFIG_TABLE__");
3
- if (!hasTable) {
4
- await knex.schema.createTable("__ASSISTANT_CONFIG_TABLE__", (table) => {
5
- table.increments("id").unsigned().primary();
6
- table.string("target_surface_id", 64).notNullable();
7
- table.string("scope_key", 160).notNullable();
8
- table.integer("workspace_id").unsigned().nullable();
9
- if ("__ASSISTANT_CONFIG_SCOPE__" === "workspace") {
10
- table.foreign("workspace_id").references("id").inTable("workspaces").onDelete("CASCADE");
11
- }
12
- table.text("system_prompt").notNullable().defaultTo("");
13
- table.timestamp("created_at").notNullable().defaultTo(knex.fn.now());
14
- table.timestamp("updated_at").notNullable().defaultTo(knex.fn.now());
15
-
16
- table.unique(["target_surface_id", "scope_key"], "uq___ASSISTANT_CONFIG_TABLE___target_surface_scope");
17
- table.index(["target_surface_id"], "idx___ASSISTANT_CONFIG_TABLE___target_surface");
18
- table.index(["workspace_id"], "idx___ASSISTANT_CONFIG_TABLE___workspace");
19
- });
20
- }
21
- };
22
-
23
- exports.down = async function down(knex) {
24
- await knex.schema.dropTableIfExists("__ASSISTANT_CONFIG_TABLE__");
25
- };
@@ -1,56 +0,0 @@
1
- exports.up = async function up(knex) {
2
- const hasConversationsTable = await knex.schema.hasTable("__ASSISTANT_CONVERSATIONS_TABLE__");
3
- if (!hasConversationsTable) {
4
- await knex.schema.createTable("__ASSISTANT_CONVERSATIONS_TABLE__", (table) => {
5
- table.increments("id").unsigned().primary();
6
- table.integer("workspace_id").unsigned().nullable();
7
- if (__ASSISTANT_RUNTIME_SURFACE_REQUIRES_WORKSPACE__) {
8
- table.foreign("workspace_id").references("id").inTable("workspaces").onDelete("CASCADE");
9
- }
10
- table.integer("created_by_user_id").unsigned().nullable().references("id").inTable("users").onDelete("SET NULL").index();
11
- table.string("title", 160).notNullable().defaultTo("New conversation");
12
- table.string("status", 32).notNullable().defaultTo("active");
13
- table.string("provider", 64).notNullable().defaultTo("");
14
- table.string("model", 128).notNullable().defaultTo("");
15
- table.string("surface_id", 32).notNullable().defaultTo("__ASSISTANT_RUNTIME_SURFACE_ID__");
16
- table.integer("message_count").unsigned().notNullable().defaultTo(0);
17
- table.text("metadata_json").nullable();
18
- table.timestamp("started_at").notNullable().defaultTo(knex.fn.now());
19
- table.timestamp("ended_at").nullable();
20
- table.timestamp("created_at").notNullable().defaultTo(knex.fn.now());
21
- table.timestamp("updated_at").notNullable().defaultTo(knex.fn.now());
22
-
23
- table.index(["workspace_id", "started_at"], "idx___ASSISTANT_CONVERSATIONS_TABLE___workspace_started_at");
24
- table.index(["created_by_user_id", "started_at"], "idx___ASSISTANT_CONVERSATIONS_TABLE___creator_started_at");
25
- });
26
- }
27
-
28
- const hasMessagesTable = await knex.schema.hasTable("__ASSISTANT_MESSAGES_TABLE__");
29
- if (!hasMessagesTable) {
30
- await knex.schema.createTable("__ASSISTANT_MESSAGES_TABLE__", (table) => {
31
- table.increments("id").unsigned().primary();
32
- table.integer("conversation_id").unsigned().notNullable().references("id").inTable("__ASSISTANT_CONVERSATIONS_TABLE__").onDelete("CASCADE");
33
- table.integer("workspace_id").unsigned().nullable();
34
- if (__ASSISTANT_RUNTIME_SURFACE_REQUIRES_WORKSPACE__) {
35
- table.foreign("workspace_id").references("id").inTable("workspaces").onDelete("CASCADE");
36
- }
37
- table.integer("seq").unsigned().notNullable();
38
- table.string("role", 32).notNullable();
39
- table.string("kind", 32).notNullable().defaultTo("chat");
40
- table.string("client_message_sid", 128).notNullable().defaultTo("");
41
- table.integer("actor_user_id").unsigned().nullable().references("id").inTable("users").onDelete("SET NULL").index();
42
- table.text("content_text").nullable();
43
- table.text("metadata_json").nullable();
44
- table.timestamp("created_at").notNullable().defaultTo(knex.fn.now());
45
-
46
- table.unique(["conversation_id", "seq"], "uq___ASSISTANT_MESSAGES_TABLE___conversation_seq");
47
- table.index(["conversation_id", "created_at"], "idx___ASSISTANT_MESSAGES_TABLE___conversation_created_at");
48
- table.index(["workspace_id"], "idx___ASSISTANT_MESSAGES_TABLE___workspace");
49
- });
50
- }
51
- };
52
-
53
- exports.down = async function down(knex) {
54
- await knex.schema.dropTableIfExists("__ASSISTANT_MESSAGES_TABLE__");
55
- await knex.schema.dropTableIfExists("__ASSISTANT_CONVERSATIONS_TABLE__");
56
- };
@@ -1,88 +0,0 @@
1
- <template>
2
- <AssistantSettingsFormCard
3
- root-class="assistant-settings-client-element"
4
- title="Assistant settings"
5
- :subtitle="subtitle"
6
- no-permission-message="You do not have permission to view assistant settings."
7
- save-label="Save assistant settings"
8
- :add-edit="addEdit"
9
- :show-form-skeleton="showFormSkeleton"
10
- >
11
- <v-textarea
12
- v-model="form.systemPrompt"
13
- label="System prompt"
14
- variant="outlined"
15
- density="comfortable"
16
- rows="8"
17
- auto-grow
18
- :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
19
- :error-messages="addEdit.fieldErrors.systemPrompt ? [addEdit.fieldErrors.systemPrompt] : []"
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 { AssistantSettingsFormCard } from "@jskit-ai/assistant-core/client";
28
- import {
29
- assistantConfigResource,
30
- assistantSettingsQueryKey
31
- } from "@jskit-ai/assistant-core/shared";
32
- import { useAddEdit } from "@jskit-ai/users-web/client/composables/useAddEdit";
33
- import { assistantRuntimeConfig } from "../../shared/assistantRuntimeConfig.js";
34
-
35
- const form = reactive({
36
- systemPrompt: ""
37
- });
38
-
39
- const subtitle = computed(() => {
40
- if (assistantRuntimeConfig.configScope === "workspace") {
41
- return `Configure the prompt used on the ${assistantRuntimeConfig.runtimeSurfaceId} surface for this workspace.`;
42
- }
43
-
44
- return `Configure the prompt used on the ${assistantRuntimeConfig.runtimeSurfaceId} surface.`;
45
- });
46
-
47
- const addEdit = useAddEdit({
48
- ownershipFilter: assistantRuntimeConfig.settingsSurfaceRequiresWorkspace ? "workspace" : "public",
49
- surfaceId: assistantRuntimeConfig.settingsSurfaceId,
50
- access: "auto",
51
- resource: assistantConfigResource,
52
- apiSuffix: "/assistant/settings",
53
- queryKeyFactory: (_surfaceId = "", workspaceSlug = "") =>
54
- assistantSettingsQueryKey({
55
- targetSurfaceId: assistantRuntimeConfig.runtimeSurfaceId,
56
- workspaceSlug
57
- }),
58
- viewPermissions: assistantRuntimeConfig.settingsSurfaceRequiresWorkspace
59
- ? ["workspace.settings.view", "workspace.settings.update"]
60
- : [],
61
- savePermissions: assistantRuntimeConfig.settingsSurfaceRequiresWorkspace
62
- ? ["workspace.settings.update"]
63
- : [],
64
- writeMethod: "PATCH",
65
- placementSource: "assistant.settings-view",
66
- fallbackLoadError: "Unable to load assistant settings.",
67
- fallbackSaveError: "Unable to update assistant settings.",
68
- fieldErrorKeys: ["systemPrompt"],
69
- model: form,
70
- parseInput: (rawPayload) =>
71
- validateOperationSection({
72
- operation: assistantConfigResource.operations.patch,
73
- section: "bodyValidator",
74
- value: rawPayload
75
- }),
76
- mapLoadedToModel(model, payload = {}) {
77
- const settings = payload?.settings && typeof payload.settings === "object" ? payload.settings : {};
78
- model.systemPrompt = String(settings.systemPrompt || "");
79
- },
80
- buildRawPayload(model) {
81
- return {
82
- systemPrompt: model.systemPrompt
83
- };
84
- }
85
- });
86
-
87
- const showFormSkeleton = computed(() => Boolean(addEdit.isInitialLoading));
88
- </script>
@@ -1,10 +0,0 @@
1
- <template>
2
- <AssistantClientElement v-bind="runtime" />
3
- </template>
4
-
5
- <script setup>
6
- import { AssistantClientElement } from "@jskit-ai/assistant-core/client";
7
- import { useAssistantRuntime } from "../composables/useAssistantRuntime.js";
8
-
9
- const runtime = useAssistantRuntime();
10
- </script>