@copilotkit/core 1.66.2-canary.1785878925 → 1.66.3

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
@@ -1983,10 +1983,15 @@ var RunHandler = class {
1983
1983
  /**
1984
1984
  * Run an agent
1985
1985
  */
1986
- async runAgent({ agent, forwardedProps, resume, runId }) {
1986
+ async runAgent({ agent, forwardedProps, resume, runId }, continuationHandoff) {
1987
1987
  if (agent.agentId) this._internal.suggestionEngine.clearSuggestions(agent.agentId);
1988
1988
  this._internal.applyHeadersToAgent(agent);
1989
- if (agent.detachActiveRun) await agent.detachActiveRun();
1989
+ if (agent.detachActiveRun) try {
1990
+ await agent.detachActiveRun();
1991
+ } catch (error) {
1992
+ continuationHandoff?.cancel();
1993
+ throw error;
1994
+ }
1990
1995
  const isTopLevel = this._runDepth === 0;
1991
1996
  let originalAbortRun;
1992
1997
  if (isTopLevel) {
@@ -2004,21 +2009,40 @@ var RunHandler = class {
2004
2009
  }
2005
2010
  this._runDepth++;
2006
2011
  try {
2007
- const runAgentResult = await agent.runAgent({
2012
+ let logicalRunId = runId;
2013
+ const agentSubscriber = this.createAgentErrorSubscriber(agent);
2014
+ let started = false;
2015
+ const onRunStartedEvent = agentSubscriber.onRunStartedEvent;
2016
+ const onRunInitialized = agentSubscriber.onRunInitialized;
2017
+ agentSubscriber.onRunInitialized = async (params) => {
2018
+ continuationHandoff?.bind(params.input);
2019
+ return onRunInitialized?.(params);
2020
+ };
2021
+ agentSubscriber.onRunStartedEvent = async (params) => {
2022
+ started = true;
2023
+ if (!continuationHandoff) logicalRunId = params.input.runId;
2024
+ return onRunStartedEvent?.(params);
2025
+ };
2026
+ const pinRunIdOnWire = runId !== void 0 && !continuationHandoff;
2027
+ const agentRunInput = {
2008
2028
  forwardedProps: {
2009
2029
  ...this._internal.properties,
2010
2030
  ...forwardedProps
2011
2031
  },
2012
2032
  ...resume !== void 0 ? { resume } : {},
2013
- ...runId !== void 0 ? { runId } : {},
2033
+ ...pinRunIdOnWire ? { runId } : {},
2014
2034
  tools: this.buildFrontendTools(agent.agentId),
2015
2035
  context: this._internal.getContextForAgent(agent.agentId)
2016
- }, this.createAgentErrorSubscriber(agent));
2036
+ };
2037
+ const runAgentResult = await agent.runAgent(agentRunInput, agentSubscriber);
2038
+ if (!started) continuationHandoff?.cancel();
2017
2039
  return await this.processAgentResult({
2018
2040
  runAgentResult,
2019
- agent
2041
+ agent,
2042
+ runId: logicalRunId
2020
2043
  });
2021
2044
  } catch (error) {
2045
+ continuationHandoff?.cancel();
2022
2046
  const runError = error instanceof Error ? error : new Error(String(error));
2023
2047
  const context = {};
2024
2048
  if (agent.agentId) context.agentId = agent.agentId;
@@ -2039,7 +2063,7 @@ var RunHandler = class {
2039
2063
  /**
2040
2064
  * Process agent result and execute tools
2041
2065
  */
2042
- async processAgentResult({ runAgentResult, agent, executeFrontendTools = true }) {
2066
+ async processAgentResult({ runAgentResult, agent, runId, executeFrontendTools = true }) {
2043
2067
  const { newMessages } = runAgentResult;
2044
2068
  const agentId = agent.agentId;
2045
2069
  let needsFollowUp = false;
@@ -2080,7 +2104,11 @@ var RunHandler = class {
2080
2104
  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.`);
2081
2105
  else {
2082
2106
  await this._internal.waitForPendingFrameworkUpdates();
2083
- return await this.runAgent({ agent });
2107
+ const continuationHandoff = this._internal.stateManager.markNextRunAsContinuation(agent, runId);
2108
+ return await this.runAgent({
2109
+ agent,
2110
+ ...runId !== void 0 ? { runId } : {}
2111
+ }, continuationHandoff);
2084
2112
  }
2085
2113
  this._internal.suggestionEngine.reloadSuggestions(agentId);
2086
2114
  return runAgentResult;
@@ -2518,6 +2546,7 @@ function parseToolArguments(rawArgs, toolName) {
2518
2546
 
2519
2547
  //#endregion
2520
2548
  //#region src/core/state-manager.ts
2549
+ const isContinuation = (input) => input.resume !== void 0 || Object.prototype.hasOwnProperty.call(input.forwardedProps?.command ?? {}, "resume");
2521
2550
  /**
2522
2551
  * Manages state and message tracking by run for CopilotKitCore.
2523
2552
  * Tracks agent state snapshots and message-to-run associations.
@@ -2527,6 +2556,7 @@ var StateManager = class {
2527
2556
  messageToRun = /* @__PURE__ */ new Map();
2528
2557
  activeRun = /* @__PURE__ */ new Map();
2529
2558
  agentSubscriptions = /* @__PURE__ */ new Map();
2559
+ pendingContinuations = /* @__PURE__ */ new WeakMap();
2530
2560
  constructor(core) {
2531
2561
  this.core = core;
2532
2562
  }
@@ -2534,6 +2564,28 @@ var StateManager = class {
2534
2564
  * Initialize state tracking for an agent
2535
2565
  */
2536
2566
  initialize() {}
2567
+ markNextRunAsContinuation(agent, expectedRunId) {
2568
+ let pendingForAgent = this.pendingContinuations.get(agent);
2569
+ if (!pendingForAgent) {
2570
+ pendingForAgent = /* @__PURE__ */ new Set();
2571
+ this.pendingContinuations.set(agent, pendingForAgent);
2572
+ }
2573
+ const pending = {
2574
+ active: true,
2575
+ expectedRunId,
2576
+ bind: (input) => {
2577
+ if (pending.active) pending.expectedInput = input;
2578
+ },
2579
+ cancel: () => {
2580
+ if (!pending.active) return;
2581
+ pending.active = false;
2582
+ pendingForAgent.delete(pending);
2583
+ if (pendingForAgent.size === 0) this.pendingContinuations.delete(agent);
2584
+ }
2585
+ };
2586
+ pendingForAgent.add(pending);
2587
+ return pending;
2588
+ }
2537
2589
  /**
2538
2590
  * Subscribe to an agent's events to track state and messages.
2539
2591
  */
@@ -2555,8 +2607,10 @@ var StateManager = class {
2555
2607
  const { unsubscribe } = agent.subscribe({
2556
2608
  onRunStartedEvent: ({ input, state }) => {
2557
2609
  if (revoked) return;
2558
- if (runFinished && input.runId === subRunId) subRunId = (0, _ag_ui_client.randomUUID)();
2559
- else subRunId = input.runId;
2610
+ const internalContinuation = [...this.pendingContinuations.get(agent) ?? []].find((pending) => pending.expectedInput === input);
2611
+ internalContinuation?.cancel();
2612
+ if (runFinished && input.runId === subRunId && !internalContinuation && !isContinuation(input)) subRunId = (0, _ag_ui_client.randomUUID)();
2613
+ else subRunId = internalContinuation?.expectedRunId ?? input.runId;
2560
2614
  runFinished = false;
2561
2615
  this.handleRunStarted(agent, effectiveInput(input), state);
2562
2616
  },
@@ -2589,6 +2643,7 @@ var StateManager = class {
2589
2643
  });
2590
2644
  this.agentSubscriptions.set(agentId, () => {
2591
2645
  revoked = true;
2646
+ this.pendingContinuations.delete(agent);
2592
2647
  unsubscribe();
2593
2648
  });
2594
2649
  }