22
33// import { z } from "zod";
44import { generateContent } from "./gemini" ;
5- import { DynamicMarkdownSection } from "../[lang]/[pageId]/pageContent" ;
65import { ReplCommand , ReplOutput } from "@my-code/runtime/interface" ;
76import {
87 addChat ,
@@ -11,6 +10,7 @@ import {
1110 initContext ,
1211} from "@/lib/chatHistory" ;
1312import { getPagesList , introSectionId , PagePath , SectionId } from "@/lib/docs" ;
13+ import { DynamicMarkdownSection } from "@/(docs)/@docs/[lang]/[pageId]/pageContent" ;
1414
1515type ChatResult =
1616 | {
@@ -149,21 +149,22 @@ export async function askAI(params: ChatParams): Promise<ChatResult> {
149149 prompt . push ( "# 指示" ) ;
150150 prompt . push ( "" ) ;
151151 prompt . push (
152- `- 1行目に、ユーザーの質問ともっとも関連性の高いドキュメント内のセクションのidを回答してください。idのみを出力してください。`
152+ `- 1行目に、ユーザーの質問ともっとも関連性の高いドキュメント内のセクションのidを回答してください。`
153+ ) ;
154+ prompt . push (
155+ " - idのみを出力してください。 セクションid: や括弧や引用符などは不要です。"
153156 ) ;
154157 prompt . push (
155158 " - ユーザーの質問がドキュメントのどのセクションとも直接的に関連しない場合は空白でも良いです。"
156159 ) ;
157- prompt . push ( "- 2行目は水平線 --- を出力してください。" ) ;
158160 prompt . push (
159- "- 次の行に 、この質問と回答を後から参照するためのわかりやすいタイトルをつけて記述してください。"
161+ "- 2行目に 、この質問と回答を後から参照するためのわかりやすいタイトルをつけて記述してください。"
160162 ) ;
161163 prompt . push (
162- "- 太字やコードブロックなどのMarkdownの記法は使わずテキストのみで出力してください。"
164+ " - 太字やコードブロックなどのMarkdownの記法は使わずテキストのみで出力してください。"
163165 ) ;
164- prompt . push ( "- その次の行は水平線 --- を出力してください。" ) ;
165166 prompt . push (
166- "- それ以降の行に 、ドキュメントの内容に基づいて、ユーザーに伝える回答をMarkdown形式で記述してください。"
167+ "- 3行目以降に 、ドキュメントの内容に基づいて、ユーザーに伝える回答をMarkdown形式で記述してください。"
167168 ) ;
168169 prompt . push (
169170 " - ユーザーが入力したターミナルのコマンドやファイルの内容、実行結果を参考にして回答してください。"
@@ -176,12 +177,7 @@ export async function askAI(params: ChatParams): Promise<ChatResult> {
176177 prompt . push (
177178 " - 水平線(---)はシステムが区切りとして認識するので、ユーザーへの回答中に水平線を使用することはできません。"
178179 ) ;
179- prompt . push (
180- "- ユーザーへのメッセージの最後の行の次には水平線 --- を出力してください。"
181- ) ;
182- prompt . push (
183- "- それ以降の行に、ドキュメントの一部を改訂したい場合はその差分を"
184- ) ;
180+ prompt . push ( "- ドキュメントの一部を改訂したい場合はその差分を" ) ;
185181 prompt . push ( "<<<<<<< SEARCH" ) ;
186182 prompt . push ( "修正したい元の文章の塊(一字一句違わずに)" ) ;
187183 prompt . push ( "=======" ) ;
@@ -197,6 +193,10 @@ export async function askAI(params: ChatParams): Promise<ChatResult> {
197193 prompt . push (
198194 " - セクションid、セクション見出し、およびコードブロックの内側を編集することはできません。それ以外の文章のみを編集してください。"
199195 ) ;
196+ prompt . push (
197+ " - 改訂後のドキュメントと同じ内容はユーザーに伝える回答としては省略できます。(修正後のドキュメントを参照してください、など)"
198+ ) ;
199+
200200 console . log ( prompt ) ;
201201
202202 try {
@@ -205,48 +205,40 @@ export async function askAI(params: ChatParams): Promise<ChatResult> {
205205 if ( ! text ) {
206206 throw new Error ( "AIからの応答が空でした" ) ;
207207 }
208- let targetSectionId = text
209- . split ( / \n - { 3 , } \n / )
210- . at ( 0 )
211- ?. trim ( ) as SectionId | undefined ;
208+ console . log ( JSON . stringify ( text ) ) ;
209+ const textMatch = text . match ( / ^ ( [ ^ \n ] * ?) \n + ( [ ^ \n ] * ?) \n + ( [ \s \S ] * ) $ / ) ;
210+ let targetSectionId = textMatch ?. at ( 1 ) ?. trim ( ) as SectionId | undefined ;
212211 if (
213212 ! targetSectionId ||
214213 ! sectionContent . some ( ( s ) => s . id === targetSectionId )
215214 ) {
216215 targetSectionId = introSectionId ( path ) ;
217216 }
218- const title = text . split ( / \n - { 3 , } \n / ) . at ( 1 ) ;
217+ const title = textMatch ?. at ( 2 ) ?. trim ( ) ;
219218 if ( ! title ) {
220219 throw new Error ( "AIからの応答にタイトルが含まれていませんでした" ) ;
221220 }
222- const responseMessage = text
223- . split ( / \n - { 3 , } \n / )
224- . at ( 2 )
225- ?. trim ( ) ;
221+ let responseMessage = textMatch ?. at ( 3 ) ?. trim ( ) ;
226222 if ( ! responseMessage ) {
227223 throw new Error ( "AIからの応答に本文が含まれていませんでした" ) ;
228224 }
225+ const diffRegex =
226+ / < { 3 , } \s * S E A R C H \n ( [ \s \S ] * ?) \n = { 3 , } \n ( [ \s \S ] * ?) \n > { 3 , } \s * R E P L A C E / g;
229227 const diffRaw : CreateChatDiff [ ] = [ ] ;
230- for ( const m of text
231- . split ( / \n - { 3 , } \n / )
232- . at ( 3 )
233- ?. matchAll (
234- / < { 3 , } \s * S E A R C H \n ( [ \s \S ] * ?) \n = { 3 , } \n ( [ \s \S ] * ?) \n > { 3 , } \s * R E P L A C E / g
235- ) ?? [ ] ) {
228+ for ( const m of responseMessage . matchAll ( diffRegex ) ?? [ ] ) {
236229 const search = m [ 1 ] ;
237230 const replace = m [ 2 ] ;
238231 const targetSection = sectionContent . find ( ( s ) =>
239- s . rawContent . includes ( search )
232+ s . replacedContent . includes ( search )
240233 ) ;
241- if ( targetSection ) {
242- diffRaw . push ( {
243- search,
244- replace,
245- sectionId : targetSection . id ,
246- targetMD5 : targetSection . md5 ,
247- } ) ;
248- }
234+ diffRaw . push ( {
235+ search,
236+ replace,
237+ sectionId : targetSection ?. id ?? ( "" as SectionId ) ,
238+ targetMD5 : targetSection ?. md5 ?? "" ,
239+ } ) ;
249240 }
241+ responseMessage = responseMessage . replace ( diffRegex , "" ) . trim ( ) ;
250242 const newChat = await addChat (
251243 path ,
252244 targetSectionId ,
0 commit comments