()
| 479 | }; |
| 480 | |
| 481 | const ChatPanelBody = () => { |
| 482 | const setChatState = useSetAtom(chatStateAtom); |
| 483 | const [activeChat, setActiveChat] = useAtom(activeChatAtom); |
| 484 | const [input, setInput] = useState(""); |
| 485 | const [newThreadInput, setNewThreadInput] = useState(""); |
| 486 | const { files, addFiles, clearFiles, removeFile } = useFileState(); |
| 487 | const newThreadInputRef = useRef<ReactCodeMirrorRef>(null); |
| 488 | const newMessageInputRef = useRef<ReactCodeMirrorRef>(null); |
| 489 | const scrollContainerRef = useRef<HTMLDivElement>(null); |
| 490 | const fileInputRef = useRef<HTMLInputElement>(null); |
| 491 | const messagesEndRef = useRef<HTMLDivElement>(null); |
| 492 | const runtimeManager = useRuntimeManager(); |
| 493 | const { invokeAiTool, sendRun } = useRequestClient(); |
| 494 | const { openModal, closeModal } = useImperativeModal(); |
| 495 | |
| 496 | const activeChatId = activeChat?.id; |
| 497 | const store = useStore(); |
| 498 | |
| 499 | const { addStagedCell } = useStagedAICellsActions(); |
| 500 | const { createNewCell, prepareForRun } = useCellActions(); |
| 501 | const toolContext: ToolNotebookContext = { |
| 502 | addStagedCell, |
| 503 | createNewCell, |
| 504 | prepareForRun, |
| 505 | sendRun, |
| 506 | store, |
| 507 | }; |
| 508 | |
| 509 | const { |
| 510 | messages, |
| 511 | sendMessage, |
| 512 | error, |
| 513 | status, |
| 514 | regenerate, |
| 515 | stop, |
| 516 | addToolOutput, |
| 517 | addToolApprovalResponse, |
| 518 | id: chatId, |
| 519 | } = useChat({ |
| 520 | id: activeChatId, |
| 521 | sendAutomaticallyWhen: ({ messages }) => hasPendingToolCalls(messages), |
| 522 | messages: activeChat?.messages || [], // initial messages |
| 523 | transport: new DefaultChatTransport({ |
| 524 | api: runtimeManager.getAiURL("chat").toString(), |
| 525 | headers: () => runtimeManager.headers(), |
| 526 | prepareSendMessagesRequest: async (options) => { |
| 527 | // Canary: flag outgoing messages that don't match the AI SDK's own |
| 528 | // schema. The server-side sanitizer in `_pydantic_ai_utils.py` corrects these before validation; |
| 529 | // this log surfaces drift early without affecting the request. |
| 530 | const validation = await safeValidateUIMessages({ |
| 531 | messages: options.messages, |
| 532 | }); |
| 533 | if (!validation.success) { |
| 534 | Logger.debug( |
| 535 | "Outgoing chat messages failed AI SDK schema validation", |
| 536 | validation.error, |
| 537 | ); |
| 538 | } |
nothing calls this directly
no test coverage detected
searching dependent graphs…