Initial commit: DrinkTracker full-stack app
Next.js 14 drink collection tracker with AI-powered search, menu scanning, ratings, wishlist, sharing, and CSV backup/restore. Features: - Auth (credentials + OAuth ready) - Drink collection with ratings and reviews - AI search via Claude/OpenAI with search history - Menu photo scanning with AI extraction - Wishlist / Try Later system - Public sharing via slug URLs - CSV backup and restore (merge/replace modes) - Docker Compose for Postgres + MinIO + dev server Security: docker-compose files use env var interpolation instead of hardcoded secrets. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
81
src/lib/ai/openai-provider.ts
Normal file
81
src/lib/ai/openai-provider.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import OpenAI from "openai"
|
||||
import { BaseAIProvider } from "./base-provider"
|
||||
|
||||
export class OpenAIProvider extends BaseAIProvider {
|
||||
name = "openai"
|
||||
private client: OpenAI
|
||||
|
||||
constructor(apiKey: string) {
|
||||
super()
|
||||
this.client = new OpenAI({ apiKey })
|
||||
}
|
||||
|
||||
async sendVisionRequest(
|
||||
systemPrompt: string,
|
||||
imageBase64: string,
|
||||
mimeType: string
|
||||
): Promise<string> {
|
||||
const dataUrl = `data:${mimeType};base64,${imageBase64}`
|
||||
|
||||
const response = await this.client.chat.completions.create({
|
||||
model: "gpt-4o",
|
||||
max_tokens: 4096,
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content: systemPrompt,
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: [
|
||||
{
|
||||
type: "image_url",
|
||||
image_url: {
|
||||
url: dataUrl,
|
||||
detail: "high",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
text: "Please analyze this image and extract the information as instructed.",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
const message = response.choices[0]?.message?.content
|
||||
if (!message) {
|
||||
throw new Error("No response received from OpenAI")
|
||||
}
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
async sendTextRequest(
|
||||
systemPrompt: string,
|
||||
userMessage: string
|
||||
): Promise<string> {
|
||||
const response = await this.client.chat.completions.create({
|
||||
model: "gpt-4o",
|
||||
max_tokens: 4096,
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content: systemPrompt,
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: userMessage,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
const message = response.choices[0]?.message?.content
|
||||
if (!message) {
|
||||
throw new Error("No response received from OpenAI")
|
||||
}
|
||||
|
||||
return message
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user