@copilotkit/react-core 1.66.2 → 1.66.4
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/copilotkit-CBCT7BlL.d.cts.map +1 -1
- package/dist/copilotkit-D0aAnD3i.d.mts.map +1 -1
- package/dist/{copilotkit-DnlgZWST.mjs → copilotkit-nRjRp2_5.mjs} +73 -19
- package/dist/copilotkit-nRjRp2_5.mjs.map +1 -0
- package/dist/{copilotkit-2v7ami2b.cjs → copilotkit-sitn7Oe8.cjs} +73 -19
- package/dist/copilotkit-sitn7Oe8.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.umd.js +35 -16
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/headless.cjs +35 -16
- package/dist/v2/headless.cjs.map +1 -1
- package/dist/v2/headless.mjs +35 -16
- package/dist/v2/headless.mjs.map +1 -1
- package/dist/v2/index.cjs +1 -1
- package/dist/v2/index.mjs +1 -1
- package/dist/v2/index.umd.js +72 -18
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +7 -7
- package/dist/copilotkit-2v7ami2b.cjs.map +0 -1
- package/dist/copilotkit-DnlgZWST.mjs.map +0 -1
|
@@ -4936,6 +4936,8 @@ function useInterrupt(config) {
|
|
|
4936
4936
|
pendingRef.current = pending;
|
|
4937
4937
|
const [handlerResult, setHandlerResult] = (0, react.useState)(null);
|
|
4938
4938
|
const interruptStateRef = (0, react.useRef)(new _copilotkit_core.ɵInterruptState());
|
|
4939
|
+
const interruptRunIdsRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
4940
|
+
const legacyRunIdRef = (0, react.useRef)(void 0);
|
|
4939
4941
|
(0, react.useEffect)(() => {
|
|
4940
4942
|
const interruptState = interruptStateRef.current;
|
|
4941
4943
|
let localLegacy = null;
|
|
@@ -4948,19 +4950,26 @@ function useInterrupt(config) {
|
|
|
4948
4950
|
};
|
|
4949
4951
|
},
|
|
4950
4952
|
onRunFinishedEvent: (params) => {
|
|
4951
|
-
if (params.outcome === "interrupt")
|
|
4953
|
+
if (params.outcome === "interrupt") {
|
|
4954
|
+
const runId = params.input.runId;
|
|
4955
|
+
for (const interrupt of params.interrupts) interruptRunIdsRef.current.set(interrupt.id, runId);
|
|
4956
|
+
localStandard = params.interrupts;
|
|
4957
|
+
}
|
|
4952
4958
|
},
|
|
4953
4959
|
onRunStartedEvent: () => {
|
|
4954
4960
|
localLegacy = null;
|
|
4955
4961
|
localStandard = null;
|
|
4962
|
+
interruptRunIdsRef.current.clear();
|
|
4963
|
+
legacyRunIdRef.current = void 0;
|
|
4956
4964
|
interruptState.clear();
|
|
4957
4965
|
setPending(null);
|
|
4958
4966
|
},
|
|
4959
|
-
onRunFinalized: () => {
|
|
4967
|
+
onRunFinalized: (params) => {
|
|
4960
4968
|
if (localStandard && localStandard.length > 0) {
|
|
4961
4969
|
interruptState.setStandard(localStandard);
|
|
4962
4970
|
setPending(interruptState.pending);
|
|
4963
4971
|
} else if (localLegacy) {
|
|
4972
|
+
legacyRunIdRef.current = params.input.runId;
|
|
4964
4973
|
interruptState.setLegacy(localLegacy);
|
|
4965
4974
|
setPending(interruptState.pending);
|
|
4966
4975
|
}
|
|
@@ -4970,6 +4979,8 @@ function useInterrupt(config) {
|
|
|
4970
4979
|
onRunFailed: () => {
|
|
4971
4980
|
localLegacy = null;
|
|
4972
4981
|
localStandard = null;
|
|
4982
|
+
interruptRunIdsRef.current.clear();
|
|
4983
|
+
legacyRunIdRef.current = void 0;
|
|
4973
4984
|
interruptState.clear();
|
|
4974
4985
|
setPending(null);
|
|
4975
4986
|
}
|
|
@@ -4984,18 +4995,22 @@ function useInterrupt(config) {
|
|
|
4984
4995
|
if (!current) return;
|
|
4985
4996
|
if (current.kind === "standard" && current.interrupts.length > 1 && interruptId === void 0) console.warn(`[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`);
|
|
4986
4997
|
const decision = interruptStateRef.current.resolve(payload, interruptId);
|
|
4987
|
-
if (decision.kind === "legacy-resume")
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4998
|
+
if (decision.kind === "legacy-resume") {
|
|
4999
|
+
const runId = legacyRunIdRef.current;
|
|
5000
|
+
try {
|
|
5001
|
+
return await copilotkit.runAgent({
|
|
5002
|
+
agent,
|
|
5003
|
+
...runId !== void 0 ? { runId } : {},
|
|
5004
|
+
forwardedProps: { command: {
|
|
5005
|
+
resume: decision.payload,
|
|
5006
|
+
interruptEvent: decision.interruptValue
|
|
5007
|
+
} }
|
|
5008
|
+
});
|
|
5009
|
+
} catch (err) {
|
|
5010
|
+
console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
|
|
5011
|
+
setPending(null);
|
|
5012
|
+
throw err;
|
|
5013
|
+
}
|
|
4999
5014
|
}
|
|
5000
5015
|
if (decision.kind === "expired") {
|
|
5001
5016
|
console.error(`[CopilotKit] useInterrupt: interrupt ${decision.interrupt.id} expired at ${decision.interrupt.expiresAt}; not resuming.`);
|
|
@@ -5004,6 +5019,7 @@ function useInterrupt(config) {
|
|
|
5004
5019
|
return;
|
|
5005
5020
|
}
|
|
5006
5021
|
if (decision.kind !== "resume") return;
|
|
5022
|
+
const runId = decision.resume.map((entry) => interruptRunIdsRef.current.get(entry.interruptId)).find((candidate) => candidate !== void 0);
|
|
5007
5023
|
for (const toolResult of decision.toolResults) agent.addMessage({
|
|
5008
5024
|
id: (0, _ag_ui_client.randomUUID)(),
|
|
5009
5025
|
role: "tool",
|
|
@@ -5013,7 +5029,8 @@ function useInterrupt(config) {
|
|
|
5013
5029
|
try {
|
|
5014
5030
|
return await copilotkit.runAgent({
|
|
5015
5031
|
agent,
|
|
5016
|
-
resume: decision.resume
|
|
5032
|
+
resume: decision.resume,
|
|
5033
|
+
...runId !== void 0 ? { runId } : {}
|
|
5017
5034
|
});
|
|
5018
5035
|
} catch (err) {
|
|
5019
5036
|
console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
|
|
@@ -5040,6 +5057,7 @@ function useInterrupt(config) {
|
|
|
5040
5057
|
return;
|
|
5041
5058
|
}
|
|
5042
5059
|
if (decision.kind !== "resume") return;
|
|
5060
|
+
const runId = decision.resume.map((entry) => interruptRunIdsRef.current.get(entry.interruptId)).find((candidate) => candidate !== void 0);
|
|
5043
5061
|
for (const toolResult of decision.toolResults) agent.addMessage({
|
|
5044
5062
|
id: (0, _ag_ui_client.randomUUID)(),
|
|
5045
5063
|
role: "tool",
|
|
@@ -5049,7 +5067,8 @@ function useInterrupt(config) {
|
|
|
5049
5067
|
try {
|
|
5050
5068
|
return await copilotkit.runAgent({
|
|
5051
5069
|
agent,
|
|
5052
|
-
resume: decision.resume
|
|
5070
|
+
resume: decision.resume,
|
|
5071
|
+
...runId !== void 0 ? { runId } : {}
|
|
5053
5072
|
});
|
|
5054
5073
|
} catch (err) {
|
|
5055
5074
|
console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
|
|
@@ -7064,6 +7083,37 @@ const MemoizedCustomMessage = react.default.memo(function MemoizedCustomMessage(
|
|
|
7064
7083
|
*
|
|
7065
7084
|
* @internal Exported for unit testing only — not part of the public API.
|
|
7066
7085
|
*/
|
|
7086
|
+
/**
|
|
7087
|
+
* Collapse tool calls that share an id, keeping first-seen order.
|
|
7088
|
+
*
|
|
7089
|
+
* AG-UI's TOOL_CALL_START handler appends to the parent message's `toolCalls`
|
|
7090
|
+
* without checking whether that id is already present. So whenever a start
|
|
7091
|
+
* event is applied twice — which the human-in-the-loop flow triggers when the
|
|
7092
|
+
* run syncs after `respond()` — the message ends up carrying the same call
|
|
7093
|
+
* twice. The second copy has EMPTY `arguments`, because a start event carries
|
|
7094
|
+
* none; the args arrive later as TOOL_CALL_ARGS deltas addressed to the first
|
|
7095
|
+
* copy.
|
|
7096
|
+
*
|
|
7097
|
+
* Left alone that renders the same tool call twice: once populated and once
|
|
7098
|
+
* blank (an approval card with no transaction id, offering live buttons for an
|
|
7099
|
+
* action already taken), and React warns "Encountered two children with the
|
|
7100
|
+
* same key" because the call id is the render key.
|
|
7101
|
+
*
|
|
7102
|
+
* The empty copy is the redundant one, so prefer whichever entry actually
|
|
7103
|
+
* carries arguments rather than blindly taking the first.
|
|
7104
|
+
*/
|
|
7105
|
+
function dedupeToolCalls(toolCalls) {
|
|
7106
|
+
const byId = /* @__PURE__ */ new Map();
|
|
7107
|
+
for (const toolCall of toolCalls) {
|
|
7108
|
+
const existing = byId.get(toolCall.id);
|
|
7109
|
+
if (!existing) {
|
|
7110
|
+
byId.set(toolCall.id, toolCall);
|
|
7111
|
+
continue;
|
|
7112
|
+
}
|
|
7113
|
+
if (!existing.function?.arguments && toolCall.function?.arguments) byId.set(toolCall.id, toolCall);
|
|
7114
|
+
}
|
|
7115
|
+
return byId.size === toolCalls.length ? toolCalls : [...byId.values()];
|
|
7116
|
+
}
|
|
7067
7117
|
function deduplicateMessages(messages) {
|
|
7068
7118
|
const acc = /* @__PURE__ */ new Map();
|
|
7069
7119
|
for (const message of messages) {
|
|
@@ -7075,9 +7125,13 @@ function deduplicateMessages(messages) {
|
|
|
7075
7125
|
...existing,
|
|
7076
7126
|
...message,
|
|
7077
7127
|
content,
|
|
7078
|
-
toolCalls
|
|
7128
|
+
toolCalls: toolCalls ? dedupeToolCalls(toolCalls) : toolCalls
|
|
7079
7129
|
});
|
|
7080
|
-
} else acc.set(message.id,
|
|
7130
|
+
} else if (message.role === "assistant" && message.toolCalls) acc.set(message.id, {
|
|
7131
|
+
...message,
|
|
7132
|
+
toolCalls: dedupeToolCalls(message.toolCalls)
|
|
7133
|
+
});
|
|
7134
|
+
else acc.set(message.id, message);
|
|
7081
7135
|
}
|
|
7082
7136
|
return [...acc.values()];
|
|
7083
7137
|
}
|
|
@@ -12267,4 +12321,4 @@ Object.defineProperty(exports, 'ɵrunMcpFollowUp', {
|
|
|
12267
12321
|
return ɵrunMcpFollowUp;
|
|
12268
12322
|
}
|
|
12269
12323
|
});
|
|
12270
|
-
//# sourceMappingURL=copilotkit-
|
|
12324
|
+
//# sourceMappingURL=copilotkit-sitn7Oe8.cjs.map
|