@copilotkit/react-core 1.56.5 → 1.57.0-canary.1778078321
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-DFaI4j2r.d.mts → copilotkit-BNlJq5UO.d.mts} +60 -6
- package/dist/copilotkit-BNlJq5UO.d.mts.map +1 -0
- package/dist/{copilotkit-Dg4r4Gi_.d.cts → copilotkit-DgC5oCFO.d.cts} +60 -6
- package/dist/copilotkit-DgC5oCFO.d.cts.map +1 -0
- package/dist/{copilotkit-OmIUrWym.mjs → copilotkit-DhuXdtE1.mjs} +317 -176
- package/dist/copilotkit-DhuXdtE1.mjs.map +1 -0
- package/dist/{copilotkit-DMFu29Kx.cjs → copilotkit-XGd8L2jL.cjs} +322 -175
- package/dist/copilotkit-XGd8L2jL.cjs.map +1 -0
- package/dist/index.cjs +2 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +2 -5
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +117 -172
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/index.cjs +2 -1
- package/dist/v2/index.css +1 -1
- package/dist/v2/index.d.cts +2 -2
- package/dist/v2/index.d.mts +2 -2
- package/dist/v2/index.mjs +2 -2
- package/dist/v2/index.umd.js +332 -181
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +6 -6
- package/src/hooks/__tests__/use-copilot-chat-internal-connect.test.tsx +5 -6
- package/src/hooks/use-copilot-chat_internal.ts +0 -1
- package/src/v2/components/chat/CopilotChat.tsx +2 -1
- package/src/v2/components/chat/CopilotChatMessageView.tsx +24 -9
- package/src/v2/components/chat/CopilotChatView.tsx +2 -2
- package/src/v2/components/chat/__tests__/CopilotChat.welcomeGate.test.tsx +1 -3
- package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.tsx +29 -25
- package/src/v2/components/chat/__tests__/MCPAppsUiMessage.e2e.test.tsx +5 -60
- package/src/v2/components/index.ts +1 -0
- package/src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx +284 -0
- package/src/v2/components/intelligence-indicator/__tests__/IntelligenceIndicator.e2e.test.tsx +464 -0
- package/src/v2/components/intelligence-indicator/index.ts +2 -0
- package/src/v2/hooks/__tests__/use-threads.test.tsx +229 -27
- package/src/v2/hooks/use-agent.tsx +7 -116
- package/src/v2/hooks/use-render-activity-message.tsx +3 -11
- package/src/v2/hooks/use-render-custom-messages.tsx +1 -6
- package/src/v2/hooks/use-threads.tsx +7 -1
- package/src/v2/styles/globals.css +118 -0
- package/dist/copilotkit-DFaI4j2r.d.mts.map +0 -1
- package/dist/copilotkit-DMFu29Kx.cjs.map +0 -1
- package/dist/copilotkit-Dg4r4Gi_.d.cts.map +0 -1
- package/dist/copilotkit-OmIUrWym.mjs.map +0 -1
- package/src/v2/hooks/__tests__/use-agent-thread-isolation.test.tsx +0 -333
|
@@ -3481,168 +3481,6 @@ function useRenderToolCall() {
|
|
|
3481
3481
|
]);
|
|
3482
3482
|
}
|
|
3483
3483
|
|
|
3484
|
-
//#endregion
|
|
3485
|
-
//#region src/v2/hooks/use-agent.tsx
|
|
3486
|
-
let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
|
|
3487
|
-
UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
|
|
3488
|
-
UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
|
|
3489
|
-
UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
|
|
3490
|
-
return UseAgentUpdate;
|
|
3491
|
-
}({});
|
|
3492
|
-
const ALL_UPDATES = [
|
|
3493
|
-
UseAgentUpdate.OnMessagesChanged,
|
|
3494
|
-
UseAgentUpdate.OnStateChanged,
|
|
3495
|
-
UseAgentUpdate.OnRunStatusChanged
|
|
3496
|
-
];
|
|
3497
|
-
/**
|
|
3498
|
-
* Clone a registry agent for per-thread isolation.
|
|
3499
|
-
* Copies agent configuration (transport, headers, etc.) but resets conversation
|
|
3500
|
-
* state (messages, threadId, state) so each thread starts fresh.
|
|
3501
|
-
*/
|
|
3502
|
-
function cloneForThread(source, threadId, headers) {
|
|
3503
|
-
const clone = source.clone();
|
|
3504
|
-
if (clone === source) throw new Error(`useAgent: ${source.constructor.name}.clone() returned the same instance. clone() must return a new, independent object.`);
|
|
3505
|
-
clone.threadId = threadId;
|
|
3506
|
-
clone.setMessages([]);
|
|
3507
|
-
clone.setState({});
|
|
3508
|
-
if (clone instanceof HttpAgent) clone.headers = { ...headers };
|
|
3509
|
-
return clone;
|
|
3510
|
-
}
|
|
3511
|
-
/**
|
|
3512
|
-
* Module-level WeakMap: registryAgent → (threadId → clone).
|
|
3513
|
-
* Shared across all useAgent() calls so that every component using the same
|
|
3514
|
-
* (agentId, threadId) pair receives the same agent instance. Using WeakMap
|
|
3515
|
-
* ensures the clone map is garbage-collected when the registry agent is
|
|
3516
|
-
* replaced (e.g. after reconnect or hot-reload).
|
|
3517
|
-
*/
|
|
3518
|
-
const globalThreadCloneMap = /* @__PURE__ */ new WeakMap();
|
|
3519
|
-
/**
|
|
3520
|
-
* Look up an existing per-thread clone without creating one.
|
|
3521
|
-
* Returns undefined when no clone has been created yet for this pair.
|
|
3522
|
-
*/
|
|
3523
|
-
function getThreadClone(registryAgent, threadId) {
|
|
3524
|
-
if (!registryAgent || !threadId) return void 0;
|
|
3525
|
-
return globalThreadCloneMap.get(registryAgent)?.get(threadId);
|
|
3526
|
-
}
|
|
3527
|
-
function getOrCreateThreadClone(existing, threadId, headers) {
|
|
3528
|
-
let byThread = globalThreadCloneMap.get(existing);
|
|
3529
|
-
if (!byThread) {
|
|
3530
|
-
byThread = /* @__PURE__ */ new Map();
|
|
3531
|
-
globalThreadCloneMap.set(existing, byThread);
|
|
3532
|
-
}
|
|
3533
|
-
const cached = byThread.get(threadId);
|
|
3534
|
-
if (cached) return cached;
|
|
3535
|
-
const clone = cloneForThread(existing, threadId, headers);
|
|
3536
|
-
byThread.set(threadId, clone);
|
|
3537
|
-
return clone;
|
|
3538
|
-
}
|
|
3539
|
-
function useAgent({ agentId, threadId, updates, throttleMs } = {}) {
|
|
3540
|
-
agentId ??= DEFAULT_AGENT_ID;
|
|
3541
|
-
const { copilotkit } = useCopilotKit();
|
|
3542
|
-
const providerThrottleMs = copilotkit.defaultThrottleMs;
|
|
3543
|
-
const chatConfig = useCopilotChatConfiguration();
|
|
3544
|
-
threadId ??= chatConfig?.threadId;
|
|
3545
|
-
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
3546
|
-
const updateFlags = useMemo(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
|
|
3547
|
-
const provisionalAgentCache = useRef(/* @__PURE__ */ new Map());
|
|
3548
|
-
const agent = useMemo(() => {
|
|
3549
|
-
const cacheKey = threadId ? `${agentId}:${threadId}` : agentId;
|
|
3550
|
-
const existing = copilotkit.getAgent(agentId);
|
|
3551
|
-
if (existing) {
|
|
3552
|
-
provisionalAgentCache.current.delete(cacheKey);
|
|
3553
|
-
provisionalAgentCache.current.delete(agentId);
|
|
3554
|
-
if (!threadId) return existing;
|
|
3555
|
-
return getOrCreateThreadClone(existing, threadId, copilotkit.headers);
|
|
3556
|
-
}
|
|
3557
|
-
const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
|
|
3558
|
-
const status = copilotkit.runtimeConnectionStatus;
|
|
3559
|
-
if (isRuntimeConfigured && (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
|
|
3560
|
-
const cached = provisionalAgentCache.current.get(cacheKey);
|
|
3561
|
-
if (cached) {
|
|
3562
|
-
cached.headers = { ...copilotkit.headers };
|
|
3563
|
-
return cached;
|
|
3564
|
-
}
|
|
3565
|
-
const provisional = new ProxiedCopilotRuntimeAgent({
|
|
3566
|
-
runtimeUrl: copilotkit.runtimeUrl,
|
|
3567
|
-
agentId,
|
|
3568
|
-
transport: copilotkit.runtimeTransport,
|
|
3569
|
-
runtimeMode: "pending"
|
|
3570
|
-
});
|
|
3571
|
-
provisional.headers = { ...copilotkit.headers };
|
|
3572
|
-
if (threadId) provisional.threadId = threadId;
|
|
3573
|
-
provisionalAgentCache.current.set(cacheKey, provisional);
|
|
3574
|
-
return provisional;
|
|
3575
|
-
}
|
|
3576
|
-
if (isRuntimeConfigured && status === CopilotKitCoreRuntimeConnectionStatus.Error) {
|
|
3577
|
-
const cached = provisionalAgentCache.current.get(cacheKey);
|
|
3578
|
-
if (cached) {
|
|
3579
|
-
cached.headers = { ...copilotkit.headers };
|
|
3580
|
-
return cached;
|
|
3581
|
-
}
|
|
3582
|
-
const provisional = new ProxiedCopilotRuntimeAgent({
|
|
3583
|
-
runtimeUrl: copilotkit.runtimeUrl,
|
|
3584
|
-
agentId,
|
|
3585
|
-
transport: copilotkit.runtimeTransport,
|
|
3586
|
-
runtimeMode: "pending"
|
|
3587
|
-
});
|
|
3588
|
-
provisional.headers = { ...copilotkit.headers };
|
|
3589
|
-
if (threadId) provisional.threadId = threadId;
|
|
3590
|
-
provisionalAgentCache.current.set(cacheKey, provisional);
|
|
3591
|
-
return provisional;
|
|
3592
|
-
}
|
|
3593
|
-
const knownAgents = Object.keys(copilotkit.agents ?? {});
|
|
3594
|
-
const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
|
|
3595
|
-
throw new Error(`useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` + (knownAgents.length ? `Known agents: [${knownAgents.join(", ")}]` : "No agents registered.") + " Verify your runtime /info and/or agents__unsafe_dev_only.");
|
|
3596
|
-
}, [
|
|
3597
|
-
agentId,
|
|
3598
|
-
threadId,
|
|
3599
|
-
copilotkit.agents,
|
|
3600
|
-
copilotkit.runtimeConnectionStatus,
|
|
3601
|
-
copilotkit.runtimeUrl,
|
|
3602
|
-
copilotkit.runtimeTransport,
|
|
3603
|
-
JSON.stringify(copilotkit.headers)
|
|
3604
|
-
]);
|
|
3605
|
-
useEffect(() => {
|
|
3606
|
-
if (updateFlags.length === 0) return;
|
|
3607
|
-
let active = true;
|
|
3608
|
-
const handlers = {};
|
|
3609
|
-
let batchScheduled = false;
|
|
3610
|
-
const batchedForceUpdate = () => {
|
|
3611
|
-
if (!active) return;
|
|
3612
|
-
if (!batchScheduled) {
|
|
3613
|
-
batchScheduled = true;
|
|
3614
|
-
queueMicrotask(() => {
|
|
3615
|
-
batchScheduled = false;
|
|
3616
|
-
if (active) forceUpdate();
|
|
3617
|
-
});
|
|
3618
|
-
}
|
|
3619
|
-
};
|
|
3620
|
-
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = forceUpdate;
|
|
3621
|
-
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
|
|
3622
|
-
if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
|
|
3623
|
-
handlers.onRunInitialized = batchedForceUpdate;
|
|
3624
|
-
handlers.onRunFinalized = batchedForceUpdate;
|
|
3625
|
-
handlers.onRunFailed = batchedForceUpdate;
|
|
3626
|
-
handlers.onRunErrorEvent = batchedForceUpdate;
|
|
3627
|
-
}
|
|
3628
|
-
const subscription = copilotkit.subscribeToAgentWithOptions(agent, handlers, { throttleMs });
|
|
3629
|
-
return () => {
|
|
3630
|
-
active = false;
|
|
3631
|
-
subscription.unsubscribe();
|
|
3632
|
-
};
|
|
3633
|
-
}, [
|
|
3634
|
-
agent,
|
|
3635
|
-
forceUpdate,
|
|
3636
|
-
throttleMs,
|
|
3637
|
-
providerThrottleMs,
|
|
3638
|
-
updateFlags
|
|
3639
|
-
]);
|
|
3640
|
-
useEffect(() => {
|
|
3641
|
-
if (agent instanceof HttpAgent) agent.headers = { ...copilotkit.headers };
|
|
3642
|
-
}, [agent, JSON.stringify(copilotkit.headers)]);
|
|
3643
|
-
return { agent };
|
|
3644
|
-
}
|
|
3645
|
-
|
|
3646
3484
|
//#endregion
|
|
3647
3485
|
//#region src/v2/hooks/use-render-custom-messages.tsx
|
|
3648
3486
|
function useRenderCustomMessages() {
|
|
@@ -3660,8 +3498,7 @@ function useRenderCustomMessages() {
|
|
|
3660
3498
|
const { message, position } = params;
|
|
3661
3499
|
const resolvedRunId = copilotkit.getRunIdForMessage(agentId, threadId, message.id) ?? copilotkit.getRunIdsForThread(agentId, threadId).slice(-1)[0];
|
|
3662
3500
|
const runId = resolvedRunId ?? `missing-run-id:${message.id}`;
|
|
3663
|
-
const
|
|
3664
|
-
const agent = getThreadClone(registryAgent, threadId) ?? registryAgent;
|
|
3501
|
+
const agent = copilotkit.getAgent(agentId);
|
|
3665
3502
|
if (!agent) return null;
|
|
3666
3503
|
const messagesIdsInRun = resolvedRunId ? agent.messages.filter((msg) => copilotkit.getRunIdForMessage(agentId, threadId, msg.id) === resolvedRunId).map((msg) => msg.id) : [message.id];
|
|
3667
3504
|
const rawMessageIndex = agent.messages.findIndex((msg) => msg.id === message.id);
|
|
@@ -3693,8 +3530,7 @@ function useRenderCustomMessages() {
|
|
|
3693
3530
|
//#region src/v2/hooks/use-render-activity-message.tsx
|
|
3694
3531
|
function useRenderActivityMessage() {
|
|
3695
3532
|
const { copilotkit } = useCopilotKit();
|
|
3696
|
-
const
|
|
3697
|
-
const agentId = config?.agentId ?? DEFAULT_AGENT_ID;
|
|
3533
|
+
const agentId = useCopilotChatConfiguration()?.agentId ?? DEFAULT_AGENT_ID;
|
|
3698
3534
|
const renderers = copilotkit.renderActivityMessages;
|
|
3699
3535
|
const findRenderer = useCallback((activityType) => {
|
|
3700
3536
|
if (!renderers.length) return null;
|
|
@@ -3710,8 +3546,7 @@ function useRenderActivityMessage() {
|
|
|
3710
3546
|
return null;
|
|
3711
3547
|
}
|
|
3712
3548
|
const Component = renderer.render;
|
|
3713
|
-
const
|
|
3714
|
-
const agent = getThreadClone(registryAgent, config?.threadId) ?? registryAgent;
|
|
3549
|
+
const agent = copilotkit.getAgent(agentId);
|
|
3715
3550
|
return /* @__PURE__ */ jsx(Component, {
|
|
3716
3551
|
activityType: message.activityType,
|
|
3717
3552
|
content: parseResult.data,
|
|
@@ -3720,7 +3555,6 @@ function useRenderActivityMessage() {
|
|
|
3720
3555
|
}, message.id);
|
|
3721
3556
|
}, [
|
|
3722
3557
|
agentId,
|
|
3723
|
-
config?.threadId,
|
|
3724
3558
|
copilotkit,
|
|
3725
3559
|
findRenderer
|
|
3726
3560
|
]);
|
|
@@ -4160,6 +3994,118 @@ function useHumanInTheLoop(tool, deps) {
|
|
|
4160
3994
|
]);
|
|
4161
3995
|
}
|
|
4162
3996
|
|
|
3997
|
+
//#endregion
|
|
3998
|
+
//#region src/v2/hooks/use-agent.tsx
|
|
3999
|
+
let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
|
|
4000
|
+
UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
|
|
4001
|
+
UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
|
|
4002
|
+
UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
|
|
4003
|
+
return UseAgentUpdate;
|
|
4004
|
+
}({});
|
|
4005
|
+
const ALL_UPDATES = [
|
|
4006
|
+
UseAgentUpdate.OnMessagesChanged,
|
|
4007
|
+
UseAgentUpdate.OnStateChanged,
|
|
4008
|
+
UseAgentUpdate.OnRunStatusChanged
|
|
4009
|
+
];
|
|
4010
|
+
function useAgent({ agentId, updates, throttleMs } = {}) {
|
|
4011
|
+
agentId ??= DEFAULT_AGENT_ID;
|
|
4012
|
+
const { copilotkit } = useCopilotKit();
|
|
4013
|
+
const providerThrottleMs = copilotkit.defaultThrottleMs;
|
|
4014
|
+
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
4015
|
+
const updateFlags = useMemo(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
|
|
4016
|
+
const provisionalAgentCache = useRef(/* @__PURE__ */ new Map());
|
|
4017
|
+
const agent = useMemo(() => {
|
|
4018
|
+
const existing = copilotkit.getAgent(agentId);
|
|
4019
|
+
if (existing) {
|
|
4020
|
+
provisionalAgentCache.current.delete(agentId);
|
|
4021
|
+
return existing;
|
|
4022
|
+
}
|
|
4023
|
+
const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
|
|
4024
|
+
const status = copilotkit.runtimeConnectionStatus;
|
|
4025
|
+
if (isRuntimeConfigured && (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
|
|
4026
|
+
const cached = provisionalAgentCache.current.get(agentId);
|
|
4027
|
+
if (cached) {
|
|
4028
|
+
cached.headers = { ...copilotkit.headers };
|
|
4029
|
+
return cached;
|
|
4030
|
+
}
|
|
4031
|
+
const provisional = new ProxiedCopilotRuntimeAgent({
|
|
4032
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
4033
|
+
agentId,
|
|
4034
|
+
transport: copilotkit.runtimeTransport,
|
|
4035
|
+
runtimeMode: "pending"
|
|
4036
|
+
});
|
|
4037
|
+
provisional.headers = { ...copilotkit.headers };
|
|
4038
|
+
provisionalAgentCache.current.set(agentId, provisional);
|
|
4039
|
+
return provisional;
|
|
4040
|
+
}
|
|
4041
|
+
if (isRuntimeConfigured && status === CopilotKitCoreRuntimeConnectionStatus.Error) {
|
|
4042
|
+
const cached = provisionalAgentCache.current.get(agentId);
|
|
4043
|
+
if (cached) {
|
|
4044
|
+
cached.headers = { ...copilotkit.headers };
|
|
4045
|
+
return cached;
|
|
4046
|
+
}
|
|
4047
|
+
const provisional = new ProxiedCopilotRuntimeAgent({
|
|
4048
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
4049
|
+
agentId,
|
|
4050
|
+
transport: copilotkit.runtimeTransport,
|
|
4051
|
+
runtimeMode: "pending"
|
|
4052
|
+
});
|
|
4053
|
+
provisional.headers = { ...copilotkit.headers };
|
|
4054
|
+
provisionalAgentCache.current.set(agentId, provisional);
|
|
4055
|
+
return provisional;
|
|
4056
|
+
}
|
|
4057
|
+
const knownAgents = Object.keys(copilotkit.agents ?? {});
|
|
4058
|
+
const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
|
|
4059
|
+
throw new Error(`useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` + (knownAgents.length ? `Known agents: [${knownAgents.join(", ")}]` : "No agents registered.") + " Verify your runtime /info and/or agents__unsafe_dev_only.");
|
|
4060
|
+
}, [
|
|
4061
|
+
agentId,
|
|
4062
|
+
copilotkit.agents,
|
|
4063
|
+
copilotkit.runtimeConnectionStatus,
|
|
4064
|
+
copilotkit.runtimeUrl,
|
|
4065
|
+
copilotkit.runtimeTransport,
|
|
4066
|
+
JSON.stringify(copilotkit.headers)
|
|
4067
|
+
]);
|
|
4068
|
+
useEffect(() => {
|
|
4069
|
+
if (updateFlags.length === 0) return;
|
|
4070
|
+
let active = true;
|
|
4071
|
+
const handlers = {};
|
|
4072
|
+
let batchScheduled = false;
|
|
4073
|
+
const batchedForceUpdate = () => {
|
|
4074
|
+
if (!active) return;
|
|
4075
|
+
if (!batchScheduled) {
|
|
4076
|
+
batchScheduled = true;
|
|
4077
|
+
queueMicrotask(() => {
|
|
4078
|
+
batchScheduled = false;
|
|
4079
|
+
if (active) forceUpdate();
|
|
4080
|
+
});
|
|
4081
|
+
}
|
|
4082
|
+
};
|
|
4083
|
+
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = forceUpdate;
|
|
4084
|
+
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
|
|
4085
|
+
if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
|
|
4086
|
+
handlers.onRunInitialized = batchedForceUpdate;
|
|
4087
|
+
handlers.onRunFinalized = batchedForceUpdate;
|
|
4088
|
+
handlers.onRunFailed = batchedForceUpdate;
|
|
4089
|
+
handlers.onRunErrorEvent = batchedForceUpdate;
|
|
4090
|
+
}
|
|
4091
|
+
const subscription = copilotkit.subscribeToAgentWithOptions(agent, handlers, { throttleMs });
|
|
4092
|
+
return () => {
|
|
4093
|
+
active = false;
|
|
4094
|
+
subscription.unsubscribe();
|
|
4095
|
+
};
|
|
4096
|
+
}, [
|
|
4097
|
+
agent,
|
|
4098
|
+
forceUpdate,
|
|
4099
|
+
throttleMs,
|
|
4100
|
+
providerThrottleMs,
|
|
4101
|
+
updateFlags
|
|
4102
|
+
]);
|
|
4103
|
+
useEffect(() => {
|
|
4104
|
+
if (agent instanceof HttpAgent) agent.headers = { ...copilotkit.headers };
|
|
4105
|
+
}, [agent, JSON.stringify(copilotkit.headers)]);
|
|
4106
|
+
return { agent };
|
|
4107
|
+
}
|
|
4108
|
+
|
|
4163
4109
|
//#endregion
|
|
4164
4110
|
//#region src/v2/hooks/use-capabilities.tsx
|
|
4165
4111
|
/**
|
|
@@ -4643,6 +4589,16 @@ function useThreads$1({ agentId, includeArchived, limit }) {
|
|
|
4643
4589
|
};
|
|
4644
4590
|
}, [store]);
|
|
4645
4591
|
const runtimeStatus = copilotkit.runtimeConnectionStatus;
|
|
4592
|
+
useEffect(() => {
|
|
4593
|
+
copilotkit.registerThreadStore(agentId, store);
|
|
4594
|
+
return () => {
|
|
4595
|
+
copilotkit.unregisterThreadStore(agentId);
|
|
4596
|
+
};
|
|
4597
|
+
}, [
|
|
4598
|
+
copilotkit,
|
|
4599
|
+
agentId,
|
|
4600
|
+
store
|
|
4601
|
+
]);
|
|
4646
4602
|
useEffect(() => {
|
|
4647
4603
|
if (!copilotkit.runtimeUrl) {
|
|
4648
4604
|
store.setContext(null);
|
|
@@ -4666,7 +4622,6 @@ function useThreads$1({ agentId, includeArchived, limit }) {
|
|
|
4666
4622
|
headersKey,
|
|
4667
4623
|
copilotkit.intelligence?.wsUrl,
|
|
4668
4624
|
agentId,
|
|
4669
|
-
copilotkit.headers,
|
|
4670
4625
|
includeArchived,
|
|
4671
4626
|
limit
|
|
4672
4627
|
]);
|
|
@@ -5616,6 +5571,190 @@ CopilotChatSuggestionView.displayName = "CopilotChatSuggestionView";
|
|
|
5616
5571
|
*/
|
|
5617
5572
|
const ScrollElementContext = React.createContext(null);
|
|
5618
5573
|
|
|
5574
|
+
//#endregion
|
|
5575
|
+
//#region src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx
|
|
5576
|
+
/**
|
|
5577
|
+
* Grace window before showing the spinner. A matching tool call must
|
|
5578
|
+
* remain unresolved (no `tool`-role result message in `agent.messages`)
|
|
5579
|
+
* for at least this long before the pill appears. This filters out
|
|
5580
|
+
* history-replay flashes — during `connectAgent` replay, tool calls and
|
|
5581
|
+
* their results arrive back-to-back in sub-millisecond bursts, so the
|
|
5582
|
+
* timer is cancelled before it fires. Live runs cross the threshold
|
|
5583
|
+
* easily because the tool actually has to execute.
|
|
5584
|
+
*/
|
|
5585
|
+
const PENDING_THRESHOLD_MS = 100;
|
|
5586
|
+
/** Hold the checkmark briefly before fading out. */
|
|
5587
|
+
const CHECK_HOLD_MS = 800;
|
|
5588
|
+
/**
|
|
5589
|
+
* Duration of the fade-out animation. Must match
|
|
5590
|
+
* `cpk-intelligence-pill-fade-out` keyframes in `v2/styles/globals.css`.
|
|
5591
|
+
*/
|
|
5592
|
+
const FADE_OUT_ANIMATION_MS = 480;
|
|
5593
|
+
/**
|
|
5594
|
+
* Tool-name regex patterns that trigger the indicator. Currently
|
|
5595
|
+
* hardcoded to the Intelligence MCP server's canonical tool name. If
|
|
5596
|
+
* we add per-instance customization later (e.g. a `CopilotKitProvider`
|
|
5597
|
+
* prop or a runtime-info field), this constant becomes the fallback.
|
|
5598
|
+
*/
|
|
5599
|
+
const DEFAULT_TOOL_PATTERNS = [/^bash$/];
|
|
5600
|
+
const isMatchingToolCallName = (name) => typeof name === "string" && DEFAULT_TOOL_PATTERNS.some((p) => p.test(name));
|
|
5601
|
+
/**
|
|
5602
|
+
* "Tool-call-like" messages do NOT count as a real follow-up: tool
|
|
5603
|
+
* result messages, assistant messages that carry tool calls, and
|
|
5604
|
+
* empty-content assistant messages (which some providers emit as a
|
|
5605
|
+
* standalone wrapper around a batch of tool calls). A real follow-up
|
|
5606
|
+
* is anything else — most importantly an assistant message with prose
|
|
5607
|
+
* content, or a fresh user message.
|
|
5608
|
+
*/
|
|
5609
|
+
const isToolCallLikeMessage = (m) => {
|
|
5610
|
+
if (m.role === "tool") return true;
|
|
5611
|
+
if (m.role === "assistant") {
|
|
5612
|
+
if ((Array.isArray(m.toolCalls) ? m.toolCalls : []).length > 0) return true;
|
|
5613
|
+
const content = m.content;
|
|
5614
|
+
return typeof content !== "string" || content.trim().length === 0;
|
|
5615
|
+
}
|
|
5616
|
+
return false;
|
|
5617
|
+
};
|
|
5618
|
+
/**
|
|
5619
|
+
* The "Using CopilotKit Intelligence" pill. Auto-mounted by
|
|
5620
|
+
* `CopilotChatMessageView` for every message slot when
|
|
5621
|
+
* `copilotkit.intelligence` is configured — callers do not register
|
|
5622
|
+
* this themselves. Self-gates so only the canonical message renders a
|
|
5623
|
+
* pill.
|
|
5624
|
+
*
|
|
5625
|
+
* Render gates (all must hold):
|
|
5626
|
+
* 1. `copilotkit.intelligence !== undefined`
|
|
5627
|
+
* 2. The message is an assistant message with at least one tool call
|
|
5628
|
+
* whose name matches {@link DEFAULT_TOOL_PATTERNS}
|
|
5629
|
+
* 3. The message is the *latest* such matching-assistant message in
|
|
5630
|
+
* `agent.messages` — tool-result messages and prose-only assistant
|
|
5631
|
+
* messages don't invalidate the slot, so the pill stays
|
|
5632
|
+
* continuously through a multi-step tool chain.
|
|
5633
|
+
* 4. The phase machine is past `idle` (the pending-grace timer fired)
|
|
5634
|
+
* and not yet `hidden`.
|
|
5635
|
+
*
|
|
5636
|
+
* Phase machine (per-instance, all timers local):
|
|
5637
|
+
* - Starts in `idle` — nothing rendered.
|
|
5638
|
+
* - `idle → spinner` once a matching tool call has been pending
|
|
5639
|
+
* (no `tool`-role result with a matching `toolCallId`) for
|
|
5640
|
+
* {@link PENDING_THRESHOLD_MS}. Replay flashes (tool call + result
|
|
5641
|
+
* in the same tick) never cross this threshold.
|
|
5642
|
+
* - `spinner → check` as soon as EITHER `agent.isRunning` flips
|
|
5643
|
+
* false OR a non-tool-call-like message appears later in
|
|
5644
|
+
* `agent.messages` (i.e. the agent has produced a "real"
|
|
5645
|
+
* follow-up — prose answer or a new user turn).
|
|
5646
|
+
* - `check → fading` after {@link CHECK_HOLD_MS}.
|
|
5647
|
+
* - `fading → hidden` after {@link FADE_OUT_ANIMATION_MS}.
|
|
5648
|
+
*
|
|
5649
|
+
* Once `hidden`, the phase is sticky — a finished pill never re-spawns
|
|
5650
|
+
* on the same message. New runs mount fresh indicator instances on
|
|
5651
|
+
* their own assistant messages.
|
|
5652
|
+
*
|
|
5653
|
+
* The "exactly one pill at a time" guarantee is structural: only one
|
|
5654
|
+
* message satisfies the latest-matching-assistant gate at any moment.
|
|
5655
|
+
*/
|
|
5656
|
+
function IntelligenceIndicator(props) {
|
|
5657
|
+
const { message, agentId, label = "Using CopilotKit Intelligence" } = props;
|
|
5658
|
+
const { copilotkit } = useCopilotKit();
|
|
5659
|
+
const config = useCopilotChatConfiguration();
|
|
5660
|
+
const { agent } = useAgent({
|
|
5661
|
+
agentId,
|
|
5662
|
+
updates: [UseAgentUpdate.OnRunStatusChanged, UseAgentUpdate.OnMessagesChanged]
|
|
5663
|
+
});
|
|
5664
|
+
const matchingToolCallIds = useMemo(() => {
|
|
5665
|
+
if (message.role !== "assistant") return [];
|
|
5666
|
+
const tcs = Array.isArray(message.toolCalls) ? message.toolCalls : [];
|
|
5667
|
+
const ids = [];
|
|
5668
|
+
for (const tc of tcs) if (isMatchingToolCallName(tc?.function?.name) && tc?.id) ids.push(tc.id);
|
|
5669
|
+
return ids;
|
|
5670
|
+
}, [message]);
|
|
5671
|
+
const hasPending = useMemo(() => {
|
|
5672
|
+
if (matchingToolCallIds.length === 0) return false;
|
|
5673
|
+
const resolved = /* @__PURE__ */ new Set();
|
|
5674
|
+
for (const m of agent.messages) if (m.role === "tool" && m.toolCallId) resolved.add(m.toolCallId);
|
|
5675
|
+
return matchingToolCallIds.some((id) => !resolved.has(id));
|
|
5676
|
+
}, [matchingToolCallIds, agent.messages]);
|
|
5677
|
+
const sawRealFollowup = useMemo(() => {
|
|
5678
|
+
const idx = agent.messages.findIndex((m) => m.id === message.id);
|
|
5679
|
+
if (idx < 0) return false;
|
|
5680
|
+
for (let i = idx + 1; i < agent.messages.length; i += 1) if (!isToolCallLikeMessage(agent.messages[i])) return true;
|
|
5681
|
+
return false;
|
|
5682
|
+
}, [agent.messages, message.id]);
|
|
5683
|
+
const [phase, setPhase] = useState("idle");
|
|
5684
|
+
useEffect(() => {
|
|
5685
|
+
if (phase !== "idle") return void 0;
|
|
5686
|
+
if (!hasPending) return void 0;
|
|
5687
|
+
const t = setTimeout(() => setPhase("spinner"), PENDING_THRESHOLD_MS);
|
|
5688
|
+
return () => clearTimeout(t);
|
|
5689
|
+
}, [phase, hasPending]);
|
|
5690
|
+
useEffect(() => {
|
|
5691
|
+
if (phase !== "spinner") return void 0;
|
|
5692
|
+
if (!agent.isRunning || sawRealFollowup) setPhase("check");
|
|
5693
|
+
}, [
|
|
5694
|
+
phase,
|
|
5695
|
+
agent.isRunning,
|
|
5696
|
+
sawRealFollowup
|
|
5697
|
+
]);
|
|
5698
|
+
useEffect(() => {
|
|
5699
|
+
if (phase !== "check") return void 0;
|
|
5700
|
+
const t = setTimeout(() => setPhase("fading"), CHECK_HOLD_MS);
|
|
5701
|
+
return () => clearTimeout(t);
|
|
5702
|
+
}, [phase]);
|
|
5703
|
+
useEffect(() => {
|
|
5704
|
+
if (phase !== "fading") return void 0;
|
|
5705
|
+
const t = setTimeout(() => setPhase("hidden"), FADE_OUT_ANIMATION_MS);
|
|
5706
|
+
return () => clearTimeout(t);
|
|
5707
|
+
}, [phase]);
|
|
5708
|
+
if (copilotkit.intelligence === void 0) return null;
|
|
5709
|
+
if (!config) return null;
|
|
5710
|
+
if (phase === "idle" || phase === "hidden") return null;
|
|
5711
|
+
if (message.role !== "assistant") return null;
|
|
5712
|
+
if (!(Array.isArray(message.toolCalls) ? message.toolCalls : []).some((tc) => isMatchingToolCallName(tc?.function?.name))) return null;
|
|
5713
|
+
let latestMatchingAssistantId;
|
|
5714
|
+
for (let i = agent.messages.length - 1; i >= 0; i -= 1) {
|
|
5715
|
+
const m = agent.messages[i];
|
|
5716
|
+
if (m.role !== "assistant") continue;
|
|
5717
|
+
if ((Array.isArray(m.toolCalls) ? m.toolCalls : []).some((tc) => isMatchingToolCallName(tc?.function?.name))) {
|
|
5718
|
+
latestMatchingAssistantId = m.id;
|
|
5719
|
+
break;
|
|
5720
|
+
}
|
|
5721
|
+
}
|
|
5722
|
+
if (latestMatchingAssistantId !== message.id) return null;
|
|
5723
|
+
const showSpinner = phase === "spinner";
|
|
5724
|
+
const isFading = phase === "fading";
|
|
5725
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
5726
|
+
className: "cpk-intelligence-pill" + (isFading ? " cpk-intelligence-pill--fading" : ""),
|
|
5727
|
+
role: "status",
|
|
5728
|
+
"aria-live": "polite",
|
|
5729
|
+
"aria-hidden": isFading || void 0,
|
|
5730
|
+
"data-testid": `cpk-intelligence-pill-${message.id}`,
|
|
5731
|
+
title: label,
|
|
5732
|
+
children: [/* @__PURE__ */ jsxs("svg", {
|
|
5733
|
+
className: "cpk-intelligence-pill__icon",
|
|
5734
|
+
viewBox: "0 0 24 24",
|
|
5735
|
+
width: "14",
|
|
5736
|
+
height: "14",
|
|
5737
|
+
"aria-hidden": "true",
|
|
5738
|
+
children: [/* @__PURE__ */ jsx("circle", {
|
|
5739
|
+
cx: "12",
|
|
5740
|
+
cy: "12",
|
|
5741
|
+
r: "9",
|
|
5742
|
+
fill: "none",
|
|
5743
|
+
strokeWidth: "2.5",
|
|
5744
|
+
strokeLinecap: "round",
|
|
5745
|
+
className: "cpk-intelligence-pill__ring" + (showSpinner ? "" : " cpk-intelligence-pill__ring--done")
|
|
5746
|
+
}), /* @__PURE__ */ jsx("path", {
|
|
5747
|
+
d: "M8 12.5l3 3 5-6",
|
|
5748
|
+
fill: "none",
|
|
5749
|
+
strokeWidth: "2.5",
|
|
5750
|
+
strokeLinecap: "round",
|
|
5751
|
+
strokeLinejoin: "round",
|
|
5752
|
+
className: "cpk-intelligence-pill__check" + (showSpinner ? "" : " cpk-intelligence-pill__check--shown")
|
|
5753
|
+
})]
|
|
5754
|
+
}), /* @__PURE__ */ jsx("span", { children: label })]
|
|
5755
|
+
});
|
|
5756
|
+
}
|
|
5757
|
+
|
|
5619
5758
|
//#endregion
|
|
5620
5759
|
//#region src/v2/components/chat/CopilotChatMessageView.tsx
|
|
5621
5760
|
/**
|
|
@@ -5773,14 +5912,12 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
|
|
|
5773
5912
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
5774
5913
|
useEffect(() => {
|
|
5775
5914
|
if (!config?.agentId) return;
|
|
5776
|
-
const
|
|
5777
|
-
const agent = getThreadClone(registryAgent, config.threadId) ?? registryAgent;
|
|
5915
|
+
const agent = copilotkit.getAgent(config.agentId);
|
|
5778
5916
|
if (!agent) return;
|
|
5779
5917
|
const subscription = agent.subscribe({ onStateChanged: forceUpdate });
|
|
5780
5918
|
return () => subscription.unsubscribe();
|
|
5781
5919
|
}, [
|
|
5782
5920
|
config?.agentId,
|
|
5783
|
-
config?.threadId,
|
|
5784
5921
|
copilotkit,
|
|
5785
5922
|
forceUpdate
|
|
5786
5923
|
]);
|
|
@@ -5863,6 +6000,10 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
|
|
|
5863
6000
|
renderCustomMessage,
|
|
5864
6001
|
stateSnapshot
|
|
5865
6002
|
}, `${message.id}-custom-after`));
|
|
6003
|
+
if (copilotkit.intelligence !== void 0 && message.role === "assistant") elements.push(/* @__PURE__ */ jsx(IntelligenceIndicator, {
|
|
6004
|
+
message,
|
|
6005
|
+
agentId: config?.agentId ?? DEFAULT_AGENT_ID
|
|
6006
|
+
}, `${message.id}-intelligence`));
|
|
5866
6007
|
return elements.filter(Boolean);
|
|
5867
6008
|
};
|
|
5868
6009
|
const messageElements = shouldVirtualize ? [] : deduplicatedMessages.flatMap(renderMessageBlock);
|
|
@@ -6811,7 +6952,6 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
6811
6952
|
const hasExplicitThreadId = !!threadId || !!existingConfig?.hasExplicitThreadId;
|
|
6812
6953
|
const { agent } = useAgent({
|
|
6813
6954
|
agentId: resolvedAgentId,
|
|
6814
|
-
threadId: resolvedThreadId,
|
|
6815
6955
|
throttleMs
|
|
6816
6956
|
});
|
|
6817
6957
|
const { copilotkit } = useCopilotKit();
|
|
@@ -6853,6 +6993,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
6853
6993
|
let detached = false;
|
|
6854
6994
|
const connectAbortController = new AbortController();
|
|
6855
6995
|
if (agent instanceof HttpAgent) agent.abortController = connectAbortController;
|
|
6996
|
+
agent.threadId = resolvedThreadId;
|
|
6856
6997
|
const connect = async (agent) => {
|
|
6857
6998
|
try {
|
|
6858
6999
|
await copilotkit.connectAgent({ agent });
|
|
@@ -9793,5 +9934,5 @@ function validateProps(props) {
|
|
|
9793
9934
|
}
|
|
9794
9935
|
|
|
9795
9936
|
//#endregion
|
|
9796
|
-
export {
|
|
9797
|
-
//# sourceMappingURL=copilotkit-
|
|
9937
|
+
export { useRenderToolCall as $, IntelligenceIndicator as A, useInterrupt as B, CopilotChatToggleButton as C, CopilotChatView_default as D, CopilotChat as E, CopilotChatAttachmentRenderer as F, useAgent as G, useSuggestions as H, CopilotChatAssistantMessage_default as I, useRenderTool as J, useHumanInTheLoop as K, CopilotChatToolCallsView as L, CopilotChatSuggestionPill as M, CopilotChatReasoningMessage_default as N, CopilotChatAttachmentQueue as O, CopilotChatUserMessage_default as P, useRenderCustomMessages as Q, useAttachments as R, CopilotModalHeader as S, DefaultOpenIcon as T, useCapabilities as U, useConfigureSuggestions as V, UseAgentUpdate as W, useFrontendTool as X, useComponent as Y, useRenderActivityMessage as Z, WildcardToolCallRender as _, ThreadsProvider as a, createA2UIMessageRenderer as at, CopilotPopupView as b, CoAgentStateRendersProvider as c, MCPAppsActivityContentSchema as ct, shouldShowDevConsole as d, CopilotKitInspector as dt, CopilotKitProvider as et, useToast as f, CopilotChatInput_default as ft, useCopilotContext as g, useCopilotChatConfiguration as gt, CopilotContext as h, CopilotChatConfigurationProvider as ht, ThreadsContext as i, defineToolCallRenderer as it, CopilotChatSuggestionView as j, CopilotChatMessageView as k, useCoAgentStateRenders as l, MCPAppsActivityRenderer as lt, useCopilotMessagesContext as m, CopilotChatAudioRecorder as mt, defaultCopilotContextCategories as n, CopilotKitCoreReact as nt, useThreads as o, SandboxFunctionsContext as ot, CopilotMessagesContext as p, AudioRecorderError as pt, useDefaultRenderTool as q, CoAgentStateRenderBridge as r, useAgentContext as rt, CoAgentStateRendersContext as s, useSandboxFunctions as st, CopilotKit as t, useCopilotKit as tt, useAsyncCallback as u, MCPAppsActivityType as ut, CopilotPopup as v, DefaultCloseIcon as w, CopilotSidebarView as x, CopilotSidebar as y, useThreads$1 as z };
|
|
9938
|
+
//# sourceMappingURL=copilotkit-DhuXdtE1.mjs.map
|