@copilotkit/react-core 1.9.2-next.19 → 1.9.2-next.20

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/{chunk-XJ34ATKP.mjs → chunk-FN3UA2ZE.mjs} +2 -2
  3. package/dist/{chunk-7EJ4IWSA.mjs → chunk-K42OD3J6.mjs} +2 -2
  4. package/dist/{chunk-5DODGOMM.mjs → chunk-MTAJI7HV.mjs} +77 -45
  5. package/dist/chunk-MTAJI7HV.mjs.map +1 -0
  6. package/dist/{chunk-WR3XTNHJ.mjs → chunk-NJA5ZLAZ.mjs} +26 -7
  7. package/dist/chunk-NJA5ZLAZ.mjs.map +1 -0
  8. package/dist/{chunk-5PE2XROA.mjs → chunk-UGJGKBFB.mjs} +2 -2
  9. package/dist/{chunk-BHGYBOR3.mjs → chunk-ZOMEQ3XC.mjs} +2 -2
  10. package/dist/hooks/index.js +102 -51
  11. package/dist/hooks/index.js.map +1 -1
  12. package/dist/hooks/index.mjs +6 -6
  13. package/dist/hooks/use-chat.js +170 -138
  14. package/dist/hooks/use-chat.js.map +1 -1
  15. package/dist/hooks/use-chat.mjs +1 -1
  16. package/dist/hooks/use-coagent.js +77 -45
  17. package/dist/hooks/use-coagent.js.map +1 -1
  18. package/dist/hooks/use-coagent.mjs +3 -3
  19. package/dist/hooks/use-copilot-action.js +25 -6
  20. package/dist/hooks/use-copilot-action.js.map +1 -1
  21. package/dist/hooks/use-copilot-action.mjs +1 -1
  22. package/dist/hooks/use-copilot-authenticated-action.js +25 -6
  23. package/dist/hooks/use-copilot-authenticated-action.js.map +1 -1
  24. package/dist/hooks/use-copilot-authenticated-action.mjs +2 -2
  25. package/dist/hooks/use-copilot-chat.js +77 -45
  26. package/dist/hooks/use-copilot-chat.js.map +1 -1
  27. package/dist/hooks/use-copilot-chat.mjs +2 -2
  28. package/dist/hooks/use-langgraph-interrupt.js +77 -45
  29. package/dist/hooks/use-langgraph-interrupt.js.map +1 -1
  30. package/dist/hooks/use-langgraph-interrupt.mjs +3 -3
  31. package/dist/index.js +101 -50
  32. package/dist/index.js.map +1 -1
  33. package/dist/index.mjs +6 -6
  34. package/package.json +3 -3
  35. package/src/hooks/use-chat.ts +110 -46
  36. package/src/hooks/use-copilot-action.ts +51 -9
  37. package/dist/chunk-5DODGOMM.mjs.map +0 -1
  38. package/dist/chunk-WR3XTNHJ.mjs.map +0 -1
  39. /package/dist/{chunk-XJ34ATKP.mjs.map → chunk-FN3UA2ZE.mjs.map} +0 -0
  40. /package/dist/{chunk-7EJ4IWSA.mjs.map → chunk-K42OD3J6.mjs.map} +0 -0
  41. /package/dist/{chunk-5PE2XROA.mjs.map → chunk-UGJGKBFB.mjs.map} +0 -0
  42. /package/dist/{chunk-BHGYBOR3.mjs.map → chunk-ZOMEQ3XC.mjs.map} +0 -0
@@ -192,6 +192,7 @@ var import_runtime_client_gql4 = require("@copilotkit/runtime-client-gql");
192
192
 
193
193
  // src/hooks/use-chat.ts
194
194
  var import_react5 = require("react");
195
+ var import_react_dom = require("react-dom");
195
196
  var import_shared4 = require("@copilotkit/shared");
196
197
  var import_runtime_client_gql3 = require("@copilotkit/runtime-client-gql");
197
198
 
@@ -798,6 +799,39 @@ function useChat(options) {
798
799
  newMessages
799
800
  );
800
801
  let didExecuteAction = false;
802
+ const executeActionFromMessage = (currentAction, actionMessage) => __async(this, null, function* () {
803
+ var _a2;
804
+ const isInterruptAction = interruptMessages.find((m) => m.id === actionMessage.id);
805
+ followUp = (_a2 = currentAction == null ? void 0 : currentAction.followUp) != null ? _a2 : !isInterruptAction;
806
+ if (currentAction == null ? void 0 : currentAction._setActivatingMessageId) {
807
+ currentAction._setActivatingMessageId(actionMessage.id);
808
+ }
809
+ const resultMessage = yield executeAction({
810
+ onFunctionCall,
811
+ message: actionMessage,
812
+ chatAbortControllerRef,
813
+ onError: (error) => {
814
+ addErrorToast([error]);
815
+ console.error(`Failed to execute action ${actionMessage.name}: ${error}`);
816
+ },
817
+ setMessages,
818
+ getFinalMessages: () => finalMessages,
819
+ isRenderAndWait: (currentAction == null ? void 0 : currentAction._isRenderAndWait) || false
820
+ });
821
+ didExecuteAction = true;
822
+ const messageIndex = finalMessages.findIndex((msg) => msg.id === actionMessage.id);
823
+ finalMessages.splice(messageIndex + 1, 0, resultMessage);
824
+ if (currentAction == null ? void 0 : currentAction._isRenderAndWait) {
825
+ const messagesForImmediateUpdate = [...finalMessages];
826
+ (0, import_react_dom.flushSync)(() => {
827
+ setMessages(messagesForImmediateUpdate);
828
+ });
829
+ }
830
+ if (currentAction == null ? void 0 : currentAction._setActivatingMessageId) {
831
+ currentAction._setActivatingMessageId(null);
832
+ }
833
+ return resultMessage;
834
+ });
801
835
  if (onFunctionCall) {
802
836
  const lastMessages = [];
803
837
  for (let i = finalMessages.length - 1; i >= 0; i--) {
@@ -814,37 +848,28 @@ function useChat(options) {
814
848
  (action2) => action2.name === message.name
815
849
  );
816
850
  const currentResultMessagePairedFeAction = message.isResultMessage() ? getPairedFeAction(actions, message) : null;
817
- const executeActionFromMessage = (action2, message2) => __async(this, null, function* () {
818
- var _a2;
819
- const isInterruptAction = interruptMessages.find((m) => m.id === message2.id);
820
- followUp = (_a2 = action2 == null ? void 0 : action2.followUp) != null ? _a2 : !isInterruptAction;
821
- const resultMessage = yield executeAction({
822
- onFunctionCall,
823
- previousMessages,
824
- message: message2,
825
- chatAbortControllerRef,
826
- onError: (error) => {
827
- addErrorToast([error]);
828
- console.error(`Failed to execute action ${message2.name}: ${error}`);
829
- }
830
- });
831
- didExecuteAction = true;
832
- const messageIndex = finalMessages.findIndex((msg) => msg.id === message2.id);
833
- finalMessages.splice(messageIndex + 1, 0, resultMessage);
834
- return resultMessage;
835
- });
836
851
  if (action && message.isActionExecutionMessage()) {
837
- const resultMessage = yield executeActionFromMessage(action, message);
838
- const pairedFeAction = getPairedFeAction(actions, resultMessage);
839
- if (pairedFeAction) {
840
- const newExecutionMessage = new import_runtime_client_gql3.ActionExecutionMessage({
841
- name: pairedFeAction.name,
842
- arguments: (0, import_shared4.parseJson)(resultMessage.result, resultMessage.result),
843
- status: message.status,
844
- createdAt: message.createdAt,
845
- parentMessageId: message.parentMessageId
846
- });
847
- yield executeActionFromMessage(pairedFeAction, newExecutionMessage);
852
+ const isRenderAndWaitAction = (action == null ? void 0 : action._isRenderAndWait) || false;
853
+ const alreadyProcessed = isRenderAndWaitAction && finalMessages.some(
854
+ (fm) => fm.isResultMessage() && fm.actionExecutionId === message.id
855
+ );
856
+ if (alreadyProcessed) {
857
+ } else {
858
+ const resultMessage = yield executeActionFromMessage(
859
+ action,
860
+ message
861
+ );
862
+ const pairedFeAction = getPairedFeAction(actions, resultMessage);
863
+ if (pairedFeAction) {
864
+ const newExecutionMessage = new import_runtime_client_gql3.ActionExecutionMessage({
865
+ name: pairedFeAction.name,
866
+ arguments: (0, import_shared4.parseJson)(resultMessage.result, resultMessage.result),
867
+ status: message.status,
868
+ createdAt: message.createdAt,
869
+ parentMessageId: message.parentMessageId
870
+ });
871
+ yield executeActionFromMessage(pairedFeAction, newExecutionMessage);
872
+ }
848
873
  }
849
874
  } else if (message.isResultMessage() && currentResultMessagePairedFeAction) {
850
875
  const newExecutionMessage = new import_runtime_client_gql3.ActionExecutionMessage({
@@ -862,13 +887,9 @@ function useChat(options) {
862
887
  }
863
888
  setMessages(finalMessages);
864
889
  }
865
- if (
866
- // if followUp is not explicitly false
867
- followUp !== false && // and we executed an action
868
- (didExecuteAction || // the last message is a server side result
869
- !isAgentRun && finalMessages.length && finalMessages[finalMessages.length - 1].isResultMessage()) && // the user did not stop generation
870
- !((_r = chatAbortControllerRef.current) == null ? void 0 : _r.signal.aborted)
871
- ) {
890
+ if (followUp !== false && (didExecuteAction || // the last message is a server side result
891
+ !isAgentRun && finalMessages.length && finalMessages[finalMessages.length - 1].isResultMessage()) && // the user did not stop generation
892
+ !((_r = chatAbortControllerRef.current) == null ? void 0 : _r.signal.aborted)) {
872
893
  yield new Promise((resolve) => setTimeout(resolve, 10));
873
894
  return yield runChatCompletionRef.current(finalMessages);
874
895
  } else if ((_s = chatAbortControllerRef.current) == null ? void 0 : _s.signal.aborted) {
@@ -1039,20 +1060,31 @@ function constructFinalMessages(syncedMessages, previousMessages, newMessages) {
1039
1060
  function executeAction(_0) {
1040
1061
  return __async(this, arguments, function* ({
1041
1062
  onFunctionCall,
1042
- previousMessages,
1043
1063
  message,
1044
1064
  chatAbortControllerRef,
1045
- onError
1065
+ onError,
1066
+ setMessages,
1067
+ getFinalMessages,
1068
+ isRenderAndWait
1046
1069
  }) {
1047
1070
  let result;
1048
1071
  let error = null;
1072
+ const currentMessagesForHandler = getFinalMessages();
1073
+ const handlerReturnedPromise = onFunctionCall({
1074
+ messages: currentMessagesForHandler,
1075
+ name: message.name,
1076
+ args: message.arguments
1077
+ });
1078
+ if (isRenderAndWait) {
1079
+ const currentMessagesForRender = getFinalMessages();
1080
+ (0, import_react_dom.flushSync)(() => {
1081
+ setMessages([...currentMessagesForRender]);
1082
+ });
1083
+ }
1049
1084
  try {
1050
1085
  result = yield Promise.race([
1051
- onFunctionCall({
1052
- messages: previousMessages,
1053
- name: message.name,
1054
- args: message.arguments
1055
- }),
1086
+ handlerReturnedPromise,
1087
+ // Await the promise returned by the handler
1056
1088
  new Promise(
1057
1089
  (resolve) => {
1058
1090
  var _a;
@@ -1100,7 +1132,7 @@ function getPairedFeAction(actions, message) {
1100
1132
 
1101
1133
  // src/components/copilot-provider/copilotkit.tsx
1102
1134
  var import_react7 = require("react");
1103
- var import_react_dom = require("react-dom");
1135
+ var import_react_dom2 = require("react-dom");
1104
1136
  var import_shared5 = require("@copilotkit/shared");
1105
1137
 
1106
1138
  // src/context/copilot-messages-context.tsx
@@ -1345,6 +1377,7 @@ function useCopilotAction(action, dependencies) {
1345
1377
  const { setAction, removeAction, actions, chatComponentsCache } = useCopilotContext();
1346
1378
  const idRef = (0, import_react9.useRef)((0, import_shared6.randomId)());
1347
1379
  const renderAndWaitRef = (0, import_react9.useRef)(null);
1380
+ const activatingMessageIdRef = (0, import_react9.useRef)(null);
1348
1381
  const { addToast } = useToast();
1349
1382
  action = __spreadValues({}, action);
1350
1383
  if (
@@ -1352,30 +1385,48 @@ function useCopilotAction(action, dependencies) {
1352
1385
  isFrontendAction(action) && // check if renderAndWaitForResponse is set
1353
1386
  (action.renderAndWait || action.renderAndWaitForResponse)
1354
1387
  ) {
1388
+ action._isRenderAndWait = true;
1355
1389
  const renderAndWait = action.renderAndWait || action.renderAndWaitForResponse;
1356
1390
  action.renderAndWait = void 0;
1357
1391
  action.renderAndWaitForResponse = void 0;
1392
+ action._setActivatingMessageId = (id) => {
1393
+ activatingMessageIdRef.current = id;
1394
+ };
1358
1395
  action.handler = useAsyncCallback(() => __async(this, null, function* () {
1396
+ const currentActivatingId = activatingMessageIdRef.current;
1359
1397
  let resolve;
1360
1398
  let reject;
1361
1399
  const promise = new Promise((resolvePromise, rejectPromise) => {
1362
1400
  resolve = resolvePromise;
1363
1401
  reject = rejectPromise;
1364
1402
  });
1365
- renderAndWaitRef.current = { promise, resolve, reject };
1366
- return yield promise;
1403
+ renderAndWaitRef.current = {
1404
+ promise,
1405
+ resolve,
1406
+ reject,
1407
+ messageId: currentActivatingId
1408
+ };
1409
+ const result = yield promise;
1410
+ return result;
1367
1411
  }), []);
1368
1412
  action.render = (props) => {
1413
+ const currentRenderMessageId = props.messageId;
1369
1414
  let status = props.status;
1370
- if (props.status === "executing" && !renderAndWaitRef.current) {
1371
- status = "inProgress";
1415
+ if (props.status === "executing") {
1416
+ if (!renderAndWaitRef.current || !renderAndWaitRef.current.promise) {
1417
+ status = "inProgress";
1418
+ } else if (renderAndWaitRef.current.messageId !== currentRenderMessageId && activatingMessageIdRef.current !== currentRenderMessageId) {
1419
+ status = "inProgress";
1420
+ }
1372
1421
  }
1373
1422
  const waitProps = {
1374
1423
  status,
1375
1424
  args: props.args,
1376
1425
  result: props.result,
1377
- handler: status === "executing" ? renderAndWaitRef.current.resolve : void 0,
1378
- respond: status === "executing" ? renderAndWaitRef.current.resolve : void 0
1426
+ // handler and respond should only be provided if this is the truly active instance
1427
+ // and its promise infrastructure is ready.
1428
+ handler: status === "executing" && renderAndWaitRef.current && renderAndWaitRef.current.messageId === currentRenderMessageId ? renderAndWaitRef.current.resolve : void 0,
1429
+ respond: status === "executing" && renderAndWaitRef.current && renderAndWaitRef.current.messageId === currentRenderMessageId ? renderAndWaitRef.current.resolve : void 0
1379
1430
  };
1380
1431
  const isNoArgsRenderWait = (_fn) => {
1381
1432
  var _a;