neoctl 0.2.33 → 0.2.35

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.
package/dist/web/index.js CHANGED
@@ -389,6 +389,7 @@ export class WebRepl {
389
389
  pendingUserImageEchoMessageId;
390
390
  runtimeContextRevision = 0;
391
391
  runtimeContextPublishQueue = Promise.resolve();
392
+ pendingRuntimeConfiguration = false;
392
393
  backgroundSessionRuns = new Map();
393
394
  suppressReattachedStreaming = new Set();
394
395
  constructor(runtime) {
@@ -513,8 +514,6 @@ export class WebRepl {
513
514
  };
514
515
  }
515
516
  async setGlobalTools(value) {
516
- if (this.busy)
517
- return actionFailure("TOOL_UPDATE_BLOCKED", "cannot change global tools while a response is running");
518
517
  if (!isRecord(value))
519
518
  return actionFailure("INVALID_REQUEST", "tool overrides must be an object");
520
519
  const support = this.runtime.toolSupport;
@@ -525,10 +524,12 @@ export class WebRepl {
525
524
  return normalized;
526
525
  try {
527
526
  support.globalOverrides = normalized.value;
528
- this.syncPluginToolRegistration();
529
- applyToolOverrides(this.runtime.tools, support.catalog, support.globalOverrides, support.sessionOverrides);
530
527
  if (support.persistGlobal)
531
528
  await support.persistGlobal(support.globalOverrides);
529
+ if (this.busy)
530
+ this.pendingRuntimeConfiguration = true;
531
+ else
532
+ await this.applyRuntimeConfiguration();
532
533
  await this.refreshToolConfiguration();
533
534
  return { ok: true, state: this.globalTools() };
534
535
  }
@@ -537,8 +538,6 @@ export class WebRepl {
537
538
  }
538
539
  }
539
540
  async setSessionTools(value) {
540
- if (this.busy)
541
- return actionFailure("TOOL_UPDATE_BLOCKED", "cannot change session tools while a response is running");
542
541
  if (!isRecord(value))
543
542
  return actionFailure("INVALID_REQUEST", "tool overrides must be an object");
544
543
  const support = this.runtime.toolSupport;
@@ -562,8 +561,6 @@ export class WebRepl {
562
561
  await this.applySessionToolOverrides(await support.resolveSession(sessionId), false);
563
562
  }
564
563
  async setSessionPlugins(value) {
565
- if (this.busy)
566
- return actionFailure("PLUGIN_UPDATE_BLOCKED", "cannot change session plugins while a response is running");
567
564
  if (!isRecord(value))
568
565
  return actionFailure("INVALID_REQUEST", "plugin overrides must be an object");
569
566
  const support = this.runtime.pluginSupport;
@@ -627,11 +624,13 @@ export class WebRepl {
627
624
  if (!support)
628
625
  return;
629
626
  support.sessionOverrides = normalizeToolOverrides(overrides, support.catalog);
630
- this.syncPluginToolRegistration();
631
- applyToolOverrides(this.runtime.tools, support.catalog, support.globalOverrides, support.sessionOverrides);
632
627
  const sessionId = this.runtime.engine.snapshot().session?.sessionId;
633
628
  if (persist && sessionId && support.persistSession)
634
629
  await support.persistSession(sessionId, support.sessionOverrides);
630
+ if (this.busy)
631
+ this.pendingRuntimeConfiguration = true;
632
+ else
633
+ await this.applyRuntimeConfiguration();
635
634
  await this.refreshToolConfiguration();
636
635
  }
637
636
  syncPluginToolRegistration() {
@@ -646,6 +645,18 @@ export class WebRepl {
646
645
  this.runtime.tools.register(tool);
647
646
  }
648
647
  }
648
+ async applyRuntimeConfiguration() {
649
+ this.syncPluginToolRegistration();
650
+ const pluginSupport = this.runtime.pluginSupport;
651
+ if (pluginSupport) {
652
+ const activePlugins = activeWebRuntimePlugins(pluginSupport.catalog, pluginSupport.overrides);
653
+ this.runtime.engine.setRuntimePlugins([...pluginSupport.basePluginIds, ...activePlugins.map((plugin) => plugin.id)], [...pluginSupport.basePromptSections, ...activePlugins.flatMap((plugin) => plugin.promptSections ?? [])]);
654
+ }
655
+ const toolSupport = this.runtime.toolSupport;
656
+ if (toolSupport)
657
+ applyToolOverrides(this.runtime.tools, toolSupport.catalog, toolSupport.globalOverrides, toolSupport.sessionOverrides);
658
+ this.pendingRuntimeConfiguration = false;
659
+ }
649
660
  async refreshToolConfiguration() {
650
661
  const metrics = await this.runtime.engine.contextMetrics();
651
662
  this.runtime.initialMetrics = metrics;
@@ -658,21 +669,14 @@ export class WebRepl {
658
669
  if (!support)
659
670
  return;
660
671
  const normalized = normalizePluginOverrides(overrides, support.catalog);
661
- for (const plugin of support.catalog)
662
- for (const tool of plugin.tools)
663
- this.runtime.tools.unregister(tool.name);
664
- const activePlugins = activeWebRuntimePlugins(support.catalog, normalized);
665
- for (const plugin of activePlugins)
666
- for (const tool of plugin.tools)
667
- this.runtime.tools.register(tool);
668
672
  support.overrides = normalized;
669
- const toolSupport = this.runtime.toolSupport;
670
- if (toolSupport)
671
- applyToolOverrides(this.runtime.tools, toolSupport.catalog, toolSupport.globalOverrides, toolSupport.sessionOverrides);
672
- this.runtime.engine.setRuntimePlugins([...support.basePluginIds, ...activePlugins.map((plugin) => plugin.id)], [...support.basePromptSections, ...activePlugins.flatMap((plugin) => plugin.promptSections ?? [])]);
673
673
  const sessionId = this.runtime.engine.snapshot().session?.sessionId;
674
674
  if (persist && sessionId && support.persist)
675
675
  await support.persist(sessionId, normalized);
676
+ if (this.busy)
677
+ this.pendingRuntimeConfiguration = true;
678
+ else
679
+ await this.applyRuntimeConfiguration();
676
680
  const metrics = await this.runtime.engine.contextMetrics();
677
681
  this.runtime.initialMetrics = metrics;
678
682
  this.setStatus({ ...this.status, metrics, activityTick: this.status.activityTick + 1 });
@@ -723,7 +727,11 @@ export class WebRepl {
723
727
  this.queuedAttachments = [...(this.queuedAttachments ?? []), ...attachments].slice(0, 20);
724
728
  }
725
729
  startRun(text, attachments = []) {
726
- const run = this.handleCommandOrPrompt(text, attachments).catch((error) => {
730
+ const run = (async () => {
731
+ if (this.pendingRuntimeConfiguration)
732
+ await this.applyRuntimeConfiguration();
733
+ await this.handleCommandOrPrompt(text, attachments);
734
+ })().catch((error) => {
727
735
  this.append({ kind: "error", text: error instanceof Error ? error.message : String(error) });
728
736
  this.setBusy(false);
729
737
  this.setStatus({ ...this.status, phase: "ready", detail: undefined });
@@ -884,8 +892,6 @@ export class WebRepl {
884
892
  }
885
893
  }
886
894
  async setContextWindowK(value) {
887
- if (this.busy)
888
- return actionFailure("CONTEXT_WINDOW_UPDATE_BLOCKED", "cannot change context window while a response is running");
889
895
  if (typeof value !== "string" || !/^\d+$/u.test(value) || Number(value) <= 0) {
890
896
  return actionFailure("CONTEXT_WINDOW_INVALID", "context window must be a positive integer in k");
891
897
  }