| 21 | } |
| 22 | |
| 23 | export async function triagePost(request: Request): Promise<Response> { |
| 24 | if (request.signal.aborted) return new Response(null, { status: 499 }) |
| 25 | |
| 26 | const [ |
| 27 | { chat, toServerSentEventsStream }, |
| 28 | { withSandbox }, |
| 29 | triage, |
| 30 | { createTriageTools }, |
| 31 | { withNgrokBridge, ngrokConfigured }, |
| 32 | ] = await Promise.all([ |
| 33 | import('@tanstack/ai'), |
| 34 | import('@tanstack/ai-sandbox'), |
| 35 | import('../sandbox-triage'), |
| 36 | import('../triage-tools'), |
| 37 | import('@tanstack/ai-sandbox/ngrok'), |
| 38 | ]) |
| 39 | const { |
| 40 | PROVIDERS, |
| 41 | buildHarnessAdapter, |
| 42 | buildSandbox, |
| 43 | buildTriagePrompt, |
| 44 | fetchIssue, |
| 45 | isHarness, |
| 46 | isProvider, |
| 47 | missingEnv, |
| 48 | parseIssueUrl, |
| 49 | } = triage |
| 50 | |
| 51 | let data: TriageData |
| 52 | try { |
| 53 | const body = (await request.json()) as { |
| 54 | data?: TriageData |
| 55 | forwardedProps?: TriageData |
| 56 | } |
| 57 | const layer = body.data ?? body.forwardedProps |
| 58 | if (layer == null || typeof layer !== 'object') { |
| 59 | throw new Error('body.data (or forwardedProps) is required') |
| 60 | } |
| 61 | data = layer |
| 62 | } catch (error) { |
| 63 | return json(400, error instanceof Error ? error.message : 'invalid body') |
| 64 | } |
| 65 | |
| 66 | if (!isHarness(data.harness) || !isProvider(data.provider)) { |
| 67 | return json(400, 'Unknown harness or provider.') |
| 68 | } |
| 69 | const { isGrokModel, isGrokProtocol, isGrokTransport } = |
| 70 | await import('../sandbox-triage-options') |
| 71 | if ( |
| 72 | data.harness === 'grok' && |
| 73 | data.grokModel !== undefined && |
| 74 | !isGrokModel(data.grokModel) |
| 75 | ) { |
| 76 | return json(400, 'Unknown grokModel.') |
| 77 | } |
| 78 | if ( |
| 79 | data.harness === 'grok' && |
| 80 | data.grokProtocol !== undefined && |