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