diff --git a/src/components/notebook/cell/ExecutableCell.tsx b/src/components/notebook/cell/ExecutableCell.tsx index 0843a827..015a79ad 100644 --- a/src/components/notebook/cell/ExecutableCell.tsx +++ b/src/components/notebook/cell/ExecutableCell.tsx @@ -613,6 +613,8 @@ export const ExecutableCell: React.FC = ({ + {cellType === "code" && ( + + )} {/* TODO: consider rendering an empty iframewhen we have a safe output currently rendered but cell input has changed */} {shouldUseIframe ? ( output.outputType === "error"); + + if ( + !errorOutput || + !errorOutput.data || + typeof errorOutput.data !== "string" + ) { + return null; + } + + return ( + + + + ); +} + +const FixCodeButton = ({ + cellId, + errorOutputData, + isLoading, +}: { + cellId: string; + errorOutputData: string; + isLoading: boolean; +}) => { + const { addCell } = useAddCell(); + + const handleFixCode = useCallback(() => { + const formattedErrorOutputData = formatErrorOutputData(errorOutputData); + const message = formatAiMessage(formattedErrorOutputData); + addCell(cellId, "ai", "after", message); + }, [addCell, cellId, errorOutputData]); + + return ( + + ); +}; + +/** Add code block to the error message */ +function formatAiMessage(errorString: string) { + return `Fix the error:\n \`\`\`json\n${errorString}\n\`\`\`\n`; +} + +/** Formats the error for AI model to fix */ +function formatErrorOutputData(errorOutputData: string) { + return JSON.stringify(JSON.parse(errorOutputData), null, 2); +} diff --git a/src/hooks/useAddCell.ts b/src/hooks/useAddCell.ts index f4bf1f55..26f3101c 100644 --- a/src/hooks/useAddCell.ts +++ b/src/hooks/useAddCell.ts @@ -18,7 +18,8 @@ export const useAddCell = () => { ( cellId?: string, cellType: CellType = "code", - position: "before" | "after" = "after" + position: "before" | "after" = "after", + source?: string ) => { const cellReferences = store.query(queries.cellsWithIndices$); const newCellId = `cell-${Date.now()}-${Math.random() @@ -99,6 +100,34 @@ export const useAddCell = () => { ); } + if (source) { + const cellEvents = [ + // set cell source + events.cellSourceChanged({ + id: newCellId, + source, + modifiedBy: userId, + }), + // hide cell input + events.cellSourceVisibilityToggled({ + id: newCellId, + sourceVisible: false, + actorId: userId, + }), + // run cell + events.executionRequested({ + cellId: newCellId, + actorId: userId, + requestedBy: userId, + queueId: `exec-${Date.now()}-${Math.random().toString(36).slice(2)}`, + executionCount: + (store.query(queries.cellQuery.byId(newCellId))?.executionCount || + 0) + 1, + }), + ]; + store.commit(...cellEvents); + } + // Focus the new cell after creation setTimeout(() => store.setSignal(focusedCellSignal$, newCellId), 0);