@@ -104,135 +104,135 @@ export async function POST(req: Request) {
104104 const model = anthropic ( "claude-sonnet-4-5" ) ;
105105 const posthogClient = await createPostHogClient ( ) ;
106106
107- try {
108- const tracedModel = withTracing ( model , posthogClient , {
109- posthogDistinctId : userInfo . sub ,
110- } ) ;
111-
112- const result = streamText ( {
113- model : tracedModel ,
114- providerOptions : {
115- anthropic : {
116- thinking : { type : "enabled" , budgetTokens : 12000 } ,
117- } satisfies AnthropicProviderOptions ,
107+ const tracedModel = withTracing ( model , posthogClient , {
108+ posthogDistinctId : userInfo . sub ,
109+ } ) ;
110+
111+ const result = streamText ( {
112+ model : tracedModel ,
113+ providerOptions : {
114+ anthropic : {
115+ thinking : { type : "enabled" , budgetTokens : 12000 } ,
116+ } satisfies AnthropicProviderOptions ,
117+ } ,
118+ messages : [
119+ {
120+ role : "system" ,
121+ content : basePrompt ,
122+ providerOptions : {
123+ anthropic : {
124+ cacheControl : {
125+ type : "ephemeral" ,
126+ } ,
127+ } satisfies AnthropicProviderOptions ,
128+ } ,
118129 } ,
119- messages : [
120- {
121- role : "system" ,
122- content : basePrompt ,
123- providerOptions : {
124- anthropic : {
125- cacheControl : {
126- type : "ephemeral" ,
127- } ,
128- } satisfies AnthropicProviderOptions ,
129- } ,
130+ {
131+ role : "system" ,
132+ content : contextSystemPrompt ( data . question ) ,
133+ providerOptions : {
134+ anthropic : {
135+ cacheControl : { type : "ephemeral" } ,
136+ } satisfies AnthropicProviderOptions ,
130137 } ,
131- {
132- role : "system" ,
133- content : contextSystemPrompt ( data . question ) ,
134- providerOptions : {
135- anthropic : {
136- cacheControl : { type : "ephemeral" } ,
137- } satisfies AnthropicProviderOptions ,
138- } ,
138+ } ,
139+ ...convertToModelMessages ( messages ) ,
140+ ] ,
141+ stopWhen : stepCountIs ( 10 ) ,
142+ tools : {
143+ getMyAnswer : tool ( {
144+ description :
145+ "取得使用者最後提交的答案結果,包括查詢結果、錯誤訊息和狀態。如果使用者問關於他們的答案,使用這個工具。" ,
146+ inputSchema : z . object ( { } ) ,
147+ execute : async ( ) => {
148+ const { data, error } = await apollo . query ( {
149+ query : USER_ANSWER_RESULT ,
150+ variables : { id : questionId } ,
151+ errorPolicy : "all" ,
152+ } ) ;
153+ if ( ! data ?. question ) {
154+ return { error : "無法取得題目資料" , details : error ?. message } ;
155+ }
156+
157+ const { lastSubmission } = data . question ;
158+ if ( ! lastSubmission ) {
159+ return { error : "使用者尚未提交答案" } ;
160+ }
161+
162+ return {
163+ status : lastSubmission . status ,
164+ submittedCode : lastSubmission . submittedCode ,
165+ queryResult : lastSubmission . queryResult
166+ ? {
167+ columns : lastSubmission . queryResult . columns ,
168+ rows : lastSubmission . queryResult . rows ,
169+ }
170+ : null ,
171+ error : lastSubmission . error ,
172+ } ;
139173 } ,
140- ...convertToModelMessages ( messages ) ,
141- ] ,
142- stopWhen : stepCountIs ( 10 ) ,
143- tools : {
144- getMyAnswer : tool ( {
145- description :
146- "取得使用者最後提交的答案結果,包括查詢結果、錯誤訊息和狀態。如果使用者問關於他們的答案,使用這個工具。" ,
147- inputSchema : z . object ( { } ) ,
148- execute : async ( ) => {
149- const { data, error } = await apollo . query ( {
150- query : USER_ANSWER_RESULT ,
151- variables : { id : questionId } ,
152- errorPolicy : "all" ,
153- } ) ;
154- if ( ! data ?. question ) {
155- return { error : "無法取得題目資料" , details : error ?. message } ;
156- }
157-
158- const { lastSubmission } = data . question ;
159- if ( ! lastSubmission ) {
160- return { error : "使用者尚未提交答案" } ;
161- }
162-
163- return {
164- status : lastSubmission . status ,
165- submittedCode : lastSubmission . submittedCode ,
166- queryResult : lastSubmission . queryResult
167- ? {
168- columns : lastSubmission . queryResult . columns ,
169- rows : lastSubmission . queryResult . rows ,
170- }
171- : null ,
172- error : lastSubmission . error ,
173- } ;
174- } ,
175- } ) ,
176- getCorrectAnswer : tool ( {
177- description : "取得題目的正確答案結果,你可以對照和使用者的答案差異。" ,
178- inputSchema : z . object ( { } ) ,
179- execute : async ( ) => {
180- const { data, error } = await apollo . query ( {
181- query : CORRECT_ANSWER_RESULT ,
182- variables : { id : questionId } ,
183- errorPolicy : "all" ,
184- } ) ;
185- if ( ! data ?. question ) {
186- return { error : "無法取得題目資料" , details : error ?. message } ;
187- }
188-
189- return {
190- queryResult : data . question . referenceAnswerResult
191- ? {
192- columns : data . question . referenceAnswerResult . columns ,
193- rows : data . question . referenceAnswerResult . rows ,
194- }
195- : null ,
196- } ;
197- } ,
198- } ) ,
199- getQuestionSchema : tool ( {
200- description : "取得題目的資料庫結構,你可以用這個數據輔助了解 SQL 結構。" ,
201- inputSchema : z . object ( { } ) ,
202- execute : async ( ) => {
203- const { data, error } = await apollo . query ( {
204- query : QUESTION_SCHEMA ,
205- variables : { id : questionId } ,
206- errorPolicy : "all" ,
207- } ) ;
208- if ( ! data ?. question ) {
209- return { error : "無法取得題目資料" , details : error ?. message } ;
210- }
211-
212- return {
213- schema : data . question . database . structure
214- ? {
215- tables : data . question . database . structure . tables . map ( ( table ) => ( {
216- name : table . name ,
217- columns : table . columns ,
218- } ) ) ,
219- }
220- : null ,
221- } ;
222- } ,
223- providerOptions : {
224- anthropic : {
225- cacheControl : { type : "ephemeral" } ,
226- } ,
174+ } ) ,
175+ getCorrectAnswer : tool ( {
176+ description : "取得題目的正確答案結果,你可以對照和使用者的答案差異。" ,
177+ inputSchema : z . object ( { } ) ,
178+ execute : async ( ) => {
179+ const { data, error } = await apollo . query ( {
180+ query : CORRECT_ANSWER_RESULT ,
181+ variables : { id : questionId } ,
182+ errorPolicy : "all" ,
183+ } ) ;
184+ if ( ! data ?. question ) {
185+ return { error : "無法取得題目資料" , details : error ?. message } ;
186+ }
187+
188+ return {
189+ queryResult : data . question . referenceAnswerResult
190+ ? {
191+ columns : data . question . referenceAnswerResult . columns ,
192+ rows : data . question . referenceAnswerResult . rows ,
193+ }
194+ : null ,
195+ } ;
196+ } ,
197+ } ) ,
198+ getQuestionSchema : tool ( {
199+ description : "取得題目的資料庫結構,你可以用這個數據輔助了解 SQL 結構。" ,
200+ inputSchema : z . object ( { } ) ,
201+ execute : async ( ) => {
202+ const { data, error } = await apollo . query ( {
203+ query : QUESTION_SCHEMA ,
204+ variables : { id : questionId } ,
205+ errorPolicy : "all" ,
206+ } ) ;
207+ if ( ! data ?. question ) {
208+ return { error : "無法取得題目資料" , details : error ?. message } ;
209+ }
210+
211+ return {
212+ schema : data . question . database . structure
213+ ? {
214+ tables : data . question . database . structure . tables . map ( ( table ) => ( {
215+ name : table . name ,
216+ columns : table . columns ,
217+ } ) ) ,
218+ }
219+ : null ,
220+ } ;
221+ } ,
222+ providerOptions : {
223+ anthropic : {
224+ cacheControl : { type : "ephemeral" } ,
227225 } ,
228- } ) ,
229- } ,
230- } ) ;
226+ } ,
227+ } ) ,
228+ } ,
229+ } ) ;
231230
232- return result . toUIMessageStreamResponse ( ) ;
233- } finally {
234- await posthogClient . shutdown ( ) ;
235- }
231+ return result . toUIMessageStreamResponse ( {
232+ async onFinish ( ) {
233+ await posthogClient . shutdown ( ) ;
234+ } ,
235+ } ) ;
236236}
237237
238238export const basePrompt =
0 commit comments