@jskit-ai/assistant-core 0.2.7 → 0.2.8

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 (214) hide show
  1. package/examples/conversation/package.json +5 -5
  2. package/package.json +18 -7
  3. package/src/client/browser.js +21 -0
  4. package/src/client/conversation/AssistantAttachmentQueue.vue +25 -108
  5. package/src/client/conversation/AssistantComposerActions.vue +1 -1
  6. package/src/client/conversation/AssistantConversationElement.vue +14 -52
  7. package/src/client/conversation/AssistantGoalControl.vue +13 -10
  8. package/src/client/conversation/AssistantPromptInput.vue +6 -91
  9. package/src/client/conversation/AssistantTranscript.css +505 -0
  10. package/src/client/conversation/AssistantTranscript.vue +24 -1197
  11. package/src/client/conversation/attachmentFiles.js +158 -0
  12. package/src/client/conversation/attachmentQueueItems.js +121 -0
  13. package/src/client/conversation/attachmentUploadRows.js +265 -0
  14. package/src/client/conversation/conversationDisplay.js +54 -0
  15. package/src/client/conversation/messageDelivery.js +13 -9
  16. package/src/client/conversation/retainedConversation.js +14 -3
  17. package/src/client/conversation/submitText.js +13 -2
  18. package/src/client/conversation/transcriptEntries.js +225 -0
  19. package/src/client/conversation/useAssistantAttachments.js +86 -388
  20. package/src/client/conversation/useAssistantQuestions.js +16 -3
  21. package/src/client/conversation/useAssistantSuggestions.js +16 -2
  22. package/src/client/conversation/useScrollToBottom.js +17 -19
  23. package/src/client/conversation/useTextareaAutoGrow.js +115 -0
  24. package/src/client/conversation/useTranscriptScrollFollow.js +525 -0
  25. package/src/client/lib/assistantApi.js +192 -161
  26. package/src/client/types.js +110 -0
  27. package/src/server/conversation/attachments.js +21 -6
  28. package/src/server/conversation/boundedToolLoop.js +1 -0
  29. package/src/server/conversation/claudeClient.js +71 -20
  30. package/src/server/conversation/claudeCommandRun.js +191 -0
  31. package/src/server/conversation/claudeHistory.js +7 -0
  32. package/src/server/conversation/claudeNativeTurn.js +708 -0
  33. package/src/server/conversation/claudeProcess.js +186 -112
  34. package/src/server/conversation/claudeProcessStart.js +214 -0
  35. package/src/server/conversation/claudePromptDelivery.js +183 -0
  36. package/src/server/conversation/claudeSessionCleanup.js +248 -0
  37. package/src/server/conversation/claudeTools.js +15 -3
  38. package/src/server/conversation/claudeTurn.js +212 -1388
  39. package/src/server/conversation/codexAccountReader.js +168 -0
  40. package/src/server/conversation/codexAuthPreflight.js +5 -4
  41. package/src/server/conversation/codexClient.js +18 -6
  42. package/src/server/conversation/codexConfiguration.js +8 -844
  43. package/src/server/conversation/codexConversationStops.js +377 -0
  44. package/src/server/conversation/codexConversationStore.js +119 -85
  45. package/src/server/conversation/codexConversationTurns.js +378 -0
  46. package/src/server/conversation/codexConversations.js +134 -866
  47. package/src/server/conversation/codexDetachedConversation.js +203 -0
  48. package/src/server/conversation/codexDetachedTurn.js +145 -104
  49. package/src/server/conversation/codexEvents.js +5 -200
  50. package/src/server/conversation/codexGoalCommands.js +14 -4
  51. package/src/server/conversation/codexHelperExecution.js +57 -57
  52. package/src/server/conversation/codexHelperThreadLedger.js +30 -288
  53. package/src/server/conversation/codexHelperThreadRecord.js +304 -0
  54. package/src/server/conversation/codexHelperThreadRecovery.js +54 -76
  55. package/src/server/conversation/codexHelperThreads.js +94 -93
  56. package/src/server/conversation/codexHistoryAdapter.js +13 -8
  57. package/src/server/conversation/codexIsolation.js +672 -0
  58. package/src/server/conversation/codexLiveItems.js +379 -0
  59. package/src/server/conversation/codexMessageCommands.js +68 -286
  60. package/src/server/conversation/codexMessageDelivery.js +46 -37
  61. package/src/server/conversation/codexModelCatalog.js +86 -7
  62. package/src/server/conversation/codexNotificationObserver.js +81 -88
  63. package/src/server/conversation/codexNotificationQueue.js +21 -10
  64. package/src/server/conversation/codexObservationControl.js +105 -89
  65. package/src/server/conversation/codexOutput.js +84 -419
  66. package/src/server/conversation/codexProcess.js +29 -1053
  67. package/src/server/conversation/codexProcessLeader.js +1 -0
  68. package/src/server/conversation/codexPromptDispatch.js +241 -0
  69. package/src/server/conversation/codexProvider.js +147 -1807
  70. package/src/server/conversation/codexProviderAuth.js +348 -0
  71. package/src/server/conversation/codexProviderInvalidation.js +371 -0
  72. package/src/server/conversation/codexProviderInventories.js +437 -0
  73. package/src/server/conversation/codexProviderOwner.js +149 -957
  74. package/src/server/conversation/codexProviderRelease.js +465 -0
  75. package/src/server/conversation/codexProviderSelection.js +26 -15
  76. package/src/server/conversation/codexProviderThreads.js +698 -0
  77. package/src/server/conversation/codexProviderTurns.js +453 -0
  78. package/src/server/conversation/codexReasoning.js +32 -23
  79. package/src/server/conversation/codexRenewalCommands.js +18 -6
  80. package/src/server/conversation/codexRenewalThreads.js +7 -22
  81. package/src/server/conversation/codexResultSettlement.js +70 -88
  82. package/src/server/conversation/codexRunJournal.js +91 -97
  83. package/src/server/conversation/codexRuntime.js +426 -0
  84. package/src/server/conversation/codexRuntimeInventory.js +113 -0
  85. package/src/server/conversation/codexRuntimeLifecycle.js +39 -13
  86. package/src/server/conversation/codexRuntimeStart.js +431 -0
  87. package/src/server/conversation/codexRuntimeStop.js +324 -0
  88. package/src/server/conversation/codexSessionCleanup.js +25 -10
  89. package/src/server/conversation/codexSessionReconciliation.js +21 -7
  90. package/src/server/conversation/codexThreadReadiness.js +49 -52
  91. package/src/server/conversation/codexThreadSnapshot.js +210 -0
  92. package/src/server/conversation/codexThreadStatus.js +48 -62
  93. package/src/server/conversation/codexTurn.js +171 -55
  94. package/src/server/conversation/codexTurnActivity.js +210 -0
  95. package/src/server/conversation/codexTurnControl.js +44 -48
  96. package/src/server/conversation/codexTurnEndings.js +610 -0
  97. package/src/server/conversation/codexTurnRecovery.js +97 -848
  98. package/src/server/conversation/codexTurnState.js +138 -111
  99. package/src/server/conversation/completedResponses.js +227 -0
  100. package/src/server/conversation/configuration.js +2 -2
  101. package/src/server/conversation/continuity.js +43 -6
  102. package/src/server/conversation/conversationDelivery.js +394 -0
  103. package/src/server/conversation/conversationEntries.js +365 -0
  104. package/src/server/conversation/conversationEvents.js +192 -0
  105. package/src/server/conversation/conversationGoals.js +187 -0
  106. package/src/server/conversation/conversationHandles.js +237 -0
  107. package/src/server/conversation/conversationReads.js +206 -0
  108. package/src/server/conversation/conversationRefusals.js +58 -0
  109. package/src/server/conversation/conversationReplacement.js +254 -0
  110. package/src/server/conversation/conversationSending.js +273 -0
  111. package/src/server/conversation/conversationStopping.js +121 -0
  112. package/src/server/conversation/conversationTurnDelivery.js +413 -0
  113. package/src/server/conversation/conversationTurns.js +511 -0
  114. package/src/server/conversation/deliveryTiming.js +25 -3
  115. package/src/server/conversation/fileStorage.js +11 -6
  116. package/src/server/conversation/hookBridge.js +14 -3
  117. package/src/server/conversation/index.js +1 -1
  118. package/src/server/conversation/localExecution.js +82 -625
  119. package/src/server/conversation/nativeCommandCallbacks.js +10 -0
  120. package/src/server/conversation/nativeConversationLifecycle.js +379 -0
  121. package/src/server/conversation/nativeHistoryExport.js +27 -18
  122. package/src/server/conversation/normalize.js +9 -0
  123. package/src/server/conversation/openCodeClient.js +295 -366
  124. package/src/server/conversation/openCodeNativeHistory.js +141 -0
  125. package/src/server/conversation/openCodeNativeSession.js +79 -0
  126. package/src/server/conversation/openCodeProcess.js +109 -53
  127. package/src/server/conversation/openCodeProcessOwner.js +565 -0
  128. package/src/server/conversation/openCodeRuntime.js +111 -1814
  129. package/src/server/conversation/openCodeSessionTurns.js +547 -0
  130. package/src/server/conversation/openCodeTemporaryConversations.js +394 -0
  131. package/src/server/conversation/openCodeTools.js +28 -14
  132. package/src/server/conversation/openCodeTurn.js +80 -74
  133. package/src/server/conversation/openCodeTurnMonitor.js +388 -0
  134. package/src/server/conversation/processIdentity.js +582 -0
  135. package/src/server/conversation/provider.js +21 -6
  136. package/src/server/conversation/providers/api.js +268 -107
  137. package/src/server/conversation/providers/claude.js +29 -6
  138. package/src/server/conversation/providers/claudeDriver.js +325 -250
  139. package/src/server/conversation/providers/codex.js +69 -33
  140. package/src/server/conversation/providers/codexDriver.js +503 -1081
  141. package/src/server/conversation/providers/codexDriverConnection.js +331 -0
  142. package/src/server/conversation/providers/codexDriverTurns.js +464 -0
  143. package/src/server/conversation/providers/opencode.js +30 -4
  144. package/src/server/conversation/providers/opencodeDriver.js +321 -659
  145. package/src/server/conversation/providers/opencodeStandalone.js +475 -0
  146. package/src/server/conversation/providers/scoped.js +64 -19
  147. package/src/server/conversation/runtime.js +171 -2863
  148. package/src/server/conversation/storage.js +91 -50
  149. package/src/server/conversation/streams.js +15 -2
  150. package/src/server/conversation/structuredOutput.js +7 -11
  151. package/src/server/conversation/systemPrompt.js +13 -1
  152. package/src/server/conversation/tools.js +47 -15
  153. package/src/server/conversation/transcript.js +49 -20
  154. package/src/server/hosts/claudeTurn.js +2 -4
  155. package/src/server/hosts/codexConfiguration.js +6 -8
  156. package/src/server/hosts/codexEvents.js +4 -2
  157. package/src/server/hosts/codexProcess.js +1 -1
  158. package/src/server/hosts/codexProvider.js +11 -9
  159. package/src/server/hosts/codexTurn.js +3 -3
  160. package/src/server/hosts/openCodeClient.js +4 -2
  161. package/src/server/index.js +0 -2
  162. package/src/server/lib/aiConnectionClient.js +35 -25
  163. package/src/server/lib/ndjson.js +1 -0
  164. package/src/server/lib/providers/anthropicClient.js +15 -6
  165. package/src/server/lib/providers/common.js +10 -6
  166. package/src/server/lib/providers/openAiCompatibleClient.js +40 -23
  167. package/src/server/lib/serviceToolCatalog.js +29 -283
  168. package/src/server/lib/serviceToolEntries.js +270 -0
  169. package/src/server/types.js +78 -0
  170. package/src/shared/assistantResource.js +0 -23
  171. package/src/shared/conversation/answerChoiceSugar.js +2 -14
  172. package/src/shared/conversation/messageInputSugar.js +18 -0
  173. package/src/shared/conversation/numberedQuestionSugar.js +6 -16
  174. package/src/shared/conversation/pagination.js +1 -1
  175. package/src/shared/conversation/questions.js +1 -0
  176. package/src/shared/conversation/streaming.js +1 -0
  177. package/src/shared/index.js +0 -1
  178. package/src/testing/conversationStorageContract.js +20 -0
  179. package/test/aiConnectionClient.test.js +42 -1
  180. package/test/apiConversationDriver.test.js +217 -38
  181. package/test/assistantBoundedToolLoop.test.js +1 -1
  182. package/test/claudeConversationSession.test.js +15 -11
  183. package/test/claudeInstructionResume.test.js +1 -1
  184. package/test/claudeProcess.test.js +9 -9
  185. package/test/claudeTurn.test.js +21 -8
  186. package/test/codexAccountChange.test.js +5 -3
  187. package/test/codexConversationSession.test.js +22 -21
  188. package/test/codexEvents.test.js +3 -1
  189. package/test/codexHelperDeletion.test.js +3 -7
  190. package/test/codexIsolation.test.js +6 -6
  191. package/test/codexModelCatalog.test.js +6 -7
  192. package/test/codexProcess.test.js +3 -3
  193. package/test/codexThreadSelection.test.js +4 -1
  194. package/test/codexTurn.test.js +29 -20
  195. package/test/conversationApiFacilities.test.js +11 -9
  196. package/test/conversationAttachments.test.js +3 -3
  197. package/test/conversationConfiguration.test.js +4 -4
  198. package/test/conversationNativeStorage.test.js +11 -10
  199. package/test/conversationReplacement.test.js +13 -13
  200. package/test/conversationRuntime.test.js +9 -5
  201. package/test/conversationSession.test.js +78 -22
  202. package/test/conversationTools.test.js +47 -26
  203. package/test/fileConversationStorage.test.js +10 -3
  204. package/test/fixtures/codexHelperThreadLedger.js +3 -3
  205. package/test/frameworkActions.test.js +33 -18
  206. package/test/localConversationExecution.test.js +4 -4
  207. package/test/localExecution.test.js +1 -1
  208. package/test/openCodeConnectionChange.test.js +3 -2
  209. package/test/openCodeRuntime.test.js +8 -7
  210. package/test/openCodeTools.test.js +1 -1
  211. package/test/opencodeConversationSession.test.js +4 -3
  212. package/test/serviceToolCatalog.test.js +3 -8
  213. package/src/server/lib/assistantCompletion.js +0 -190
  214. package/src/server/lib/assistantToolLoop.js +0 -259
@@ -3,7 +3,33 @@ import { setTimeout as delay } from "node:timers/promises";
3
3
 
4
4
  const INSTRUCTION_REVISION_ENV = "JSKIT_CONVERSATION_INSTRUCTIONS";
5
5
 
6
- /** Codex native context restoration; host callbacks own resources and access. */
6
+ /**
7
+ * The host a Codex provider gives its conversation adapter: its client, runtime and request runner, and the steps
8
+ * that prepare, verify and record its threads.
9
+ * @typedef {object} CodexConversationAdapterHost
10
+ * @property {() => Promise<object>} client
11
+ * @property {() => object | null} runtime
12
+ * @property {<T>(run: () => Promise<T>, reason: string) => Promise<T>} runRequest
13
+ * @property {number} [timeoutMs]
14
+ * @property {Record<string, string>} [environment]
15
+ * @property {(params: object, threadId?: string) => Promise<string | null | undefined> | string | null | undefined} readInstructions
16
+ * @property {(environment: Record<string, string>) => Promise<Record<string, string>> | Record<string, string>} prepareEnvironment
17
+ * @property {(params: object) => Promise<object | undefined> | object | undefined} prepareParameters
18
+ * @property {(threadId: string, params: object, context: object) => Promise<object | undefined> | object | undefined} prepareResume
19
+ * @property {(threadId: string) => Promise<void> | void} beforeResume
20
+ * @property {(params: object, client: object, context: object) => Promise<object>} prepareHistory
21
+ * @property {(params: object, environment: Record<string, string>) => object} threadParameters
22
+ * @property {(...args: unknown[]) => Promise<void>} verifyEnvironment
23
+ * @property {(threadId: string, turnId: string) => void} recordInterruption
24
+ * @property {(threadId: string) => void} onRecoveryFailure
25
+ * @property {(threadId: string, goal: object) => void} publishGoal
26
+ * @property {(event: string, fields: object, context: object) => void} log
27
+ */
28
+
29
+ /**
30
+ * Codex native context restoration; host callbacks own resources and access.
31
+ * @param {CodexConversationAdapterHost} host
32
+ */
7
33
  export function createCodexConversationAdapter(host) {
8
34
  const bindings = new Map();
9
35
  // Losing a control binding does not erase an acknowledged prompt. Keeping
@@ -31,7 +57,7 @@ export function createCodexConversationAdapter(host) {
31
57
 
32
58
  async function prepareInstructions({ systemPrompt, ...params }, threadId) {
33
59
  if (systemPrompt === undefined && params.developerInstructions != null) return params;
34
- const supplied = systemPrompt ?? await host.readInstructions?.(params, threadId);
60
+ const supplied = systemPrompt ?? await host.readInstructions(params, threadId);
35
61
  if (supplied === undefined || supplied === null) return params;
36
62
  if (typeof supplied !== "string" || !supplied.trim()) throw new TypeError("Codex instructions must contain text.");
37
63
  return { ...params, developerInstructions: supplied };
@@ -75,7 +101,7 @@ export function createCodexConversationAdapter(host) {
75
101
  if (status !== "active") throw new Error("Codex's current turn could not be observed before changing settings.");
76
102
  if (!settings.deferred) {
77
103
  settings.deferred = true;
78
- try { host.log?.("settings_deferred", {}, { threadId }); } catch { /* Diagnostics do not own scheduling. */ }
104
+ try { host.log("settings_deferred", {}, { threadId }); } catch { /* Diagnostics do not own scheduling. */ }
79
105
  settings.accepted.resolve({ ok: true, pending: true });
80
106
  }
81
107
  await delay(250, undefined, { signal: settings.controller.signal });
@@ -83,7 +109,7 @@ export function createCodexConversationAdapter(host) {
83
109
  settings.prepared = true;
84
110
  }
85
111
  requestedSettings = settings.params;
86
- params = await host.prepareParameters?.(requestedSettings) || requestedSettings;
112
+ params = await host.prepareParameters(requestedSettings) || requestedSettings;
87
113
  }
88
114
  const requestedParams = params;
89
115
  const retainInstalledInstructions = bound?.params.developerInstructions != null && !params.ephemeral && !bound.params.ephemeral;
@@ -152,7 +178,7 @@ export function createCodexConversationAdapter(host) {
152
178
  // A restored observer has no saved request parameters. Recover the
153
179
  // native thread's provider configuration before resuming its controls.
154
180
  requestParams = { ...requestParams, modelProvider: nativeModelProvider };
155
- requestParams = await host.prepareParameters?.(requestParams) || requestParams;
181
+ requestParams = await host.prepareParameters(requestParams) || requestParams;
156
182
  }
157
183
  requestParams = await host.prepareHistory(requestParams, client, { signal, historyPath: nativeHistoryPath });
158
184
  const providerChanged = Boolean(requestParams.modelProvider && nativeModelProvider &&
@@ -169,7 +195,7 @@ export function createCodexConversationAdapter(host) {
169
195
  // process. A new socket or a changed command environment is not evidence
170
196
  // that the provider process died.
171
197
  if (nativeStatus === "notLoaded" && executionId && bound?.executionId !== executionId) {
172
- requestParams = await host.prepareResume?.(threadId, requestParams, {
198
+ requestParams = await host.prepareResume(threadId, requestParams, {
173
199
  runtime: host.runtime(),
174
200
  processChanged: Boolean(bound?.executionId)
175
201
  }) || requestParams;
@@ -207,7 +233,7 @@ export function createCodexConversationAdapter(host) {
207
233
  let instructionsChanged = requestParams.developerInstructions != null &&
208
234
  instructionPrompts.get(threadId) !== requestParams.developerInstructions;
209
235
  let resumed = null;
210
- const log = (event, fields = {}) => host.log?.(event, fields, { threadId, environment });
236
+ const log = (event, fields = {}) => host.log(event, fields, { threadId, environment });
211
237
  try {
212
238
  assertRecoveryOpen();
213
239
  if (instructionOnly) {
@@ -246,7 +272,7 @@ export function createCodexConversationAdapter(host) {
246
272
  const turnId = page.data?.[0]?.id;
247
273
  if (!turnId) throw new Error("Codex's running turn could not be identified for control recovery.");
248
274
  assertRecoveryOpen();
249
- host.recordInterruption?.(threadId, turnId);
275
+ host.recordInterruption(threadId, turnId);
250
276
  await request("turn/interrupt", { threadId, turnId });
251
277
  while (await readStatus() !== "idle") {
252
278
  signal.throwIfAborted();
@@ -267,7 +293,7 @@ export function createCodexConversationAdapter(host) {
267
293
  }
268
294
  if (!bindingMatches || nativeStatus === "notLoaded") {
269
295
  bindings.delete(threadId);
270
- await host.beforeResume?.(threadId);
296
+ await host.beforeResume(threadId);
271
297
  resumed = await request("thread/resume", { excludeTurns: true, ...requestParams, threadId });
272
298
  if (requestParams.modelProvider && resumed.modelProvider !== requestParams.modelProvider) {
273
299
  throw Object.assign(new Error("Another native subscriber retained the previous model provider. Close the native assistant terminal and retry."), {
@@ -302,7 +328,7 @@ export function createCodexConversationAdapter(host) {
302
328
  }
303
329
  }
304
330
  } catch (cause) {
305
- host.onRecoveryFailure?.(threadId);
331
+ host.onRecoveryFailure(threadId);
306
332
  bindings.delete(threadId);
307
333
  log("recovery_failed", { code: cause?.code || "", reason: cause.message });
308
334
  throw Object.assign(new Error(["assistant_agent_control_binding_retained", "assistant_codex_provider_binding_retained"].includes(cause?.code)
@@ -355,20 +381,20 @@ export function createCodexConversationAdapter(host) {
355
381
  settingsUpdates.set(threadId, settings);
356
382
  const task = withThreadContext(threadId, params, operation, settings);
357
383
  void task.then(result => {
358
- try { host.log?.("settings_applied", { model: settings.params.model, modelProvider: settings.params.modelProvider }, { threadId }); } catch { /* Diagnostics do not own scheduling. */ }
384
+ try { host.log("settings_applied", { model: settings.params.model, modelProvider: settings.params.modelProvider }, { threadId }); } catch { /* Diagnostics do not own scheduling. */ }
359
385
  accepted.resolve(result);
360
386
  }, async error => {
361
387
  accepted.reject(error);
362
- try { host.log?.("settings_failed", { code: error.code || "native_settings_failed" }, { threadId }); } catch { /* Logging cannot own native cleanup. */ }
388
+ try { host.log("settings_failed", { code: error.code || "native_settings_failed" }, { threadId }); } catch { /* Logging cannot own native cleanup. */ }
363
389
  // If a deferred reload fails, expose the actual paused goal for explicit
364
390
  // recovery. Never resume it speculatively or hide a user's later control.
365
391
  if (settingsUpdates.get(threadId) === settings) settingsUpdates.delete(threadId);
366
- if (!settings.controller.signal.aborted && settings.client?.isOpen?.()) {
392
+ if (!settings.controller.signal.aborted && settings.client?.isOpen()) {
367
393
  try {
368
394
  const { goal } = await settings.client.request("thread/goal/get", { threadId }, {
369
395
  signal: AbortSignal.timeout(host.timeoutMs || 10_000)
370
396
  });
371
- host.publishGoal?.(threadId, goal);
397
+ host.publishGoal(threadId, goal);
372
398
  } catch { /* Native observation owns disconnect failures. */ }
373
399
  }
374
400
  }).finally(() => {
@@ -385,33 +411,43 @@ export function createCodexConversationAdapter(host) {
385
411
  return goal;
386
412
  }
387
413
 
414
+ const hasPendingSettings = id => settingsUpdates.has(id);
415
+
416
+ function registerThread(id, binding) {
417
+ bindings.set(id, binding);
418
+ if (binding.params.developerInstructions != null) instructionPrompts.set(id, binding.params.developerInstructions);
419
+ }
420
+
421
+ function invalidateThread(id) {
422
+ settingsUpdates.get(id)?.controller.abort();
423
+ settingsUpdates.delete(id);
424
+ threadGenerations.set(id, (threadGenerations.get(id) || 0) + 1);
425
+ bindings.delete(id);
426
+ }
427
+
428
+ const goalChanged = (id) => goalChanges.set(id, (goalChanges.get(id) || 0) + 1);
429
+
430
+ function close() {
431
+ contextGeneration += 1;
432
+ for (const pending of settingsUpdates.values()) pending.controller.abort();
433
+ settingsUpdates.clear();
434
+ bindings.clear();
435
+ instructionPrompts.clear();
436
+ }
437
+
388
438
  return Object.freeze({
389
439
  scheduleSettings,
390
- hasPendingSettings: id => settingsUpdates.has(id),
440
+ hasPendingSettings,
391
441
  projectGoal,
392
442
  prepareInstructions,
393
443
  threadParameters,
394
444
  withThreadContext,
395
- registerThread(id, binding) {
396
- bindings.set(id, binding);
397
- if (binding.params.developerInstructions != null) instructionPrompts.set(id, binding.params.developerInstructions);
398
- },
399
- invalidateThread(id) {
400
- settingsUpdates.get(id)?.controller.abort();
401
- settingsUpdates.delete(id);
402
- threadGenerations.set(id, (threadGenerations.get(id) || 0) + 1);
403
- bindings.delete(id);
404
- },
405
- goalChanged: (id) => goalChanges.set(id, (goalChanges.get(id) || 0) + 1),
445
+ registerThread,
446
+ invalidateThread,
447
+ goalChanged,
406
448
  get bindingCount() { return bindings.size; },
407
449
  get threadEnvironments() { return bindings; },
408
450
  get threadEnvironmentTasks() { return tasks; },
409
- close() {
410
- contextGeneration += 1;
411
- for (const pending of settingsUpdates.values()) pending.controller.abort();
412
- settingsUpdates.clear();
413
- bindings.clear();
414
- instructionPrompts.clear();
415
- }
451
+ close
416
452
  });
417
453
  }