@copilotkit/react-core 1.56.5 → 1.57.0-canary.1778082736
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-DMFu29Kx.cjs → copilotkit-B_k0HSNz.cjs} +322 -175
- package/dist/copilotkit-B_k0HSNz.cjs.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-ak8sGvQr.mjs} +317 -176
- package/dist/copilotkit-ak8sGvQr.mjs.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 +286 -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
|
@@ -3511,168 +3511,6 @@ function useRenderToolCall() {
|
|
|
3511
3511
|
]);
|
|
3512
3512
|
}
|
|
3513
3513
|
|
|
3514
|
-
//#endregion
|
|
3515
|
-
//#region src/v2/hooks/use-agent.tsx
|
|
3516
|
-
let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
|
|
3517
|
-
UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
|
|
3518
|
-
UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
|
|
3519
|
-
UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
|
|
3520
|
-
return UseAgentUpdate;
|
|
3521
|
-
}({});
|
|
3522
|
-
const ALL_UPDATES = [
|
|
3523
|
-
UseAgentUpdate.OnMessagesChanged,
|
|
3524
|
-
UseAgentUpdate.OnStateChanged,
|
|
3525
|
-
UseAgentUpdate.OnRunStatusChanged
|
|
3526
|
-
];
|
|
3527
|
-
/**
|
|
3528
|
-
* Clone a registry agent for per-thread isolation.
|
|
3529
|
-
* Copies agent configuration (transport, headers, etc.) but resets conversation
|
|
3530
|
-
* state (messages, threadId, state) so each thread starts fresh.
|
|
3531
|
-
*/
|
|
3532
|
-
function cloneForThread(source, threadId, headers) {
|
|
3533
|
-
const clone = source.clone();
|
|
3534
|
-
if (clone === source) throw new Error(`useAgent: ${source.constructor.name}.clone() returned the same instance. clone() must return a new, independent object.`);
|
|
3535
|
-
clone.threadId = threadId;
|
|
3536
|
-
clone.setMessages([]);
|
|
3537
|
-
clone.setState({});
|
|
3538
|
-
if (clone instanceof _ag_ui_client.HttpAgent) clone.headers = { ...headers };
|
|
3539
|
-
return clone;
|
|
3540
|
-
}
|
|
3541
|
-
/**
|
|
3542
|
-
* Module-level WeakMap: registryAgent → (threadId → clone).
|
|
3543
|
-
* Shared across all useAgent() calls so that every component using the same
|
|
3544
|
-
* (agentId, threadId) pair receives the same agent instance. Using WeakMap
|
|
3545
|
-
* ensures the clone map is garbage-collected when the registry agent is
|
|
3546
|
-
* replaced (e.g. after reconnect or hot-reload).
|
|
3547
|
-
*/
|
|
3548
|
-
const globalThreadCloneMap = /* @__PURE__ */ new WeakMap();
|
|
3549
|
-
/**
|
|
3550
|
-
* Look up an existing per-thread clone without creating one.
|
|
3551
|
-
* Returns undefined when no clone has been created yet for this pair.
|
|
3552
|
-
*/
|
|
3553
|
-
function getThreadClone(registryAgent, threadId) {
|
|
3554
|
-
if (!registryAgent || !threadId) return void 0;
|
|
3555
|
-
return globalThreadCloneMap.get(registryAgent)?.get(threadId);
|
|
3556
|
-
}
|
|
3557
|
-
function getOrCreateThreadClone(existing, threadId, headers) {
|
|
3558
|
-
let byThread = globalThreadCloneMap.get(existing);
|
|
3559
|
-
if (!byThread) {
|
|
3560
|
-
byThread = /* @__PURE__ */ new Map();
|
|
3561
|
-
globalThreadCloneMap.set(existing, byThread);
|
|
3562
|
-
}
|
|
3563
|
-
const cached = byThread.get(threadId);
|
|
3564
|
-
if (cached) return cached;
|
|
3565
|
-
const clone = cloneForThread(existing, threadId, headers);
|
|
3566
|
-
byThread.set(threadId, clone);
|
|
3567
|
-
return clone;
|
|
3568
|
-
}
|
|
3569
|
-
function useAgent({ agentId, threadId, updates, throttleMs } = {}) {
|
|
3570
|
-
agentId ??= _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
3571
|
-
const { copilotkit } = useCopilotKit();
|
|
3572
|
-
const providerThrottleMs = copilotkit.defaultThrottleMs;
|
|
3573
|
-
const chatConfig = useCopilotChatConfiguration();
|
|
3574
|
-
threadId ??= chatConfig?.threadId;
|
|
3575
|
-
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
3576
|
-
const updateFlags = (0, react.useMemo)(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
|
|
3577
|
-
const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
3578
|
-
const agent = (0, react.useMemo)(() => {
|
|
3579
|
-
const cacheKey = threadId ? `${agentId}:${threadId}` : agentId;
|
|
3580
|
-
const existing = copilotkit.getAgent(agentId);
|
|
3581
|
-
if (existing) {
|
|
3582
|
-
provisionalAgentCache.current.delete(cacheKey);
|
|
3583
|
-
provisionalAgentCache.current.delete(agentId);
|
|
3584
|
-
if (!threadId) return existing;
|
|
3585
|
-
return getOrCreateThreadClone(existing, threadId, copilotkit.headers);
|
|
3586
|
-
}
|
|
3587
|
-
const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
|
|
3588
|
-
const status = copilotkit.runtimeConnectionStatus;
|
|
3589
|
-
if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
|
|
3590
|
-
const cached = provisionalAgentCache.current.get(cacheKey);
|
|
3591
|
-
if (cached) {
|
|
3592
|
-
cached.headers = { ...copilotkit.headers };
|
|
3593
|
-
return cached;
|
|
3594
|
-
}
|
|
3595
|
-
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
3596
|
-
runtimeUrl: copilotkit.runtimeUrl,
|
|
3597
|
-
agentId,
|
|
3598
|
-
transport: copilotkit.runtimeTransport,
|
|
3599
|
-
runtimeMode: "pending"
|
|
3600
|
-
});
|
|
3601
|
-
provisional.headers = { ...copilotkit.headers };
|
|
3602
|
-
if (threadId) provisional.threadId = threadId;
|
|
3603
|
-
provisionalAgentCache.current.set(cacheKey, provisional);
|
|
3604
|
-
return provisional;
|
|
3605
|
-
}
|
|
3606
|
-
if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
|
|
3607
|
-
const cached = provisionalAgentCache.current.get(cacheKey);
|
|
3608
|
-
if (cached) {
|
|
3609
|
-
cached.headers = { ...copilotkit.headers };
|
|
3610
|
-
return cached;
|
|
3611
|
-
}
|
|
3612
|
-
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
3613
|
-
runtimeUrl: copilotkit.runtimeUrl,
|
|
3614
|
-
agentId,
|
|
3615
|
-
transport: copilotkit.runtimeTransport,
|
|
3616
|
-
runtimeMode: "pending"
|
|
3617
|
-
});
|
|
3618
|
-
provisional.headers = { ...copilotkit.headers };
|
|
3619
|
-
if (threadId) provisional.threadId = threadId;
|
|
3620
|
-
provisionalAgentCache.current.set(cacheKey, provisional);
|
|
3621
|
-
return provisional;
|
|
3622
|
-
}
|
|
3623
|
-
const knownAgents = Object.keys(copilotkit.agents ?? {});
|
|
3624
|
-
const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
|
|
3625
|
-
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.");
|
|
3626
|
-
}, [
|
|
3627
|
-
agentId,
|
|
3628
|
-
threadId,
|
|
3629
|
-
copilotkit.agents,
|
|
3630
|
-
copilotkit.runtimeConnectionStatus,
|
|
3631
|
-
copilotkit.runtimeUrl,
|
|
3632
|
-
copilotkit.runtimeTransport,
|
|
3633
|
-
JSON.stringify(copilotkit.headers)
|
|
3634
|
-
]);
|
|
3635
|
-
(0, react.useEffect)(() => {
|
|
3636
|
-
if (updateFlags.length === 0) return;
|
|
3637
|
-
let active = true;
|
|
3638
|
-
const handlers = {};
|
|
3639
|
-
let batchScheduled = false;
|
|
3640
|
-
const batchedForceUpdate = () => {
|
|
3641
|
-
if (!active) return;
|
|
3642
|
-
if (!batchScheduled) {
|
|
3643
|
-
batchScheduled = true;
|
|
3644
|
-
queueMicrotask(() => {
|
|
3645
|
-
batchScheduled = false;
|
|
3646
|
-
if (active) forceUpdate();
|
|
3647
|
-
});
|
|
3648
|
-
}
|
|
3649
|
-
};
|
|
3650
|
-
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = forceUpdate;
|
|
3651
|
-
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
|
|
3652
|
-
if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
|
|
3653
|
-
handlers.onRunInitialized = batchedForceUpdate;
|
|
3654
|
-
handlers.onRunFinalized = batchedForceUpdate;
|
|
3655
|
-
handlers.onRunFailed = batchedForceUpdate;
|
|
3656
|
-
handlers.onRunErrorEvent = batchedForceUpdate;
|
|
3657
|
-
}
|
|
3658
|
-
const subscription = copilotkit.subscribeToAgentWithOptions(agent, handlers, { throttleMs });
|
|
3659
|
-
return () => {
|
|
3660
|
-
active = false;
|
|
3661
|
-
subscription.unsubscribe();
|
|
3662
|
-
};
|
|
3663
|
-
}, [
|
|
3664
|
-
agent,
|
|
3665
|
-
forceUpdate,
|
|
3666
|
-
throttleMs,
|
|
3667
|
-
providerThrottleMs,
|
|
3668
|
-
updateFlags
|
|
3669
|
-
]);
|
|
3670
|
-
(0, react.useEffect)(() => {
|
|
3671
|
-
if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...copilotkit.headers };
|
|
3672
|
-
}, [agent, JSON.stringify(copilotkit.headers)]);
|
|
3673
|
-
return { agent };
|
|
3674
|
-
}
|
|
3675
|
-
|
|
3676
3514
|
//#endregion
|
|
3677
3515
|
//#region src/v2/hooks/use-render-custom-messages.tsx
|
|
3678
3516
|
function useRenderCustomMessages() {
|
|
@@ -3690,8 +3528,7 @@ function useRenderCustomMessages() {
|
|
|
3690
3528
|
const { message, position } = params;
|
|
3691
3529
|
const resolvedRunId = copilotkit.getRunIdForMessage(agentId, threadId, message.id) ?? copilotkit.getRunIdsForThread(agentId, threadId).slice(-1)[0];
|
|
3692
3530
|
const runId = resolvedRunId ?? `missing-run-id:${message.id}`;
|
|
3693
|
-
const
|
|
3694
|
-
const agent = getThreadClone(registryAgent, threadId) ?? registryAgent;
|
|
3531
|
+
const agent = copilotkit.getAgent(agentId);
|
|
3695
3532
|
if (!agent) return null;
|
|
3696
3533
|
const messagesIdsInRun = resolvedRunId ? agent.messages.filter((msg) => copilotkit.getRunIdForMessage(agentId, threadId, msg.id) === resolvedRunId).map((msg) => msg.id) : [message.id];
|
|
3697
3534
|
const rawMessageIndex = agent.messages.findIndex((msg) => msg.id === message.id);
|
|
@@ -3723,8 +3560,7 @@ function useRenderCustomMessages() {
|
|
|
3723
3560
|
//#region src/v2/hooks/use-render-activity-message.tsx
|
|
3724
3561
|
function useRenderActivityMessage() {
|
|
3725
3562
|
const { copilotkit } = useCopilotKit();
|
|
3726
|
-
const
|
|
3727
|
-
const agentId = config?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
3563
|
+
const agentId = useCopilotChatConfiguration()?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
3728
3564
|
const renderers = copilotkit.renderActivityMessages;
|
|
3729
3565
|
const findRenderer = (0, react.useCallback)((activityType) => {
|
|
3730
3566
|
if (!renderers.length) return null;
|
|
@@ -3740,8 +3576,7 @@ function useRenderActivityMessage() {
|
|
|
3740
3576
|
return null;
|
|
3741
3577
|
}
|
|
3742
3578
|
const Component = renderer.render;
|
|
3743
|
-
const
|
|
3744
|
-
const agent = getThreadClone(registryAgent, config?.threadId) ?? registryAgent;
|
|
3579
|
+
const agent = copilotkit.getAgent(agentId);
|
|
3745
3580
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {
|
|
3746
3581
|
activityType: message.activityType,
|
|
3747
3582
|
content: parseResult.data,
|
|
@@ -3750,7 +3585,6 @@ function useRenderActivityMessage() {
|
|
|
3750
3585
|
}, message.id);
|
|
3751
3586
|
}, [
|
|
3752
3587
|
agentId,
|
|
3753
|
-
config?.threadId,
|
|
3754
3588
|
copilotkit,
|
|
3755
3589
|
findRenderer
|
|
3756
3590
|
]);
|
|
@@ -4190,6 +4024,118 @@ function useHumanInTheLoop(tool, deps) {
|
|
|
4190
4024
|
]);
|
|
4191
4025
|
}
|
|
4192
4026
|
|
|
4027
|
+
//#endregion
|
|
4028
|
+
//#region src/v2/hooks/use-agent.tsx
|
|
4029
|
+
let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
|
|
4030
|
+
UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
|
|
4031
|
+
UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
|
|
4032
|
+
UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
|
|
4033
|
+
return UseAgentUpdate;
|
|
4034
|
+
}({});
|
|
4035
|
+
const ALL_UPDATES = [
|
|
4036
|
+
UseAgentUpdate.OnMessagesChanged,
|
|
4037
|
+
UseAgentUpdate.OnStateChanged,
|
|
4038
|
+
UseAgentUpdate.OnRunStatusChanged
|
|
4039
|
+
];
|
|
4040
|
+
function useAgent({ agentId, updates, throttleMs } = {}) {
|
|
4041
|
+
agentId ??= _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
4042
|
+
const { copilotkit } = useCopilotKit();
|
|
4043
|
+
const providerThrottleMs = copilotkit.defaultThrottleMs;
|
|
4044
|
+
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
4045
|
+
const updateFlags = (0, react.useMemo)(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
|
|
4046
|
+
const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
4047
|
+
const agent = (0, react.useMemo)(() => {
|
|
4048
|
+
const existing = copilotkit.getAgent(agentId);
|
|
4049
|
+
if (existing) {
|
|
4050
|
+
provisionalAgentCache.current.delete(agentId);
|
|
4051
|
+
return existing;
|
|
4052
|
+
}
|
|
4053
|
+
const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
|
|
4054
|
+
const status = copilotkit.runtimeConnectionStatus;
|
|
4055
|
+
if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
|
|
4056
|
+
const cached = provisionalAgentCache.current.get(agentId);
|
|
4057
|
+
if (cached) {
|
|
4058
|
+
cached.headers = { ...copilotkit.headers };
|
|
4059
|
+
return cached;
|
|
4060
|
+
}
|
|
4061
|
+
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
4062
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
4063
|
+
agentId,
|
|
4064
|
+
transport: copilotkit.runtimeTransport,
|
|
4065
|
+
runtimeMode: "pending"
|
|
4066
|
+
});
|
|
4067
|
+
provisional.headers = { ...copilotkit.headers };
|
|
4068
|
+
provisionalAgentCache.current.set(agentId, provisional);
|
|
4069
|
+
return provisional;
|
|
4070
|
+
}
|
|
4071
|
+
if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
|
|
4072
|
+
const cached = provisionalAgentCache.current.get(agentId);
|
|
4073
|
+
if (cached) {
|
|
4074
|
+
cached.headers = { ...copilotkit.headers };
|
|
4075
|
+
return cached;
|
|
4076
|
+
}
|
|
4077
|
+
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
4078
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
4079
|
+
agentId,
|
|
4080
|
+
transport: copilotkit.runtimeTransport,
|
|
4081
|
+
runtimeMode: "pending"
|
|
4082
|
+
});
|
|
4083
|
+
provisional.headers = { ...copilotkit.headers };
|
|
4084
|
+
provisionalAgentCache.current.set(agentId, provisional);
|
|
4085
|
+
return provisional;
|
|
4086
|
+
}
|
|
4087
|
+
const knownAgents = Object.keys(copilotkit.agents ?? {});
|
|
4088
|
+
const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
|
|
4089
|
+
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.");
|
|
4090
|
+
}, [
|
|
4091
|
+
agentId,
|
|
4092
|
+
copilotkit.agents,
|
|
4093
|
+
copilotkit.runtimeConnectionStatus,
|
|
4094
|
+
copilotkit.runtimeUrl,
|
|
4095
|
+
copilotkit.runtimeTransport,
|
|
4096
|
+
JSON.stringify(copilotkit.headers)
|
|
4097
|
+
]);
|
|
4098
|
+
(0, react.useEffect)(() => {
|
|
4099
|
+
if (updateFlags.length === 0) return;
|
|
4100
|
+
let active = true;
|
|
4101
|
+
const handlers = {};
|
|
4102
|
+
let batchScheduled = false;
|
|
4103
|
+
const batchedForceUpdate = () => {
|
|
4104
|
+
if (!active) return;
|
|
4105
|
+
if (!batchScheduled) {
|
|
4106
|
+
batchScheduled = true;
|
|
4107
|
+
queueMicrotask(() => {
|
|
4108
|
+
batchScheduled = false;
|
|
4109
|
+
if (active) forceUpdate();
|
|
4110
|
+
});
|
|
4111
|
+
}
|
|
4112
|
+
};
|
|
4113
|
+
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = forceUpdate;
|
|
4114
|
+
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
|
|
4115
|
+
if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
|
|
4116
|
+
handlers.onRunInitialized = batchedForceUpdate;
|
|
4117
|
+
handlers.onRunFinalized = batchedForceUpdate;
|
|
4118
|
+
handlers.onRunFailed = batchedForceUpdate;
|
|
4119
|
+
handlers.onRunErrorEvent = batchedForceUpdate;
|
|
4120
|
+
}
|
|
4121
|
+
const subscription = copilotkit.subscribeToAgentWithOptions(agent, handlers, { throttleMs });
|
|
4122
|
+
return () => {
|
|
4123
|
+
active = false;
|
|
4124
|
+
subscription.unsubscribe();
|
|
4125
|
+
};
|
|
4126
|
+
}, [
|
|
4127
|
+
agent,
|
|
4128
|
+
forceUpdate,
|
|
4129
|
+
throttleMs,
|
|
4130
|
+
providerThrottleMs,
|
|
4131
|
+
updateFlags
|
|
4132
|
+
]);
|
|
4133
|
+
(0, react.useEffect)(() => {
|
|
4134
|
+
if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...copilotkit.headers };
|
|
4135
|
+
}, [agent, JSON.stringify(copilotkit.headers)]);
|
|
4136
|
+
return { agent };
|
|
4137
|
+
}
|
|
4138
|
+
|
|
4193
4139
|
//#endregion
|
|
4194
4140
|
//#region src/v2/hooks/use-capabilities.tsx
|
|
4195
4141
|
/**
|
|
@@ -4673,6 +4619,16 @@ function useThreads$1({ agentId, includeArchived, limit }) {
|
|
|
4673
4619
|
};
|
|
4674
4620
|
}, [store]);
|
|
4675
4621
|
const runtimeStatus = copilotkit.runtimeConnectionStatus;
|
|
4622
|
+
(0, react.useEffect)(() => {
|
|
4623
|
+
copilotkit.registerThreadStore(agentId, store);
|
|
4624
|
+
return () => {
|
|
4625
|
+
copilotkit.unregisterThreadStore(agentId);
|
|
4626
|
+
};
|
|
4627
|
+
}, [
|
|
4628
|
+
copilotkit,
|
|
4629
|
+
agentId,
|
|
4630
|
+
store
|
|
4631
|
+
]);
|
|
4676
4632
|
(0, react.useEffect)(() => {
|
|
4677
4633
|
if (!copilotkit.runtimeUrl) {
|
|
4678
4634
|
store.setContext(null);
|
|
@@ -4696,7 +4652,6 @@ function useThreads$1({ agentId, includeArchived, limit }) {
|
|
|
4696
4652
|
headersKey,
|
|
4697
4653
|
copilotkit.intelligence?.wsUrl,
|
|
4698
4654
|
agentId,
|
|
4699
|
-
copilotkit.headers,
|
|
4700
4655
|
includeArchived,
|
|
4701
4656
|
limit
|
|
4702
4657
|
]);
|
|
@@ -5646,6 +5601,190 @@ CopilotChatSuggestionView.displayName = "CopilotChatSuggestionView";
|
|
|
5646
5601
|
*/
|
|
5647
5602
|
const ScrollElementContext = react.default.createContext(null);
|
|
5648
5603
|
|
|
5604
|
+
//#endregion
|
|
5605
|
+
//#region src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx
|
|
5606
|
+
/**
|
|
5607
|
+
* Grace window before showing the spinner. A matching tool call must
|
|
5608
|
+
* remain unresolved (no `tool`-role result message in `agent.messages`)
|
|
5609
|
+
* for at least this long before the pill appears. This filters out
|
|
5610
|
+
* history-replay flashes — during `connectAgent` replay, tool calls and
|
|
5611
|
+
* their results arrive back-to-back in sub-millisecond bursts, so the
|
|
5612
|
+
* timer is cancelled before it fires. Live runs cross the threshold
|
|
5613
|
+
* easily because the tool actually has to execute.
|
|
5614
|
+
*/
|
|
5615
|
+
const PENDING_THRESHOLD_MS = 100;
|
|
5616
|
+
/** Hold the checkmark briefly before fading out. */
|
|
5617
|
+
const CHECK_HOLD_MS = 800;
|
|
5618
|
+
/**
|
|
5619
|
+
* Duration of the fade-out animation. Must match
|
|
5620
|
+
* `cpk-intelligence-pill-fade-out` keyframes in `v2/styles/globals.css`.
|
|
5621
|
+
*/
|
|
5622
|
+
const FADE_OUT_ANIMATION_MS = 480;
|
|
5623
|
+
/**
|
|
5624
|
+
* Tool-name regex patterns that trigger the indicator. Currently
|
|
5625
|
+
* hardcoded to the Intelligence MCP server's canonical tool name. If
|
|
5626
|
+
* we add per-instance customization later (e.g. a `CopilotKitProvider`
|
|
5627
|
+
* prop or a runtime-info field), this constant becomes the fallback.
|
|
5628
|
+
*/
|
|
5629
|
+
const DEFAULT_TOOL_PATTERNS = [/^copilotkit_knowledge_base_shell$/];
|
|
5630
|
+
const isMatchingToolCallName = (name) => typeof name === "string" && DEFAULT_TOOL_PATTERNS.some((p) => p.test(name));
|
|
5631
|
+
/**
|
|
5632
|
+
* "Tool-call-like" messages do NOT count as a real follow-up: tool
|
|
5633
|
+
* result messages, assistant messages that carry tool calls, and
|
|
5634
|
+
* empty-content assistant messages (which some providers emit as a
|
|
5635
|
+
* standalone wrapper around a batch of tool calls). A real follow-up
|
|
5636
|
+
* is anything else — most importantly an assistant message with prose
|
|
5637
|
+
* content, or a fresh user message.
|
|
5638
|
+
*/
|
|
5639
|
+
const isToolCallLikeMessage = (m) => {
|
|
5640
|
+
if (m.role === "tool") return true;
|
|
5641
|
+
if (m.role === "assistant") {
|
|
5642
|
+
if ((Array.isArray(m.toolCalls) ? m.toolCalls : []).length > 0) return true;
|
|
5643
|
+
const content = m.content;
|
|
5644
|
+
return typeof content !== "string" || content.trim().length === 0;
|
|
5645
|
+
}
|
|
5646
|
+
return false;
|
|
5647
|
+
};
|
|
5648
|
+
/**
|
|
5649
|
+
* The "Using CopilotKit Intelligence" pill. Auto-mounted by
|
|
5650
|
+
* `CopilotChatMessageView` for every message slot when
|
|
5651
|
+
* `copilotkit.intelligence` is configured — callers do not register
|
|
5652
|
+
* this themselves. Self-gates so only the canonical message renders a
|
|
5653
|
+
* pill.
|
|
5654
|
+
*
|
|
5655
|
+
* Render gates (all must hold):
|
|
5656
|
+
* 1. `copilotkit.intelligence !== undefined`
|
|
5657
|
+
* 2. The message is an assistant message with at least one tool call
|
|
5658
|
+
* whose name matches {@link DEFAULT_TOOL_PATTERNS}
|
|
5659
|
+
* 3. The message is the *latest* such matching-assistant message in
|
|
5660
|
+
* `agent.messages` — tool-result messages and prose-only assistant
|
|
5661
|
+
* messages don't invalidate the slot, so the pill stays
|
|
5662
|
+
* continuously through a multi-step tool chain.
|
|
5663
|
+
* 4. The phase machine is past `idle` (the pending-grace timer fired)
|
|
5664
|
+
* and not yet `hidden`.
|
|
5665
|
+
*
|
|
5666
|
+
* Phase machine (per-instance, all timers local):
|
|
5667
|
+
* - Starts in `idle` — nothing rendered.
|
|
5668
|
+
* - `idle → spinner` once a matching tool call has been pending
|
|
5669
|
+
* (no `tool`-role result with a matching `toolCallId`) for
|
|
5670
|
+
* {@link PENDING_THRESHOLD_MS}. Replay flashes (tool call + result
|
|
5671
|
+
* in the same tick) never cross this threshold.
|
|
5672
|
+
* - `spinner → check` as soon as EITHER `agent.isRunning` flips
|
|
5673
|
+
* false OR a non-tool-call-like message appears later in
|
|
5674
|
+
* `agent.messages` (i.e. the agent has produced a "real"
|
|
5675
|
+
* follow-up — prose answer or a new user turn).
|
|
5676
|
+
* - `check → fading` after {@link CHECK_HOLD_MS}.
|
|
5677
|
+
* - `fading → hidden` after {@link FADE_OUT_ANIMATION_MS}.
|
|
5678
|
+
*
|
|
5679
|
+
* Once `hidden`, the phase is sticky — a finished pill never re-spawns
|
|
5680
|
+
* on the same message. New runs mount fresh indicator instances on
|
|
5681
|
+
* their own assistant messages.
|
|
5682
|
+
*
|
|
5683
|
+
* The "exactly one pill at a time" guarantee is structural: only one
|
|
5684
|
+
* message satisfies the latest-matching-assistant gate at any moment.
|
|
5685
|
+
*/
|
|
5686
|
+
function IntelligenceIndicator(props) {
|
|
5687
|
+
const { message, agentId, label = "Using CopilotKit Intelligence" } = props;
|
|
5688
|
+
const { copilotkit } = useCopilotKit();
|
|
5689
|
+
const config = useCopilotChatConfiguration();
|
|
5690
|
+
const { agent } = useAgent({
|
|
5691
|
+
agentId,
|
|
5692
|
+
updates: [UseAgentUpdate.OnRunStatusChanged, UseAgentUpdate.OnMessagesChanged]
|
|
5693
|
+
});
|
|
5694
|
+
const matchingToolCallIds = (0, react.useMemo)(() => {
|
|
5695
|
+
if (message.role !== "assistant") return [];
|
|
5696
|
+
const tcs = Array.isArray(message.toolCalls) ? message.toolCalls : [];
|
|
5697
|
+
const ids = [];
|
|
5698
|
+
for (const tc of tcs) if (isMatchingToolCallName(tc?.function?.name) && tc?.id) ids.push(tc.id);
|
|
5699
|
+
return ids;
|
|
5700
|
+
}, [message]);
|
|
5701
|
+
const hasPending = (0, react.useMemo)(() => {
|
|
5702
|
+
if (matchingToolCallIds.length === 0) return false;
|
|
5703
|
+
const resolved = /* @__PURE__ */ new Set();
|
|
5704
|
+
for (const m of agent.messages) if (m.role === "tool" && m.toolCallId) resolved.add(m.toolCallId);
|
|
5705
|
+
return matchingToolCallIds.some((id) => !resolved.has(id));
|
|
5706
|
+
}, [matchingToolCallIds, agent.messages]);
|
|
5707
|
+
const sawRealFollowup = (0, react.useMemo)(() => {
|
|
5708
|
+
const idx = agent.messages.findIndex((m) => m.id === message.id);
|
|
5709
|
+
if (idx < 0) return false;
|
|
5710
|
+
for (let i = idx + 1; i < agent.messages.length; i += 1) if (!isToolCallLikeMessage(agent.messages[i])) return true;
|
|
5711
|
+
return false;
|
|
5712
|
+
}, [agent.messages, message.id]);
|
|
5713
|
+
const [phase, setPhase] = (0, react.useState)("idle");
|
|
5714
|
+
(0, react.useEffect)(() => {
|
|
5715
|
+
if (phase !== "idle") return void 0;
|
|
5716
|
+
if (!hasPending) return void 0;
|
|
5717
|
+
const t = setTimeout(() => setPhase("spinner"), PENDING_THRESHOLD_MS);
|
|
5718
|
+
return () => clearTimeout(t);
|
|
5719
|
+
}, [phase, hasPending]);
|
|
5720
|
+
(0, react.useEffect)(() => {
|
|
5721
|
+
if (phase !== "spinner") return void 0;
|
|
5722
|
+
if (!agent.isRunning || sawRealFollowup) setPhase("check");
|
|
5723
|
+
}, [
|
|
5724
|
+
phase,
|
|
5725
|
+
agent.isRunning,
|
|
5726
|
+
sawRealFollowup
|
|
5727
|
+
]);
|
|
5728
|
+
(0, react.useEffect)(() => {
|
|
5729
|
+
if (phase !== "check") return void 0;
|
|
5730
|
+
const t = setTimeout(() => setPhase("fading"), CHECK_HOLD_MS);
|
|
5731
|
+
return () => clearTimeout(t);
|
|
5732
|
+
}, [phase]);
|
|
5733
|
+
(0, react.useEffect)(() => {
|
|
5734
|
+
if (phase !== "fading") return void 0;
|
|
5735
|
+
const t = setTimeout(() => setPhase("hidden"), FADE_OUT_ANIMATION_MS);
|
|
5736
|
+
return () => clearTimeout(t);
|
|
5737
|
+
}, [phase]);
|
|
5738
|
+
if (copilotkit.intelligence === void 0) return null;
|
|
5739
|
+
if (!config) return null;
|
|
5740
|
+
if (phase === "idle" || phase === "hidden") return null;
|
|
5741
|
+
if (message.role !== "assistant") return null;
|
|
5742
|
+
if (!(Array.isArray(message.toolCalls) ? message.toolCalls : []).some((tc) => isMatchingToolCallName(tc?.function?.name))) return null;
|
|
5743
|
+
let latestMatchingAssistantId;
|
|
5744
|
+
for (let i = agent.messages.length - 1; i >= 0; i -= 1) {
|
|
5745
|
+
const m = agent.messages[i];
|
|
5746
|
+
if (m.role !== "assistant") continue;
|
|
5747
|
+
if ((Array.isArray(m.toolCalls) ? m.toolCalls : []).some((tc) => isMatchingToolCallName(tc?.function?.name))) {
|
|
5748
|
+
latestMatchingAssistantId = m.id;
|
|
5749
|
+
break;
|
|
5750
|
+
}
|
|
5751
|
+
}
|
|
5752
|
+
if (latestMatchingAssistantId !== message.id) return null;
|
|
5753
|
+
const showSpinner = phase === "spinner";
|
|
5754
|
+
const isFading = phase === "fading";
|
|
5755
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5756
|
+
className: "cpk-intelligence-pill" + (isFading ? " cpk-intelligence-pill--fading" : ""),
|
|
5757
|
+
role: "status",
|
|
5758
|
+
"aria-live": "polite",
|
|
5759
|
+
"aria-hidden": isFading || void 0,
|
|
5760
|
+
"data-testid": `cpk-intelligence-pill-${message.id}`,
|
|
5761
|
+
title: label,
|
|
5762
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
5763
|
+
className: "cpk-intelligence-pill__icon",
|
|
5764
|
+
viewBox: "0 0 24 24",
|
|
5765
|
+
width: "14",
|
|
5766
|
+
height: "14",
|
|
5767
|
+
"aria-hidden": "true",
|
|
5768
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
5769
|
+
cx: "12",
|
|
5770
|
+
cy: "12",
|
|
5771
|
+
r: "9",
|
|
5772
|
+
fill: "none",
|
|
5773
|
+
strokeWidth: "2.5",
|
|
5774
|
+
strokeLinecap: "round",
|
|
5775
|
+
className: "cpk-intelligence-pill__ring" + (showSpinner ? "" : " cpk-intelligence-pill__ring--done")
|
|
5776
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
5777
|
+
d: "M8 12.5l3 3 5-6",
|
|
5778
|
+
fill: "none",
|
|
5779
|
+
strokeWidth: "2.5",
|
|
5780
|
+
strokeLinecap: "round",
|
|
5781
|
+
strokeLinejoin: "round",
|
|
5782
|
+
className: "cpk-intelligence-pill__check" + (showSpinner ? "" : " cpk-intelligence-pill__check--shown")
|
|
5783
|
+
})]
|
|
5784
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label })]
|
|
5785
|
+
});
|
|
5786
|
+
}
|
|
5787
|
+
|
|
5649
5788
|
//#endregion
|
|
5650
5789
|
//#region src/v2/components/chat/CopilotChatMessageView.tsx
|
|
5651
5790
|
/**
|
|
@@ -5803,14 +5942,12 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
|
|
|
5803
5942
|
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
5804
5943
|
(0, react.useEffect)(() => {
|
|
5805
5944
|
if (!config?.agentId) return;
|
|
5806
|
-
const
|
|
5807
|
-
const agent = getThreadClone(registryAgent, config.threadId) ?? registryAgent;
|
|
5945
|
+
const agent = copilotkit.getAgent(config.agentId);
|
|
5808
5946
|
if (!agent) return;
|
|
5809
5947
|
const subscription = agent.subscribe({ onStateChanged: forceUpdate });
|
|
5810
5948
|
return () => subscription.unsubscribe();
|
|
5811
5949
|
}, [
|
|
5812
5950
|
config?.agentId,
|
|
5813
|
-
config?.threadId,
|
|
5814
5951
|
copilotkit,
|
|
5815
5952
|
forceUpdate
|
|
5816
5953
|
]);
|
|
@@ -5893,6 +6030,10 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
|
|
|
5893
6030
|
renderCustomMessage,
|
|
5894
6031
|
stateSnapshot
|
|
5895
6032
|
}, `${message.id}-custom-after`));
|
|
6033
|
+
if (copilotkit.intelligence !== void 0 && message.role === "assistant") elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IntelligenceIndicator, {
|
|
6034
|
+
message,
|
|
6035
|
+
agentId: config?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID
|
|
6036
|
+
}, `${message.id}-intelligence`));
|
|
5896
6037
|
return elements.filter(Boolean);
|
|
5897
6038
|
};
|
|
5898
6039
|
const messageElements = shouldVirtualize ? [] : deduplicatedMessages.flatMap(renderMessageBlock);
|
|
@@ -6841,7 +6982,6 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
6841
6982
|
const hasExplicitThreadId = !!threadId || !!existingConfig?.hasExplicitThreadId;
|
|
6842
6983
|
const { agent } = useAgent({
|
|
6843
6984
|
agentId: resolvedAgentId,
|
|
6844
|
-
threadId: resolvedThreadId,
|
|
6845
6985
|
throttleMs
|
|
6846
6986
|
});
|
|
6847
6987
|
const { copilotkit } = useCopilotKit();
|
|
@@ -6883,6 +7023,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
6883
7023
|
let detached = false;
|
|
6884
7024
|
const connectAbortController = new AbortController();
|
|
6885
7025
|
if (agent instanceof _ag_ui_client.HttpAgent) agent.abortController = connectAbortController;
|
|
7026
|
+
agent.threadId = resolvedThreadId;
|
|
6886
7027
|
const connect = async (agent) => {
|
|
6887
7028
|
try {
|
|
6888
7029
|
await copilotkit.connectAgent({ agent });
|
|
@@ -10015,6 +10156,12 @@ Object.defineProperty(exports, 'DefaultOpenIcon', {
|
|
|
10015
10156
|
return DefaultOpenIcon;
|
|
10016
10157
|
}
|
|
10017
10158
|
});
|
|
10159
|
+
Object.defineProperty(exports, 'IntelligenceIndicator', {
|
|
10160
|
+
enumerable: true,
|
|
10161
|
+
get: function () {
|
|
10162
|
+
return IntelligenceIndicator;
|
|
10163
|
+
}
|
|
10164
|
+
});
|
|
10018
10165
|
Object.defineProperty(exports, 'MCPAppsActivityContentSchema', {
|
|
10019
10166
|
enumerable: true,
|
|
10020
10167
|
get: function () {
|
|
@@ -10243,4 +10390,4 @@ Object.defineProperty(exports, 'useToast', {
|
|
|
10243
10390
|
return useToast;
|
|
10244
10391
|
}
|
|
10245
10392
|
});
|
|
10246
|
-
//# sourceMappingURL=copilotkit-
|
|
10393
|
+
//# sourceMappingURL=copilotkit-B_k0HSNz.cjs.map
|