@copilotkit/core 1.63.0 → 1.63.2-canary.1784918757

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/index.cjs CHANGED
@@ -602,6 +602,12 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
602
602
  get capabilities() {
603
603
  return this._capabilities;
604
604
  }
605
+ requestInit(input) {
606
+ return {
607
+ ...super.requestInit(input),
608
+ ...this.credentials ? { credentials: this.credentials } : {}
609
+ };
610
+ }
605
611
  async getCapabilities() {
606
612
  return this._capabilities ?? {};
607
613
  }
@@ -695,10 +701,12 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
695
701
  }
696
702
  }
697
703
  connect(input) {
704
+ if (this.runtimeMode === "pending" || this.transport === "auto" && this.runtimeMode !== _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return (0, rxjs.defer)(() => (0, rxjs.from)(this.ensureRuntimeConfiguration())).pipe((0, rxjs_operators.switchMap)(() => this.connect(input)));
698
705
  if (this.runtimeMode === _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return this.#connectViaDelegate(input);
699
706
  return this.#connectViaHttp(input);
700
707
  }
701
708
  run(input) {
709
+ if (this.runtimeMode === "pending" || this.transport === "auto" && this.runtimeMode !== _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return (0, rxjs.defer)(() => (0, rxjs.from)(this.ensureRuntimeConfiguration())).pipe((0, rxjs_operators.switchMap)(() => this.run(input)));
702
710
  if (this.runtimeMode === _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return this.#runViaDelegate(input);
703
711
  return this.#runViaHttp(input);
704
712
  }
@@ -768,7 +776,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
768
776
  this.delegate?.clearReconnectCursor?.(threadId);
769
777
  }
770
778
  async resolveDelegate() {
771
- await this.ensureRuntimeMode();
779
+ await this.ensureRuntimeConfiguration();
772
780
  if (!this.delegate) {
773
781
  if (this.runtimeMode !== _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) throw new Error("A delegate is only created for Intelligence mode");
774
782
  this.delegate = this.createIntelligenceDelegate();
@@ -776,14 +784,21 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
776
784
  this.syncDelegate(this.delegate);
777
785
  return this.delegate;
778
786
  }
779
- async ensureRuntimeMode() {
780
- if (this.runtimeMode !== "pending") return;
787
+ /** Resolve transport and runtime mode before the first outbound request. */
788
+ async ensureRuntimeConfiguration() {
789
+ if (this.runtimeMode === _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE || this.runtimeMode !== "pending" && this.transport !== "auto") return;
781
790
  if (!this.runtimeUrl) throw new Error("Runtime URL is not set");
782
- this.runtimeInfoPromise ??= this.fetchRuntimeInfo().then((runtimeInfo) => {
791
+ const runtimeInfoPromise = this.runtimeInfoPromise ?? this.fetchRuntimeInfo().then((runtimeInfo) => {
783
792
  this.runtimeMode = runtimeInfo.mode ?? _copilotkit_shared.RUNTIME_MODE_SSE;
784
793
  this.intelligence = runtimeInfo.intelligence;
785
794
  });
786
- await this.runtimeInfoPromise;
795
+ this.runtimeInfoPromise = runtimeInfoPromise;
796
+ try {
797
+ await runtimeInfoPromise;
798
+ } catch (error) {
799
+ if (this.runtimeInfoPromise === runtimeInfoPromise) this.runtimeInfoPromise = void 0;
800
+ throw error;
801
+ }
787
802
  }
788
803
  async fetchRuntimeInfo() {
789
804
  const headers = { ...this.headers };
@@ -1738,6 +1753,19 @@ const SUGGEST_TOOL = {
1738
1753
  //#endregion
1739
1754
  //#region src/core/run-handler.ts
1740
1755
  /**
1756
+ * Absolute safety cap on the depth of recursive follow-up runs triggered by
1757
+ * `processAgentResult`. Without this, any scenario that keeps
1758
+ * `needsFollowUp = true` (e.g. the LLM repeatedly calling the same tool, a
1759
+ * backend that errors after receiving tool results, or input processors that
1760
+ * reprocess tool messages) would loop indefinitely, silently consuming API
1761
+ * quota and potentially DOS'ing the backend.
1762
+ *
1763
+ * The cap is deliberately high so that legitimate multi-step agent workflows
1764
+ * (search → fill form → confirm → update → send email, etc.) are never
1765
+ * affected; it only trips on runaway recursion.
1766
+ */
1767
+ const MAX_FOLLOW_UP_DEPTH = 100;
1768
+ /**
1741
1769
  * Handles agent execution, tool calling, and agent connectivity for CopilotKitCore.
1742
1770
  * Manages the complete lifecycle of agent runs including tool execution and follow-ups.
1743
1771
  */
@@ -1992,7 +2020,8 @@ var RunHandler = class {
1992
2020
  }
1993
2021
  }
1994
2022
  }
1995
- if (needsFollowUp && !this._runAbortController?.signal.aborted) {
2023
+ if (needsFollowUp && !this._runAbortController?.signal.aborted) if (this._runDepth >= MAX_FOLLOW_UP_DEPTH) _copilotkit_shared.logger.warn(`[CopilotKit] Follow-up depth limit (${MAX_FOLLOW_UP_DEPTH}) reached for agent "${agentId}". Stopping recursive follow-up runs to prevent an infinite loop. This usually indicates a tool that keeps requesting a follow-up (e.g. the LLM repeatedly calling the same tool). Consider setting "followUp: false" on the offending tool.`);
2024
+ else {
1996
2025
  await this._internal.waitForPendingFrameworkUpdates();
1997
2026
  return await this.runAgent({ agent });
1998
2027
  }
@@ -2315,6 +2344,7 @@ var RunHandler = class {
2315
2344
  await emitAgentError(error, error instanceof AgentThreadLockedError ? CopilotKitCoreErrorCode.AGENT_THREAD_LOCKED : CopilotKitCoreErrorCode.AGENT_RUN_FAILED_EVENT, { source: "onRunFailed" });
2316
2345
  },
2317
2346
  onRunErrorEvent: async ({ event }) => {
2347
+ if (this._runAbortController?.signal.aborted === true || event?.code === "abort") return;
2318
2348
  const eventError = event?.rawEvent instanceof Error ? event.rawEvent : event?.rawEvent?.error instanceof Error ? event.rawEvent.error : void 0;
2319
2349
  const errorMessage = typeof event?.rawEvent?.error === "string" ? event.rawEvent.error : event?.message ?? "Agent run error";
2320
2350
  const rawError = eventError ?? new Error(errorMessage);
@@ -5248,6 +5278,111 @@ function ɵisCopilotKitFeature(name) {
5248
5278
  return FEATURE_SET.has(name);
5249
5279
  }
5250
5280
 
5281
+ //#endregion
5282
+ //#region src/interrupt-state.ts
5283
+ function toolResultContent(response) {
5284
+ if (response.status === "cancelled") return JSON.stringify({ status: "cancelled" });
5285
+ return JSON.stringify(response.payload ?? { status: "resolved" });
5286
+ }
5287
+ /**
5288
+ * @internal Framework-neutral interrupt response state shared by framework
5289
+ * adapters. Application authors must not depend on this API.
5290
+ */
5291
+ var ɵInterruptState = class {
5292
+ #responses = {};
5293
+ #pending = null;
5294
+ #sealed = false;
5295
+ /** Return the active normalized interrupt without exposing mutable state. */
5296
+ get pending() {
5297
+ const pending = this.#pending;
5298
+ if (pending?.kind === "standard") return {
5299
+ kind: "standard",
5300
+ interrupts: [...pending.interrupts]
5301
+ };
5302
+ return pending;
5303
+ }
5304
+ /** Replace the current interrupt with a legacy custom-event interrupt. */
5305
+ setLegacy(event) {
5306
+ this.#replace({
5307
+ kind: "legacy",
5308
+ event
5309
+ });
5310
+ }
5311
+ /** Replace the current interrupt with an AG-UI standard interrupt set. */
5312
+ setStandard(interrupts) {
5313
+ this.#replace({
5314
+ kind: "standard",
5315
+ interrupts: [...interrupts]
5316
+ });
5317
+ }
5318
+ /** Clear all pending interrupt data and accumulated responses. */
5319
+ clear() {
5320
+ this.#pending = null;
5321
+ this.#sealed = false;
5322
+ for (const id of Object.keys(this.#responses)) delete this.#responses[id];
5323
+ }
5324
+ /** Record a resolved response and return the next framework action. */
5325
+ resolve(payload, interruptId) {
5326
+ const pending = this.#pending;
5327
+ if (!pending || this.#sealed) return { kind: "ignored" };
5328
+ if (pending.kind === "legacy") {
5329
+ this.#sealed = true;
5330
+ return {
5331
+ kind: "legacy-resume",
5332
+ payload,
5333
+ interruptValue: pending.event.value
5334
+ };
5335
+ }
5336
+ return this.#respond(pending.interrupts, interruptId, {
5337
+ status: "resolved",
5338
+ payload
5339
+ });
5340
+ }
5341
+ /** Record a cancelled response and return the next framework action. */
5342
+ cancel(interruptId) {
5343
+ const pending = this.#pending;
5344
+ if (!pending || this.#sealed) return { kind: "ignored" };
5345
+ if (pending.kind === "legacy") {
5346
+ this.#sealed = true;
5347
+ return { kind: "dismiss" };
5348
+ }
5349
+ return this.#respond(pending.interrupts, interruptId, { status: "cancelled" });
5350
+ }
5351
+ #replace(pending) {
5352
+ this.clear();
5353
+ this.#pending = pending;
5354
+ }
5355
+ #respond(interrupts, interruptId, response) {
5356
+ const id = interruptId ?? interrupts[0]?.id;
5357
+ if (!id || !interrupts.some((interrupt) => interrupt.id === id)) return { kind: "ignored" };
5358
+ this.#responses[id] = response;
5359
+ if (!interrupts.every((interrupt) => this.#responses[interrupt.id])) return { kind: "waiting" };
5360
+ const expired = interrupts.find((interrupt) => (0, _ag_ui_client.isInterruptExpired)(interrupt));
5361
+ if (expired) {
5362
+ this.#sealed = true;
5363
+ return {
5364
+ kind: "expired",
5365
+ interrupt: expired
5366
+ };
5367
+ }
5368
+ const mutableInterrupts = [...interrupts];
5369
+ const resume = (0, _ag_ui_client.buildResumeArray)(mutableInterrupts, this.#responses);
5370
+ const toolResults = mutableInterrupts.flatMap((interrupt) => {
5371
+ if (!interrupt.toolCallId) return [];
5372
+ return [{
5373
+ toolCallId: interrupt.toolCallId,
5374
+ content: toolResultContent(this.#responses[interrupt.id])
5375
+ }];
5376
+ });
5377
+ this.#sealed = true;
5378
+ return {
5379
+ kind: "resume",
5380
+ resume,
5381
+ toolResults
5382
+ };
5383
+ }
5384
+ };
5385
+
5251
5386
  //#endregion
5252
5387
  exports.AgentRegistry = AgentRegistry;
5253
5388
  exports.AgentThreadLockedError = AgentThreadLockedError;
@@ -5279,6 +5414,7 @@ exports.parseToolArguments = parseToolArguments;
5279
5414
  exports.props = props;
5280
5415
  exports.select = select;
5281
5416
  exports.ɵCOPILOTKIT_FEATURES = ɵCOPILOTKIT_FEATURES;
5417
+ exports.ɵInterruptState = ɵInterruptState;
5282
5418
  exports.ɵMAX_SOCKET_RETRIES = ɵMAX_SOCKET_RETRIES;
5283
5419
  exports.ɵcreateMemoryStore = createMemoryStore;
5284
5420
  exports.ɵcreateThreadSelectors = ɵcreateThreadSelectors;