Skip to content

Commit dd66bbb

Browse files
authored
feat: temp test api endpoint for bedrock (supabase#36668)
* feat: temp test api endpoint for bedrock * refactor: consolidate ai imports
1 parent d2b9eee commit dd66bbb

File tree

5 files changed

+234
-31
lines changed

5 files changed

+234
-31
lines changed

apps/studio/middleware.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const HOSTED_SUPPORTED_API_URLS = [
1414
'/ai/sql/title',
1515
'/ai/sql/cron',
1616
'/ai/feedback/classify',
17+
'/ai/temp/bedrock-test',
1718
'/get-ip-address',
1819
'/get-utc-time',
1920
'/edge-functions/test',

apps/studio/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"build:graphql-types:watch": "pnpm graphql-codegen --config scripts/codegen.ts --watch"
2626
},
2727
"dependencies": {
28+
"@ai-sdk/amazon-bedrock": "^2.2.10",
2829
"@ai-sdk/openai": "^0.0.72",
2930
"@dagrejs/dagre": "^1.0.4",
3031
"@deno/eszip": "0.83.0",
@@ -60,9 +61,11 @@
6061
"@tanstack/react-query-devtools": "4.35.7",
6162
"@tanstack/react-table": "^8.21.3",
6263
"@uidotdev/usehooks": "^2.4.1",
64+
"@vercel/functions": "^2.2.2",
6365
"@vitejs/plugin-react": "^4.3.4",
6466
"@zip.js/zip.js": "^2.7.29",
6567
"ai": "^3.4.33",
68+
"ai-4": "npm:ai@4",
6669
"ai-commands": "workspace:*",
6770
"awesome-debounce-promise": "^2.1.0",
6871
"common": "workspace:*",
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock'
2+
import { awsCredentialsProvider } from '@vercel/functions/oidc'
3+
import { CoreMessage, streamText } from 'ai-4'
4+
import apiWrapper from 'lib/api/apiWrapper'
5+
import { NextApiRequest, NextApiResponse } from 'next'
6+
import { z } from 'zod'
7+
8+
const bedrock = createAmazonBedrock({
9+
credentialProvider: awsCredentialsProvider({
10+
roleArn: process.env.AWS_BEDROCK_ROLE_ARN!,
11+
}),
12+
})
13+
14+
const messageSchema = z.object({
15+
role: z.enum(['user', 'assistant']),
16+
content: z.string(),
17+
})
18+
19+
const requestBodySchema = z.object({
20+
messages: z.array(messageSchema),
21+
})
22+
23+
async function handler(req: NextApiRequest, res: NextApiResponse) {
24+
const { method } = req
25+
26+
switch (method) {
27+
case 'POST':
28+
return handlePost(req, res)
29+
default:
30+
res.setHeader('Allow', ['POST'])
31+
res.status(405).json({ data: null, error: { message: `Method ${method} Not Allowed` } })
32+
}
33+
}
34+
35+
async function handlePost(req: NextApiRequest, res: NextApiResponse) {
36+
const { data, error: parseError } = requestBodySchema.safeParse(req.body)
37+
38+
if (parseError) {
39+
return res.status(400).json({
40+
error: 'Invalid request body',
41+
issues: parseError.issues,
42+
})
43+
}
44+
45+
const { messages: clientMessages } = data
46+
47+
const model = bedrock('us.anthropic.claude-sonnet-4-20250514-v1:0')
48+
const messages: CoreMessage[] = [
49+
{
50+
role: 'system',
51+
content: 'You are a helpful assistant.',
52+
},
53+
...clientMessages,
54+
]
55+
56+
const result = streamText({
57+
model,
58+
messages,
59+
onError: ({ error }) => {
60+
console.error(error)
61+
},
62+
})
63+
64+
return result.pipeDataStreamToResponse(res)
65+
}
66+
67+
const wrapper = (req: NextApiRequest, res: NextApiResponse) =>
68+
apiWrapper(req, res, handler, { withAuth: false })
69+
70+
export default wrapper

0 commit comments

Comments
 (0)