@jskit-ai/assistant-runtime 0.2.12 → 0.2.14

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.
@@ -50,7 +50,20 @@ if (new URLSearchParams(window.location.search).has("applicationDefaults")) {
50
50
  otherApp.mount(otherRoot);
51
51
  },
52
52
  other() { return otherBinding.runtime.value; },
53
- unmountOtherApp() { otherApp.unmount(); otherRoot.remove(); }
53
+ unmountOtherApp() { otherApp.unmount(); otherRoot.remove(); },
54
+ // An application without realtime: returns what mounting a conversation there fails with.
55
+ mountWithoutSocket() {
56
+ let refusal = "";
57
+ const application = createApp({ setup() {
58
+ useAssistantConversation({ conversationId: "chat:1" });
59
+ return () => null;
60
+ } });
61
+ application.config.errorHandler = failure => { refusal = failure.message; };
62
+ application.provide("jskit.shell-web.runtime.web-placement.client", placement);
63
+ application.use(router);
64
+ application.mount(document.createElement("div"));
65
+ return refusal;
66
+ }
54
67
  };
55
68
  }
56
69
  app.provide("jskit.shell-web.runtime.web-placement.client", placement);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/assistant-runtime",
3
- "version": "0.2.12",
3
+ "version": "0.2.14",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test --test-concurrency=1"
@@ -14,19 +14,19 @@
14
14
  "./locales/en.json": "./locales/en.json"
15
15
  },
16
16
  "dependencies": {
17
- "@jskit-ai/assistant-core": "0.2.10",
17
+ "@jskit-ai/assistant-core": "0.2.12",
18
18
  "json-rest-schema": "^1.0.17"
19
19
  },
20
20
  "peerDependencies": {
21
- "@jskit-ai/http-runtime": "0.2.4",
22
- "@jskit-ai/http-web": "0.2.8",
23
- "@jskit-ai/kernel": "0.2.4",
24
- "@jskit-ai/realtime": "0.2.7",
25
- "@jskit-ai/shell-web": "0.2.4",
21
+ "@jskit-ai/http-runtime": "0.2.5",
22
+ "@jskit-ai/http-web": "0.2.10",
23
+ "@jskit-ai/kernel": "0.2.5",
24
+ "@jskit-ai/realtime": "0.2.9",
25
+ "@jskit-ai/shell-web": "0.2.6",
26
26
  "@tanstack/vue-query": "^5.90.5",
27
27
  "vue": "^3.5.13",
28
28
  "vuetify": "^4.0.0",
29
- "@jskit-ai/database-runtime": "0.1.253"
29
+ "@jskit-ai/database-runtime": "0.1.254"
30
30
  },
31
31
  "description": "Capability-based assistant runtime with per-surface chat, transcripts, settings, and action tools.",
32
32
  "jskit": {
@@ -16,7 +16,7 @@
16
16
  rows="8"
17
17
  auto-grow
18
18
  :readonly="!addEdit.canSave || addEdit.isSaving || addEdit.isRefetching"
19
- :error-messages="fieldErrors.systemPrompt ? [fieldErrors.systemPrompt] : []"
19
+ :error-messages="fieldErrors.systemPrompt"
20
20
  />
21
21
  </AssistantSettingsFormCard>
22
22
  </template>
@@ -4,7 +4,7 @@ import { retainAssistantConversation } from "@jskit-ai/assistant-core/client/con
4
4
  import { createAssistantTextSubmission } from "@jskit-ai/assistant-core/client/conversation";
5
5
  import { assistantHttpClient, createAssistantApi } from "@jskit-ai/assistant-core/client";
6
6
  import { conversationTurnsFromMessages } from "@jskit-ai/assistant-core/shared/conversation";
7
- import { useRealtimeSocket } from "@jskit-ai/realtime/client/composables/useRealtimeEvent";
7
+ import { NO_REALTIME_SOCKET, useRealtimeSocket } from "@jskit-ai/realtime/client/composables/useRealtimeEvent";
8
8
  import { SHELL_WEB_PLACEMENT_RUNTIME_KEY } from "@jskit-ai/shell-web/client/placement";
9
9
  import { useSurfaceRouteContext } from "@jskit-ai/shell-web/client/navigation/useSurfaceRouteContext";
10
10
  import { resolveAssistantRuntimeRoute, resolveAssistantSurfaceConfig } from "../../shared/assistantSurfaces.js";
@@ -206,6 +206,13 @@ function useBoundedTask({ command, endpoint, scope, input, result, onResult = ig
206
206
  return { runtime, adapter, error: computed(() => "") };
207
207
  }
208
208
 
209
+ /** The application's socket, for a binding given none: on the disabled socket a conversation would never hear its updates. */
210
+ function useRequiredRealtimeSocket() {
211
+ const socket = useRealtimeSocket();
212
+ if (socket === NO_REALTIME_SOCKET) throw new Error("Realtime client socket is not available in Vue injection context.");
213
+ return socket;
214
+ }
215
+
209
216
  /**
210
217
  * What a binding takes from the application's setup: the shell's route, placement and socket, and the application's
211
218
  * conversation defaults.
@@ -227,7 +234,7 @@ function conversationBindingSetup({ socket, boundedTask }) {
227
234
  routeContext,
228
235
  placement,
229
236
  workspaceScope: useWorkspaceWebScopeSupport(),
230
- socket: socket || useRealtimeSocket({ required: true }),
237
+ socket: socket || useRequiredRealtimeSocket(),
231
238
  config: getClientAppConfig()
232
239
  };
233
240
  }
@@ -1,7 +1,7 @@
1
1
  // The types the assistant runtime's client hands out and receives across its files. Types assistant-core owns are
2
2
  // imported from `@jskit-ai/assistant-core/client/types` where they are used.
3
3
 
4
- /** @typedef {ReturnType<typeof import("@jskit-ai/realtime/client/composables/useRealtimeEvent").useRealtimeSocket>} RealtimeSocket The application's shared realtime socket. */
4
+ /** @typedef {import("@jskit-ai/realtime/client/types").RealtimeSocket} RealtimeSocket The application's shared realtime socket. */
5
5
  /** @typedef {ReturnType<typeof import("@jskit-ai/shell-web/client/navigation/useSurfaceRouteContext").useSurfaceRouteContext>} SurfaceRouteContext The current route's surface and placement context. */
6
6
 
7
7
  /**
@@ -2542,6 +2542,11 @@ test("saved prepared conversations can Stop before the first read while inactive
2542
2542
  }
2543
2543
  });
2544
2544
 
2545
+ test("a conversation in an application without the realtime socket refuses at once", options, async t => {
2546
+ const f = await fixture(t, 1280, { applicationDefaults: true });
2547
+ assert.match(await f.page.evaluate(() => window.conversationDefaultsFixture.mountWithoutSocket()), /Realtime client socket is not available/u);
2548
+ });
2549
+
2545
2550
  test("application defaults configure standard cards once while preserving overrides and actor isolation", options, async t => {
2546
2551
  const f = await fixture(t, 1280, { applicationDefaults: true });
2547
2552
  assert.equal(await f.page.evaluate(() => window.conversationFixture.current().identity.actorKey), "application-user");
@@ -174,7 +174,7 @@ async function fixture(t, { diagnostics = false, onSetup } = {}) {
174
174
  } });
175
175
  clients.push(socket);
176
176
  clientSessions.set(socket, session);
177
- if (recovery) cleanups.push(attachSocketConnectionRecovery(socket));
177
+ if (recovery) cleanups.push(attachSocketConnectionRecovery(socket, { prepareReconnect() {} }));
178
178
  await new Promise((resolve, reject) => {
179
179
  const timer = setTimeout(() => finish(new Error("Socket connection timed out.")), 5_000);
180
180
  const connected = () => finish();