useSyncMessageAndCustomBody.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { useCallback, useRef } from 'react';
  2. import { MESSAGE_ROLES } from '../constants/playground.constants';
  3. export const useSyncMessageAndCustomBody = (
  4. customRequestMode,
  5. customRequestBody,
  6. message,
  7. inputs,
  8. setCustomRequestBody,
  9. setMessage,
  10. debouncedSaveConfig
  11. ) => {
  12. const isUpdatingFromMessage = useRef(false);
  13. const isUpdatingFromCustomBody = useRef(false);
  14. const lastMessageHash = useRef('');
  15. const lastCustomBodyHash = useRef('');
  16. const getMessageHash = useCallback((messages) => {
  17. return JSON.stringify(messages.map(msg => ({
  18. id: msg.id,
  19. role: msg.role,
  20. content: msg.content
  21. })));
  22. }, []);
  23. const getCustomBodyHash = useCallback((customBody) => {
  24. try {
  25. const parsed = JSON.parse(customBody);
  26. return JSON.stringify(parsed.messages || []);
  27. } catch {
  28. return '';
  29. }
  30. }, []);
  31. const syncMessageToCustomBody = useCallback(() => {
  32. if (!customRequestMode || isUpdatingFromCustomBody.current) return;
  33. const currentMessageHash = getMessageHash(message);
  34. if (currentMessageHash === lastMessageHash.current) return;
  35. try {
  36. isUpdatingFromMessage.current = true;
  37. let customPayload;
  38. try {
  39. customPayload = JSON.parse(customRequestBody || '{}');
  40. } catch {
  41. customPayload = {
  42. model: inputs.model || 'gpt-4o',
  43. messages: [],
  44. temperature: inputs.temperature || 0.7,
  45. stream: inputs.stream !== false
  46. };
  47. }
  48. customPayload.messages = message.map(msg => ({
  49. role: msg.role,
  50. content: msg.content
  51. }));
  52. const newCustomBody = JSON.stringify(customPayload, null, 2);
  53. setCustomRequestBody(newCustomBody);
  54. lastMessageHash.current = currentMessageHash;
  55. lastCustomBodyHash.current = getCustomBodyHash(newCustomBody);
  56. setTimeout(() => {
  57. debouncedSaveConfig();
  58. }, 0);
  59. } finally {
  60. isUpdatingFromMessage.current = false;
  61. }
  62. }, [customRequestMode, customRequestBody, message, inputs.model, inputs.temperature, inputs.stream, getMessageHash, getCustomBodyHash, setCustomRequestBody, debouncedSaveConfig]);
  63. const syncCustomBodyToMessage = useCallback(() => {
  64. if (!customRequestMode || isUpdatingFromMessage.current) return;
  65. const currentCustomBodyHash = getCustomBodyHash(customRequestBody);
  66. if (currentCustomBodyHash === lastCustomBodyHash.current) return;
  67. try {
  68. isUpdatingFromCustomBody.current = true;
  69. const customPayload = JSON.parse(customRequestBody || '{}');
  70. if (customPayload.messages && Array.isArray(customPayload.messages)) {
  71. const newMessages = customPayload.messages.map((msg, index) => ({
  72. id: msg.id || (index + 1).toString(),
  73. role: msg.role || MESSAGE_ROLES.USER,
  74. content: msg.content || '',
  75. createAt: Date.now(),
  76. ...(msg.role === MESSAGE_ROLES.ASSISTANT && {
  77. reasoningContent: msg.reasoningContent || '',
  78. isReasoningExpanded: false
  79. })
  80. }));
  81. setMessage(newMessages);
  82. lastCustomBodyHash.current = currentCustomBodyHash;
  83. lastMessageHash.current = getMessageHash(newMessages);
  84. }
  85. } catch (error) {
  86. console.warn('同步自定义请求体到消息失败:', error);
  87. } finally {
  88. isUpdatingFromCustomBody.current = false;
  89. }
  90. }, [customRequestMode, customRequestBody, getCustomBodyHash, getMessageHash, setMessage]);
  91. return {
  92. syncMessageToCustomBody,
  93. syncCustomBodyToMessage
  94. };
  95. };