@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
|
@@ -1294,6 +1294,197 @@ function useKatexStyles() {
|
|
|
1294
1294
|
}, []);
|
|
1295
1295
|
}
|
|
1296
1296
|
|
|
1297
|
+
//#endregion
|
|
1298
|
+
//#region src/v2/lib/react-core.ts
|
|
1299
|
+
var CopilotKitCoreReact = class extends CopilotKitCore {
|
|
1300
|
+
constructor(config) {
|
|
1301
|
+
super(config);
|
|
1302
|
+
this._renderToolCalls = [];
|
|
1303
|
+
this._hookRenderToolCalls = /* @__PURE__ */ new Map();
|
|
1304
|
+
this._cachedMergedRenderToolCalls = null;
|
|
1305
|
+
this._renderCustomMessages = [];
|
|
1306
|
+
this._renderActivityMessages = [];
|
|
1307
|
+
this._interruptElement = null;
|
|
1308
|
+
this._renderToolCalls = config.renderToolCalls ?? [];
|
|
1309
|
+
this._renderCustomMessages = config.renderCustomMessages ?? [];
|
|
1310
|
+
this._renderActivityMessages = config.renderActivityMessages ?? [];
|
|
1311
|
+
}
|
|
1312
|
+
get renderCustomMessages() {
|
|
1313
|
+
return this._renderCustomMessages;
|
|
1314
|
+
}
|
|
1315
|
+
get renderActivityMessages() {
|
|
1316
|
+
return this._renderActivityMessages;
|
|
1317
|
+
}
|
|
1318
|
+
get renderToolCalls() {
|
|
1319
|
+
if (this._hookRenderToolCalls.size === 0) return this._renderToolCalls;
|
|
1320
|
+
if (this._cachedMergedRenderToolCalls) return this._cachedMergedRenderToolCalls;
|
|
1321
|
+
const merged = /* @__PURE__ */ new Map();
|
|
1322
|
+
for (const rc of this._renderToolCalls) merged.set(`${rc.agentId ?? ""}:${rc.name}`, rc);
|
|
1323
|
+
for (const [key, rc] of this._hookRenderToolCalls) merged.set(key, rc);
|
|
1324
|
+
this._cachedMergedRenderToolCalls = Array.from(merged.values());
|
|
1325
|
+
return this._cachedMergedRenderToolCalls;
|
|
1326
|
+
}
|
|
1327
|
+
setRenderActivityMessages(renderers) {
|
|
1328
|
+
this._renderActivityMessages = renderers;
|
|
1329
|
+
}
|
|
1330
|
+
setRenderCustomMessages(renderers) {
|
|
1331
|
+
this._renderCustomMessages = renderers;
|
|
1332
|
+
}
|
|
1333
|
+
setRenderToolCalls(renderToolCalls) {
|
|
1334
|
+
this._renderToolCalls = renderToolCalls;
|
|
1335
|
+
this._cachedMergedRenderToolCalls = null;
|
|
1336
|
+
this._notifyRenderToolCallsChanged();
|
|
1337
|
+
}
|
|
1338
|
+
addHookRenderToolCall(entry) {
|
|
1339
|
+
const key = `${entry.agentId ?? ""}:${entry.name}`;
|
|
1340
|
+
this._hookRenderToolCalls.set(key, entry);
|
|
1341
|
+
this._cachedMergedRenderToolCalls = null;
|
|
1342
|
+
this._notifyRenderToolCallsChanged();
|
|
1343
|
+
}
|
|
1344
|
+
removeHookRenderToolCall(name, agentId) {
|
|
1345
|
+
const key = `${agentId ?? ""}:${name}`;
|
|
1346
|
+
if (this._hookRenderToolCalls.delete(key)) {
|
|
1347
|
+
this._cachedMergedRenderToolCalls = null;
|
|
1348
|
+
this._notifyRenderToolCallsChanged();
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
_notifyRenderToolCallsChanged() {
|
|
1352
|
+
this.notifySubscribers((subscriber) => {
|
|
1353
|
+
const reactSubscriber = subscriber;
|
|
1354
|
+
if (reactSubscriber.onRenderToolCallsChanged) reactSubscriber.onRenderToolCallsChanged({
|
|
1355
|
+
copilotkit: this,
|
|
1356
|
+
renderToolCalls: this.renderToolCalls
|
|
1357
|
+
});
|
|
1358
|
+
}, "Subscriber onRenderToolCallsChanged error:");
|
|
1359
|
+
}
|
|
1360
|
+
get interruptElement() {
|
|
1361
|
+
return this._interruptElement;
|
|
1362
|
+
}
|
|
1363
|
+
setInterruptElement(element) {
|
|
1364
|
+
this._interruptElement = element;
|
|
1365
|
+
this.notifySubscribers((subscriber) => {
|
|
1366
|
+
subscriber.onInterruptElementChanged?.({
|
|
1367
|
+
copilotkit: this,
|
|
1368
|
+
interruptElement: this._interruptElement
|
|
1369
|
+
});
|
|
1370
|
+
}, "Subscriber onInterruptElementChanged error:");
|
|
1371
|
+
}
|
|
1372
|
+
subscribe(subscriber) {
|
|
1373
|
+
return super.subscribe(subscriber);
|
|
1374
|
+
}
|
|
1375
|
+
/**
|
|
1376
|
+
* Wait for pending React state updates before the follow-up agent run.
|
|
1377
|
+
*
|
|
1378
|
+
* When a frontend tool handler calls setState(), React 18 batches the update
|
|
1379
|
+
* and schedules a commit via its internal scheduler (MessageChannel). The
|
|
1380
|
+
* useAgentContext hook registers context via useLayoutEffect, which runs
|
|
1381
|
+
* synchronously after React commits that batch.
|
|
1382
|
+
*
|
|
1383
|
+
* Awaiting a zero-delay timeout yields to the macrotask queue. React's
|
|
1384
|
+
* MessageChannel task runs first, committing the pending state and running
|
|
1385
|
+
* useLayoutEffect (which updates the context store). The follow-up runAgent
|
|
1386
|
+
* call then reads fresh context.
|
|
1387
|
+
*/
|
|
1388
|
+
async waitForPendingFrameworkUpdates() {
|
|
1389
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1390
|
+
}
|
|
1391
|
+
};
|
|
1392
|
+
|
|
1393
|
+
//#endregion
|
|
1394
|
+
//#region src/v2/context.ts
|
|
1395
|
+
const CopilotKitContext = createContext(null);
|
|
1396
|
+
const useCopilotKit = () => {
|
|
1397
|
+
const context = useContext(CopilotKitContext);
|
|
1398
|
+
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
1399
|
+
if (!context) throw new Error("useCopilotKit must be used within CopilotKitProvider");
|
|
1400
|
+
useEffect(() => {
|
|
1401
|
+
const subscription = context.copilotkit.subscribe({ onRuntimeConnectionStatusChanged: () => {
|
|
1402
|
+
forceUpdate();
|
|
1403
|
+
} });
|
|
1404
|
+
return () => {
|
|
1405
|
+
subscription.unsubscribe();
|
|
1406
|
+
};
|
|
1407
|
+
}, []);
|
|
1408
|
+
return context;
|
|
1409
|
+
};
|
|
1410
|
+
const LicenseContext = createContext({
|
|
1411
|
+
status: null,
|
|
1412
|
+
license: null,
|
|
1413
|
+
checkFeature: () => true,
|
|
1414
|
+
getLimit: () => null
|
|
1415
|
+
});
|
|
1416
|
+
const useLicenseContext = () => useContext(LicenseContext);
|
|
1417
|
+
|
|
1418
|
+
//#endregion
|
|
1419
|
+
//#region src/v2/hooks/use-render-tool-call.tsx
|
|
1420
|
+
/**
|
|
1421
|
+
* Memoized component that renders a single tool call.
|
|
1422
|
+
* This prevents unnecessary re-renders when parent components update
|
|
1423
|
+
* but the tool call data hasn't changed.
|
|
1424
|
+
*/
|
|
1425
|
+
const ToolCallRenderer = React.memo(function ToolCallRenderer({ toolCall, toolMessage, RenderComponent, isExecuting }) {
|
|
1426
|
+
const args = useMemo(() => partialJSONParse(toolCall.function.arguments), [toolCall.function.arguments]);
|
|
1427
|
+
const toolName = toolCall.function.name;
|
|
1428
|
+
if (toolMessage) return /* @__PURE__ */ jsx(RenderComponent, {
|
|
1429
|
+
name: toolName,
|
|
1430
|
+
toolCallId: toolCall.id,
|
|
1431
|
+
args,
|
|
1432
|
+
status: ToolCallStatus.Complete,
|
|
1433
|
+
result: toolMessage.content
|
|
1434
|
+
});
|
|
1435
|
+
else if (isExecuting) return /* @__PURE__ */ jsx(RenderComponent, {
|
|
1436
|
+
name: toolName,
|
|
1437
|
+
toolCallId: toolCall.id,
|
|
1438
|
+
args,
|
|
1439
|
+
status: ToolCallStatus.Executing,
|
|
1440
|
+
result: void 0
|
|
1441
|
+
});
|
|
1442
|
+
else return /* @__PURE__ */ jsx(RenderComponent, {
|
|
1443
|
+
name: toolName,
|
|
1444
|
+
toolCallId: toolCall.id,
|
|
1445
|
+
args,
|
|
1446
|
+
status: ToolCallStatus.InProgress,
|
|
1447
|
+
result: void 0
|
|
1448
|
+
});
|
|
1449
|
+
}, (prevProps, nextProps) => {
|
|
1450
|
+
if (prevProps.toolCall.id !== nextProps.toolCall.id) return false;
|
|
1451
|
+
if (prevProps.toolCall.function.name !== nextProps.toolCall.function.name) return false;
|
|
1452
|
+
if (prevProps.toolCall.function.arguments !== nextProps.toolCall.function.arguments) return false;
|
|
1453
|
+
if (prevProps.toolMessage?.content !== nextProps.toolMessage?.content) return false;
|
|
1454
|
+
if (prevProps.isExecuting !== nextProps.isExecuting) return false;
|
|
1455
|
+
if (prevProps.RenderComponent !== nextProps.RenderComponent) return false;
|
|
1456
|
+
return true;
|
|
1457
|
+
});
|
|
1458
|
+
/**
|
|
1459
|
+
* Hook that returns a function to render tool calls based on the render functions
|
|
1460
|
+
* defined in CopilotKitProvider.
|
|
1461
|
+
*
|
|
1462
|
+
* @returns A function that takes a tool call and optional tool message and returns the rendered component
|
|
1463
|
+
*/
|
|
1464
|
+
function useRenderToolCall() {
|
|
1465
|
+
const { copilotkit, executingToolCallIds } = useCopilotKit();
|
|
1466
|
+
const agentId = useCopilotChatConfiguration()?.agentId ?? DEFAULT_AGENT_ID;
|
|
1467
|
+
const renderToolCalls = useSyncExternalStore((callback) => {
|
|
1468
|
+
return copilotkit.subscribe({ onRenderToolCallsChanged: callback }).unsubscribe;
|
|
1469
|
+
}, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
|
|
1470
|
+
return useCallback(({ toolCall, toolMessage }) => {
|
|
1471
|
+
const exactMatches = renderToolCalls.filter((rc) => rc.name === toolCall.function.name);
|
|
1472
|
+
const renderConfig = exactMatches.find((rc) => rc.agentId === agentId) || exactMatches.find((rc) => !rc.agentId) || exactMatches[0] || renderToolCalls.find((rc) => rc.name === "*");
|
|
1473
|
+
if (!renderConfig) return null;
|
|
1474
|
+
const RenderComponent = renderConfig.render;
|
|
1475
|
+
return /* @__PURE__ */ jsx(ToolCallRenderer, {
|
|
1476
|
+
toolCall,
|
|
1477
|
+
toolMessage,
|
|
1478
|
+
RenderComponent,
|
|
1479
|
+
isExecuting: executingToolCallIds.has(toolCall.id)
|
|
1480
|
+
}, toolCall.id);
|
|
1481
|
+
}, [
|
|
1482
|
+
renderToolCalls,
|
|
1483
|
+
executingToolCallIds,
|
|
1484
|
+
agentId
|
|
1485
|
+
]);
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1297
1488
|
//#endregion
|
|
1298
1489
|
//#region src/v2/components/CopilotKitInspector.tsx
|
|
1299
1490
|
const CopilotKitInspector = ({ core, ...rest }) => {
|
|
@@ -2937,102 +3128,6 @@ function A2UICatalogContext({ catalog, includeSchema }) {
|
|
|
2937
3128
|
return null;
|
|
2938
3129
|
}
|
|
2939
3130
|
|
|
2940
|
-
//#endregion
|
|
2941
|
-
//#region src/v2/lib/react-core.ts
|
|
2942
|
-
var CopilotKitCoreReact = class extends CopilotKitCore {
|
|
2943
|
-
constructor(config) {
|
|
2944
|
-
super(config);
|
|
2945
|
-
this._renderToolCalls = [];
|
|
2946
|
-
this._hookRenderToolCalls = /* @__PURE__ */ new Map();
|
|
2947
|
-
this._cachedMergedRenderToolCalls = null;
|
|
2948
|
-
this._renderCustomMessages = [];
|
|
2949
|
-
this._renderActivityMessages = [];
|
|
2950
|
-
this._interruptElement = null;
|
|
2951
|
-
this._renderToolCalls = config.renderToolCalls ?? [];
|
|
2952
|
-
this._renderCustomMessages = config.renderCustomMessages ?? [];
|
|
2953
|
-
this._renderActivityMessages = config.renderActivityMessages ?? [];
|
|
2954
|
-
}
|
|
2955
|
-
get renderCustomMessages() {
|
|
2956
|
-
return this._renderCustomMessages;
|
|
2957
|
-
}
|
|
2958
|
-
get renderActivityMessages() {
|
|
2959
|
-
return this._renderActivityMessages;
|
|
2960
|
-
}
|
|
2961
|
-
get renderToolCalls() {
|
|
2962
|
-
if (this._hookRenderToolCalls.size === 0) return this._renderToolCalls;
|
|
2963
|
-
if (this._cachedMergedRenderToolCalls) return this._cachedMergedRenderToolCalls;
|
|
2964
|
-
const merged = /* @__PURE__ */ new Map();
|
|
2965
|
-
for (const rc of this._renderToolCalls) merged.set(`${rc.agentId ?? ""}:${rc.name}`, rc);
|
|
2966
|
-
for (const [key, rc] of this._hookRenderToolCalls) merged.set(key, rc);
|
|
2967
|
-
this._cachedMergedRenderToolCalls = Array.from(merged.values());
|
|
2968
|
-
return this._cachedMergedRenderToolCalls;
|
|
2969
|
-
}
|
|
2970
|
-
setRenderActivityMessages(renderers) {
|
|
2971
|
-
this._renderActivityMessages = renderers;
|
|
2972
|
-
}
|
|
2973
|
-
setRenderCustomMessages(renderers) {
|
|
2974
|
-
this._renderCustomMessages = renderers;
|
|
2975
|
-
}
|
|
2976
|
-
setRenderToolCalls(renderToolCalls) {
|
|
2977
|
-
this._renderToolCalls = renderToolCalls;
|
|
2978
|
-
this._cachedMergedRenderToolCalls = null;
|
|
2979
|
-
this._notifyRenderToolCallsChanged();
|
|
2980
|
-
}
|
|
2981
|
-
addHookRenderToolCall(entry) {
|
|
2982
|
-
const key = `${entry.agentId ?? ""}:${entry.name}`;
|
|
2983
|
-
this._hookRenderToolCalls.set(key, entry);
|
|
2984
|
-
this._cachedMergedRenderToolCalls = null;
|
|
2985
|
-
this._notifyRenderToolCallsChanged();
|
|
2986
|
-
}
|
|
2987
|
-
removeHookRenderToolCall(name, agentId) {
|
|
2988
|
-
const key = `${agentId ?? ""}:${name}`;
|
|
2989
|
-
if (this._hookRenderToolCalls.delete(key)) {
|
|
2990
|
-
this._cachedMergedRenderToolCalls = null;
|
|
2991
|
-
this._notifyRenderToolCallsChanged();
|
|
2992
|
-
}
|
|
2993
|
-
}
|
|
2994
|
-
_notifyRenderToolCallsChanged() {
|
|
2995
|
-
this.notifySubscribers((subscriber) => {
|
|
2996
|
-
const reactSubscriber = subscriber;
|
|
2997
|
-
if (reactSubscriber.onRenderToolCallsChanged) reactSubscriber.onRenderToolCallsChanged({
|
|
2998
|
-
copilotkit: this,
|
|
2999
|
-
renderToolCalls: this.renderToolCalls
|
|
3000
|
-
});
|
|
3001
|
-
}, "Subscriber onRenderToolCallsChanged error:");
|
|
3002
|
-
}
|
|
3003
|
-
get interruptElement() {
|
|
3004
|
-
return this._interruptElement;
|
|
3005
|
-
}
|
|
3006
|
-
setInterruptElement(element) {
|
|
3007
|
-
this._interruptElement = element;
|
|
3008
|
-
this.notifySubscribers((subscriber) => {
|
|
3009
|
-
subscriber.onInterruptElementChanged?.({
|
|
3010
|
-
copilotkit: this,
|
|
3011
|
-
interruptElement: this._interruptElement
|
|
3012
|
-
});
|
|
3013
|
-
}, "Subscriber onInterruptElementChanged error:");
|
|
3014
|
-
}
|
|
3015
|
-
subscribe(subscriber) {
|
|
3016
|
-
return super.subscribe(subscriber);
|
|
3017
|
-
}
|
|
3018
|
-
/**
|
|
3019
|
-
* Wait for pending React state updates before the follow-up agent run.
|
|
3020
|
-
*
|
|
3021
|
-
* When a frontend tool handler calls setState(), React 18 batches the update
|
|
3022
|
-
* and schedules a commit via its internal scheduler (MessageChannel). The
|
|
3023
|
-
* useAgentContext hook registers context via useLayoutEffect, which runs
|
|
3024
|
-
* synchronously after React commits that batch.
|
|
3025
|
-
*
|
|
3026
|
-
* Awaiting a zero-delay timeout yields to the macrotask queue. React's
|
|
3027
|
-
* MessageChannel task runs first, committing the pending state and running
|
|
3028
|
-
* useLayoutEffect (which updates the context store). The follow-up runAgent
|
|
3029
|
-
* call then reads fresh context.
|
|
3030
|
-
*/
|
|
3031
|
-
async waitForPendingFrameworkUpdates() {
|
|
3032
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
3033
|
-
}
|
|
3034
|
-
};
|
|
3035
|
-
|
|
3036
3131
|
//#endregion
|
|
3037
3132
|
//#region src/v2/providers/CopilotKitProvider.tsx
|
|
3038
3133
|
const HEADER_NAME = "X-CopilotCloud-Public-Api-Key";
|
|
@@ -3048,12 +3143,6 @@ const DEFAULT_DESIGN_SKILL = `When generating UI with generateSandboxedUi, follo
|
|
|
3048
3143
|
- Minimal transitions (150ms) for hover/focus states only. No decorative animations.
|
|
3049
3144
|
- Keep the UI focused and dense — avoid excessive padding. Use compact spacing (8–12px gaps, 10–14px padding in controls).`;
|
|
3050
3145
|
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)";
|
|
3051
|
-
const CopilotKitContext = createContext({
|
|
3052
|
-
copilotkit: null,
|
|
3053
|
-
executingToolCallIds: /* @__PURE__ */ new Set()
|
|
3054
|
-
});
|
|
3055
|
-
const LicenseContext = createContext(createLicenseContextValue(null));
|
|
3056
|
-
const useLicenseContext = () => useContext(LicenseContext);
|
|
3057
3146
|
function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
|
|
3058
3147
|
const empty = useMemo(() => [], []);
|
|
3059
3148
|
const value = prop ?? empty;
|
|
@@ -3275,13 +3364,9 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = {}, c
|
|
|
3275
3364
|
onErrorRef.current = onError;
|
|
3276
3365
|
}, [onError]);
|
|
3277
3366
|
useEffect(() => {
|
|
3278
|
-
if (!onErrorRef.current) return;
|
|
3279
3367
|
const subscription = copilotkit.subscribe({ onError: (event) => {
|
|
3280
|
-
onErrorRef.current
|
|
3281
|
-
|
|
3282
|
-
code: event.code,
|
|
3283
|
-
context: event.context
|
|
3284
|
-
});
|
|
3368
|
+
if (onErrorRef.current) onErrorRef.current(event);
|
|
3369
|
+
else console.error(`[CopilotKit] Error (${event.code}):`, event.error, event.context ?? {});
|
|
3285
3370
|
} });
|
|
3286
3371
|
return () => {
|
|
3287
3372
|
subscription.unsubscribe();
|
|
@@ -3321,327 +3406,81 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = {}, c
|
|
|
3321
3406
|
useEffect(() => {
|
|
3322
3407
|
if (!didMountRef.current) return;
|
|
3323
3408
|
copilotkit.setRenderCustomMessages(renderCustomMessagesList);
|
|
3324
|
-
}, [copilotkit, renderCustomMessagesList]);
|
|
3325
|
-
useEffect(() => {
|
|
3326
|
-
didMountRef.current = true;
|
|
3327
|
-
}, []);
|
|
3328
|
-
useEffect(() => {
|
|
3329
|
-
copilotkit.setDefaultThrottleMs(defaultThrottleMs);
|
|
3330
|
-
}, [copilotkit, defaultThrottleMs]);
|
|
3331
|
-
const designSkill = openGenerativeUI?.designSkill ?? DEFAULT_DESIGN_SKILL;
|
|
3332
|
-
useLayoutEffect(() => {
|
|
3333
|
-
if (!copilotkit || !openGenUIActive) return;
|
|
3334
|
-
const id = copilotkit.addContext({
|
|
3335
|
-
description: "Design guidelines for the generateSandboxedUi tool. Follow these when building UI.",
|
|
3336
|
-
value: designSkill
|
|
3337
|
-
});
|
|
3338
|
-
return () => {
|
|
3339
|
-
copilotkit.removeContext(id);
|
|
3340
|
-
};
|
|
3341
|
-
}, [
|
|
3342
|
-
copilotkit,
|
|
3343
|
-
designSkill,
|
|
3344
|
-
openGenUIActive
|
|
3345
|
-
]);
|
|
3346
|
-
const sandboxFunctionsDescriptors = useMemo(() => {
|
|
3347
|
-
if (sandboxFunctionsList.length === 0) return null;
|
|
3348
|
-
return JSON.stringify(sandboxFunctionsList.map((fn) => ({
|
|
3349
|
-
name: fn.name,
|
|
3350
|
-
description: fn.description,
|
|
3351
|
-
parameters: schemaToJsonSchema(fn.parameters, { zodToJsonSchema })
|
|
3352
|
-
})));
|
|
3353
|
-
}, [sandboxFunctionsList]);
|
|
3354
|
-
useLayoutEffect(() => {
|
|
3355
|
-
if (!copilotkit || !sandboxFunctionsDescriptors || !openGenUIActive) return;
|
|
3356
|
-
const id = copilotkit.addContext({
|
|
3357
|
-
description: "Sandbox functions available in generated sandboxed UI code. Call via: await Websandbox.connection.remote.<functionName>(args)",
|
|
3358
|
-
value: sandboxFunctionsDescriptors
|
|
3359
|
-
});
|
|
3360
|
-
return () => {
|
|
3361
|
-
copilotkit.removeContext(id);
|
|
3362
|
-
};
|
|
3363
|
-
}, [
|
|
3364
|
-
copilotkit,
|
|
3365
|
-
sandboxFunctionsDescriptors,
|
|
3366
|
-
openGenUIActive
|
|
3367
|
-
]);
|
|
3368
|
-
const contextValue = useMemo(() => ({
|
|
3369
|
-
copilotkit,
|
|
3370
|
-
executingToolCallIds
|
|
3371
|
-
}), [copilotkit, executingToolCallIds]);
|
|
3372
|
-
const licenseContextValue = useMemo(() => createLicenseContextValue(null), []);
|
|
3373
|
-
return /* @__PURE__ */ jsx(SandboxFunctionsContext.Provider, {
|
|
3374
|
-
value: sandboxFunctionsList,
|
|
3375
|
-
children: /* @__PURE__ */ jsx(CopilotKitContext.Provider, {
|
|
3376
|
-
value: contextValue,
|
|
3377
|
-
children: /* @__PURE__ */ jsxs(LicenseContext.Provider, {
|
|
3378
|
-
value: licenseContextValue,
|
|
3379
|
-
children: [
|
|
3380
|
-
runtimeA2UIEnabled && /* @__PURE__ */ jsx(A2UIBuiltInToolCallRenderer, {}),
|
|
3381
|
-
runtimeA2UIEnabled && /* @__PURE__ */ jsx(A2UICatalogContext, {
|
|
3382
|
-
catalog: a2ui?.catalog,
|
|
3383
|
-
includeSchema: a2ui?.includeSchema
|
|
3384
|
-
}),
|
|
3385
|
-
children,
|
|
3386
|
-
shouldRenderInspector ? /* @__PURE__ */ jsx(CopilotKitInspector, {
|
|
3387
|
-
core: copilotkit,
|
|
3388
|
-
defaultAnchor: inspectorDefaultAnchor
|
|
3389
|
-
}) : null,
|
|
3390
|
-
runtimeLicenseStatus === "none" && !resolvedPublicKey && /* @__PURE__ */ jsx(LicenseWarningBanner, { type: "no_license" }),
|
|
3391
|
-
runtimeLicenseStatus === "expired" && /* @__PURE__ */ jsx(LicenseWarningBanner, { type: "expired" }),
|
|
3392
|
-
runtimeLicenseStatus === "invalid" && /* @__PURE__ */ jsx(LicenseWarningBanner, { type: "invalid" }),
|
|
3393
|
-
runtimeLicenseStatus === "expiring" && /* @__PURE__ */ jsx(LicenseWarningBanner, { type: "expiring" })
|
|
3394
|
-
]
|
|
3395
|
-
})
|
|
3396
|
-
})
|
|
3397
|
-
});
|
|
3398
|
-
};
|
|
3399
|
-
const useCopilotKit = () => {
|
|
3400
|
-
const context = useContext(CopilotKitContext);
|
|
3401
|
-
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
3402
|
-
if (!context) throw new Error("useCopilotKit must be used within CopilotKitProvider");
|
|
3403
|
-
useEffect(() => {
|
|
3404
|
-
const subscription = context.copilotkit.subscribe({ onRuntimeConnectionStatusChanged: () => {
|
|
3405
|
-
forceUpdate();
|
|
3406
|
-
} });
|
|
3407
|
-
return () => {
|
|
3408
|
-
subscription.unsubscribe();
|
|
3409
|
-
};
|
|
3410
|
-
}, []);
|
|
3411
|
-
return context;
|
|
3412
|
-
};
|
|
3413
|
-
|
|
3414
|
-
//#endregion
|
|
3415
|
-
//#region src/v2/hooks/use-render-tool-call.tsx
|
|
3416
|
-
/**
|
|
3417
|
-
* Memoized component that renders a single tool call.
|
|
3418
|
-
* This prevents unnecessary re-renders when parent components update
|
|
3419
|
-
* but the tool call data hasn't changed.
|
|
3420
|
-
*/
|
|
3421
|
-
const ToolCallRenderer = React.memo(function ToolCallRenderer({ toolCall, toolMessage, RenderComponent, isExecuting }) {
|
|
3422
|
-
const args = useMemo(() => partialJSONParse(toolCall.function.arguments), [toolCall.function.arguments]);
|
|
3423
|
-
const toolName = toolCall.function.name;
|
|
3424
|
-
if (toolMessage) return /* @__PURE__ */ jsx(RenderComponent, {
|
|
3425
|
-
name: toolName,
|
|
3426
|
-
toolCallId: toolCall.id,
|
|
3427
|
-
args,
|
|
3428
|
-
status: ToolCallStatus.Complete,
|
|
3429
|
-
result: toolMessage.content
|
|
3430
|
-
});
|
|
3431
|
-
else if (isExecuting) return /* @__PURE__ */ jsx(RenderComponent, {
|
|
3432
|
-
name: toolName,
|
|
3433
|
-
toolCallId: toolCall.id,
|
|
3434
|
-
args,
|
|
3435
|
-
status: ToolCallStatus.Executing,
|
|
3436
|
-
result: void 0
|
|
3437
|
-
});
|
|
3438
|
-
else return /* @__PURE__ */ jsx(RenderComponent, {
|
|
3439
|
-
name: toolName,
|
|
3440
|
-
toolCallId: toolCall.id,
|
|
3441
|
-
args,
|
|
3442
|
-
status: ToolCallStatus.InProgress,
|
|
3443
|
-
result: void 0
|
|
3444
|
-
});
|
|
3445
|
-
}, (prevProps, nextProps) => {
|
|
3446
|
-
if (prevProps.toolCall.id !== nextProps.toolCall.id) return false;
|
|
3447
|
-
if (prevProps.toolCall.function.name !== nextProps.toolCall.function.name) return false;
|
|
3448
|
-
if (prevProps.toolCall.function.arguments !== nextProps.toolCall.function.arguments) return false;
|
|
3449
|
-
if (prevProps.toolMessage?.content !== nextProps.toolMessage?.content) return false;
|
|
3450
|
-
if (prevProps.isExecuting !== nextProps.isExecuting) return false;
|
|
3451
|
-
if (prevProps.RenderComponent !== nextProps.RenderComponent) return false;
|
|
3452
|
-
return true;
|
|
3453
|
-
});
|
|
3454
|
-
/**
|
|
3455
|
-
* Hook that returns a function to render tool calls based on the render functions
|
|
3456
|
-
* defined in CopilotKitProvider.
|
|
3457
|
-
*
|
|
3458
|
-
* @returns A function that takes a tool call and optional tool message and returns the rendered component
|
|
3459
|
-
*/
|
|
3460
|
-
function useRenderToolCall() {
|
|
3461
|
-
const { copilotkit, executingToolCallIds } = useCopilotKit();
|
|
3462
|
-
const agentId = useCopilotChatConfiguration()?.agentId ?? DEFAULT_AGENT_ID;
|
|
3463
|
-
const renderToolCalls = useSyncExternalStore((callback) => {
|
|
3464
|
-
return copilotkit.subscribe({ onRenderToolCallsChanged: callback }).unsubscribe;
|
|
3465
|
-
}, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
|
|
3466
|
-
return useCallback(({ toolCall, toolMessage }) => {
|
|
3467
|
-
const exactMatches = renderToolCalls.filter((rc) => rc.name === toolCall.function.name);
|
|
3468
|
-
const renderConfig = exactMatches.find((rc) => rc.agentId === agentId) || exactMatches.find((rc) => !rc.agentId) || exactMatches[0] || renderToolCalls.find((rc) => rc.name === "*");
|
|
3469
|
-
if (!renderConfig) return null;
|
|
3470
|
-
const RenderComponent = renderConfig.render;
|
|
3471
|
-
return /* @__PURE__ */ jsx(ToolCallRenderer, {
|
|
3472
|
-
toolCall,
|
|
3473
|
-
toolMessage,
|
|
3474
|
-
RenderComponent,
|
|
3475
|
-
isExecuting: executingToolCallIds.has(toolCall.id)
|
|
3476
|
-
}, toolCall.id);
|
|
3477
|
-
}, [
|
|
3478
|
-
renderToolCalls,
|
|
3479
|
-
executingToolCallIds,
|
|
3480
|
-
agentId
|
|
3481
|
-
]);
|
|
3482
|
-
}
|
|
3483
|
-
|
|
3484
|
-
//#endregion
|
|
3485
|
-
//#region src/v2/hooks/use-agent.tsx
|
|
3486
|
-
let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
|
|
3487
|
-
UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
|
|
3488
|
-
UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
|
|
3489
|
-
UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
|
|
3490
|
-
return UseAgentUpdate;
|
|
3491
|
-
}({});
|
|
3492
|
-
const ALL_UPDATES = [
|
|
3493
|
-
UseAgentUpdate.OnMessagesChanged,
|
|
3494
|
-
UseAgentUpdate.OnStateChanged,
|
|
3495
|
-
UseAgentUpdate.OnRunStatusChanged
|
|
3496
|
-
];
|
|
3497
|
-
/**
|
|
3498
|
-
* Clone a registry agent for per-thread isolation.
|
|
3499
|
-
* Copies agent configuration (transport, headers, etc.) but resets conversation
|
|
3500
|
-
* state (messages, threadId, state) so each thread starts fresh.
|
|
3501
|
-
*/
|
|
3502
|
-
function cloneForThread(source, threadId, headers) {
|
|
3503
|
-
const clone = source.clone();
|
|
3504
|
-
if (clone === source) throw new Error(`useAgent: ${source.constructor.name}.clone() returned the same instance. clone() must return a new, independent object.`);
|
|
3505
|
-
clone.threadId = threadId;
|
|
3506
|
-
clone.setMessages([]);
|
|
3507
|
-
clone.setState({});
|
|
3508
|
-
if (clone instanceof HttpAgent) clone.headers = { ...headers };
|
|
3509
|
-
return clone;
|
|
3510
|
-
}
|
|
3511
|
-
/**
|
|
3512
|
-
* Module-level WeakMap: registryAgent → (threadId → clone).
|
|
3513
|
-
* Shared across all useAgent() calls so that every component using the same
|
|
3514
|
-
* (agentId, threadId) pair receives the same agent instance. Using WeakMap
|
|
3515
|
-
* ensures the clone map is garbage-collected when the registry agent is
|
|
3516
|
-
* replaced (e.g. after reconnect or hot-reload).
|
|
3517
|
-
*/
|
|
3518
|
-
const globalThreadCloneMap = /* @__PURE__ */ new WeakMap();
|
|
3519
|
-
/**
|
|
3520
|
-
* Look up an existing per-thread clone without creating one.
|
|
3521
|
-
* Returns undefined when no clone has been created yet for this pair.
|
|
3522
|
-
*/
|
|
3523
|
-
function getThreadClone(registryAgent, threadId) {
|
|
3524
|
-
if (!registryAgent || !threadId) return void 0;
|
|
3525
|
-
return globalThreadCloneMap.get(registryAgent)?.get(threadId);
|
|
3526
|
-
}
|
|
3527
|
-
function getOrCreateThreadClone(existing, threadId, headers) {
|
|
3528
|
-
let byThread = globalThreadCloneMap.get(existing);
|
|
3529
|
-
if (!byThread) {
|
|
3530
|
-
byThread = /* @__PURE__ */ new Map();
|
|
3531
|
-
globalThreadCloneMap.set(existing, byThread);
|
|
3532
|
-
}
|
|
3533
|
-
const cached = byThread.get(threadId);
|
|
3534
|
-
if (cached) return cached;
|
|
3535
|
-
const clone = cloneForThread(existing, threadId, headers);
|
|
3536
|
-
byThread.set(threadId, clone);
|
|
3537
|
-
return clone;
|
|
3538
|
-
}
|
|
3539
|
-
function useAgent({ agentId, threadId, updates, throttleMs } = {}) {
|
|
3540
|
-
agentId ??= DEFAULT_AGENT_ID;
|
|
3541
|
-
const { copilotkit } = useCopilotKit();
|
|
3542
|
-
const providerThrottleMs = copilotkit.defaultThrottleMs;
|
|
3543
|
-
const chatConfig = useCopilotChatConfiguration();
|
|
3544
|
-
threadId ??= chatConfig?.threadId;
|
|
3545
|
-
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
3546
|
-
const updateFlags = useMemo(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
|
|
3547
|
-
const provisionalAgentCache = useRef(/* @__PURE__ */ new Map());
|
|
3548
|
-
const agent = useMemo(() => {
|
|
3549
|
-
const cacheKey = threadId ? `${agentId}:${threadId}` : agentId;
|
|
3550
|
-
const existing = copilotkit.getAgent(agentId);
|
|
3551
|
-
if (existing) {
|
|
3552
|
-
provisionalAgentCache.current.delete(cacheKey);
|
|
3553
|
-
provisionalAgentCache.current.delete(agentId);
|
|
3554
|
-
if (!threadId) return existing;
|
|
3555
|
-
return getOrCreateThreadClone(existing, threadId, copilotkit.headers);
|
|
3556
|
-
}
|
|
3557
|
-
const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
|
|
3558
|
-
const status = copilotkit.runtimeConnectionStatus;
|
|
3559
|
-
if (isRuntimeConfigured && (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
|
|
3560
|
-
const cached = provisionalAgentCache.current.get(cacheKey);
|
|
3561
|
-
if (cached) {
|
|
3562
|
-
cached.headers = { ...copilotkit.headers };
|
|
3563
|
-
return cached;
|
|
3564
|
-
}
|
|
3565
|
-
const provisional = new ProxiedCopilotRuntimeAgent({
|
|
3566
|
-
runtimeUrl: copilotkit.runtimeUrl,
|
|
3567
|
-
agentId,
|
|
3568
|
-
transport: copilotkit.runtimeTransport,
|
|
3569
|
-
runtimeMode: "pending"
|
|
3570
|
-
});
|
|
3571
|
-
provisional.headers = { ...copilotkit.headers };
|
|
3572
|
-
if (threadId) provisional.threadId = threadId;
|
|
3573
|
-
provisionalAgentCache.current.set(cacheKey, provisional);
|
|
3574
|
-
return provisional;
|
|
3575
|
-
}
|
|
3576
|
-
if (isRuntimeConfigured && status === CopilotKitCoreRuntimeConnectionStatus.Error) {
|
|
3577
|
-
const cached = provisionalAgentCache.current.get(cacheKey);
|
|
3578
|
-
if (cached) {
|
|
3579
|
-
cached.headers = { ...copilotkit.headers };
|
|
3580
|
-
return cached;
|
|
3581
|
-
}
|
|
3582
|
-
const provisional = new ProxiedCopilotRuntimeAgent({
|
|
3583
|
-
runtimeUrl: copilotkit.runtimeUrl,
|
|
3584
|
-
agentId,
|
|
3585
|
-
transport: copilotkit.runtimeTransport,
|
|
3586
|
-
runtimeMode: "pending"
|
|
3587
|
-
});
|
|
3588
|
-
provisional.headers = { ...copilotkit.headers };
|
|
3589
|
-
if (threadId) provisional.threadId = threadId;
|
|
3590
|
-
provisionalAgentCache.current.set(cacheKey, provisional);
|
|
3591
|
-
return provisional;
|
|
3592
|
-
}
|
|
3593
|
-
const knownAgents = Object.keys(copilotkit.agents ?? {});
|
|
3594
|
-
const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
|
|
3595
|
-
throw new Error(`useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` + (knownAgents.length ? `Known agents: [${knownAgents.join(", ")}]` : "No agents registered.") + " Verify your runtime /info and/or agents__unsafe_dev_only.");
|
|
3596
|
-
}, [
|
|
3597
|
-
agentId,
|
|
3598
|
-
threadId,
|
|
3599
|
-
copilotkit.agents,
|
|
3600
|
-
copilotkit.runtimeConnectionStatus,
|
|
3601
|
-
copilotkit.runtimeUrl,
|
|
3602
|
-
copilotkit.runtimeTransport,
|
|
3603
|
-
JSON.stringify(copilotkit.headers)
|
|
3604
|
-
]);
|
|
3409
|
+
}, [copilotkit, renderCustomMessagesList]);
|
|
3605
3410
|
useEffect(() => {
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3411
|
+
didMountRef.current = true;
|
|
3412
|
+
}, []);
|
|
3413
|
+
useEffect(() => {
|
|
3414
|
+
copilotkit.setDefaultThrottleMs(defaultThrottleMs);
|
|
3415
|
+
}, [copilotkit, defaultThrottleMs]);
|
|
3416
|
+
const designSkill = openGenerativeUI?.designSkill ?? DEFAULT_DESIGN_SKILL;
|
|
3417
|
+
useLayoutEffect(() => {
|
|
3418
|
+
if (!copilotkit || !openGenUIActive) return;
|
|
3419
|
+
const id = copilotkit.addContext({
|
|
3420
|
+
description: "Design guidelines for the generateSandboxedUi tool. Follow these when building UI.",
|
|
3421
|
+
value: designSkill
|
|
3422
|
+
});
|
|
3423
|
+
return () => {
|
|
3424
|
+
copilotkit.removeContext(id);
|
|
3619
3425
|
};
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3426
|
+
}, [
|
|
3427
|
+
copilotkit,
|
|
3428
|
+
designSkill,
|
|
3429
|
+
openGenUIActive
|
|
3430
|
+
]);
|
|
3431
|
+
const sandboxFunctionsDescriptors = useMemo(() => {
|
|
3432
|
+
if (sandboxFunctionsList.length === 0) return null;
|
|
3433
|
+
return JSON.stringify(sandboxFunctionsList.map((fn) => ({
|
|
3434
|
+
name: fn.name,
|
|
3435
|
+
description: fn.description,
|
|
3436
|
+
parameters: schemaToJsonSchema(fn.parameters, { zodToJsonSchema })
|
|
3437
|
+
})));
|
|
3438
|
+
}, [sandboxFunctionsList]);
|
|
3439
|
+
useLayoutEffect(() => {
|
|
3440
|
+
if (!copilotkit || !sandboxFunctionsDescriptors || !openGenUIActive) return;
|
|
3441
|
+
const id = copilotkit.addContext({
|
|
3442
|
+
description: "Sandbox functions available in generated sandboxed UI code. Call via: await Websandbox.connection.remote.<functionName>(args)",
|
|
3443
|
+
value: sandboxFunctionsDescriptors
|
|
3444
|
+
});
|
|
3629
3445
|
return () => {
|
|
3630
|
-
|
|
3631
|
-
subscription.unsubscribe();
|
|
3446
|
+
copilotkit.removeContext(id);
|
|
3632
3447
|
};
|
|
3633
3448
|
}, [
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
providerThrottleMs,
|
|
3638
|
-
updateFlags
|
|
3449
|
+
copilotkit,
|
|
3450
|
+
sandboxFunctionsDescriptors,
|
|
3451
|
+
openGenUIActive
|
|
3639
3452
|
]);
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3453
|
+
const contextValue = useMemo(() => ({
|
|
3454
|
+
copilotkit,
|
|
3455
|
+
executingToolCallIds
|
|
3456
|
+
}), [copilotkit, executingToolCallIds]);
|
|
3457
|
+
const licenseContextValue = useMemo(() => createLicenseContextValue(null), []);
|
|
3458
|
+
return /* @__PURE__ */ jsx(SandboxFunctionsContext.Provider, {
|
|
3459
|
+
value: sandboxFunctionsList,
|
|
3460
|
+
children: /* @__PURE__ */ jsx(CopilotKitContext.Provider, {
|
|
3461
|
+
value: contextValue,
|
|
3462
|
+
children: /* @__PURE__ */ jsxs(LicenseContext.Provider, {
|
|
3463
|
+
value: licenseContextValue,
|
|
3464
|
+
children: [
|
|
3465
|
+
runtimeA2UIEnabled && /* @__PURE__ */ jsx(A2UIBuiltInToolCallRenderer, {}),
|
|
3466
|
+
runtimeA2UIEnabled && /* @__PURE__ */ jsx(A2UICatalogContext, {
|
|
3467
|
+
catalog: a2ui?.catalog,
|
|
3468
|
+
includeSchema: a2ui?.includeSchema
|
|
3469
|
+
}),
|
|
3470
|
+
children,
|
|
3471
|
+
shouldRenderInspector ? /* @__PURE__ */ jsx(CopilotKitInspector, {
|
|
3472
|
+
core: copilotkit,
|
|
3473
|
+
defaultAnchor: inspectorDefaultAnchor
|
|
3474
|
+
}) : null,
|
|
3475
|
+
runtimeLicenseStatus === "none" && !resolvedPublicKey && /* @__PURE__ */ jsx(LicenseWarningBanner, { type: "no_license" }),
|
|
3476
|
+
runtimeLicenseStatus === "expired" && /* @__PURE__ */ jsx(LicenseWarningBanner, { type: "expired" }),
|
|
3477
|
+
runtimeLicenseStatus === "invalid" && /* @__PURE__ */ jsx(LicenseWarningBanner, { type: "invalid" }),
|
|
3478
|
+
runtimeLicenseStatus === "expiring" && /* @__PURE__ */ jsx(LicenseWarningBanner, { type: "expiring" })
|
|
3479
|
+
]
|
|
3480
|
+
})
|
|
3481
|
+
})
|
|
3482
|
+
});
|
|
3483
|
+
};
|
|
3645
3484
|
|
|
3646
3485
|
//#endregion
|
|
3647
3486
|
//#region src/v2/hooks/use-render-custom-messages.tsx
|
|
@@ -3660,8 +3499,7 @@ function useRenderCustomMessages() {
|
|
|
3660
3499
|
const { message, position } = params;
|
|
3661
3500
|
const resolvedRunId = copilotkit.getRunIdForMessage(agentId, threadId, message.id) ?? copilotkit.getRunIdsForThread(agentId, threadId).slice(-1)[0];
|
|
3662
3501
|
const runId = resolvedRunId ?? `missing-run-id:${message.id}`;
|
|
3663
|
-
const
|
|
3664
|
-
const agent = getThreadClone(registryAgent, threadId) ?? registryAgent;
|
|
3502
|
+
const agent = copilotkit.getAgent(agentId);
|
|
3665
3503
|
if (!agent) return null;
|
|
3666
3504
|
const messagesIdsInRun = resolvedRunId ? agent.messages.filter((msg) => copilotkit.getRunIdForMessage(agentId, threadId, msg.id) === resolvedRunId).map((msg) => msg.id) : [message.id];
|
|
3667
3505
|
const rawMessageIndex = agent.messages.findIndex((msg) => msg.id === message.id);
|
|
@@ -3693,8 +3531,7 @@ function useRenderCustomMessages() {
|
|
|
3693
3531
|
//#region src/v2/hooks/use-render-activity-message.tsx
|
|
3694
3532
|
function useRenderActivityMessage() {
|
|
3695
3533
|
const { copilotkit } = useCopilotKit();
|
|
3696
|
-
const
|
|
3697
|
-
const agentId = config?.agentId ?? DEFAULT_AGENT_ID;
|
|
3534
|
+
const agentId = useCopilotChatConfiguration()?.agentId ?? DEFAULT_AGENT_ID;
|
|
3698
3535
|
const renderers = copilotkit.renderActivityMessages;
|
|
3699
3536
|
const findRenderer = useCallback((activityType) => {
|
|
3700
3537
|
if (!renderers.length) return null;
|
|
@@ -3710,8 +3547,7 @@ function useRenderActivityMessage() {
|
|
|
3710
3547
|
return null;
|
|
3711
3548
|
}
|
|
3712
3549
|
const Component = renderer.render;
|
|
3713
|
-
const
|
|
3714
|
-
const agent = getThreadClone(registryAgent, config?.threadId) ?? registryAgent;
|
|
3550
|
+
const agent = copilotkit.getAgent(agentId);
|
|
3715
3551
|
return /* @__PURE__ */ jsx(Component, {
|
|
3716
3552
|
activityType: message.activityType,
|
|
3717
3553
|
content: parseResult.data,
|
|
@@ -3720,7 +3556,6 @@ function useRenderActivityMessage() {
|
|
|
3720
3556
|
}, message.id);
|
|
3721
3557
|
}, [
|
|
3722
3558
|
agentId,
|
|
3723
|
-
config?.threadId,
|
|
3724
3559
|
copilotkit,
|
|
3725
3560
|
findRenderer
|
|
3726
3561
|
]);
|
|
@@ -3759,8 +3594,7 @@ function useFrontendTool(tool, deps) {
|
|
|
3759
3594
|
tool.name,
|
|
3760
3595
|
tool.available,
|
|
3761
3596
|
copilotkit,
|
|
3762
|
-
extraDeps
|
|
3763
|
-
...extraDeps
|
|
3597
|
+
JSON.stringify(extraDeps)
|
|
3764
3598
|
]);
|
|
3765
3599
|
}
|
|
3766
3600
|
|
|
@@ -3899,8 +3733,7 @@ function useRenderTool(config, deps) {
|
|
|
3899
3733
|
}, [
|
|
3900
3734
|
config.name,
|
|
3901
3735
|
copilotkit,
|
|
3902
|
-
extraDeps
|
|
3903
|
-
...extraDeps
|
|
3736
|
+
JSON.stringify(extraDeps)
|
|
3904
3737
|
]);
|
|
3905
3738
|
}
|
|
3906
3739
|
|
|
@@ -4160,6 +3993,118 @@ function useHumanInTheLoop(tool, deps) {
|
|
|
4160
3993
|
]);
|
|
4161
3994
|
}
|
|
4162
3995
|
|
|
3996
|
+
//#endregion
|
|
3997
|
+
//#region src/v2/hooks/use-agent.tsx
|
|
3998
|
+
let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
|
|
3999
|
+
UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
|
|
4000
|
+
UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
|
|
4001
|
+
UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
|
|
4002
|
+
return UseAgentUpdate;
|
|
4003
|
+
}({});
|
|
4004
|
+
const ALL_UPDATES = [
|
|
4005
|
+
UseAgentUpdate.OnMessagesChanged,
|
|
4006
|
+
UseAgentUpdate.OnStateChanged,
|
|
4007
|
+
UseAgentUpdate.OnRunStatusChanged
|
|
4008
|
+
];
|
|
4009
|
+
function useAgent({ agentId, updates, throttleMs } = {}) {
|
|
4010
|
+
agentId ??= DEFAULT_AGENT_ID;
|
|
4011
|
+
const { copilotkit } = useCopilotKit();
|
|
4012
|
+
const providerThrottleMs = copilotkit.defaultThrottleMs;
|
|
4013
|
+
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
4014
|
+
const updateFlags = useMemo(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
|
|
4015
|
+
const provisionalAgentCache = useRef(/* @__PURE__ */ new Map());
|
|
4016
|
+
const agent = useMemo(() => {
|
|
4017
|
+
const existing = copilotkit.getAgent(agentId);
|
|
4018
|
+
if (existing) {
|
|
4019
|
+
provisionalAgentCache.current.delete(agentId);
|
|
4020
|
+
return existing;
|
|
4021
|
+
}
|
|
4022
|
+
const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
|
|
4023
|
+
const status = copilotkit.runtimeConnectionStatus;
|
|
4024
|
+
if (isRuntimeConfigured && (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
|
|
4025
|
+
const cached = provisionalAgentCache.current.get(agentId);
|
|
4026
|
+
if (cached) {
|
|
4027
|
+
cached.headers = { ...copilotkit.headers };
|
|
4028
|
+
return cached;
|
|
4029
|
+
}
|
|
4030
|
+
const provisional = new ProxiedCopilotRuntimeAgent({
|
|
4031
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
4032
|
+
agentId,
|
|
4033
|
+
transport: copilotkit.runtimeTransport,
|
|
4034
|
+
runtimeMode: "pending"
|
|
4035
|
+
});
|
|
4036
|
+
provisional.headers = { ...copilotkit.headers };
|
|
4037
|
+
provisionalAgentCache.current.set(agentId, provisional);
|
|
4038
|
+
return provisional;
|
|
4039
|
+
}
|
|
4040
|
+
if (isRuntimeConfigured && status === CopilotKitCoreRuntimeConnectionStatus.Error) {
|
|
4041
|
+
const cached = provisionalAgentCache.current.get(agentId);
|
|
4042
|
+
if (cached) {
|
|
4043
|
+
cached.headers = { ...copilotkit.headers };
|
|
4044
|
+
return cached;
|
|
4045
|
+
}
|
|
4046
|
+
const provisional = new ProxiedCopilotRuntimeAgent({
|
|
4047
|
+
runtimeUrl: copilotkit.runtimeUrl,
|
|
4048
|
+
agentId,
|
|
4049
|
+
transport: copilotkit.runtimeTransport,
|
|
4050
|
+
runtimeMode: "pending"
|
|
4051
|
+
});
|
|
4052
|
+
provisional.headers = { ...copilotkit.headers };
|
|
4053
|
+
provisionalAgentCache.current.set(agentId, provisional);
|
|
4054
|
+
return provisional;
|
|
4055
|
+
}
|
|
4056
|
+
const knownAgents = Object.keys(copilotkit.agents ?? {});
|
|
4057
|
+
const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
|
|
4058
|
+
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.");
|
|
4059
|
+
}, [
|
|
4060
|
+
agentId,
|
|
4061
|
+
copilotkit.agents,
|
|
4062
|
+
copilotkit.runtimeConnectionStatus,
|
|
4063
|
+
copilotkit.runtimeUrl,
|
|
4064
|
+
copilotkit.runtimeTransport,
|
|
4065
|
+
JSON.stringify(copilotkit.headers)
|
|
4066
|
+
]);
|
|
4067
|
+
useEffect(() => {
|
|
4068
|
+
if (updateFlags.length === 0) return;
|
|
4069
|
+
let active = true;
|
|
4070
|
+
const handlers = {};
|
|
4071
|
+
let batchScheduled = false;
|
|
4072
|
+
const batchedForceUpdate = () => {
|
|
4073
|
+
if (!active) return;
|
|
4074
|
+
if (!batchScheduled) {
|
|
4075
|
+
batchScheduled = true;
|
|
4076
|
+
queueMicrotask(() => {
|
|
4077
|
+
batchScheduled = false;
|
|
4078
|
+
if (active) forceUpdate();
|
|
4079
|
+
});
|
|
4080
|
+
}
|
|
4081
|
+
};
|
|
4082
|
+
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = batchedForceUpdate;
|
|
4083
|
+
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
|
|
4084
|
+
if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
|
|
4085
|
+
handlers.onRunInitialized = batchedForceUpdate;
|
|
4086
|
+
handlers.onRunFinalized = batchedForceUpdate;
|
|
4087
|
+
handlers.onRunFailed = batchedForceUpdate;
|
|
4088
|
+
handlers.onRunErrorEvent = batchedForceUpdate;
|
|
4089
|
+
}
|
|
4090
|
+
const subscription = copilotkit.subscribeToAgentWithOptions(agent, handlers, { throttleMs });
|
|
4091
|
+
return () => {
|
|
4092
|
+
active = false;
|
|
4093
|
+
subscription.unsubscribe();
|
|
4094
|
+
};
|
|
4095
|
+
}, [
|
|
4096
|
+
agent,
|
|
4097
|
+
forceUpdate,
|
|
4098
|
+
throttleMs,
|
|
4099
|
+
providerThrottleMs,
|
|
4100
|
+
updateFlags
|
|
4101
|
+
]);
|
|
4102
|
+
useEffect(() => {
|
|
4103
|
+
if (agent instanceof HttpAgent) agent.headers = { ...copilotkit.headers };
|
|
4104
|
+
}, [agent, JSON.stringify(copilotkit.headers)]);
|
|
4105
|
+
return { agent };
|
|
4106
|
+
}
|
|
4107
|
+
|
|
4163
4108
|
//#endregion
|
|
4164
4109
|
//#region src/v2/hooks/use-capabilities.tsx
|
|
4165
4110
|
/**
|
|
@@ -5625,6 +5570,190 @@ CopilotChatSuggestionView.displayName = "CopilotChatSuggestionView";
|
|
|
5625
5570
|
*/
|
|
5626
5571
|
const ScrollElementContext = React.createContext(null);
|
|
5627
5572
|
|
|
5573
|
+
//#endregion
|
|
5574
|
+
//#region src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx
|
|
5575
|
+
/**
|
|
5576
|
+
* Grace window before showing the spinner. A matching tool call must
|
|
5577
|
+
* remain unresolved (no `tool`-role result message in `agent.messages`)
|
|
5578
|
+
* for at least this long before the pill appears. This filters out
|
|
5579
|
+
* history-replay flashes — during `connectAgent` replay, tool calls and
|
|
5580
|
+
* their results arrive back-to-back in sub-millisecond bursts, so the
|
|
5581
|
+
* timer is cancelled before it fires. Live runs cross the threshold
|
|
5582
|
+
* easily because the tool actually has to execute.
|
|
5583
|
+
*/
|
|
5584
|
+
const PENDING_THRESHOLD_MS = 100;
|
|
5585
|
+
/** Hold the checkmark briefly before fading out. */
|
|
5586
|
+
const CHECK_HOLD_MS = 800;
|
|
5587
|
+
/**
|
|
5588
|
+
* Duration of the fade-out animation. Must match
|
|
5589
|
+
* `cpk-intelligence-pill-fade-out` keyframes in `v2/styles/globals.css`.
|
|
5590
|
+
*/
|
|
5591
|
+
const FADE_OUT_ANIMATION_MS = 480;
|
|
5592
|
+
/**
|
|
5593
|
+
* Tool-name regex patterns that trigger the indicator. Currently
|
|
5594
|
+
* hardcoded to the Intelligence MCP server's canonical tool name. If
|
|
5595
|
+
* we add per-instance customization later (e.g. a `CopilotKitProvider`
|
|
5596
|
+
* prop or a runtime-info field), this constant becomes the fallback.
|
|
5597
|
+
*/
|
|
5598
|
+
const DEFAULT_TOOL_PATTERNS = [/^copilotkit_knowledge_base_shell$/];
|
|
5599
|
+
const isMatchingToolCallName = (name) => typeof name === "string" && DEFAULT_TOOL_PATTERNS.some((p) => p.test(name));
|
|
5600
|
+
/**
|
|
5601
|
+
* "Tool-call-like" messages do NOT count as a real follow-up: tool
|
|
5602
|
+
* result messages, assistant messages that carry tool calls, and
|
|
5603
|
+
* empty-content assistant messages (which some providers emit as a
|
|
5604
|
+
* standalone wrapper around a batch of tool calls). A real follow-up
|
|
5605
|
+
* is anything else — most importantly an assistant message with prose
|
|
5606
|
+
* content, or a fresh user message.
|
|
5607
|
+
*/
|
|
5608
|
+
const isToolCallLikeMessage = (m) => {
|
|
5609
|
+
if (m.role === "tool") return true;
|
|
5610
|
+
if (m.role === "assistant") {
|
|
5611
|
+
if ((Array.isArray(m.toolCalls) ? m.toolCalls : []).length > 0) return true;
|
|
5612
|
+
const content = m.content;
|
|
5613
|
+
return typeof content !== "string" || content.trim().length === 0;
|
|
5614
|
+
}
|
|
5615
|
+
return false;
|
|
5616
|
+
};
|
|
5617
|
+
/**
|
|
5618
|
+
* The "Using CopilotKit Intelligence" pill. Auto-mounted by
|
|
5619
|
+
* `CopilotChatMessageView` for every message slot when
|
|
5620
|
+
* `copilotkit.intelligence` is configured — callers do not register
|
|
5621
|
+
* this themselves. Self-gates so only the canonical message renders a
|
|
5622
|
+
* pill.
|
|
5623
|
+
*
|
|
5624
|
+
* Render gates (all must hold):
|
|
5625
|
+
* 1. `copilotkit.intelligence !== undefined`
|
|
5626
|
+
* 2. The message is an assistant message with at least one tool call
|
|
5627
|
+
* whose name matches {@link DEFAULT_TOOL_PATTERNS}
|
|
5628
|
+
* 3. The message is the *latest* such matching-assistant message in
|
|
5629
|
+
* `agent.messages` — tool-result messages and prose-only assistant
|
|
5630
|
+
* messages don't invalidate the slot, so the pill stays
|
|
5631
|
+
* continuously through a multi-step tool chain.
|
|
5632
|
+
* 4. The phase machine is past `idle` (the pending-grace timer fired)
|
|
5633
|
+
* and not yet `hidden`.
|
|
5634
|
+
*
|
|
5635
|
+
* Phase machine (per-instance, all timers local):
|
|
5636
|
+
* - Starts in `idle` — nothing rendered.
|
|
5637
|
+
* - `idle → spinner` once a matching tool call has been pending
|
|
5638
|
+
* (no `tool`-role result with a matching `toolCallId`) for
|
|
5639
|
+
* {@link PENDING_THRESHOLD_MS}. Replay flashes (tool call + result
|
|
5640
|
+
* in the same tick) never cross this threshold.
|
|
5641
|
+
* - `spinner → check` as soon as EITHER `agent.isRunning` flips
|
|
5642
|
+
* false OR a non-tool-call-like message appears later in
|
|
5643
|
+
* `agent.messages` (i.e. the agent has produced a "real"
|
|
5644
|
+
* follow-up — prose answer or a new user turn).
|
|
5645
|
+
* - `check → fading` after {@link CHECK_HOLD_MS}.
|
|
5646
|
+
* - `fading → hidden` after {@link FADE_OUT_ANIMATION_MS}.
|
|
5647
|
+
*
|
|
5648
|
+
* Once `hidden`, the phase is sticky — a finished pill never re-spawns
|
|
5649
|
+
* on the same message. New runs mount fresh indicator instances on
|
|
5650
|
+
* their own assistant messages.
|
|
5651
|
+
*
|
|
5652
|
+
* The "exactly one pill at a time" guarantee is structural: only one
|
|
5653
|
+
* message satisfies the latest-matching-assistant gate at any moment.
|
|
5654
|
+
*/
|
|
5655
|
+
function IntelligenceIndicator(props) {
|
|
5656
|
+
const { message, agentId, label = "Using CopilotKit Intelligence" } = props;
|
|
5657
|
+
const { copilotkit } = useCopilotKit();
|
|
5658
|
+
const config = useCopilotChatConfiguration();
|
|
5659
|
+
const { agent } = useAgent({
|
|
5660
|
+
agentId,
|
|
5661
|
+
updates: [UseAgentUpdate.OnRunStatusChanged, UseAgentUpdate.OnMessagesChanged]
|
|
5662
|
+
});
|
|
5663
|
+
const matchingToolCallIds = useMemo(() => {
|
|
5664
|
+
if (message.role !== "assistant") return [];
|
|
5665
|
+
const tcs = Array.isArray(message.toolCalls) ? message.toolCalls : [];
|
|
5666
|
+
const ids = [];
|
|
5667
|
+
for (const tc of tcs) if (isMatchingToolCallName(tc?.function?.name) && tc?.id) ids.push(tc.id);
|
|
5668
|
+
return ids;
|
|
5669
|
+
}, [message]);
|
|
5670
|
+
const hasPending = useMemo(() => {
|
|
5671
|
+
if (matchingToolCallIds.length === 0) return false;
|
|
5672
|
+
const resolved = /* @__PURE__ */ new Set();
|
|
5673
|
+
for (const m of agent.messages) if (m.role === "tool" && m.toolCallId) resolved.add(m.toolCallId);
|
|
5674
|
+
return matchingToolCallIds.some((id) => !resolved.has(id));
|
|
5675
|
+
}, [matchingToolCallIds, agent.messages]);
|
|
5676
|
+
const sawRealFollowup = useMemo(() => {
|
|
5677
|
+
const idx = agent.messages.findIndex((m) => m.id === message.id);
|
|
5678
|
+
if (idx < 0) return false;
|
|
5679
|
+
for (let i = idx + 1; i < agent.messages.length; i += 1) if (!isToolCallLikeMessage(agent.messages[i])) return true;
|
|
5680
|
+
return false;
|
|
5681
|
+
}, [agent.messages, message.id]);
|
|
5682
|
+
const [phase, setPhase] = useState("idle");
|
|
5683
|
+
useEffect(() => {
|
|
5684
|
+
if (phase !== "idle") return void 0;
|
|
5685
|
+
if (!hasPending) return void 0;
|
|
5686
|
+
const t = setTimeout(() => setPhase("spinner"), PENDING_THRESHOLD_MS);
|
|
5687
|
+
return () => clearTimeout(t);
|
|
5688
|
+
}, [phase, hasPending]);
|
|
5689
|
+
useEffect(() => {
|
|
5690
|
+
if (phase !== "spinner") return void 0;
|
|
5691
|
+
if (!agent.isRunning || sawRealFollowup) setPhase("check");
|
|
5692
|
+
}, [
|
|
5693
|
+
phase,
|
|
5694
|
+
agent.isRunning,
|
|
5695
|
+
sawRealFollowup
|
|
5696
|
+
]);
|
|
5697
|
+
useEffect(() => {
|
|
5698
|
+
if (phase !== "check") return void 0;
|
|
5699
|
+
const t = setTimeout(() => setPhase("fading"), CHECK_HOLD_MS);
|
|
5700
|
+
return () => clearTimeout(t);
|
|
5701
|
+
}, [phase]);
|
|
5702
|
+
useEffect(() => {
|
|
5703
|
+
if (phase !== "fading") return void 0;
|
|
5704
|
+
const t = setTimeout(() => setPhase("hidden"), FADE_OUT_ANIMATION_MS);
|
|
5705
|
+
return () => clearTimeout(t);
|
|
5706
|
+
}, [phase]);
|
|
5707
|
+
if (copilotkit.intelligence === void 0) return null;
|
|
5708
|
+
if (!config) return null;
|
|
5709
|
+
if (phase === "idle" || phase === "hidden") return null;
|
|
5710
|
+
if (message.role !== "assistant") return null;
|
|
5711
|
+
if (!(Array.isArray(message.toolCalls) ? message.toolCalls : []).some((tc) => isMatchingToolCallName(tc?.function?.name))) return null;
|
|
5712
|
+
let latestMatchingAssistantId;
|
|
5713
|
+
for (let i = agent.messages.length - 1; i >= 0; i -= 1) {
|
|
5714
|
+
const m = agent.messages[i];
|
|
5715
|
+
if (m.role !== "assistant") continue;
|
|
5716
|
+
if ((Array.isArray(m.toolCalls) ? m.toolCalls : []).some((tc) => isMatchingToolCallName(tc?.function?.name))) {
|
|
5717
|
+
latestMatchingAssistantId = m.id;
|
|
5718
|
+
break;
|
|
5719
|
+
}
|
|
5720
|
+
}
|
|
5721
|
+
if (latestMatchingAssistantId !== message.id) return null;
|
|
5722
|
+
const showSpinner = phase === "spinner";
|
|
5723
|
+
const isFading = phase === "fading";
|
|
5724
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
5725
|
+
className: "cpk-intelligence-pill" + (isFading ? " cpk-intelligence-pill--fading" : ""),
|
|
5726
|
+
role: "status",
|
|
5727
|
+
"aria-live": "polite",
|
|
5728
|
+
"aria-hidden": isFading || void 0,
|
|
5729
|
+
"data-testid": `cpk-intelligence-pill-${message.id}`,
|
|
5730
|
+
title: label,
|
|
5731
|
+
children: [/* @__PURE__ */ jsxs("svg", {
|
|
5732
|
+
className: "cpk-intelligence-pill__icon",
|
|
5733
|
+
viewBox: "0 0 24 24",
|
|
5734
|
+
width: "14",
|
|
5735
|
+
height: "14",
|
|
5736
|
+
"aria-hidden": "true",
|
|
5737
|
+
children: [/* @__PURE__ */ jsx("circle", {
|
|
5738
|
+
cx: "12",
|
|
5739
|
+
cy: "12",
|
|
5740
|
+
r: "9",
|
|
5741
|
+
fill: "none",
|
|
5742
|
+
strokeWidth: "2.5",
|
|
5743
|
+
strokeLinecap: "round",
|
|
5744
|
+
className: "cpk-intelligence-pill__ring" + (showSpinner ? "" : " cpk-intelligence-pill__ring--done")
|
|
5745
|
+
}), /* @__PURE__ */ jsx("path", {
|
|
5746
|
+
d: "M8 12.5l3 3 5-6",
|
|
5747
|
+
fill: "none",
|
|
5748
|
+
strokeWidth: "2.5",
|
|
5749
|
+
strokeLinecap: "round",
|
|
5750
|
+
strokeLinejoin: "round",
|
|
5751
|
+
className: "cpk-intelligence-pill__check" + (showSpinner ? "" : " cpk-intelligence-pill__check--shown")
|
|
5752
|
+
})]
|
|
5753
|
+
}), /* @__PURE__ */ jsx("span", { children: label })]
|
|
5754
|
+
});
|
|
5755
|
+
}
|
|
5756
|
+
|
|
5628
5757
|
//#endregion
|
|
5629
5758
|
//#region src/v2/components/chat/CopilotChatMessageView.tsx
|
|
5630
5759
|
/**
|
|
@@ -5782,14 +5911,12 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
|
|
|
5782
5911
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
5783
5912
|
useEffect(() => {
|
|
5784
5913
|
if (!config?.agentId) return;
|
|
5785
|
-
const
|
|
5786
|
-
const agent = getThreadClone(registryAgent, config.threadId) ?? registryAgent;
|
|
5914
|
+
const agent = copilotkit.getAgent(config.agentId);
|
|
5787
5915
|
if (!agent) return;
|
|
5788
5916
|
const subscription = agent.subscribe({ onStateChanged: forceUpdate });
|
|
5789
5917
|
return () => subscription.unsubscribe();
|
|
5790
5918
|
}, [
|
|
5791
5919
|
config?.agentId,
|
|
5792
|
-
config?.threadId,
|
|
5793
5920
|
copilotkit,
|
|
5794
5921
|
forceUpdate
|
|
5795
5922
|
]);
|
|
@@ -5872,6 +5999,10 @@ function CopilotChatMessageView({ messages = [], assistantMessage, userMessage,
|
|
|
5872
5999
|
renderCustomMessage,
|
|
5873
6000
|
stateSnapshot
|
|
5874
6001
|
}, `${message.id}-custom-after`));
|
|
6002
|
+
if (copilotkit.intelligence !== void 0 && message.role === "assistant") elements.push(/* @__PURE__ */ jsx(IntelligenceIndicator, {
|
|
6003
|
+
message,
|
|
6004
|
+
agentId: config?.agentId ?? DEFAULT_AGENT_ID
|
|
6005
|
+
}, `${message.id}-intelligence`));
|
|
5875
6006
|
return elements.filter(Boolean);
|
|
5876
6007
|
};
|
|
5877
6008
|
const messageElements = shouldVirtualize ? [] : deduplicatedMessages.flatMap(renderMessageBlock);
|
|
@@ -6820,7 +6951,6 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
6820
6951
|
const hasExplicitThreadId = !!threadId || !!existingConfig?.hasExplicitThreadId;
|
|
6821
6952
|
const { agent } = useAgent({
|
|
6822
6953
|
agentId: resolvedAgentId,
|
|
6823
|
-
threadId: resolvedThreadId,
|
|
6824
6954
|
throttleMs
|
|
6825
6955
|
});
|
|
6826
6956
|
const { copilotkit } = useCopilotKit();
|
|
@@ -6862,6 +6992,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
6862
6992
|
let detached = false;
|
|
6863
6993
|
const connectAbortController = new AbortController();
|
|
6864
6994
|
if (agent instanceof HttpAgent) agent.abortController = connectAbortController;
|
|
6995
|
+
agent.threadId = resolvedThreadId;
|
|
6865
6996
|
const connect = async (agent) => {
|
|
6866
6997
|
try {
|
|
6867
6998
|
await copilotkit.connectAgent({ agent });
|
|
@@ -9802,5 +9933,5 @@ function validateProps(props) {
|
|
|
9802
9933
|
}
|
|
9803
9934
|
|
|
9804
9935
|
//#endregion
|
|
9805
|
-
export { CopilotKitProvider as $,
|
|
9806
|
-
//# sourceMappingURL=copilotkit-
|
|
9936
|
+
export { CopilotKitProvider as $, IntelligenceIndicator as A, useInterrupt as B, CopilotChatToggleButton as C, CopilotChatView_default as D, CopilotChat as E, CopilotChatAttachmentRenderer as F, useAgent as G, useSuggestions as H, CopilotChatAssistantMessage_default as I, useRenderTool as J, useHumanInTheLoop as K, CopilotChatToolCallsView as L, CopilotChatSuggestionPill as M, CopilotChatReasoningMessage_default as N, CopilotChatAttachmentQueue as O, CopilotChatUserMessage_default as P, useRenderCustomMessages as Q, useAttachments as R, CopilotModalHeader as S, DefaultOpenIcon as T, useCapabilities as U, useConfigureSuggestions as V, UseAgentUpdate as W, useFrontendTool as X, useComponent as Y, useRenderActivityMessage as Z, WildcardToolCallRender as _, ThreadsProvider as a, MCPAppsActivityContentSchema as at, CopilotPopupView as b, CoAgentStateRendersProvider as c, CopilotKitInspector as ct, shouldShowDevConsole as d, CopilotKitCoreReact as dt, useAgentContext as et, useToast as f, CopilotChatInput_default as ft, useCopilotContext as g, useCopilotChatConfiguration as gt, CopilotContext as h, CopilotChatConfigurationProvider as ht, ThreadsContext as i, useSandboxFunctions as it, CopilotChatSuggestionView as j, CopilotChatMessageView as k, useCoAgentStateRenders as l, useRenderToolCall as lt, useCopilotMessagesContext as m, CopilotChatAudioRecorder as mt, defaultCopilotContextCategories as n, createA2UIMessageRenderer as nt, useThreads as o, MCPAppsActivityRenderer as ot, CopilotMessagesContext as p, AudioRecorderError as pt, useDefaultRenderTool as q, CoAgentStateRenderBridge as r, SandboxFunctionsContext as rt, CoAgentStateRendersContext as s, MCPAppsActivityType as st, CopilotKit as t, defineToolCallRenderer as tt, useAsyncCallback as u, useCopilotKit as ut, CopilotPopup as v, DefaultCloseIcon as w, CopilotSidebarView as x, CopilotSidebar as y, useThreads$1 as z };
|
|
9937
|
+
//# sourceMappingURL=copilotkit-DjxXMYHG.mjs.map
|