@copilotkitnext/react 0.0.8 → 0.0.9-alpha.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/index.js CHANGED
@@ -41,6 +41,7 @@ __export(index_exports, {
41
41
  CopilotChatUserMessage: () => CopilotChatUserMessage_default,
42
42
  CopilotChatView: () => CopilotChatView_default,
43
43
  CopilotKitProvider: () => CopilotKitProvider,
44
+ defineToolCallRender: () => defineToolCallRender,
44
45
  useAgent: () => useAgent,
45
46
  useAgentContext: () => useAgentContext,
46
47
  useCopilotChatConfiguration: () => useCopilotChatConfiguration,
@@ -58,6 +59,7 @@ var import_lucide_react2 = require("lucide-react");
58
59
 
59
60
  // src/providers/CopilotChatConfigurationProvider.tsx
60
61
  var import_react = require("react");
62
+ var import_shared = require("@copilotkitnext/shared");
61
63
  var import_jsx_runtime = require("react/jsx-runtime");
62
64
  var CopilotChatDefaultLabels = {
63
65
  chatInputPlaceholder: "Type a message...",
@@ -78,16 +80,20 @@ var CopilotChatDefaultLabels = {
78
80
  chatDisclaimerText: "AI can make mistakes. Please verify important information."
79
81
  };
80
82
  var CopilotChatConfiguration = (0, import_react.createContext)(null);
81
- var CopilotChatConfigurationProvider = ({ children, labels = {}, inputValue, onSubmitInput, onChangeInput }) => {
83
+ var CopilotChatConfigurationProvider = ({
84
+ children,
85
+ labels = {},
86
+ agentId,
87
+ threadId
88
+ }) => {
82
89
  const mergedLabels = {
83
90
  ...CopilotChatDefaultLabels,
84
91
  ...labels
85
92
  };
86
93
  const configurationValue = {
87
94
  labels: mergedLabels,
88
- inputValue,
89
- onSubmitInput,
90
- onChangeInput
95
+ agentId: agentId ?? import_shared.DEFAULT_AGENT_ID,
96
+ threadId
91
97
  };
92
98
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CopilotChatConfiguration.Provider, { value: configurationValue, children });
93
99
  };
@@ -537,10 +543,14 @@ function CopilotChatInput({
537
543
  className,
538
544
  ...props
539
545
  }) {
540
- const { inputValue, onSubmitInput, onChangeInput } = useCopilotChatConfiguration();
541
- value ??= inputValue;
542
- onSubmitMessage ??= onSubmitInput;
543
- onChange ??= onChangeInput;
546
+ const isControlled = value !== void 0;
547
+ const [internalValue, setInternalValue] = (0, import_react4.useState)(() => value ?? "");
548
+ (0, import_react4.useEffect)(() => {
549
+ if (!isControlled && value !== void 0) {
550
+ setInternalValue(value);
551
+ }
552
+ }, [isControlled, value]);
553
+ const resolvedValue = isControlled ? value ?? "" : internalValue;
544
554
  const inputRef = (0, import_react4.useRef)(null);
545
555
  const audioRecorderRef = (0, import_react4.useRef)(null);
546
556
  (0, import_react4.useEffect)(() => {
@@ -557,7 +567,11 @@ function CopilotChatInput({
557
567
  }
558
568
  }, [mode]);
559
569
  const handleChange = (e) => {
560
- onChange?.(e.target.value);
570
+ const nextValue = e.target.value;
571
+ if (!isControlled) {
572
+ setInternalValue(nextValue);
573
+ }
574
+ onChange?.(nextValue);
561
575
  };
562
576
  const handleKeyDown = (e) => {
563
577
  if (e.key === "Enter" && !e.shiftKey) {
@@ -566,17 +580,25 @@ function CopilotChatInput({
566
580
  }
567
581
  };
568
582
  const send = () => {
569
- const trimmed = value?.trim();
570
- if (trimmed) {
571
- onSubmitMessage?.(trimmed);
572
- if (inputRef.current) {
573
- inputRef.current.focus();
574
- }
583
+ if (!onSubmitMessage) {
584
+ return;
585
+ }
586
+ const trimmed = resolvedValue.trim();
587
+ if (!trimmed) {
588
+ return;
589
+ }
590
+ onSubmitMessage(trimmed);
591
+ if (!isControlled) {
592
+ setInternalValue("");
593
+ onChange?.("");
594
+ }
595
+ if (inputRef.current) {
596
+ inputRef.current.focus();
575
597
  }
576
598
  };
577
599
  const BoundTextArea = renderSlot(textArea, CopilotChatInput.TextArea, {
578
600
  ref: inputRef,
579
- value,
601
+ value: resolvedValue,
580
602
  onChange: handleChange,
581
603
  onKeyDown: handleKeyDown,
582
604
  autoFocus
@@ -590,7 +612,7 @@ function CopilotChatInput({
590
612
  );
591
613
  const BoundSendButton = renderSlot(sendButton, CopilotChatInput.SendButton, {
592
614
  onClick: send,
593
- disabled: !value?.trim() || !onSubmitMessage
615
+ disabled: !resolvedValue.trim() || !onSubmitMessage
594
616
  });
595
617
  const BoundStartTranscribeButton = renderSlot(
596
618
  startTranscribeButton,
@@ -924,6 +946,7 @@ var import_core2 = require("@copilotkitnext/core");
924
946
 
925
947
  // src/providers/CopilotKitProvider.tsx
926
948
  var import_react5 = require("react");
949
+ var import_zod = require("zod");
927
950
  var import_core = require("@copilotkitnext/core");
928
951
  var import_jsx_runtime7 = require("react/jsx-runtime");
929
952
  var CopilotKitContext = (0, import_react5.createContext)({
@@ -1009,24 +1032,23 @@ var CopilotKitProvider = ({
1009
1032
  return { tools: processedTools, renderToolCalls: processedRenderToolCalls };
1010
1033
  }, [humanInTheLoopList]);
1011
1034
  const allTools = (0, import_react5.useMemo)(() => {
1012
- const tools = {};
1013
- frontendToolsList.forEach((tool) => {
1014
- tools[tool.name] = tool;
1015
- });
1016
- processedHumanInTheLoopTools.tools.forEach((tool) => {
1017
- tools[tool.name] = tool;
1018
- });
1035
+ const tools = [];
1036
+ tools.push(...frontendToolsList);
1037
+ tools.push(...processedHumanInTheLoopTools.tools);
1019
1038
  return tools;
1020
1039
  }, [frontendToolsList, processedHumanInTheLoopTools]);
1021
1040
  const allRenderToolCalls = (0, import_react5.useMemo)(() => {
1022
1041
  const combined = [...renderToolCallsList];
1023
1042
  frontendToolsList.forEach((tool) => {
1024
- if (tool.render && tool.parameters) {
1025
- combined.push({
1026
- name: tool.name,
1027
- args: tool.parameters,
1028
- render: tool.render
1029
- });
1043
+ if (tool.render) {
1044
+ const args = tool.parameters || (tool.name === "*" ? import_zod.z.any() : void 0);
1045
+ if (args) {
1046
+ combined.push({
1047
+ name: tool.name,
1048
+ args,
1049
+ render: tool.render
1050
+ });
1051
+ }
1030
1052
  }
1031
1053
  });
1032
1054
  combined.push(...processedHumanInTheLoopTools.renderToolCalls);
@@ -1045,9 +1067,30 @@ var CopilotKitProvider = ({
1045
1067
  return copilotkit2;
1046
1068
  }, [allTools]);
1047
1069
  (0, import_react5.useEffect)(() => {
1048
- setCurrentRenderToolCalls(
1049
- (prev) => prev === allRenderToolCalls ? prev : allRenderToolCalls
1050
- );
1070
+ setCurrentRenderToolCalls((prev) => {
1071
+ const keyOf = (rc) => `${rc?.agentId ?? ""}:${rc?.name ?? ""}`;
1072
+ const computedMap = /* @__PURE__ */ new Map();
1073
+ for (const rc of allRenderToolCalls) {
1074
+ computedMap.set(keyOf(rc), rc);
1075
+ }
1076
+ const merged = [...computedMap.values()];
1077
+ for (const rc of prev) {
1078
+ const k = keyOf(rc);
1079
+ if (!computedMap.has(k)) merged.push(rc);
1080
+ }
1081
+ const sameLength = merged.length === prev.length;
1082
+ if (sameLength) {
1083
+ let same = true;
1084
+ for (let i = 0; i < merged.length; i++) {
1085
+ if (merged[i] !== prev[i]) {
1086
+ same = false;
1087
+ break;
1088
+ }
1089
+ }
1090
+ if (same) return prev;
1091
+ }
1092
+ return merged;
1093
+ });
1051
1094
  }, [allRenderToolCalls]);
1052
1095
  (0, import_react5.useEffect)(() => {
1053
1096
  copilotkit.setRuntimeUrl(runtimeUrl);
@@ -1076,10 +1119,7 @@ var useCopilotKit = () => {
1076
1119
  }
1077
1120
  (0, import_react5.useEffect)(() => {
1078
1121
  const unsubscribe = context.copilotkit.subscribe({
1079
- onRuntimeLoaded: () => {
1080
- forceUpdate();
1081
- },
1082
- onRuntimeLoadError: () => {
1122
+ onRuntimeConnectionStatusChanged: () => {
1083
1123
  forceUpdate();
1084
1124
  }
1085
1125
  });
@@ -1091,38 +1131,76 @@ var useCopilotKit = () => {
1091
1131
  };
1092
1132
 
1093
1133
  // src/hooks/use-render-tool-call.tsx
1094
- var import_shared = require("@copilotkitnext/shared");
1134
+ var import_shared2 = require("@copilotkitnext/shared");
1095
1135
  var import_jsx_runtime8 = require("react/jsx-runtime");
1096
1136
  function useRenderToolCall() {
1097
- const { currentRenderToolCalls } = useCopilotKit();
1137
+ const { currentRenderToolCalls, copilotkit } = useCopilotKit();
1138
+ const { agentId } = useCopilotChatConfiguration();
1139
+ const [executingToolCallIds, setExecutingToolCallIds] = (0, import_react6.useState)(() => /* @__PURE__ */ new Set());
1140
+ (0, import_react6.useEffect)(() => {
1141
+ const unsubscribe = copilotkit.subscribe({
1142
+ onToolExecutionStart: ({ toolCallId }) => {
1143
+ setExecutingToolCallIds((prev) => {
1144
+ if (prev.has(toolCallId)) return prev;
1145
+ const next = new Set(prev);
1146
+ next.add(toolCallId);
1147
+ return next;
1148
+ });
1149
+ },
1150
+ onToolExecutionEnd: ({ toolCallId }) => {
1151
+ setExecutingToolCallIds((prev) => {
1152
+ if (!prev.has(toolCallId)) return prev;
1153
+ const next = new Set(prev);
1154
+ next.delete(toolCallId);
1155
+ return next;
1156
+ });
1157
+ }
1158
+ });
1159
+ return () => unsubscribe();
1160
+ }, [copilotkit]);
1098
1161
  const renderToolCall = (0, import_react6.useCallback)(
1099
1162
  ({
1100
1163
  toolCall,
1101
1164
  toolMessage,
1102
- isLoading
1165
+ isRunning
1103
1166
  }) => {
1104
- const renderConfig = currentRenderToolCalls.find(
1167
+ const exactMatches = currentRenderToolCalls.filter(
1105
1168
  (rc) => rc.name === toolCall.function.name
1106
- ) || currentRenderToolCalls.find((rc) => rc.name === "*");
1169
+ );
1170
+ const renderConfig = exactMatches.find((rc) => rc.agentId === agentId) || exactMatches.find((rc) => !rc.agentId) || exactMatches[0] || currentRenderToolCalls.find((rc) => rc.name === "*");
1107
1171
  if (!renderConfig) {
1108
1172
  return null;
1109
1173
  }
1110
1174
  const RenderComponent = renderConfig.render;
1111
- const args = (0, import_shared.partialJSONParse)(toolCall.function.arguments);
1175
+ const args = (0, import_shared2.partialJSONParse)(toolCall.function.arguments);
1176
+ const toolName = toolCall.function.name;
1112
1177
  if (toolMessage) {
1113
1178
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1114
1179
  RenderComponent,
1115
1180
  {
1181
+ name: toolName,
1116
1182
  args,
1117
1183
  status: import_core2.ToolCallStatus.Complete,
1118
1184
  result: toolMessage.content
1119
1185
  },
1120
1186
  toolCall.id
1121
1187
  );
1122
- } else if (isLoading) {
1188
+ } else if (executingToolCallIds.has(toolCall.id)) {
1189
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1190
+ RenderComponent,
1191
+ {
1192
+ name: toolName,
1193
+ args,
1194
+ status: import_core2.ToolCallStatus.Executing,
1195
+ result: void 0
1196
+ },
1197
+ toolCall.id
1198
+ );
1199
+ } else if (isRunning) {
1123
1200
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1124
1201
  RenderComponent,
1125
1202
  {
1203
+ name: toolName,
1126
1204
  args,
1127
1205
  status: import_core2.ToolCallStatus.InProgress,
1128
1206
  result: void 0
@@ -1133,6 +1211,7 @@ function useRenderToolCall() {
1133
1211
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1134
1212
  RenderComponent,
1135
1213
  {
1214
+ name: toolName,
1136
1215
  args,
1137
1216
  status: import_core2.ToolCallStatus.Complete,
1138
1217
  result: ""
@@ -1141,7 +1220,7 @@ function useRenderToolCall() {
1141
1220
  );
1142
1221
  }
1143
1222
  },
1144
- [currentRenderToolCalls]
1223
+ [currentRenderToolCalls, executingToolCallIds, agentId]
1145
1224
  );
1146
1225
  return renderToolCall;
1147
1226
  }
@@ -1149,36 +1228,36 @@ function useRenderToolCall() {
1149
1228
  // src/hooks/use-frontend-tool.tsx
1150
1229
  var import_react7 = require("react");
1151
1230
  function useFrontendTool(tool) {
1152
- const { renderToolCalls, copilotkit, setCurrentRenderToolCalls } = useCopilotKit();
1231
+ const { copilotkit, setCurrentRenderToolCalls } = useCopilotKit();
1153
1232
  (0, import_react7.useEffect)(() => {
1154
- if (tool.name in copilotkit.tools) {
1233
+ const name = tool.name;
1234
+ if (copilotkit.getTool({ toolName: name, agentId: tool.agentId })) {
1155
1235
  console.warn(
1156
- `Tool '${tool.name}' already exists. It will be overridden.`
1236
+ `Tool '${name}' already exists for agent '${tool.agentId || "global"}'. Overriding with latest registration.`
1157
1237
  );
1238
+ copilotkit.removeTool(name, tool.agentId);
1158
1239
  }
1159
1240
  copilotkit.addTool(tool);
1160
- if (tool.render && tool.name in renderToolCalls) {
1161
- console.warn(
1162
- `Render component for tool '${tool.name}' already exists. It will be overridden.`
1163
- );
1164
- }
1165
- if (tool.render && tool.parameters) {
1166
- setCurrentRenderToolCalls((prev) => [
1167
- ...prev,
1168
- {
1169
- name: tool.name,
1170
- args: tool.parameters,
1171
- render: tool.render
1172
- }
1173
- ]);
1241
+ if (tool.render) {
1242
+ setCurrentRenderToolCalls((prev) => {
1243
+ const replaced = prev.filter(
1244
+ (rc) => !(rc.name === name && rc.agentId === tool.agentId)
1245
+ );
1246
+ return [
1247
+ ...replaced,
1248
+ {
1249
+ name,
1250
+ args: tool.parameters,
1251
+ agentId: tool.agentId,
1252
+ render: tool.render
1253
+ }
1254
+ ];
1255
+ });
1174
1256
  }
1175
1257
  return () => {
1176
- copilotkit.removeTool(tool.name);
1177
- setCurrentRenderToolCalls(
1178
- (prev) => prev.filter((rc) => rc.name !== tool.name)
1179
- );
1258
+ copilotkit.removeTool(name, tool.agentId);
1180
1259
  };
1181
- }, [tool, copilotkit, renderToolCalls, setCurrentRenderToolCalls]);
1260
+ }, [tool.name, copilotkit, setCurrentRenderToolCalls]);
1182
1261
  }
1183
1262
 
1184
1263
  // src/hooks/use-human-in-the-loop.tsx
@@ -1188,7 +1267,10 @@ function useHumanInTheLoop(tool) {
1188
1267
  const [status, setStatus] = (0, import_react8.useState)(
1189
1268
  "inProgress"
1190
1269
  );
1270
+ const statusRef = (0, import_react8.useRef)(status);
1191
1271
  const resolvePromiseRef = (0, import_react8.useRef)(null);
1272
+ const { setCurrentRenderToolCalls } = useCopilotKit();
1273
+ statusRef.current = status;
1192
1274
  const respond = (0, import_react8.useCallback)(async (result) => {
1193
1275
  if (resolvePromiseRef.current) {
1194
1276
  resolvePromiseRef.current(result);
@@ -1205,7 +1287,8 @@ function useHumanInTheLoop(tool) {
1205
1287
  const RenderComponent = (0, import_react8.useCallback)(
1206
1288
  (props) => {
1207
1289
  const ToolComponent = tool.render;
1208
- if (status === "inProgress" && props.status === "inProgress") {
1290
+ const currentStatus = statusRef.current;
1291
+ if (currentStatus === "inProgress" && props.status === "inProgress") {
1209
1292
  const enhancedProps = {
1210
1293
  ...props,
1211
1294
  name: tool.name,
@@ -1213,7 +1296,7 @@ function useHumanInTheLoop(tool) {
1213
1296
  respond: void 0
1214
1297
  };
1215
1298
  return import_react9.default.createElement(ToolComponent, enhancedProps);
1216
- } else if (status === "executing" && props.status === "executing") {
1299
+ } else if (currentStatus === "executing" && props.status === "executing") {
1217
1300
  const enhancedProps = {
1218
1301
  ...props,
1219
1302
  name: tool.name,
@@ -1221,7 +1304,7 @@ function useHumanInTheLoop(tool) {
1221
1304
  respond
1222
1305
  };
1223
1306
  return import_react9.default.createElement(ToolComponent, enhancedProps);
1224
- } else if (status === "complete" && props.status === "complete") {
1307
+ } else if (currentStatus === "complete" && props.status === "complete") {
1225
1308
  const enhancedProps = {
1226
1309
  ...props,
1227
1310
  name: tool.name,
@@ -1232,7 +1315,7 @@ function useHumanInTheLoop(tool) {
1232
1315
  }
1233
1316
  return import_react9.default.createElement(ToolComponent, props);
1234
1317
  },
1235
- [tool.render, tool.name, tool.description, status, respond]
1318
+ [tool.render, tool.name, tool.description, respond]
1236
1319
  );
1237
1320
  const frontendTool = {
1238
1321
  ...tool,
@@ -1240,42 +1323,75 @@ function useHumanInTheLoop(tool) {
1240
1323
  render: RenderComponent
1241
1324
  };
1242
1325
  useFrontendTool(frontendTool);
1326
+ (0, import_react8.useEffect)(() => {
1327
+ return () => {
1328
+ setCurrentRenderToolCalls(
1329
+ (prev) => prev.filter(
1330
+ (rc) => rc.name !== tool.name || rc.agentId !== tool.agentId
1331
+ )
1332
+ );
1333
+ };
1334
+ }, [setCurrentRenderToolCalls, tool.name, tool.agentId]);
1243
1335
  }
1244
1336
 
1245
1337
  // src/hooks/use-agent.tsx
1246
1338
  var import_react10 = require("react");
1247
- var import_shared2 = require("@copilotkitnext/shared");
1248
- function useAgent({ agentId } = {}) {
1249
- agentId ??= import_shared2.DEFAULT_AGENT_ID;
1339
+ var import_shared3 = require("@copilotkitnext/shared");
1340
+ var ALL_UPDATES = [
1341
+ "OnMessagesChanged" /* OnMessagesChanged */,
1342
+ "OnStateChanged" /* OnStateChanged */,
1343
+ "OnRunStatusChanged" /* OnRunStatusChanged */
1344
+ ];
1345
+ function useAgent({ agentId, updates } = {}) {
1346
+ agentId ??= import_shared3.DEFAULT_AGENT_ID;
1250
1347
  const { copilotkit } = useCopilotKit();
1251
1348
  const [, forceUpdate] = (0, import_react10.useReducer)((x) => x + 1, 0);
1252
- const [isRunning, setIsRunning] = (0, import_react10.useState)(false);
1349
+ const updateFlags = (0, import_react10.useMemo)(
1350
+ () => updates ?? ALL_UPDATES,
1351
+ [JSON.stringify(updates)]
1352
+ );
1253
1353
  const agent = (0, import_react10.useMemo)(() => {
1254
1354
  return copilotkit.getAgent(agentId);
1255
- }, [agentId, copilotkit.agents, copilotkit.didLoadRuntime, copilotkit]);
1355
+ }, [
1356
+ agentId,
1357
+ copilotkit.agents,
1358
+ copilotkit.runtimeConnectionStatus,
1359
+ copilotkit
1360
+ ]);
1256
1361
  (0, import_react10.useEffect)(() => {
1257
- const subscription = agent?.subscribe({
1258
- onMessagesChanged() {
1362
+ if (!agent) {
1363
+ return;
1364
+ }
1365
+ if (updateFlags.length === 0) {
1366
+ return;
1367
+ }
1368
+ const handlers = {};
1369
+ if (updateFlags.includes("OnMessagesChanged" /* OnMessagesChanged */)) {
1370
+ handlers.onMessagesChanged = () => {
1259
1371
  forceUpdate();
1260
- },
1261
- onStateChanged() {
1372
+ };
1373
+ }
1374
+ if (updateFlags.includes("OnStateChanged" /* OnStateChanged */)) {
1375
+ handlers.onStateChanged = () => {
1262
1376
  forceUpdate();
1263
- },
1264
- onRunInitialized() {
1265
- setIsRunning(true);
1266
- },
1267
- onRunFinalized() {
1268
- setIsRunning(false);
1269
- },
1270
- onRunFailed() {
1271
- setIsRunning(false);
1272
- }
1273
- });
1274
- return () => subscription?.unsubscribe();
1275
- }, [agent]);
1377
+ };
1378
+ }
1379
+ if (updateFlags.includes("OnRunStatusChanged" /* OnRunStatusChanged */)) {
1380
+ handlers.onRunInitialized = () => {
1381
+ forceUpdate();
1382
+ };
1383
+ handlers.onRunFinalized = () => {
1384
+ forceUpdate();
1385
+ };
1386
+ handlers.onRunFailed = () => {
1387
+ forceUpdate();
1388
+ };
1389
+ }
1390
+ const subscription = agent.subscribe(handlers);
1391
+ return () => subscription.unsubscribe();
1392
+ }, [agent, forceUpdate, JSON.stringify(updateFlags)]);
1276
1393
  return {
1277
- agent,
1278
- isRunning
1394
+ agent
1279
1395
  };
1280
1396
  }
1281
1397
 
@@ -1299,7 +1415,7 @@ var import_jsx_runtime9 = require("react/jsx-runtime");
1299
1415
  function CopilotChatToolCallsView({
1300
1416
  message,
1301
1417
  messages = [],
1302
- isLoading = false
1418
+ isRunning = false
1303
1419
  }) {
1304
1420
  const renderToolCall = useRenderToolCall();
1305
1421
  if (!message.toolCalls || message.toolCalls.length === 0) {
@@ -1312,7 +1428,7 @@ function CopilotChatToolCallsView({
1312
1428
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react12.default.Fragment, { children: renderToolCall({
1313
1429
  toolCall,
1314
1430
  toolMessage,
1315
- isLoading
1431
+ isRunning
1316
1432
  }) }, toolCall.id);
1317
1433
  }) });
1318
1434
  }
@@ -1323,7 +1439,7 @@ var import_jsx_runtime10 = require("react/jsx-runtime");
1323
1439
  function CopilotChatAssistantMessage({
1324
1440
  message,
1325
1441
  messages,
1326
- isLoading,
1442
+ isRunning,
1327
1443
  onThumbsUp,
1328
1444
  onThumbsDown,
1329
1445
  onReadAloud,
@@ -1412,9 +1528,11 @@ function CopilotChatAssistantMessage({
1412
1528
  {
1413
1529
  message,
1414
1530
  messages,
1415
- isLoading
1531
+ isRunning
1416
1532
  }
1417
1533
  );
1534
+ const hasContent = !!(message.content && message.content.trim().length > 0);
1535
+ const shouldShowToolbar = toolbarVisible && hasContent;
1418
1536
  if (children) {
1419
1537
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: children({
1420
1538
  markdownRenderer: boundMarkdownRenderer,
@@ -1427,13 +1545,13 @@ function CopilotChatAssistantMessage({
1427
1545
  regenerateButton: boundRegenerateButton,
1428
1546
  message,
1429
1547
  messages,
1430
- isLoading,
1548
+ isRunning,
1431
1549
  onThumbsUp,
1432
1550
  onThumbsDown,
1433
1551
  onReadAloud,
1434
1552
  onRegenerate,
1435
1553
  additionalToolbarItems,
1436
- toolbarVisible
1554
+ toolbarVisible: shouldShowToolbar
1437
1555
  }) });
1438
1556
  }
1439
1557
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
@@ -1448,7 +1566,7 @@ function CopilotChatAssistantMessage({
1448
1566
  children: [
1449
1567
  boundMarkdownRenderer,
1450
1568
  boundToolCallsView,
1451
- toolbarVisible && boundToolbar
1569
+ shouldShowToolbar && boundToolbar
1452
1570
  ]
1453
1571
  }
1454
1572
  );
@@ -1900,7 +2018,7 @@ function CopilotChatMessageView({
1900
2018
  assistantMessage,
1901
2019
  userMessage,
1902
2020
  cursor,
1903
- isLoading = false,
2021
+ isRunning = false,
1904
2022
  children,
1905
2023
  className,
1906
2024
  ...props
@@ -1911,7 +2029,7 @@ function CopilotChatMessageView({
1911
2029
  key: message.id,
1912
2030
  message,
1913
2031
  messages,
1914
- isLoading
2032
+ isRunning
1915
2033
  });
1916
2034
  } else if (message.role === "user") {
1917
2035
  return renderSlot(userMessage, CopilotChatUserMessage_default, {
@@ -1922,11 +2040,11 @@ function CopilotChatMessageView({
1922
2040
  return;
1923
2041
  }).filter(Boolean);
1924
2042
  if (children) {
1925
- return children({ messageElements, messages, isLoading });
2043
+ return children({ messageElements, messages, isRunning });
1926
2044
  }
1927
2045
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: (0, import_tailwind_merge6.twMerge)("flex flex-col", className), ...props, children: [
1928
2046
  messageElements,
1929
- isLoading && renderSlot(cursor, CopilotChatMessageView.Cursor, {})
2047
+ isRunning && renderSlot(cursor, CopilotChatMessageView.Cursor, {})
1930
2048
  ] });
1931
2049
  }
1932
2050
  CopilotChatMessageView.Cursor = function Cursor({
@@ -1962,6 +2080,8 @@ function CopilotChatView({
1962
2080
  disclaimer,
1963
2081
  messages = [],
1964
2082
  autoScroll = true,
2083
+ inputProps,
2084
+ isRunning = false,
1965
2085
  children,
1966
2086
  className,
1967
2087
  ...props
@@ -2001,9 +2121,14 @@ function CopilotChatView({
2001
2121
  };
2002
2122
  }, []);
2003
2123
  const BoundMessageView = renderSlot(messageView, CopilotChatMessageView_default, {
2004
- messages
2124
+ messages,
2125
+ isRunning
2005
2126
  });
2006
- const BoundInput = renderSlot(input, CopilotChatInput_default, {});
2127
+ const BoundInput = renderSlot(
2128
+ input,
2129
+ CopilotChatInput_default,
2130
+ inputProps ?? {}
2131
+ );
2007
2132
  const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
2008
2133
  const BoundScrollView = renderSlot(scrollView, CopilotChatView.ScrollView, {
2009
2134
  autoScroll,
@@ -2221,83 +2346,101 @@ function CopilotChatView({
2221
2346
  var CopilotChatView_default = CopilotChatView;
2222
2347
 
2223
2348
  // src/components/chat/CopilotChat.tsx
2224
- var import_shared3 = require("@copilotkitnext/shared");
2349
+ var import_shared4 = require("@copilotkitnext/shared");
2225
2350
  var import_react16 = require("react");
2226
2351
  var import_ts_deepmerge = require("ts-deepmerge");
2352
+ var import_client = require("@ag-ui/client");
2227
2353
  var import_jsx_runtime14 = require("react/jsx-runtime");
2228
2354
  function CopilotChat({
2229
- agentId = import_shared3.DEFAULT_AGENT_ID,
2355
+ agentId = import_shared4.DEFAULT_AGENT_ID,
2230
2356
  threadId,
2231
2357
  ...props
2232
2358
  }) {
2233
2359
  const { agent } = useAgent({ agentId });
2234
- const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
2235
- threadId = threadId ?? (0, import_react16.useMemo)(() => (0, import_shared3.randomUUID)(), []);
2236
- const subscriber = {
2237
- onTextMessageStartEvent: () => setIsLoading(false),
2238
- onToolCallStartEvent: () => setIsLoading(false)
2239
- };
2360
+ const { copilotkit } = useCopilotKit();
2361
+ const resolvedThreadId = (0, import_react16.useMemo)(() => threadId ?? (0, import_shared4.randomUUID)(), [threadId]);
2240
2362
  (0, import_react16.useEffect)(() => {
2241
- const connect = async () => {
2242
- setIsLoading(true);
2243
- await agent?.runAgent(
2244
- {
2245
- forwardedProps: { __copilotkitConnect: true }
2246
- },
2247
- subscriber
2248
- );
2249
- setIsLoading(false);
2363
+ const connect = async (agent2) => {
2364
+ try {
2365
+ await copilotkit.connectAgent({ agent: agent2, agentId });
2366
+ } catch (error) {
2367
+ if (error instanceof import_client.AGUIConnectNotImplementedError) {
2368
+ } else {
2369
+ throw error;
2370
+ }
2371
+ }
2250
2372
  };
2251
2373
  if (agent) {
2252
- agent.threadId = threadId;
2253
- if ("isCopilotKitAgent" in agent) {
2254
- connect();
2255
- } else {
2256
- setIsLoading(false);
2257
- }
2374
+ agent.threadId = resolvedThreadId;
2375
+ connect(agent);
2258
2376
  }
2259
2377
  return () => {
2260
2378
  };
2261
- }, [threadId, agent]);
2262
- const [inputValue, setInputValue] = (0, import_react16.useState)("");
2379
+ }, [resolvedThreadId, agent, copilotkit, agentId]);
2263
2380
  const onSubmitInput = (0, import_react16.useCallback)(
2264
2381
  async (value) => {
2265
- setInputValue("");
2266
2382
  agent?.addMessage({
2267
- id: (0, import_shared3.randomUUID)(),
2383
+ id: (0, import_shared4.randomUUID)(),
2268
2384
  role: "user",
2269
2385
  content: value
2270
2386
  });
2271
- setIsLoading(true);
2272
- await agent?.runAgent({}, subscriber);
2273
- setIsLoading(false);
2387
+ if (agent) {
2388
+ try {
2389
+ await copilotkit.runAgent({ agent, agentId });
2390
+ } catch (error) {
2391
+ console.error("CopilotChat: runAgent failed", error);
2392
+ }
2393
+ }
2274
2394
  },
2275
- [agent]
2395
+ [agent, copilotkit, agentId]
2276
2396
  );
2397
+ const {
2398
+ inputProps: providedInputProps,
2399
+ messageView: providedMessageView,
2400
+ ...restProps
2401
+ } = props;
2277
2402
  const mergedProps = (0, import_ts_deepmerge.merge)(
2278
2403
  {
2279
- messageView: { isLoading }
2404
+ isRunning: agent?.isRunning ?? false
2280
2405
  },
2281
2406
  {
2282
- ...props,
2283
- ...typeof props.messageView === "string" ? { messageView: { className: props.messageView } } : props.messageView !== void 0 ? { messageView: props.messageView } : {}
2407
+ ...restProps,
2408
+ ...typeof providedMessageView === "string" ? { messageView: { className: providedMessageView } } : providedMessageView !== void 0 ? { messageView: providedMessageView } : {}
2284
2409
  }
2285
2410
  );
2286
2411
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2287
2412
  CopilotChatConfigurationProvider,
2288
2413
  {
2289
- inputValue,
2290
- onSubmitInput,
2291
- onChangeInput: setInputValue,
2414
+ agentId,
2415
+ threadId: resolvedThreadId,
2292
2416
  children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2293
2417
  CopilotChatView,
2294
2418
  {
2295
- ...{ messages: agent?.messages ?? [], ...mergedProps }
2419
+ ...{
2420
+ messages: agent?.messages ?? [],
2421
+ inputProps: {
2422
+ onSubmitMessage: onSubmitInput,
2423
+ ...providedInputProps
2424
+ },
2425
+ ...mergedProps
2426
+ }
2296
2427
  }
2297
2428
  )
2298
2429
  }
2299
2430
  );
2300
2431
  }
2432
+
2433
+ // src/types/defineToolCallRender.ts
2434
+ var import_zod2 = require("zod");
2435
+ function defineToolCallRender(def) {
2436
+ const argsSchema = def.name === "*" && !def.args ? import_zod2.z.any() : def.args;
2437
+ return {
2438
+ name: def.name,
2439
+ args: argsSchema,
2440
+ render: def.render,
2441
+ ...def.agentId ? { agentId: def.agentId } : {}
2442
+ };
2443
+ }
2301
2444
  // Annotate the CommonJS export names for ESM import in node:
2302
2445
  0 && (module.exports = {
2303
2446
  AudioRecorderError,
@@ -2311,6 +2454,7 @@ function CopilotChat({
2311
2454
  CopilotChatUserMessage,
2312
2455
  CopilotChatView,
2313
2456
  CopilotKitProvider,
2457
+ defineToolCallRender,
2314
2458
  useAgent,
2315
2459
  useAgentContext,
2316
2460
  useCopilotChatConfiguration,