@copilotkit/react-core 1.57.0 → 1.57.1
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-BN4I_y1n.d.mts} +64 -8
- package/dist/copilotkit-BN4I_y1n.d.mts.map +1 -0
- package/dist/{copilotkit-DGbvw8n2.cjs → copilotkit-C3k13WZn.cjs} +572 -435
- package/dist/copilotkit-C3k13WZn.cjs.map +1 -0
- package/dist/{copilotkit-CPe2-340.mjs → copilotkit-DjxXMYHG.mjs} +571 -440
- package/dist/copilotkit-DjxXMYHG.mjs.map +1 -0
- package/dist/{copilotkit-Dg4r4Gi_.d.cts → copilotkit-sQWiKtxA.d.cts} +64 -8
- package/dist/copilotkit-sQWiKtxA.d.cts.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 +449 -502
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/context.cjs +135 -0
- package/dist/v2/context.cjs.map +1 -0
- package/dist/v2/context.d.cts +148 -0
- package/dist/v2/context.d.cts.map +1 -0
- package/dist/v2/context.d.mts +148 -0
- package/dist/v2/context.d.mts.map +1 -0
- package/dist/v2/context.mjs +129 -0
- package/dist/v2/context.mjs.map +1 -0
- package/dist/v2/headless.cjs +1043 -0
- package/dist/v2/headless.cjs.map +1 -0
- package/dist/v2/headless.d.cts +605 -0
- package/dist/v2/headless.d.cts.map +1 -0
- package/dist/v2/headless.d.mts +512 -0
- package/dist/v2/headless.d.mts.map +1 -0
- package/dist/v2/headless.mjs +997 -0
- package/dist/v2/headless.mjs.map +1 -0
- 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 +584 -441
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +14 -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/context.ts +62 -0
- package/src/v2/headless.ts +42 -0
- package/src/v2/hooks/__tests__/standard-schema.test.tsx +2 -2
- package/src/v2/hooks/__tests__/use-agent-context.test.tsx +3 -3
- package/src/v2/hooks/__tests__/use-agent-stability.test.tsx +3 -3
- package/src/v2/hooks/__tests__/use-agent-throttle.test.tsx +85 -85
- package/src/v2/hooks/__tests__/use-interrupt.test.tsx +2 -2
- package/src/v2/hooks/__tests__/use-render-tool.test.tsx +2 -2
- package/src/v2/hooks/__tests__/use-threads.test.tsx +2 -2
- package/src/v2/hooks/__tests__/zod-regression.test.tsx +2 -2
- package/src/v2/hooks/use-agent-context.tsx +1 -1
- package/src/v2/hooks/use-agent.tsx +9 -118
- package/src/v2/hooks/use-configure-suggestions.tsx +1 -1
- package/src/v2/hooks/use-frontend-tool.tsx +2 -2
- package/src/v2/hooks/use-human-in-the-loop.tsx +1 -1
- package/src/v2/hooks/use-interrupt.tsx +1 -1
- 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-render-tool-call.tsx +1 -1
- package/src/v2/hooks/use-render-tool.tsx +2 -2
- package/src/v2/hooks/use-suggestions.tsx +1 -1
- package/src/v2/hooks/use-threads.tsx +1 -1
- package/src/v2/providers/CopilotKitProvider.tsx +19 -59
- package/src/v2/styles/globals.css +118 -0
- package/tsdown.config.ts +75 -0
- package/dist/copilotkit-CPe2-340.mjs.map +0 -1
- package/dist/copilotkit-DFaI4j2r.d.mts.map +0 -1
- package/dist/copilotkit-DGbvw8n2.cjs.map +0 -1
- package/dist/copilotkit-Dg4r4Gi_.d.cts.map +0 -1
- package/src/v2/hooks/__tests__/use-agent-thread-isolation.test.tsx +0 -333
|
@@ -1324,6 +1324,197 @@ function useKatexStyles() {
|
|
|
1324
1324
|
}, []);
|
|
1325
1325
|
}
|
|
1326
1326
|
|
|
1327
|
+
//#endregion
|
|
1328
|
+
//#region src/v2/lib/react-core.ts
|
|
1329
|
+
var CopilotKitCoreReact = class extends _copilotkit_core.CopilotKitCore {
|
|
1330
|
+
constructor(config) {
|
|
1331
|
+
super(config);
|
|
1332
|
+
this._renderToolCalls = [];
|
|
1333
|
+
this._hookRenderToolCalls = /* @__PURE__ */ new Map();
|
|
1334
|
+
this._cachedMergedRenderToolCalls = null;
|
|
1335
|
+
this._renderCustomMessages = [];
|
|
1336
|
+
this._renderActivityMessages = [];
|
|
1337
|
+
this._interruptElement = null;
|
|
1338
|
+
this._renderToolCalls = config.renderToolCalls ?? [];
|
|
1339
|
+
this._renderCustomMessages = config.renderCustomMessages ?? [];
|
|
1340
|
+
this._renderActivityMessages = config.renderActivityMessages ?? [];
|
|
1341
|
+
}
|
|
1342
|
+
get renderCustomMessages() {
|
|
1343
|
+
return this._renderCustomMessages;
|
|
1344
|
+
}
|
|
1345
|
+
get renderActivityMessages() {
|
|
1346
|
+
return this._renderActivityMessages;
|
|
1347
|
+
}
|
|
1348
|
+
get renderToolCalls() {
|
|
1349
|
+
if (this._hookRenderToolCalls.size === 0) return this._renderToolCalls;
|
|
1350
|
+
if (this._cachedMergedRenderToolCalls) return this._cachedMergedRenderToolCalls;
|
|
1351
|
+
const merged = /* @__PURE__ */ new Map();
|
|
1352
|
+
for (const rc of this._renderToolCalls) merged.set(`${rc.agentId ?? ""}:${rc.name}`, rc);
|
|
1353
|
+
for (const [key, rc] of this._hookRenderToolCalls) merged.set(key, rc);
|
|
1354
|
+
this._cachedMergedRenderToolCalls = Array.from(merged.values());
|
|
1355
|
+
return this._cachedMergedRenderToolCalls;
|
|
1356
|
+
}
|
|
1357
|
+
setRenderActivityMessages(renderers) {
|
|
1358
|
+
this._renderActivityMessages = renderers;
|
|
1359
|
+
}
|
|
1360
|
+
setRenderCustomMessages(renderers) {
|
|
1361
|
+
this._renderCustomMessages = renderers;
|
|
1362
|
+
}
|
|
1363
|
+
setRenderToolCalls(renderToolCalls) {
|
|
1364
|
+
this._renderToolCalls = renderToolCalls;
|
|
1365
|
+
this._cachedMergedRenderToolCalls = null;
|
|
1366
|
+
this._notifyRenderToolCallsChanged();
|
|
1367
|
+
}
|
|
1368
|
+
addHookRenderToolCall(entry) {
|
|
1369
|
+
const key = `${entry.agentId ?? ""}:${entry.name}`;
|
|
1370
|
+
this._hookRenderToolCalls.set(key, entry);
|
|
1371
|
+
this._cachedMergedRenderToolCalls = null;
|
|
1372
|
+
this._notifyRenderToolCallsChanged();
|
|
1373
|
+
}
|
|
1374
|
+
removeHookRenderToolCall(name, agentId) {
|
|
1375
|
+
const key = `${agentId ?? ""}:${name}`;
|
|
1376
|
+
if (this._hookRenderToolCalls.delete(key)) {
|
|
1377
|
+
this._cachedMergedRenderToolCalls = null;
|
|
1378
|
+
this._notifyRenderToolCallsChanged();
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
_notifyRenderToolCallsChanged() {
|
|
1382
|
+
this.notifySubscribers((subscriber) => {
|
|
1383
|
+
const reactSubscriber = subscriber;
|
|
1384
|
+
if (reactSubscriber.onRenderToolCallsChanged) reactSubscriber.onRenderToolCallsChanged({
|
|
1385
|
+
copilotkit: this,
|
|
1386
|
+
renderToolCalls: this.renderToolCalls
|
|
1387
|
+
});
|
|
1388
|
+
}, "Subscriber onRenderToolCallsChanged error:");
|
|
1389
|
+
}
|
|
1390
|
+
get interruptElement() {
|
|
1391
|
+
return this._interruptElement;
|
|
1392
|
+
}
|
|
1393
|
+
setInterruptElement(element) {
|
|
1394
|
+
this._interruptElement = element;
|
|
1395
|
+
this.notifySubscribers((subscriber) => {
|
|
1396
|
+
subscriber.onInterruptElementChanged?.({
|
|
1397
|
+
copilotkit: this,
|
|
1398
|
+
interruptElement: this._interruptElement
|
|
1399
|
+
});
|
|
1400
|
+
}, "Subscriber onInterruptElementChanged error:");
|
|
1401
|
+
}
|
|
1402
|
+
subscribe(subscriber) {
|
|
1403
|
+
return super.subscribe(subscriber);
|
|
1404
|
+
}
|
|
1405
|
+
/**
|
|
1406
|
+
* Wait for pending React state updates before the follow-up agent run.
|
|
1407
|
+
*
|
|
1408
|
+
* When a frontend tool handler calls setState(), React 18 batches the update
|
|
1409
|
+
* and schedules a commit via its internal scheduler (MessageChannel). The
|
|
1410
|
+
* useAgentContext hook registers context via useLayoutEffect, which runs
|
|
1411
|
+
* synchronously after React commits that batch.
|
|
1412
|
+
*
|
|
1413
|
+
* Awaiting a zero-delay timeout yields to the macrotask queue. React's
|
|
1414
|
+
* MessageChannel task runs first, committing the pending state and running
|
|
1415
|
+
* useLayoutEffect (which updates the context store). The follow-up runAgent
|
|
1416
|
+
* call then reads fresh context.
|
|
1417
|
+
*/
|
|
1418
|
+
async waitForPendingFrameworkUpdates() {
|
|
1419
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1420
|
+
}
|
|
1421
|
+
};
|
|
1422
|
+
|
|
1423
|
+
//#endregion
|
|
1424
|
+
//#region src/v2/context.ts
|
|
1425
|
+
const CopilotKitContext = (0, react.createContext)(null);
|
|
1426
|
+
const useCopilotKit = () => {
|
|
1427
|
+
const context = (0, react.useContext)(CopilotKitContext);
|
|
1428
|
+
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
1429
|
+
if (!context) throw new Error("useCopilotKit must be used within CopilotKitProvider");
|
|
1430
|
+
(0, react.useEffect)(() => {
|
|
1431
|
+
const subscription = context.copilotkit.subscribe({ onRuntimeConnectionStatusChanged: () => {
|
|
1432
|
+
forceUpdate();
|
|
1433
|
+
} });
|
|
1434
|
+
return () => {
|
|
1435
|
+
subscription.unsubscribe();
|
|
1436
|
+
};
|
|
1437
|
+
}, []);
|
|
1438
|
+
return context;
|
|
1439
|
+
};
|
|
1440
|
+
const LicenseContext = (0, react.createContext)({
|
|
1441
|
+
status: null,
|
|
1442
|
+
license: null,
|
|
1443
|
+
checkFeature: () => true,
|
|
1444
|
+
getLimit: () => null
|
|
1445
|
+
});
|
|
1446
|
+
const useLicenseContext = () => (0, react.useContext)(LicenseContext);
|
|
1447
|
+
|
|
1448
|
+
//#endregion
|
|
1449
|
+
//#region src/v2/hooks/use-render-tool-call.tsx
|
|
1450
|
+
/**
|
|
1451
|
+
* Memoized component that renders a single tool call.
|
|
1452
|
+
* This prevents unnecessary re-renders when parent components update
|
|
1453
|
+
* but the tool call data hasn't changed.
|
|
1454
|
+
*/
|
|
1455
|
+
const ToolCallRenderer = react.default.memo(function ToolCallRenderer({ toolCall, toolMessage, RenderComponent, isExecuting }) {
|
|
1456
|
+
const args = (0, react.useMemo)(() => (0, _copilotkit_shared.partialJSONParse)(toolCall.function.arguments), [toolCall.function.arguments]);
|
|
1457
|
+
const toolName = toolCall.function.name;
|
|
1458
|
+
if (toolMessage) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RenderComponent, {
|
|
1459
|
+
name: toolName,
|
|
1460
|
+
toolCallId: toolCall.id,
|
|
1461
|
+
args,
|
|
1462
|
+
status: _copilotkit_core.ToolCallStatus.Complete,
|
|
1463
|
+
result: toolMessage.content
|
|
1464
|
+
});
|
|
1465
|
+
else if (isExecuting) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RenderComponent, {
|
|
1466
|
+
name: toolName,
|
|
1467
|
+
toolCallId: toolCall.id,
|
|
1468
|
+
args,
|
|
1469
|
+
status: _copilotkit_core.ToolCallStatus.Executing,
|
|
1470
|
+
result: void 0
|
|
1471
|
+
});
|
|
1472
|
+
else return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RenderComponent, {
|
|
1473
|
+
name: toolName,
|
|
1474
|
+
toolCallId: toolCall.id,
|
|
1475
|
+
args,
|
|
1476
|
+
status: _copilotkit_core.ToolCallStatus.InProgress,
|
|
1477
|
+
result: void 0
|
|
1478
|
+
});
|
|
1479
|
+
}, (prevProps, nextProps) => {
|
|
1480
|
+
if (prevProps.toolCall.id !== nextProps.toolCall.id) return false;
|
|
1481
|
+
if (prevProps.toolCall.function.name !== nextProps.toolCall.function.name) return false;
|
|
1482
|
+
if (prevProps.toolCall.function.arguments !== nextProps.toolCall.function.arguments) return false;
|
|
1483
|
+
if (prevProps.toolMessage?.content !== nextProps.toolMessage?.content) return false;
|
|
1484
|
+
if (prevProps.isExecuting !== nextProps.isExecuting) return false;
|
|
1485
|
+
if (prevProps.RenderComponent !== nextProps.RenderComponent) return false;
|
|
1486
|
+
return true;
|
|
1487
|
+
});
|
|
1488
|
+
/**
|
|
1489
|
+
* Hook that returns a function to render tool calls based on the render functions
|
|
1490
|
+
* defined in CopilotKitProvider.
|
|
1491
|
+
*
|
|
1492
|
+
* @returns A function that takes a tool call and optional tool message and returns the rendered component
|
|
1493
|
+
*/
|
|
1494
|
+
function useRenderToolCall() {
|
|
1495
|
+
const { copilotkit, executingToolCallIds } = useCopilotKit();
|
|
1496
|
+
const agentId = useCopilotChatConfiguration()?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
1497
|
+
const renderToolCalls = (0, react.useSyncExternalStore)((callback) => {
|
|
1498
|
+
return copilotkit.subscribe({ onRenderToolCallsChanged: callback }).unsubscribe;
|
|
1499
|
+
}, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
|
|
1500
|
+
return (0, react.useCallback)(({ toolCall, toolMessage }) => {
|
|
1501
|
+
const exactMatches = renderToolCalls.filter((rc) => rc.name === toolCall.function.name);
|
|
1502
|
+
const renderConfig = exactMatches.find((rc) => rc.agentId === agentId) || exactMatches.find((rc) => !rc.agentId) || exactMatches[0] || renderToolCalls.find((rc) => rc.name === "*");
|
|
1503
|
+
if (!renderConfig) return null;
|
|
1504
|
+
const RenderComponent = renderConfig.render;
|
|
1505
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallRenderer, {
|
|
1506
|
+
toolCall,
|
|
1507
|
+
toolMessage,
|
|
1508
|
+
RenderComponent,
|
|
1509
|
+
isExecuting: executingToolCallIds.has(toolCall.id)
|
|
1510
|
+
}, toolCall.id);
|
|
1511
|
+
}, [
|
|
1512
|
+
renderToolCalls,
|
|
1513
|
+
executingToolCallIds,
|
|
1514
|
+
agentId
|
|
1515
|
+
]);
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1327
1518
|
//#endregion
|
|
1328
1519
|
//#region src/v2/components/CopilotKitInspector.tsx
|
|
1329
1520
|
const CopilotKitInspector = ({ core, ...rest }) => {
|
|
@@ -2967,102 +3158,6 @@ function A2UICatalogContext({ catalog, includeSchema }) {
|
|
|
2967
3158
|
return null;
|
|
2968
3159
|
}
|
|
2969
3160
|
|
|
2970
|
-
//#endregion
|
|
2971
|
-
//#region src/v2/lib/react-core.ts
|
|
2972
|
-
var CopilotKitCoreReact = class extends _copilotkit_core.CopilotKitCore {
|
|
2973
|
-
constructor(config) {
|
|
2974
|
-
super(config);
|
|
2975
|
-
this._renderToolCalls = [];
|
|
2976
|
-
this._hookRenderToolCalls = /* @__PURE__ */ new Map();
|
|
2977
|
-
this._cachedMergedRenderToolCalls = null;
|
|
2978
|
-
this._renderCustomMessages = [];
|
|
2979
|
-
this._renderActivityMessages = [];
|
|
2980
|
-
this._interruptElement = null;
|
|
2981
|
-
this._renderToolCalls = config.renderToolCalls ?? [];
|
|
2982
|
-
this._renderCustomMessages = config.renderCustomMessages ?? [];
|
|
2983
|
-
this._renderActivityMessages = config.renderActivityMessages ?? [];
|
|
2984
|
-
}
|
|
2985
|
-
get renderCustomMessages() {
|
|
2986
|
-
return this._renderCustomMessages;
|
|
2987
|
-
}
|
|
2988
|
-
get renderActivityMessages() {
|
|
2989
|
-
return this._renderActivityMessages;
|
|
2990
|
-
}
|
|
2991
|
-
get renderToolCalls() {
|
|
2992
|
-
if (this._hookRenderToolCalls.size === 0) return this._renderToolCalls;
|
|
2993
|
-
if (this._cachedMergedRenderToolCalls) return this._cachedMergedRenderToolCalls;
|
|
2994
|
-
const merged = /* @__PURE__ */ new Map();
|
|
2995
|
-
for (const rc of this._renderToolCalls) merged.set(`${rc.agentId ?? ""}:${rc.name}`, rc);
|
|
2996
|
-
for (const [key, rc] of this._hookRenderToolCalls) merged.set(key, rc);
|
|
2997
|
-
this._cachedMergedRenderToolCalls = Array.from(merged.values());
|
|
2998
|
-
return this._cachedMergedRenderToolCalls;
|
|
2999
|
-
}
|
|
3000
|
-
setRenderActivityMessages(renderers) {
|
|
3001
|
-
this._renderActivityMessages = renderers;
|
|
3002
|
-
}
|
|
3003
|
-
setRenderCustomMessages(renderers) {
|
|
3004
|
-
this._renderCustomMessages = renderers;
|
|
3005
|
-
}
|
|
3006
|
-
setRenderToolCalls(renderToolCalls) {
|
|
3007
|
-
this._renderToolCalls = renderToolCalls;
|
|
3008
|
-
this._cachedMergedRenderToolCalls = null;
|
|
3009
|
-
this._notifyRenderToolCallsChanged();
|
|
3010
|
-
}
|
|
3011
|
-
addHookRenderToolCall(entry) {
|
|
3012
|
-
const key = `${entry.agentId ?? ""}:${entry.name}`;
|
|
3013
|
-
this._hookRenderToolCalls.set(key, entry);
|
|
3014
|
-
this._cachedMergedRenderToolCalls = null;
|
|
3015
|
-
this._notifyRenderToolCallsChanged();
|
|
3016
|
-
}
|
|
3017
|
-
removeHookRenderToolCall(name, agentId) {
|
|
3018
|
-
const key = `${agentId ?? ""}:${name}`;
|
|
3019
|
-
if (this._hookRenderToolCalls.delete(key)) {
|
|
3020
|
-
this._cachedMergedRenderToolCalls = null;
|
|
3021
|
-
this._notifyRenderToolCallsChanged();
|
|
3022
|
-
}
|
|
3023
|
-
}
|
|
3024
|
-
_notifyRenderToolCallsChanged() {
|
|
3025
|
-
this.notifySubscribers((subscriber) => {
|
|
3026
|
-
const reactSubscriber = subscriber;
|
|
3027
|
-
if (reactSubscriber.onRenderToolCallsChanged) reactSubscriber.onRenderToolCallsChanged({
|
|
3028
|
-
copilotkit: this,
|
|
3029
|
-
renderToolCalls: this.renderToolCalls
|
|
3030
|
-
});
|
|
3031
|
-
}, "Subscriber onRenderToolCallsChanged error:");
|
|
3032
|
-
}
|
|
3033
|
-
get interruptElement() {
|
|
3034
|
-
return this._interruptElement;
|
|
3035
|
-
}
|
|
3036
|
-
setInterruptElement(element) {
|
|
3037
|
-
this._interruptElement = element;
|
|
3038
|
-
this.notifySubscribers((subscriber) => {
|
|
3039
|
-
subscriber.onInterruptElementChanged?.({
|
|
3040
|
-
copilotkit: this,
|
|
3041
|
-
interruptElement: this._interruptElement
|
|
3042
|
-
});
|
|
3043
|
-
}, "Subscriber onInterruptElementChanged error:");
|
|
3044
|
-
}
|
|
3045
|
-
subscribe(subscriber) {
|
|
3046
|
-
return super.subscribe(subscriber);
|
|
3047
|
-
}
|
|
3048
|
-
/**
|
|
3049
|
-
* Wait for pending React state updates before the follow-up agent run.
|
|
3050
|
-
*
|
|
3051
|
-
* When a frontend tool handler calls setState(), React 18 batches the update
|
|
3052
|
-
* and schedules a commit via its internal scheduler (MessageChannel). The
|
|
3053
|
-
* useAgentContext hook registers context via useLayoutEffect, which runs
|
|
3054
|
-
* synchronously after React commits that batch.
|
|
3055
|
-
*
|
|
3056
|
-
* Awaiting a zero-delay timeout yields to the macrotask queue. React's
|
|
3057
|
-
* MessageChannel task runs first, committing the pending state and running
|
|
3058
|
-
* useLayoutEffect (which updates the context store). The follow-up runAgent
|
|
3059
|
-
* call then reads fresh context.
|
|
3060
|
-
*/
|
|
3061
|
-
async waitForPendingFrameworkUpdates() {
|
|
3062
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
3063
|
-
}
|
|
3064
|
-
};
|
|
3065
|
-
|
|
3066
3161
|
//#endregion
|
|
3067
3162
|
//#region src/v2/providers/CopilotKitProvider.tsx
|
|
3068
3163
|
const HEADER_NAME = "X-CopilotCloud-Public-Api-Key";
|
|
@@ -3078,12 +3173,6 @@ const DEFAULT_DESIGN_SKILL = `When generating UI with generateSandboxedUi, follo
|
|
|
3078
3173
|
- Minimal transitions (150ms) for hover/focus states only. No decorative animations.
|
|
3079
3174
|
- Keep the UI focused and dense — avoid excessive padding. Use compact spacing (8–12px gaps, 10–14px padding in controls).`;
|
|
3080
3175
|
const GENERATE_SANDBOXED_UI_DESCRIPTION = "Generate sandboxed UI. IMPORTANT: The generated code runs in a sandboxed iframe WITHOUT same-origin access. Do NOT use localStorage, sessionStorage, document.cookie, IndexedDB, or fetch/XMLHttpRequest to same-origin URLs. To communicate with the host application, use Websandbox.connection.remote.<functionName>(args) which returns a Promise.\n\nYou CAN use external libraries from CDNs by including <script> or <link> tags in the HTML <head> (e.g., Chart.js, D3, Three.js, x-data-spreadsheet, etc.). CDN resources load normally inside the sandbox.\n\nPARAMETER ORDER IS CRITICAL — generate parameters in exactly this order:\n1. initialHeight + placeholderMessages (shown to user while generating)\n2. css (all styles FIRST — the user sees a placeholder until CSS is complete)\n3. html (streams in live — the user watches the UI build as HTML is generated)\n4. jsFunctions (reusable helper functions)\n5. jsExpressions (applied one-by-one — the user sees each expression take effect)";
|
|
3081
|
-
const CopilotKitContext = (0, react.createContext)({
|
|
3082
|
-
copilotkit: null,
|
|
3083
|
-
executingToolCallIds: /* @__PURE__ */ new Set()
|
|
3084
|
-
});
|
|
3085
|
-
const LicenseContext = (0, react.createContext)((0, _copilotkit_shared.createLicenseContextValue)(null));
|
|
3086
|
-
const useLicenseContext = () => (0, react.useContext)(LicenseContext);
|
|
3087
3176
|
function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
|
|
3088
3177
|
const empty = (0, react.useMemo)(() => [], []);
|
|
3089
3178
|
const value = prop ?? empty;
|
|
@@ -3305,13 +3394,9 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = {}, c
|
|
|
3305
3394
|
onErrorRef.current = onError;
|
|
3306
3395
|
}, [onError]);
|
|
3307
3396
|
(0, react.useEffect)(() => {
|
|
3308
|
-
if (!onErrorRef.current) return;
|
|
3309
3397
|
const subscription = copilotkit.subscribe({ onError: (event) => {
|
|
3310
|
-
onErrorRef.current
|
|
3311
|
-
|
|
3312
|
-
code: event.code,
|
|
3313
|
-
context: event.context
|
|
3314
|
-
});
|
|
3398
|
+
if (onErrorRef.current) onErrorRef.current(event);
|
|
3399
|
+
else console.error(`[CopilotKit] Error (${event.code}):`, event.error, event.context ?? {});
|
|
3315
3400
|
} });
|
|
3316
3401
|
return () => {
|
|
3317
3402
|
subscription.unsubscribe();
|
|
@@ -3356,322 +3441,76 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = {}, c
|
|
|
3356
3441
|
didMountRef.current = true;
|
|
3357
3442
|
}, []);
|
|
3358
3443
|
(0, react.useEffect)(() => {
|
|
3359
|
-
copilotkit.setDefaultThrottleMs(defaultThrottleMs);
|
|
3360
|
-
}, [copilotkit, defaultThrottleMs]);
|
|
3361
|
-
const designSkill = openGenerativeUI?.designSkill ?? DEFAULT_DESIGN_SKILL;
|
|
3362
|
-
(0, react.useLayoutEffect)(() => {
|
|
3363
|
-
if (!copilotkit || !openGenUIActive) return;
|
|
3364
|
-
const id = copilotkit.addContext({
|
|
3365
|
-
description: "Design guidelines for the generateSandboxedUi tool. Follow these when building UI.",
|
|
3366
|
-
value: designSkill
|
|
3367
|
-
});
|
|
3368
|
-
return () => {
|
|
3369
|
-
copilotkit.removeContext(id);
|
|
3370
|
-
};
|
|
3371
|
-
}, [
|
|
3372
|
-
copilotkit,
|
|
3373
|
-
designSkill,
|
|
3374
|
-
openGenUIActive
|
|
3375
|
-
]);
|
|
3376
|
-
const sandboxFunctionsDescriptors = (0, react.useMemo)(() => {
|
|
3377
|
-
if (sandboxFunctionsList.length === 0) return null;
|
|
3378
|
-
return JSON.stringify(sandboxFunctionsList.map((fn) => ({
|
|
3379
|
-
name: fn.name,
|
|
3380
|
-
description: fn.description,
|
|
3381
|
-
parameters: (0, _copilotkit_shared.schemaToJsonSchema)(fn.parameters, { zodToJsonSchema: zod_to_json_schema.zodToJsonSchema })
|
|
3382
|
-
})));
|
|
3383
|
-
}, [sandboxFunctionsList]);
|
|
3384
|
-
(0, react.useLayoutEffect)(() => {
|
|
3385
|
-
if (!copilotkit || !sandboxFunctionsDescriptors || !openGenUIActive) return;
|
|
3386
|
-
const id = copilotkit.addContext({
|
|
3387
|
-
description: "Sandbox functions available in generated sandboxed UI code. Call via: await Websandbox.connection.remote.<functionName>(args)",
|
|
3388
|
-
value: sandboxFunctionsDescriptors
|
|
3389
|
-
});
|
|
3390
|
-
return () => {
|
|
3391
|
-
copilotkit.removeContext(id);
|
|
3392
|
-
};
|
|
3393
|
-
}, [
|
|
3394
|
-
copilotkit,
|
|
3395
|
-
sandboxFunctionsDescriptors,
|
|
3396
|
-
openGenUIActive
|
|
3397
|
-
]);
|
|
3398
|
-
const contextValue = (0, react.useMemo)(() => ({
|
|
3399
|
-
copilotkit,
|
|
3400
|
-
executingToolCallIds
|
|
3401
|
-
}), [copilotkit, executingToolCallIds]);
|
|
3402
|
-
const licenseContextValue = (0, react.useMemo)(() => (0, _copilotkit_shared.createLicenseContextValue)(null), []);
|
|
3403
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SandboxFunctionsContext.Provider, {
|
|
3404
|
-
value: sandboxFunctionsList,
|
|
3405
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitContext.Provider, {
|
|
3406
|
-
value: contextValue,
|
|
3407
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(LicenseContext.Provider, {
|
|
3408
|
-
value: licenseContextValue,
|
|
3409
|
-
children: [
|
|
3410
|
-
runtimeA2UIEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIBuiltInToolCallRenderer, {}),
|
|
3411
|
-
runtimeA2UIEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UICatalogContext, {
|
|
3412
|
-
catalog: a2ui?.catalog,
|
|
3413
|
-
includeSchema: a2ui?.includeSchema
|
|
3414
|
-
}),
|
|
3415
|
-
children,
|
|
3416
|
-
shouldRenderInspector ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitInspector, {
|
|
3417
|
-
core: copilotkit,
|
|
3418
|
-
defaultAnchor: inspectorDefaultAnchor
|
|
3419
|
-
}) : null,
|
|
3420
|
-
runtimeLicenseStatus === "none" && !resolvedPublicKey && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "no_license" }),
|
|
3421
|
-
runtimeLicenseStatus === "expired" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expired" }),
|
|
3422
|
-
runtimeLicenseStatus === "invalid" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "invalid" }),
|
|
3423
|
-
runtimeLicenseStatus === "expiring" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expiring" })
|
|
3424
|
-
]
|
|
3425
|
-
})
|
|
3426
|
-
})
|
|
3427
|
-
});
|
|
3428
|
-
};
|
|
3429
|
-
const useCopilotKit = () => {
|
|
3430
|
-
const context = (0, react.useContext)(CopilotKitContext);
|
|
3431
|
-
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
3432
|
-
if (!context) throw new Error("useCopilotKit must be used within CopilotKitProvider");
|
|
3433
|
-
(0, react.useEffect)(() => {
|
|
3434
|
-
const subscription = context.copilotkit.subscribe({ onRuntimeConnectionStatusChanged: () => {
|
|
3435
|
-
forceUpdate();
|
|
3436
|
-
} });
|
|
3437
|
-
return () => {
|
|
3438
|
-
subscription.unsubscribe();
|
|
3439
|
-
};
|
|
3440
|
-
}, []);
|
|
3441
|
-
return context;
|
|
3442
|
-
};
|
|
3443
|
-
|
|
3444
|
-
//#endregion
|
|
3445
|
-
//#region src/v2/hooks/use-render-tool-call.tsx
|
|
3446
|
-
/**
|
|
3447
|
-
* Memoized component that renders a single tool call.
|
|
3448
|
-
* This prevents unnecessary re-renders when parent components update
|
|
3449
|
-
* but the tool call data hasn't changed.
|
|
3450
|
-
*/
|
|
3451
|
-
const ToolCallRenderer = react.default.memo(function ToolCallRenderer({ toolCall, toolMessage, RenderComponent, isExecuting }) {
|
|
3452
|
-
const args = (0, react.useMemo)(() => (0, _copilotkit_shared.partialJSONParse)(toolCall.function.arguments), [toolCall.function.arguments]);
|
|
3453
|
-
const toolName = toolCall.function.name;
|
|
3454
|
-
if (toolMessage) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RenderComponent, {
|
|
3455
|
-
name: toolName,
|
|
3456
|
-
toolCallId: toolCall.id,
|
|
3457
|
-
args,
|
|
3458
|
-
status: _copilotkit_core.ToolCallStatus.Complete,
|
|
3459
|
-
result: toolMessage.content
|
|
3460
|
-
});
|
|
3461
|
-
else if (isExecuting) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RenderComponent, {
|
|
3462
|
-
name: toolName,
|
|
3463
|
-
toolCallId: toolCall.id,
|
|
3464
|
-
args,
|
|
3465
|
-
status: _copilotkit_core.ToolCallStatus.Executing,
|
|
3466
|
-
result: void 0
|
|
3467
|
-
});
|
|
3468
|
-
else return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RenderComponent, {
|
|
3469
|
-
name: toolName,
|
|
3470
|
-
toolCallId: toolCall.id,
|
|
3471
|
-
args,
|
|
3472
|
-
status: _copilotkit_core.ToolCallStatus.InProgress,
|
|
3473
|
-
result: void 0
|
|
3474
|
-
});
|
|
3475
|
-
}, (prevProps, nextProps) => {
|
|
3476
|
-
if (prevProps.toolCall.id !== nextProps.toolCall.id) return false;
|
|
3477
|
-
if (prevProps.toolCall.function.name !== nextProps.toolCall.function.name) return false;
|
|
3478
|
-
if (prevProps.toolCall.function.arguments !== nextProps.toolCall.function.arguments) return false;
|
|
3479
|
-
if (prevProps.toolMessage?.content !== nextProps.toolMessage?.content) return false;
|
|
3480
|
-
if (prevProps.isExecuting !== nextProps.isExecuting) return false;
|
|
3481
|
-
if (prevProps.RenderComponent !== nextProps.RenderComponent) return false;
|
|
3482
|
-
return true;
|
|
3483
|
-
});
|
|
3484
|
-
/**
|
|
3485
|
-
* Hook that returns a function to render tool calls based on the render functions
|
|
3486
|
-
* defined in CopilotKitProvider.
|
|
3487
|
-
*
|
|
3488
|
-
* @returns A function that takes a tool call and optional tool message and returns the rendered component
|
|
3489
|
-
*/
|
|
3490
|
-
function useRenderToolCall() {
|
|
3491
|
-
const { copilotkit, executingToolCallIds } = useCopilotKit();
|
|
3492
|
-
const agentId = useCopilotChatConfiguration()?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
3493
|
-
const renderToolCalls = (0, react.useSyncExternalStore)((callback) => {
|
|
3494
|
-
return copilotkit.subscribe({ onRenderToolCallsChanged: callback }).unsubscribe;
|
|
3495
|
-
}, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
|
|
3496
|
-
return (0, react.useCallback)(({ toolCall, toolMessage }) => {
|
|
3497
|
-
const exactMatches = renderToolCalls.filter((rc) => rc.name === toolCall.function.name);
|
|
3498
|
-
const renderConfig = exactMatches.find((rc) => rc.agentId === agentId) || exactMatches.find((rc) => !rc.agentId) || exactMatches[0] || renderToolCalls.find((rc) => rc.name === "*");
|
|
3499
|
-
if (!renderConfig) return null;
|
|
3500
|
-
const RenderComponent = renderConfig.render;
|
|
3501
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallRenderer, {
|
|
3502
|
-
toolCall,
|
|
3503
|
-
toolMessage,
|
|
3504
|
-
RenderComponent,
|
|
3505
|
-
isExecuting: executingToolCallIds.has(toolCall.id)
|
|
3506
|
-
}, toolCall.id);
|
|
3507
|
-
}, [
|
|
3508
|
-
renderToolCalls,
|
|
3509
|
-
executingToolCallIds,
|
|
3510
|
-
agentId
|
|
3511
|
-
]);
|
|
3512
|
-
}
|
|
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
|
-
}
|
|
3444
|
+
copilotkit.setDefaultThrottleMs(defaultThrottleMs);
|
|
3445
|
+
}, [copilotkit, defaultThrottleMs]);
|
|
3446
|
+
const designSkill = openGenerativeUI?.designSkill ?? DEFAULT_DESIGN_SKILL;
|
|
3447
|
+
(0, react.useLayoutEffect)(() => {
|
|
3448
|
+
if (!copilotkit || !openGenUIActive) return;
|
|
3449
|
+
const id = copilotkit.addContext({
|
|
3450
|
+
description: "Design guidelines for the generateSandboxedUi tool. Follow these when building UI.",
|
|
3451
|
+
value: designSkill
|
|
3452
|
+
});
|
|
3453
|
+
return () => {
|
|
3454
|
+
copilotkit.removeContext(id);
|
|
3649
3455
|
};
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3456
|
+
}, [
|
|
3457
|
+
copilotkit,
|
|
3458
|
+
designSkill,
|
|
3459
|
+
openGenUIActive
|
|
3460
|
+
]);
|
|
3461
|
+
const sandboxFunctionsDescriptors = (0, react.useMemo)(() => {
|
|
3462
|
+
if (sandboxFunctionsList.length === 0) return null;
|
|
3463
|
+
return JSON.stringify(sandboxFunctionsList.map((fn) => ({
|
|
3464
|
+
name: fn.name,
|
|
3465
|
+
description: fn.description,
|
|
3466
|
+
parameters: (0, _copilotkit_shared.schemaToJsonSchema)(fn.parameters, { zodToJsonSchema: zod_to_json_schema.zodToJsonSchema })
|
|
3467
|
+
})));
|
|
3468
|
+
}, [sandboxFunctionsList]);
|
|
3469
|
+
(0, react.useLayoutEffect)(() => {
|
|
3470
|
+
if (!copilotkit || !sandboxFunctionsDescriptors || !openGenUIActive) return;
|
|
3471
|
+
const id = copilotkit.addContext({
|
|
3472
|
+
description: "Sandbox functions available in generated sandboxed UI code. Call via: await Websandbox.connection.remote.<functionName>(args)",
|
|
3473
|
+
value: sandboxFunctionsDescriptors
|
|
3474
|
+
});
|
|
3659
3475
|
return () => {
|
|
3660
|
-
|
|
3661
|
-
subscription.unsubscribe();
|
|
3476
|
+
copilotkit.removeContext(id);
|
|
3662
3477
|
};
|
|
3663
3478
|
}, [
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
providerThrottleMs,
|
|
3668
|
-
updateFlags
|
|
3479
|
+
copilotkit,
|
|
3480
|
+
sandboxFunctionsDescriptors,
|
|
3481
|
+
openGenUIActive
|
|
3669
3482
|
]);
|
|
3670
|
-
(0, react.
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3483
|
+
const contextValue = (0, react.useMemo)(() => ({
|
|
3484
|
+
copilotkit,
|
|
3485
|
+
executingToolCallIds
|
|
3486
|
+
}), [copilotkit, executingToolCallIds]);
|
|
3487
|
+
const licenseContextValue = (0, react.useMemo)(() => (0, _copilotkit_shared.createLicenseContextValue)(null), []);
|
|
3488
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SandboxFunctionsContext.Provider, {
|
|
3489
|
+
value: sandboxFunctionsList,
|
|
3490
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitContext.Provider, {
|
|
3491
|
+
value: contextValue,
|
|
3492
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(LicenseContext.Provider, {
|
|
3493
|
+
value: licenseContextValue,
|
|
3494
|
+
children: [
|
|
3495
|
+
runtimeA2UIEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIBuiltInToolCallRenderer, {}),
|
|
3496
|
+
runtimeA2UIEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UICatalogContext, {
|
|
3497
|
+
catalog: a2ui?.catalog,
|
|
3498
|
+
includeSchema: a2ui?.includeSchema
|
|
3499
|
+
}),
|
|
3500
|
+
children,
|
|
3501
|
+
shouldRenderInspector ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotKitInspector, {
|
|
3502
|
+
core: copilotkit,
|
|
3503
|
+
defaultAnchor: inspectorDefaultAnchor
|
|
3504
|
+
}) : null,
|
|
3505
|
+
runtimeLicenseStatus === "none" && !resolvedPublicKey && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "no_license" }),
|
|
3506
|
+
runtimeLicenseStatus === "expired" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expired" }),
|
|
3507
|
+
runtimeLicenseStatus === "invalid" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "invalid" }),
|
|
3508
|
+
runtimeLicenseStatus === "expiring" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LicenseWarningBanner, { type: "expiring" })
|
|
3509
|
+
]
|
|
3510
|
+
})
|
|
3511
|
+
})
|
|
3512
|
+
});
|
|
3513
|
+
};
|
|
3675
3514
|
|
|
3676
3515
|
//#endregion
|
|
3677
3516
|
//#region src/v2/hooks/use-render-custom-messages.tsx
|
|
@@ -3690,8 +3529,7 @@ function useRenderCustomMessages() {
|
|
|
3690
3529
|
const { message, position } = params;
|
|
3691
3530
|
const resolvedRunId = copilotkit.getRunIdForMessage(agentId, threadId, message.id) ?? copilotkit.getRunIdsForThread(agentId, threadId).slice(-1)[0];
|
|
3692
3531
|
const runId = resolvedRunId ?? `missing-run-id:${message.id}`;
|
|
3693
|
-
const
|
|
3694
|
-
const agent = getThreadClone(registryAgent, threadId) ?? registryAgent;
|
|
3532
|
+
const agent = copilotkit.getAgent(agentId);
|
|
3695
3533
|
if (!agent) return null;
|
|
3696
3534
|
const messagesIdsInRun = resolvedRunId ? agent.messages.filter((msg) => copilotkit.getRunIdForMessage(agentId, threadId, msg.id) === resolvedRunId).map((msg) => msg.id) : [message.id];
|
|
3697
3535
|
const rawMessageIndex = agent.messages.findIndex((msg) => msg.id === message.id);
|
|
@@ -3723,8 +3561,7 @@ function useRenderCustomMessages() {
|
|
|
3723
3561
|
//#region src/v2/hooks/use-render-activity-message.tsx
|
|
3724
3562
|
function useRenderActivityMessage() {
|
|
3725
3563
|
const { copilotkit } = useCopilotKit();
|
|
3726
|
-
const
|
|
3727
|
-
const agentId = config?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
3564
|
+
const agentId = useCopilotChatConfiguration()?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
3728
3565
|
const renderers = copilotkit.renderActivityMessages;
|
|
3729
3566
|
const findRenderer = (0, react.useCallback)((activityType) => {
|
|
3730
3567
|
if (!renderers.length) return null;
|
|
@@ -3740,8 +3577,7 @@ function useRenderActivityMessage() {
|
|
|
3740
3577
|
return null;
|
|
3741
3578
|
}
|
|
3742
3579
|
const Component = renderer.render;
|
|
3743
|
-
const
|
|
3744
|
-
const agent = getThreadClone(registryAgent, config?.threadId) ?? registryAgent;
|
|
3580
|
+
const agent = copilotkit.getAgent(agentId);
|
|
3745
3581
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {
|
|
3746
3582
|
activityType: message.activityType,
|
|
3747
3583
|
content: parseResult.data,
|
|
@@ -3750,7 +3586,6 @@ function useRenderActivityMessage() {
|
|
|
3750
3586
|
}, message.id);
|
|
3751
3587
|
}, [
|
|
3752
3588
|
agentId,
|
|
3753
|
-
config?.threadId,
|
|
3754
3589
|
copilotkit,
|
|
3755
3590
|
findRenderer
|
|
3756
3591
|
]);
|
|
@@ -3789,8 +3624,7 @@ function useFrontendTool(tool, deps) {
|
|
|
3789
3624
|
tool.name,
|
|
3790
3625
|
tool.available,
|
|
3791
3626
|
copilotkit,
|
|
3792
|
-
extraDeps
|
|
3793
|
-
...extraDeps
|
|
3627
|
+
JSON.stringify(extraDeps)
|
|
3794
3628
|
]);
|
|
3795
3629
|
}
|
|
3796
3630
|
|
|
@@ -3929,8 +3763,7 @@ function useRenderTool(config, deps) {
|
|
|
3929
3763
|
}, [
|
|
3930
3764
|
config.name,
|
|
3931
3765
|
copilotkit,
|
|
3932
|
-
extraDeps
|
|
3933
|
-
...extraDeps
|
|
3766
|
+
JSON.stringify(extraDeps)
|
|
3934
3767
|
]);
|
|
3935
3768
|
}
|
|
3936
3769
|
|
|
@@ -4190,6 +4023,118 @@ function useHumanInTheLoop(tool, deps) {
|
|
|
4190
4023
|
]);
|
|
4191
4024
|
}
|
|
4192
4025
|
|
|
4026
|
+
//#endregion
|
|
4027
|
+
//#region src/v2/hooks/use-agent.tsx
|
|
4028
|
+
let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
|
|
4029
|
+
UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
|
|
4030
|
+
UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
|
|
4031
|
+
UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
|
|
4032
|
+
return UseAgentUpdate;
|
|
4033
|
+
}({});
|
|
4034
|
+
const ALL_UPDATES = [
|
|
4035
|
+
UseAgentUpdate.OnMessagesChanged,
|
|
4036
|
+
UseAgentUpdate.OnStateChanged,
|
|
4037
|
+
UseAgentUpdate.OnRunStatusChanged
|
|
4038
|
+
];
|
|
4039
|
+
function useAgent({ agentId, updates, throttleMs } = {}) {
|
|
4040
|
+
agentId ??= _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
4041
|
+
const { copilotkit } = useCopilotKit();
|
|
4042
|
+
const providerThrottleMs = copilotkit.defaultThrottleMs;
|
|
4043
|
+
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
4044
|
+
const updateFlags = (0, react.useMemo)(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
|
|
4045
|
+
const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
4046
|
+
const agent = (0, react.useMemo)(() => {
|
|
4047
|
+
const existing = copilotkit.getAgent(agentId);
|
|
4048
|
+
if (existing) {
|
|
4049
|
+
provisionalAgentCache.current.delete(agentId);
|
|
4050
|
+
return existing;
|
|
4051
|
+
}
|
|
4052
|
+
const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
|
|
4053
|
+
const status = copilotkit.runtimeConnectionStatus;
|
|
4054
|
+
if (isRuntimeConfigured && (status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
|
|
4055
|
+
const cached = provisionalAgentCache.current.get(agentId);
|
|
4056
|
+
if (cached) {
|
|
4057
|
+
cached.headers = { ...copilotkit.headers };
|
|
4058
|
+
return cached;
|
|
4059
|
+
}
|
|
4060
|
+
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
4061
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
4062
|
+
agentId,
|
|
4063
|
+
transport: copilotkit.runtimeTransport,
|
|
4064
|
+
runtimeMode: "pending"
|
|
4065
|
+
});
|
|
4066
|
+
provisional.headers = { ...copilotkit.headers };
|
|
4067
|
+
provisionalAgentCache.current.set(agentId, provisional);
|
|
4068
|
+
return provisional;
|
|
4069
|
+
}
|
|
4070
|
+
if (isRuntimeConfigured && status === _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Error) {
|
|
4071
|
+
const cached = provisionalAgentCache.current.get(agentId);
|
|
4072
|
+
if (cached) {
|
|
4073
|
+
cached.headers = { ...copilotkit.headers };
|
|
4074
|
+
return cached;
|
|
4075
|
+
}
|
|
4076
|
+
const provisional = new _copilotkit_core.ProxiedCopilotRuntimeAgent({
|
|
4077
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
4078
|
+
agentId,
|
|
4079
|
+
transport: copilotkit.runtimeTransport,
|
|
4080
|
+
runtimeMode: "pending"
|
|
4081
|
+
});
|
|
4082
|
+
provisional.headers = { ...copilotkit.headers };
|
|
4083
|
+
provisionalAgentCache.current.set(agentId, provisional);
|
|
4084
|
+
return provisional;
|
|
4085
|
+
}
|
|
4086
|
+
const knownAgents = Object.keys(copilotkit.agents ?? {});
|
|
4087
|
+
const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
|
|
4088
|
+
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.");
|
|
4089
|
+
}, [
|
|
4090
|
+
agentId,
|
|
4091
|
+
copilotkit.agents,
|
|
4092
|
+
copilotkit.runtimeConnectionStatus,
|
|
4093
|
+
copilotkit.runtimeUrl,
|
|
4094
|
+
copilotkit.runtimeTransport,
|
|
4095
|
+
JSON.stringify(copilotkit.headers)
|
|
4096
|
+
]);
|
|
4097
|
+
(0, react.useEffect)(() => {
|
|
4098
|
+
if (updateFlags.length === 0) return;
|
|
4099
|
+
let active = true;
|
|
4100
|
+
const handlers = {};
|
|
4101
|
+
let batchScheduled = false;
|
|
4102
|
+
const batchedForceUpdate = () => {
|
|
4103
|
+
if (!active) return;
|
|
4104
|
+
if (!batchScheduled) {
|
|
4105
|
+
batchScheduled = true;
|
|
4106
|
+
queueMicrotask(() => {
|
|
4107
|
+
batchScheduled = false;
|
|
4108
|
+
if (active) forceUpdate();
|
|
4109
|
+
});
|
|
4110
|
+
}
|
|
4111
|
+
};
|
|
4112
|
+
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = batchedForceUpdate;
|
|
4113
|
+
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
|
|
4114
|
+
if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
|
|
4115
|
+
handlers.onRunInitialized = batchedForceUpdate;
|
|
4116
|
+
handlers.onRunFinalized = batchedForceUpdate;
|
|
4117
|
+
handlers.onRunFailed = batchedForceUpdate;
|
|
4118
|
+
handlers.onRunErrorEvent = batchedForceUpdate;
|
|
4119
|
+
}
|
|
4120
|
+
const subscription = copilotkit.subscribeToAgentWithOptions(agent, handlers, { throttleMs });
|
|
4121
|
+
return () => {
|
|
4122
|
+
active = false;
|
|
4123
|
+
subscription.unsubscribe();
|
|
4124
|
+
};
|
|
4125
|
+
}, [
|
|
4126
|
+
agent,
|
|
4127
|
+
forceUpdate,
|
|
4128
|
+
throttleMs,
|
|
4129
|
+
providerThrottleMs,
|
|
4130
|
+
updateFlags
|
|
4131
|
+
]);
|
|
4132
|
+
(0, react.useEffect)(() => {
|
|
4133
|
+
if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...copilotkit.headers };
|
|
4134
|
+
}, [agent, JSON.stringify(copilotkit.headers)]);
|
|
4135
|
+
return { agent };
|
|
4136
|
+
}
|
|
4137
|
+
|
|
4193
4138
|
//#endregion
|
|
4194
4139
|
//#region src/v2/hooks/use-capabilities.tsx
|
|
4195
4140
|
/**
|
|
@@ -5655,6 +5600,190 @@ CopilotChatSuggestionView.displayName = "CopilotChatSuggestionView";
|
|
|
5655
5600
|
*/
|
|
5656
5601
|
const ScrollElementContext = react.default.createContext(null);
|
|
5657
5602
|
|
|
5603
|
+
//#endregion
|
|
5604
|
+
//#region src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx
|
|
5605
|
+
/**
|
|
5606
|
+
* Grace window before showing the spinner. A matching tool call must
|
|
5607
|
+
* remain unresolved (no `tool`-role result message in `agent.messages`)
|
|
5608
|
+
* for at least this long before the pill appears. This filters out
|
|
5609
|
+
* history-replay flashes — during `connectAgent` replay, tool calls and
|
|
5610
|
+
* their results arrive back-to-back in sub-millisecond bursts, so the
|
|
5611
|
+
* timer is cancelled before it fires. Live runs cross the threshold
|
|
5612
|
+
* easily because the tool actually has to execute.
|
|
5613
|
+
*/
|
|
5614
|
+
const PENDING_THRESHOLD_MS = 100;
|
|
5615
|
+
/** Hold the checkmark briefly before fading out. */
|
|
5616
|
+
const CHECK_HOLD_MS = 800;
|
|
5617
|
+
/**
|
|
5618
|
+
* Duration of the fade-out animation. Must match
|
|
5619
|
+
* `cpk-intelligence-pill-fade-out` keyframes in `v2/styles/globals.css`.
|
|
5620
|
+
*/
|
|
5621
|
+
const FADE_OUT_ANIMATION_MS = 480;
|
|
5622
|
+
/**
|
|
5623
|
+
* Tool-name regex patterns that trigger the indicator. Currently
|
|
5624
|
+
* hardcoded to the Intelligence MCP server's canonical tool name. If
|
|
5625
|
+
* we add per-instance customization later (e.g. a `CopilotKitProvider`
|
|
5626
|
+
* prop or a runtime-info field), this constant becomes the fallback.
|
|
5627
|
+
*/
|
|
5628
|
+
const DEFAULT_TOOL_PATTERNS = [/^copilotkit_knowledge_base_shell$/];
|
|
5629
|
+
const isMatchingToolCallName = (name) => typeof name === "string" && DEFAULT_TOOL_PATTERNS.some((p) => p.test(name));
|
|
5630
|
+
/**
|
|
5631
|
+
* "Tool-call-like" messages do NOT count as a real follow-up: tool
|
|
5632
|
+
* result messages, assistant messages that carry tool calls, and
|
|
5633
|
+
* empty-content assistant messages (which some providers emit as a
|
|
5634
|
+
* standalone wrapper around a batch of tool calls). A real follow-up
|
|
5635
|
+
* is anything else — most importantly an assistant message with prose
|
|
5636
|
+
* content, or a fresh user message.
|
|
5637
|
+
*/
|
|
5638
|
+
const isToolCallLikeMessage = (m) => {
|
|
5639
|
+
if (m.role === "tool") return true;
|
|
5640
|
+
if (m.role === "assistant") {
|
|
5641
|
+
if ((Array.isArray(m.toolCalls) ? m.toolCalls : []).length > 0) return true;
|
|
5642
|
+
const content = m.content;
|
|
5643
|
+
return typeof content !== "string" || content.trim().length === 0;
|
|
5644
|
+
}
|
|
5645
|
+
return false;
|
|
5646
|
+
};
|
|
5647
|
+
/**
|
|
5648
|
+
* The "Using CopilotKit Intelligence" pill. Auto-mounted by
|
|
5649
|
+
* `CopilotChatMessageView` for every message slot when
|
|
5650
|
+
* `copilotkit.intelligence` is configured — callers do not register
|
|
5651
|
+
* this themselves. Self-gates so only the canonical message renders a
|
|
5652
|
+
* pill.
|
|
5653
|
+
*
|
|
5654
|
+
* Render gates (all must hold):
|
|
5655
|
+
* 1. `copilotkit.intelligence !== undefined`
|
|
5656
|
+
* 2. The message is an assistant message with at least one tool call
|
|
5657
|
+
* whose name matches {@link DEFAULT_TOOL_PATTERNS}
|
|
5658
|
+
* 3. The message is the *latest* such matching-assistant message in
|
|
5659
|
+
* `agent.messages` — tool-result messages and prose-only assistant
|
|
5660
|
+
* messages don't invalidate the slot, so the pill stays
|
|
5661
|
+
* continuously through a multi-step tool chain.
|
|
5662
|
+
* 4. The phase machine is past `idle` (the pending-grace timer fired)
|
|
5663
|
+
* and not yet `hidden`.
|
|
5664
|
+
*
|
|
5665
|
+
* Phase machine (per-instance, all timers local):
|
|
5666
|
+
* - Starts in `idle` — nothing rendered.
|
|
5667
|
+
* - `idle → spinner` once a matching tool call has been pending
|
|
5668
|
+
* (no `tool`-role result with a matching `toolCallId`) for
|
|
5669
|
+
* {@link PENDING_THRESHOLD_MS}. Replay flashes (tool call + result
|
|
5670
|
+
* in the same tick) never cross this threshold.
|
|
5671
|
+
* - `spinner → check` as soon as EITHER `agent.isRunning` flips
|
|
5672
|
+
* false OR a non-tool-call-like message appears later in
|
|
5673
|
+
* `agent.messages` (i.e. the agent has produced a "real"
|
|
5674
|
+
* follow-up — prose answer or a new user turn).
|
|
5675
|
+
* - `check → fading` after {@link CHECK_HOLD_MS}.
|
|
5676
|
+
* - `fading → hidden` after {@link FADE_OUT_ANIMATION_MS}.
|
|
5677
|
+
*
|
|
5678
|
+
* Once `hidden`, the phase is sticky — a finished pill never re-spawns
|
|
5679
|
+
* on the same message. New runs mount fresh indicator instances on
|
|
5680
|
+
* their own assistant messages.
|
|
5681
|
+
*
|
|
5682
|
+
* The "exactly one pill at a time" guarantee is structural: only one
|
|
5683
|
+
* message satisfies the latest-matching-assistant gate at any moment.
|
|
5684
|
+
*/
|
|
5685
|
+
function IntelligenceIndicator(props) {
|
|
5686
|
+
const { message, agentId, label = "Using CopilotKit Intelligence" } = props;
|
|
5687
|
+
const { copilotkit } = useCopilotKit();
|
|
5688
|
+
const config = useCopilotChatConfiguration();
|
|
5689
|
+
const { agent } = useAgent({
|
|
5690
|
+
agentId,
|
|
5691
|
+
updates: [UseAgentUpdate.OnRunStatusChanged, UseAgentUpdate.OnMessagesChanged]
|
|
5692
|
+
});
|
|
5693
|
+
const matchingToolCallIds = (0, react.useMemo)(() => {
|
|
5694
|
+
if (message.role !== "assistant") return [];
|
|
5695
|
+
const tcs = Array.isArray(message.toolCalls) ? message.toolCalls : [];
|
|
5696
|
+
const ids = [];
|
|
5697
|
+
for (const tc of tcs) if (isMatchingToolCallName(tc?.function?.name) && tc?.id) ids.push(tc.id);
|
|
5698
|
+
return ids;
|
|
5699
|
+
}, [message]);
|
|
5700
|
+
const hasPending = (0, react.useMemo)(() => {
|
|
5701
|
+
if (matchingToolCallIds.length === 0) return false;
|
|
5702
|
+
const resolved = /* @__PURE__ */ new Set();
|
|
5703
|
+
for (const m of agent.messages) if (m.role === "tool" && m.toolCallId) resolved.add(m.toolCallId);
|
|
5704
|
+
return matchingToolCallIds.some((id) => !resolved.has(id));
|
|
5705
|
+
}, [matchingToolCallIds, agent.messages]);
|
|
5706
|
+
const sawRealFollowup = (0, react.useMemo)(() => {
|
|
5707
|
+
const idx = agent.messages.findIndex((m) => m.id === message.id);
|
|
5708
|
+
if (idx < 0) return false;
|
|
5709
|
+
for (let i = idx + 1; i < agent.messages.length; i += 1) if (!isToolCallLikeMessage(agent.messages[i])) return true;
|
|
5710
|
+
return false;
|
|
5711
|
+
}, [agent.messages, message.id]);
|
|
5712
|
+
const [phase, setPhase] = (0, react.useState)("idle");
|
|
5713
|
+
(0, react.useEffect)(() => {
|
|
5714
|
+
if (phase !== "idle") return void 0;
|
|
5715
|
+
if (!hasPending) return void 0;
|
|
5716
|
+
const t = setTimeout(() => setPhase("spinner"), PENDING_THRESHOLD_MS);
|
|
5717
|
+
return () => clearTimeout(t);
|
|
5718
|
+
}, [phase, hasPending]);
|
|
5719
|
+
(0, react.useEffect)(() => {
|
|
5720
|
+
if (phase !== "spinner") return void 0;
|
|
5721
|
+
if (!agent.isRunning || sawRealFollowup) setPhase("check");
|
|
5722
|
+
}, [
|
|
5723
|
+
phase,
|
|
5724
|
+
agent.isRunning,
|
|
5725
|
+
sawRealFollowup
|
|
5726
|
+
]);
|
|
5727
|
+
(0, react.useEffect)(() => {
|
|
5728
|
+
if (phase !== "check") return void 0;
|
|
5729
|
+
const t = setTimeout(() => setPhase("fading"), CHECK_HOLD_MS);
|
|
5730
|
+
return () => clearTimeout(t);
|
|
5731
|
+
}, [phase]);
|
|
5732
|
+
(0, react.useEffect)(() => {
|
|
5733
|
+
if (phase !== "fading") return void 0;
|
|
5734
|
+
const t = setTimeout(() => setPhase("hidden"), FADE_OUT_ANIMATION_MS);
|
|
5735
|
+
return () => clearTimeout(t);
|
|
5736
|
+
}, [phase]);
|
|
5737
|
+
if (copilotkit.intelligence === void 0) return null;
|
|
5738
|
+
if (!config) return null;
|
|
5739
|
+
if (phase === "idle" || phase === "hidden") return null;
|
|
5740
|
+
if (message.role !== "assistant") return null;
|
|
5741
|
+
if (!(Array.isArray(message.toolCalls) ? message.toolCalls : []).some((tc) => isMatchingToolCallName(tc?.function?.name))) return null;
|
|
5742
|
+
let latestMatchingAssistantId;
|
|
5743
|
+
for (let i = agent.messages.length - 1; i >= 0; i -= 1) {
|
|
5744
|
+
const m = agent.messages[i];
|
|
5745
|
+
if (m.role !== "assistant") continue;
|
|
5746
|
+
if ((Array.isArray(m.toolCalls) ? m.toolCalls : []).some((tc) => isMatchingToolCallName(tc?.function?.name))) {
|
|
5747
|
+
latestMatchingAssistantId = m.id;
|
|
5748
|
+
break;
|
|
5749
|
+
}
|
|
5750
|
+
}
|
|
5751
|
+
if (latestMatchingAssistantId !== message.id) return null;
|
|
5752
|
+
const showSpinner = phase === "spinner";
|
|
5753
|
+
const isFading = phase === "fading";
|
|
5754
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5755
|
+
className: "cpk-intelligence-pill" + (isFading ? " cpk-intelligence-pill--fading" : ""),
|
|
5756
|
+
role: "status",
|
|
5757
|
+
"aria-live": "polite",
|
|
5758
|
+
"aria-hidden": isFading || void 0,
|
|
5759
|
+
"data-testid": `cpk-intelligence-pill-${message.id}`,
|
|
5760
|
+
title: label,
|
|
5761
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
5762
|
+
className: "cpk-intelligence-pill__icon",
|
|
5763
|
+
viewBox: "0 0 24 24",
|
|
5764
|
+
width: "14",
|
|
5765
|
+
height: "14",
|
|
5766
|
+
"aria-hidden": "true",
|
|
5767
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
5768
|
+
cx: "12",
|
|
5769
|
+
cy: "12",
|
|
5770
|
+
r: "9",
|
|
5771
|
+
fill: "none",
|
|
5772
|
+
strokeWidth: "2.5",
|
|
5773
|
+
strokeLinecap: "round",
|
|
5774
|
+
className: "cpk-intelligence-pill__ring" + (showSpinner ? "" : " cpk-intelligence-pill__ring--done")
|
|
5775
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
5776
|
+
d: "M8 12.5l3 3 5-6",
|
|
5777
|
+
fill: "none",
|
|
5778
|
+
strokeWidth: "2.5",
|
|
5779
|
+
strokeLinecap: "round",
|
|
5780
|
+
strokeLinejoin: "round",
|
|
5781
|
+
className: "cpk-intelligence-pill__check" + (showSpinner ? "" : " cpk-intelligence-pill__check--shown")
|
|
5782
|
+
})]
|
|
5783
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label })]
|
|
5784
|
+
});
|
|
5785
|
+
}
|
|
5786
|
+
|
|
5658
5787
|
//#endregion
|
|
5659
5788
|
//#region src/v2/components/chat/CopilotChatMessageView.tsx
|
|
5660
5789
|
/**
|
|
@@ -5812,14 +5941,12 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
|
|
|
5812
5941
|
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
5813
5942
|
(0, react.useEffect)(() => {
|
|
5814
5943
|
if (!config?.agentId) return;
|
|
5815
|
-
const
|
|
5816
|
-
const agent = getThreadClone(registryAgent, config.threadId) ?? registryAgent;
|
|
5944
|
+
const agent = copilotkit.getAgent(config.agentId);
|
|
5817
5945
|
if (!agent) return;
|
|
5818
5946
|
const subscription = agent.subscribe({ onStateChanged: forceUpdate });
|
|
5819
5947
|
return () => subscription.unsubscribe();
|
|
5820
5948
|
}, [
|
|
5821
5949
|
config?.agentId,
|
|
5822
|
-
config?.threadId,
|
|
5823
5950
|
copilotkit,
|
|
5824
5951
|
forceUpdate
|
|
5825
5952
|
]);
|
|
@@ -5902,6 +6029,10 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
|
|
|
5902
6029
|
renderCustomMessage,
|
|
5903
6030
|
stateSnapshot
|
|
5904
6031
|
}, `${message.id}-custom-after`));
|
|
6032
|
+
if (copilotkit.intelligence !== void 0 && message.role === "assistant") elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IntelligenceIndicator, {
|
|
6033
|
+
message,
|
|
6034
|
+
agentId: config?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID
|
|
6035
|
+
}, `${message.id}-intelligence`));
|
|
5905
6036
|
return elements.filter(Boolean);
|
|
5906
6037
|
};
|
|
5907
6038
|
const messageElements = shouldVirtualize ? [] : deduplicatedMessages.flatMap(renderMessageBlock);
|
|
@@ -6850,7 +6981,6 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
6850
6981
|
const hasExplicitThreadId = !!threadId || !!existingConfig?.hasExplicitThreadId;
|
|
6851
6982
|
const { agent } = useAgent({
|
|
6852
6983
|
agentId: resolvedAgentId,
|
|
6853
|
-
threadId: resolvedThreadId,
|
|
6854
6984
|
throttleMs
|
|
6855
6985
|
});
|
|
6856
6986
|
const { copilotkit } = useCopilotKit();
|
|
@@ -6892,6 +7022,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
6892
7022
|
let detached = false;
|
|
6893
7023
|
const connectAbortController = new AbortController();
|
|
6894
7024
|
if (agent instanceof _ag_ui_client.HttpAgent) agent.abortController = connectAbortController;
|
|
7025
|
+
agent.threadId = resolvedThreadId;
|
|
6895
7026
|
const connect = async (agent) => {
|
|
6896
7027
|
try {
|
|
6897
7028
|
await copilotkit.connectAgent({ agent });
|
|
@@ -10024,6 +10155,12 @@ Object.defineProperty(exports, 'DefaultOpenIcon', {
|
|
|
10024
10155
|
return DefaultOpenIcon;
|
|
10025
10156
|
}
|
|
10026
10157
|
});
|
|
10158
|
+
Object.defineProperty(exports, 'IntelligenceIndicator', {
|
|
10159
|
+
enumerable: true,
|
|
10160
|
+
get: function () {
|
|
10161
|
+
return IntelligenceIndicator;
|
|
10162
|
+
}
|
|
10163
|
+
});
|
|
10027
10164
|
Object.defineProperty(exports, 'MCPAppsActivityContentSchema', {
|
|
10028
10165
|
enumerable: true,
|
|
10029
10166
|
get: function () {
|
|
@@ -10252,4 +10389,4 @@ Object.defineProperty(exports, 'useToast', {
|
|
|
10252
10389
|
return useToast;
|
|
10253
10390
|
}
|
|
10254
10391
|
});
|
|
10255
|
-
//# sourceMappingURL=copilotkit-
|
|
10392
|
+
//# sourceMappingURL=copilotkit-C3k13WZn.cjs.map
|