From f5cd1e77e2e0d8e216e84c61eeb34d43c0e31c13 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 06:23:35 +0000 Subject: [PATCH 1/3] Initial plan From 47ea2aba02396fca8c767c42ccca365739bae685 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 06:29:48 +0000 Subject: [PATCH 2/3] Add terminal logs, file contents, and exec results to AI chat context Co-authored-by: na-trium-144 <100704180+na-trium-144@users.noreply.github.com> --- app/[docs_id]/chatForm.tsx | 20 ++++++++++++- app/[docs_id]/section.tsx | 11 ++++--- app/actions/chatActions.ts | 59 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 83 insertions(+), 7 deletions(-) diff --git a/app/[docs_id]/chatForm.tsx b/app/[docs_id]/chatForm.tsx index f8939c2..64a48b7 100644 --- a/app/[docs_id]/chatForm.tsx +++ b/app/[docs_id]/chatForm.tsx @@ -12,9 +12,24 @@ import { getLanguageName } from "../pagesList"; interface ChatFormProps { documentContent: string; sectionId: string; + replOutputs: Array<{ + command: string; + output: Array<{ + type: "stdout" | "stderr" | "error" | "return" | "trace" | "system"; + message: string; + }>; + }>; + fileContents: Array<{ + name: string; + content: string; + }>; + execResults: Record>; } -export function ChatForm({ documentContent, sectionId }: ChatFormProps) { +export function ChatForm({ documentContent, sectionId, replOutputs, fileContents, execResults }: ChatFormProps) { const [messages, updateChatHistory] = useChatHistory(sectionId); const [inputValue, setInputValue] = useState(""); const [isLoading, setIsLoading] = useState(false); @@ -56,6 +71,9 @@ export function ChatForm({ documentContent, sectionId }: ChatFormProps) { const result = await askAI({ userQuestion, documentContent: documentContent, + replOutputs, + fileContents, + execResults, }); if (result.error) { diff --git a/app/[docs_id]/section.tsx b/app/[docs_id]/section.tsx index 9399c4a..d06cfdc 100644 --- a/app/[docs_id]/section.tsx +++ b/app/[docs_id]/section.tsx @@ -31,15 +31,12 @@ interface SectionProps { // 1つのセクションのタイトルと内容を表示する。内容はMarkdownとしてレンダリングする export function Section({ section, sectionId }: SectionProps) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars const [replOutputs, setReplOutputs] = useState([]); - // eslint-disable-next-line @typescript-eslint/no-unused-vars const [execResults, setExecResults] = useState>( {} ); const [filenames, setFilenames] = useState([]); const { files } = useFile(); - // eslint-disable-next-line @typescript-eslint/no-unused-vars const fileContents: { name: string; content: string }[] = filenames.map( (name) => ({ name, content: files[name] || "" }) ); @@ -76,7 +73,13 @@ export function Section({ section, sectionId }: SectionProps) {
{section.title} - +
); diff --git a/app/actions/chatActions.ts b/app/actions/chatActions.ts index 1eed26b..773e7f5 100644 --- a/app/actions/chatActions.ts +++ b/app/actions/chatActions.ts @@ -11,6 +11,21 @@ interface FormState { const ChatSchema = z.object({ userQuestion: z.string().min(1, { message: "メッセージを入力してください。" }), documentContent: z.string().min(1, { message: "コンテキストとなるドキュメントがありません。"}), + replOutputs: z.array(z.object({ + command: z.string(), + output: z.array(z.object({ + type: z.enum(["stdout", "stderr", "error", "return", "trace", "system"]), + message: z.string(), + })), + })).optional(), + fileContents: z.array(z.object({ + name: z.string(), + content: z.string(), + })).optional(), + execResults: z.record(z.string(), z.array(z.object({ + type: z.enum(["stdout", "stderr", "error", "return", "trace", "system"]), + message: z.string(), + }))).optional(), }); type ChatParams = z.input; @@ -25,22 +40,62 @@ export async function askAI(params: ChatParams): Promise { }; } - const { userQuestion, documentContent } = parseResult.data; + const { userQuestion, documentContent, replOutputs, fileContents, execResults } = parseResult.data; try { + // ターミナルログの文字列を構築 + let terminalLogsSection = ""; + if (replOutputs && replOutputs.length > 0) { + terminalLogsSection = "\n# ターミナルのログ(ユーザーが入力したコマンドとその実行結果)\n"; + for (const replCmd of replOutputs) { + terminalLogsSection += `\n## コマンド: ${replCmd.command}\n`; + terminalLogsSection += "```\n"; + for (const output of replCmd.output) { + terminalLogsSection += `${output.message}\n`; + } + terminalLogsSection += "```\n"; + } + } + + // ファイルエディターの内容を構築 + let fileContentsSection = ""; + if (fileContents && fileContents.length > 0) { + fileContentsSection = "\n# ファイルエディターの内容\n"; + for (const file of fileContents) { + fileContentsSection += `\n## ファイル: ${file.name}\n`; + fileContentsSection += "```\n"; + fileContentsSection += file.content; + fileContentsSection += "\n```\n"; + } + } + + // ファイル実行結果を構築 + let execResultsSection = ""; + if (execResults && Object.keys(execResults).length > 0) { + execResultsSection = "\n# ファイルの実行結果\n"; + for (const [filename, outputs] of Object.entries(execResults)) { + execResultsSection += `\n## ファイル: ${filename}\n`; + execResultsSection += "```\n"; + for (const output of outputs) { + execResultsSection += `${output.message}\n`; + } + execResultsSection += "```\n"; + } + } const prompt = ` 以下のPythonチュートリアルのドキュメントの内容を正確に理解し、ユーザーからの質問に対して、初心者にも分かりやすく、丁寧な解説を提供してください。 # ドキュメント ${documentContent} - +${terminalLogsSection}${fileContentsSection}${execResultsSection} # ユーザーからの質問 ${userQuestion} # 指示 - 回答はMarkdown形式で記述し、コードブロックを適切に使用してください。 - ドキュメントの内容に基づいて回答してください。 +- ユーザーが入力したターミナルのコマンドやファイルの内容、実行結果を参考にして回答してください。 - ユーザーへの回答のみを出力してください。 - 必要であれば、具体的なコード例を提示してください。 - From 07dbeb2d77e96c637f20d91588f35b3e147f5c2e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 07:00:19 +0000 Subject: [PATCH 3/3] Use imported ReplCommand and ReplOutput types in ChatFormProps Co-authored-by: na-trium-144 <100704180+na-trium-144@users.noreply.github.com> --- app/[docs_id]/chatForm.tsx | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/app/[docs_id]/chatForm.tsx b/app/[docs_id]/chatForm.tsx index 64a48b7..c16a87c 100644 --- a/app/[docs_id]/chatForm.tsx +++ b/app/[docs_id]/chatForm.tsx @@ -8,25 +8,17 @@ import { useChatHistory, type Message } from "../hooks/useChathistory"; import useSWR from "swr"; import { getQuestionExample } from "../actions/questionExample"; import { getLanguageName } from "../pagesList"; +import { ReplCommand, ReplOutput } from "../terminal/repl"; interface ChatFormProps { documentContent: string; sectionId: string; - replOutputs: Array<{ - command: string; - output: Array<{ - type: "stdout" | "stderr" | "error" | "return" | "trace" | "system"; - message: string; - }>; - }>; + replOutputs: ReplCommand[]; fileContents: Array<{ name: string; content: string; }>; - execResults: Record>; + execResults: Record; } export function ChatForm({ documentContent, sectionId, replOutputs, fileContents, execResults }: ChatFormProps) {