@copilotkit/core 1.69.0 → 1.69.2

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.mjs CHANGED
@@ -1998,6 +1998,30 @@ const SUGGEST_TOOL = {
1998
1998
  }
1999
1999
  };
2000
2000
 
2001
+ //#endregion
2002
+ //#region src/core/tool-result-content.ts
2003
+ /**
2004
+ * Single authority for the forwarded-to-client sentinel used by StateManager
2005
+ * and RunHandler.
2006
+ */
2007
+ const FORWARDED_TO_CLIENT = "Forwarded to client";
2008
+ function normalizeToolResultContent(content) {
2009
+ if (typeof content === "string") return content.trim();
2010
+ if (Array.isArray(content)) {
2011
+ const text = content.flatMap((part) => {
2012
+ if (typeof part === "string") return [part];
2013
+ if (part && typeof part === "object" && "text" in part && typeof part.text === "string") return [part.text];
2014
+ return [];
2015
+ }).join("").trim();
2016
+ return text.length > 0 ? text : null;
2017
+ }
2018
+ if (content && typeof content === "object" && "text" in content && typeof content.text === "string") return content.text.trim();
2019
+ return null;
2020
+ }
2021
+ function isForwardedToClientPlaceholder(content) {
2022
+ return normalizeToolResultContent(content) === FORWARDED_TO_CLIENT;
2023
+ }
2024
+
2001
2025
  //#endregion
2002
2026
  //#region src/core/run-handler.ts
2003
2027
  /**
@@ -2181,8 +2205,8 @@ var RunHandler = class {
2181
2205
  * Connect an agent (establish initial connection)
2182
2206
  */
2183
2207
  async connectAgent({ agent }) {
2208
+ const incomingThreadId = agent.threadId ?? null;
2184
2209
  try {
2185
- const incomingThreadId = agent.threadId ?? null;
2186
2210
  const restoreKey = this.getConnectRestoreKey(agent);
2187
2211
  const isFreshRestore = incomingThreadId !== (this._lastConnectedThreadIdsByAgent.get(restoreKey) ?? null);
2188
2212
  this._lastConnectedThreadIdsByAgent.set(restoreKey, incomingThreadId);
@@ -2216,6 +2240,7 @@ var RunHandler = class {
2216
2240
  if (!(connectError.name === "AbortError" || connectError.message === "Fetch is aborted" || connectError.message === "signal is aborted without reason" || connectError.message === "component unmounted")) {
2217
2241
  const context = {};
2218
2242
  if (agent.agentId) context.agentId = agent.agentId;
2243
+ if (incomingThreadId) context.threadId = incomingThreadId;
2219
2244
  await this._internal.emitError({
2220
2245
  error: connectError,
2221
2246
  code: CopilotKitCoreErrorCode.AGENT_CONNECT_FAILED,
@@ -2362,21 +2387,7 @@ var RunHandler = class {
2362
2387
  return runAgentResult;
2363
2388
  }
2364
2389
  isFrontendPlaceholderResult(message) {
2365
- if (message.role !== "tool") return false;
2366
- return this.normalizeToolResultContent(message.content) === "Forwarded to client";
2367
- }
2368
- normalizeToolResultContent(content) {
2369
- if (typeof content === "string") return content.trim();
2370
- if (Array.isArray(content)) {
2371
- const text = content.flatMap((part) => {
2372
- if (typeof part === "string") return [part];
2373
- if (part && typeof part === "object" && "text" in part && typeof part.text === "string") return [part.text];
2374
- return [];
2375
- }).join("").trim();
2376
- return text.length > 0 ? text : null;
2377
- }
2378
- if (content && typeof content === "object" && "text" in content && typeof content.text === "string") return content.text.trim();
2379
- return null;
2390
+ return message.role === "tool" && isForwardedToClientPlaceholder(message.content);
2380
2391
  }
2381
2392
  /**
2382
2393
  * Shared handler execution logic used by executeSpecificTool, executeWildcardTool, and runTool.
@@ -2849,6 +2860,61 @@ var StateManager = class {
2849
2860
  let revoked = false;
2850
2861
  let subRunId;
2851
2862
  let runFinished = false;
2863
+ const pendingResults = /* @__PURE__ */ new WeakMap();
2864
+ const reconcilePendingResults = (historyMessages, input) => {
2865
+ const events = pendingResults.get(input);
2866
+ if (!events) return void 0;
2867
+ const messages = [...historyMessages];
2868
+ let changed = false;
2869
+ for (const event of events.values()) {
2870
+ const ownerIndex = messages.findIndex((message) => message.role === "assistant" && message.toolCalls?.some((toolCall) => toolCall.id === event.toolCallId));
2871
+ if (ownerIndex < 0) continue;
2872
+ const matchingIndexes = messages.reduce((indexes, message, index) => {
2873
+ if (message.role === "tool" && message.toolCallId === event.toolCallId) indexes.push(index);
2874
+ return indexes;
2875
+ }, []);
2876
+ const realIndex = matchingIndexes.find((index) => !isForwardedToClientPlaceholder(messages[index]?.content));
2877
+ if (realIndex !== void 0) {
2878
+ for (const duplicateIndex of matchingIndexes.filter((candidateIndex) => candidateIndex !== realIndex).sort((a, b) => b - a)) {
2879
+ messages.splice(duplicateIndex, 1);
2880
+ changed = true;
2881
+ }
2882
+ continue;
2883
+ }
2884
+ const placeholderIndex = matchingIndexes.find((index) => isForwardedToClientPlaceholder(messages[index]?.content));
2885
+ if (placeholderIndex !== void 0) {
2886
+ if (isForwardedToClientPlaceholder(event.content)) {
2887
+ for (const duplicateIndex of matchingIndexes.slice(1).sort((a, b) => b - a)) {
2888
+ messages.splice(duplicateIndex, 1);
2889
+ changed = true;
2890
+ }
2891
+ continue;
2892
+ }
2893
+ messages[placeholderIndex] = {
2894
+ ...messages[placeholderIndex],
2895
+ id: event.messageId,
2896
+ content: event.content
2897
+ };
2898
+ changed = true;
2899
+ for (const duplicateIndex of matchingIndexes.filter((candidateIndex) => candidateIndex !== placeholderIndex && isForwardedToClientPlaceholder(messages[candidateIndex]?.content)).sort((a, b) => b - a)) messages.splice(duplicateIndex, 1);
2900
+ continue;
2901
+ }
2902
+ const result = {
2903
+ id: event.messageId,
2904
+ role: "tool",
2905
+ toolCallId: event.toolCallId,
2906
+ content: event.content
2907
+ };
2908
+ let insertIndex = ownerIndex + 1;
2909
+ while (messages[insertIndex]?.role === "tool") insertIndex++;
2910
+ messages.splice(insertIndex, 0, result);
2911
+ changed = true;
2912
+ }
2913
+ return changed ? { messages } : void 0;
2914
+ };
2915
+ const clearPendingResults = (input) => {
2916
+ pendingResults.delete(input);
2917
+ };
2852
2918
  const effectiveInput = (input) => ({
2853
2919
  ...input,
2854
2920
  runId: subRunId ?? input.runId
@@ -2864,15 +2930,39 @@ var StateManager = class {
2864
2930
  runFinished = false;
2865
2931
  this.handleRunStarted(agent, effectiveInput(input), state);
2866
2932
  },
2867
- onRunFinishedEvent: ({ input, state }) => {
2933
+ onRunFinishedEvent: ({ input, state, messages }) => {
2868
2934
  if (revoked) return;
2869
2935
  runFinished = true;
2870
- this.handleRunFinished(agent, effectiveInput(input), state);
2936
+ const effective = effectiveInput(input);
2937
+ const mutation = reconcilePendingResults(messages, input);
2938
+ clearPendingResults(input);
2939
+ this.handleRunFinished(agent, effective, state);
2940
+ return mutation;
2871
2941
  },
2872
- onRunErrorEvent: ({ input, state }) => {
2942
+ onRunErrorEvent: ({ input, state, messages }) => {
2873
2943
  if (revoked) return;
2874
2944
  runFinished = true;
2875
- this.handleRunFinished(agent, effectiveInput(input), state);
2945
+ const effective = effectiveInput(input);
2946
+ const mutation = reconcilePendingResults(messages, input);
2947
+ this.handleRunFinished(agent, effective, state);
2948
+ return mutation;
2949
+ },
2950
+ onRunFailed: ({ input, messages }) => {
2951
+ if (revoked) return;
2952
+ return reconcilePendingResults(messages, input);
2953
+ },
2954
+ onRunFinalized: ({ input }) => {
2955
+ if (revoked) return;
2956
+ clearPendingResults(input);
2957
+ },
2958
+ onToolCallResultEvent: ({ event, input }) => {
2959
+ if (revoked) return;
2960
+ let events = pendingResults.get(input);
2961
+ if (!events) {
2962
+ events = /* @__PURE__ */ new Map();
2963
+ pendingResults.set(input, events);
2964
+ }
2965
+ events.set(event.toolCallId, event);
2876
2966
  },
2877
2967
  onStateSnapshotEvent: ({ event, input, state }) => {
2878
2968
  if (revoked) return;
@@ -3011,7 +3101,7 @@ var StateManager = class {
3011
3101
  /**
3012
3102
  * Handle messages snapshot event
3013
3103
  */
3014
- handleMessagesSnapshot(agent, event, input, messages) {
3104
+ handleMessagesSnapshot(agent, event, input, _messages) {
3015
3105
  if (!agent.agentId) return;
3016
3106
  const { threadId, runId } = input;
3017
3107
  for (const message of event.messages) if (this.getRunIdForMessage(agent.agentId, threadId, message.id) === void 0) this.associateMessageWithRun(agent.agentId, threadId, message.id, runId);
@@ -5979,5 +6069,100 @@ var ɵInterruptState = class {
5979
6069
  };
5980
6070
 
5981
6071
  //#endregion
5982
- export { AgentRegistry, AgentThreadLockedError, ContextStore, CopilotKitCore, CopilotKitCoreErrorCode, CopilotKitCoreRuntimeConnectionStatus, IntelligenceAgent, MEMORY_ERROR_REGISTRY, MemoryError, ProxiedCopilotRuntimeAgent, RunHandler, StateManager, SuggestionEngine, ToolCallStatus, completePartialMarkdown, createActionGroup, createEffect, createReducer, createSelector, createStore, empty, ensureObjectArgs, isAbortError, isRunCompletionAware, ofType, on, parseToolArguments, props, select, ɵCOPILOTKIT_FEATURES, ɵInterruptState, ɵMAX_SOCKET_RETRIES, createMemoryStore as ɵcreateMemoryStore, ɵcreateThreadSelectors, createThreadStore as ɵcreateThreadStore, ɵisCopilotKitFeature, isRetryableStatus as ɵisRetryableMemoryStatus, ɵjoinPhoenixChannel$, ɵmapMemoryMetadataEvent, ɵmemoryAdapterEvents, ɵmemoryDomainEvents, ɵmemoryReducer, ɵmemoryRestEvents, ɵobservePhoenixEvent$, ɵobservePhoenixJoinOutcome$, ɵobservePhoenixSocketHealth$, ɵobservePhoenixSocketSignals$, ɵphoenixChannel$, ɵphoenixSocket$, ɵselectFetchMoreError, ɵselectHasNextPage, ɵselectIsFetchingNextPage, ɵselectIsMutating, ɵselectMemories, ɵselectMemoriesAvailable, ɵselectMemoriesError, ɵselectMemoriesIsLoading, ɵselectMemoriesIsMutating, ɵselectMemoriesRealtimeStatus, ɵselectThreads, ɵselectThreadsError, ɵselectThreadsIsLoading, ɵthreadAdapterEvents };
6072
+ //#region src/inspector-thread-bridge.ts
6073
+ const INSPECTOR_THREAD_BRIDGE_PLUGIN_ID = "cpk-inspector-thread";
6074
+ const EVENT_PREFIX = `copilotkit:${INSPECTOR_THREAD_BRIDGE_PLUGIN_ID}`;
6075
+ function eventName(suffix) {
6076
+ return `${EVENT_PREFIX}:${suffix}`;
6077
+ }
6078
+ function getEventTarget() {
6079
+ if (typeof window !== "undefined" && typeof window.addEventListener === "function") return window;
6080
+ if (typeof EventTarget === "undefined") return null;
6081
+ const sharedGlobal = globalThis;
6082
+ sharedGlobal.__COPILOTKIT_INSPECTOR_THREAD_EVENT_TARGET__ ??= new EventTarget();
6083
+ return sharedGlobal.__COPILOTKIT_INSPECTOR_THREAD_EVENT_TARGET__;
6084
+ }
6085
+ function createDetailEvent(name, detail) {
6086
+ if (typeof CustomEvent !== "undefined") return new CustomEvent(name, { detail });
6087
+ const event = new Event(name);
6088
+ Object.defineProperty(event, "detail", { value: detail });
6089
+ return event;
6090
+ }
6091
+ function detailFromEvent(event) {
6092
+ return event.detail;
6093
+ }
6094
+ /** The Inspector thread bridge is development-only. */
6095
+ function isInspectorThreadBridgeEnabled() {
6096
+ return process.env.NODE_ENV !== "production";
6097
+ }
6098
+ function createInspectorThreadRequestId() {
6099
+ if (typeof crypto !== "undefined" && "randomUUID" in crypto) return crypto.randomUUID();
6100
+ return `inspector-${Date.now()}-${Math.random().toString(36).slice(2)}`;
6101
+ }
6102
+ function dispatch(suffix, payload) {
6103
+ if (!isInspectorThreadBridgeEnabled()) return;
6104
+ const target = getEventTarget();
6105
+ if (!target) return;
6106
+ target.dispatchEvent(createDetailEvent(eventName(suffix), payload));
6107
+ }
6108
+ function on$1(suffix, handler) {
6109
+ if (!isInspectorThreadBridgeEnabled()) return () => void 0;
6110
+ const target = getEventTarget();
6111
+ if (!target) return () => void 0;
6112
+ const listener = (event) => {
6113
+ handler(detailFromEvent(event));
6114
+ };
6115
+ const name = eventName(suffix);
6116
+ target.addEventListener(name, listener);
6117
+ return () => target.removeEventListener(name, listener);
6118
+ }
6119
+ /**
6120
+ * Ask the first mounted official chat for the matching agent to load a thread.
6121
+ * Returns false when no chat claims the request synchronously.
6122
+ */
6123
+ function emitInspectorViewThread(payload) {
6124
+ if (!isInspectorThreadBridgeEnabled()) return false;
6125
+ const target = getEventTarget();
6126
+ if (!target) return false;
6127
+ const detail = {
6128
+ payload,
6129
+ claimed: false
6130
+ };
6131
+ target.dispatchEvent(createDetailEvent(eventName("view-thread"), detail));
6132
+ return detail.claimed;
6133
+ }
6134
+ function emitInspectorStopViewing(payload) {
6135
+ dispatch("stop-viewing", payload);
6136
+ }
6137
+ function emitInspectorActiveThread(payload) {
6138
+ dispatch("active-thread", payload);
6139
+ }
6140
+ function emitInspectorViewThreadResult(payload) {
6141
+ dispatch("view-thread-result", payload);
6142
+ }
6143
+ function onInspectorViewThread(handler) {
6144
+ if (!isInspectorThreadBridgeEnabled()) return () => void 0;
6145
+ const target = getEventTarget();
6146
+ if (!target) return () => void 0;
6147
+ const listener = (event) => {
6148
+ const detail = detailFromEvent(event);
6149
+ if (detail.claimed) return;
6150
+ detail.claimed = handler(detail.payload);
6151
+ };
6152
+ const name = eventName("view-thread");
6153
+ target.addEventListener(name, listener);
6154
+ return () => target.removeEventListener(name, listener);
6155
+ }
6156
+ function onInspectorStopViewing(handler) {
6157
+ return on$1("stop-viewing", handler);
6158
+ }
6159
+ function onInspectorActiveThread(handler) {
6160
+ return on$1("active-thread", handler);
6161
+ }
6162
+ function onInspectorViewThreadResult(handler) {
6163
+ return on$1("view-thread-result", handler);
6164
+ }
6165
+
6166
+ //#endregion
6167
+ export { AgentRegistry, AgentThreadLockedError, ContextStore, CopilotKitCore, CopilotKitCoreErrorCode, CopilotKitCoreRuntimeConnectionStatus, INSPECTOR_THREAD_BRIDGE_PLUGIN_ID, IntelligenceAgent, MEMORY_ERROR_REGISTRY, MemoryError, ProxiedCopilotRuntimeAgent, RunHandler, StateManager, SuggestionEngine, ToolCallStatus, completePartialMarkdown, createActionGroup, createEffect, createInspectorThreadRequestId, createReducer, createSelector, createStore, emitInspectorActiveThread, emitInspectorStopViewing, emitInspectorViewThread, emitInspectorViewThreadResult, empty, ensureObjectArgs, isAbortError, isInspectorThreadBridgeEnabled, isRunCompletionAware, ofType, on, onInspectorActiveThread, onInspectorStopViewing, onInspectorViewThread, onInspectorViewThreadResult, parseToolArguments, props, select, ɵCOPILOTKIT_FEATURES, ɵInterruptState, ɵMAX_SOCKET_RETRIES, createMemoryStore as ɵcreateMemoryStore, ɵcreateThreadSelectors, createThreadStore as ɵcreateThreadStore, ɵisCopilotKitFeature, isRetryableStatus as ɵisRetryableMemoryStatus, ɵjoinPhoenixChannel$, ɵmapMemoryMetadataEvent, ɵmemoryAdapterEvents, ɵmemoryDomainEvents, ɵmemoryReducer, ɵmemoryRestEvents, ɵobservePhoenixEvent$, ɵobservePhoenixJoinOutcome$, ɵobservePhoenixSocketHealth$, ɵobservePhoenixSocketSignals$, ɵphoenixChannel$, ɵphoenixSocket$, ɵselectFetchMoreError, ɵselectHasNextPage, ɵselectIsFetchingNextPage, ɵselectIsMutating, ɵselectMemories, ɵselectMemoriesAvailable, ɵselectMemoriesError, ɵselectMemoriesIsLoading, ɵselectMemoriesIsMutating, ɵselectMemoriesRealtimeStatus, ɵselectThreads, ɵselectThreadsError, ɵselectThreadsIsLoading, ɵthreadAdapterEvents };
5983
6168
  //# sourceMappingURL=index.mjs.map