@jskit-ai/assistant-core 0.1.223 → 0.1.225

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/examples/conversation/package.json +1 -1
  2. package/fixtures/responsive-assistant/DeliveryFixture.vue +3 -2
  3. package/package.json +1 -1
  4. package/src/client/conversation/AssistantGoalControl.vue +8 -8
  5. package/src/client/conversation/AssistantTranscript.vue +6 -4
  6. package/src/server/conversation/agentRun.js +12 -0
  7. package/src/server/conversation/claudeHistory.js +9 -3
  8. package/src/server/conversation/claudeProcess.js +60 -20
  9. package/src/server/conversation/claudeTurn.js +190 -41
  10. package/src/server/conversation/codexProvider.js +67 -3
  11. package/src/server/conversation/index.js +2 -2
  12. package/src/server/conversation/openCodeRuntime.js +8 -4
  13. package/src/server/conversation/providers/claude.js +5 -1
  14. package/src/server/conversation/providers/claudeDriver.js +5 -1
  15. package/src/server/conversation/providers/codex.js +325 -216
  16. package/src/server/conversation/providers/codexDriver.js +14 -1
  17. package/src/server/conversation/providers/scoped.js +39 -23
  18. package/src/server/conversation/runtime.js +20 -1
  19. package/src/server/conversation/runtimeStateUpgrade.js +42 -0
  20. package/test/claudeConversationSession.test.js +3 -2
  21. package/test/claudeProcess.test.js +139 -1
  22. package/test/claudeTurn.test.js +253 -3
  23. package/test/codexConversationSession.test.js +27 -4
  24. package/test/codexGoal.test.js +152 -0
  25. package/test/conversationRuntime.test.js +168 -4
  26. package/test/conversationRuntimeStateUpgrade.test.js +69 -1
  27. package/test/conversationSession.test.js +48 -0
  28. package/test/messageDelivery.browser.test.js +15 -0
  29. package/test/openCodeRuntime.test.js +71 -1
@@ -248,10 +248,13 @@ export function createOpenCodeSharedRuntime({ onStop = () => {}, scope } = {}) {
248
248
  currentConnection?.fingerprint === selected.fingerprint &&
249
249
  currentConnection?.endpointCode === selected.endpointCode
250
250
  )) {
251
+ const probe = AbortSignal.timeout(1_000);
251
252
  try {
252
- await sharedProcess.server.client.health({ signal: AbortSignal.timeout(1_000) });
253
+ await sharedProcess.server.client.health({ signal: probe });
253
254
  return sharedProcess;
254
- } catch {
255
+ } catch (error) {
256
+ // A slow probe is not proof that the shared server stopped working.
257
+ if (probe.aborted) throw error;
255
258
  requireConnectionAvailable();
256
259
  await stop("opencode-health-check-failed");
257
260
  }
@@ -1567,12 +1570,13 @@ export function createOpenCodeSharedRuntime({ onStop = () => {}, scope } = {}) {
1567
1570
  const observedProcess = sharedProcess;
1568
1571
  const observedServer = target.server;
1569
1572
  let healthy = false;
1573
+ const probe = AbortSignal.timeout(1_000);
1570
1574
  try {
1571
- await target.server.client.health({ signal: AbortSignal.timeout(1_000) });
1575
+ await target.server.client.health({ signal: probe });
1572
1576
  healthy = true;
1573
1577
  ready = Boolean(await target.server.client.readSession(target.upstreamSessionId));
1574
1578
  } catch (error) {
1575
- if (healthy && error?.statusCode !== 404) {
1579
+ if ((!healthy && probe.aborted) || (healthy && error?.statusCode !== 404)) {
1576
1580
  throw error;
1577
1581
  }
1578
1582
  if (!healthy) {
@@ -9,6 +9,7 @@ export function createClaudeConversationAdapter({ getProcess, isActive, startPro
9
9
  let pending = Promise.resolve();
10
10
  let updateIdentity;
11
11
  let installedMode;
12
+ let installedPrompt;
12
13
 
13
14
  function instructionArguments({ systemPrompt, instructionMode = "append" }) {
14
15
  if (typeof systemPrompt !== "string" || !systemPrompt.trim()) throw new TypeError("Claude instructions must contain text.");
@@ -27,7 +28,9 @@ export function createClaudeConversationAdapter({ getProcess, isActive, startPro
27
28
  const instructionMode = input.instructionMode || "append";
28
29
  const contextIdentity = JSON.stringify([input.contextIdentity, instructionMode]);
29
30
  if (!getProcess()) instructions.invalidate();
30
- if (getProcess() && isActive() && !instructions.isCurrent({ systemPrompt, contextIdentity })) {
31
+ const canUpdate = getProcess() && installedPrompt === systemPrompt && installedMode === instructionMode &&
32
+ liveUpdateIdentity !== undefined && updateIdentity === liveUpdateIdentity;
33
+ if (getProcess() && isActive() && !canUpdate && !instructions.isCurrent({ systemPrompt, contextIdentity })) {
31
34
  throw new Error("Stop the current Claude turn before changing its settings.");
32
35
  }
33
36
  return instructions.ensure({
@@ -51,6 +54,7 @@ export function createClaudeConversationAdapter({ getProcess, isActive, startPro
51
54
  }
52
55
  updateIdentity = liveUpdateIdentity;
53
56
  installedMode = instructionMode;
57
+ installedPrompt = systemPrompt;
54
58
  return native;
55
59
  }
56
60
  });
@@ -271,6 +271,11 @@ export function createClaudeConversationDriver({ connections, host = {}, limits
271
271
  const entry = await native.owner.acquire(context);
272
272
  return native.owner.ensureReady(entry);
273
273
  },
274
+ async updateConversationSettings({ native, context, input }) {
275
+ const entry = await native.owner.acquire(context, input.threadId);
276
+ if (entry.process) await native.owner.ensureProcess(entry);
277
+ return { ok: true };
278
+ },
274
279
  disposeNative,
275
280
  async interruptDetachedConversation({ native, input, context }) {
276
281
  const entry = await native.owner.acquire(context, input.conversationId || input.threadId,
@@ -467,7 +472,6 @@ export function createClaudeConversationDriver({ connections, host = {}, limits
467
472
  result = await disposeNative({ native: supplied, options: scoped ? scoped.context : options });
468
473
  if (result?.ok === false) throw Object.assign(new Error(result.error || (scoped ? "Scoped cleanup could not be confirmed." : "Claude cleanup could not be confirmed.")), result);
469
474
  } else {
470
- await entry.nativeTurn.whenIdle().catch(() => {});
471
475
  for (const id of pendingAccountStops) await stopAccount(id);
472
476
  await owner.close(entry);
473
477
  }