94Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
95
96### OpenAI
97
98```ts
99import { OpenAI } from "https://esm.town/v/std/openai";
100const openai = new OpenAI();
101const completion = await openai.chat.completions.create({
102 messages: [
103 { role: "user", content: "Say hello in a creative way" },
1import { OpenAI } from "https://esm.town/v/std/openai";
2import type { ValInfo, ValSummary } from "../shared/types.ts";
3
4const openai = new OpenAI();
5
6export async function summarizeVal(val: ValInfo): Promise<ValSummary> {
22\`\`\``;
23
24 const completion = await openai.chat.completions.create({
25 messages: [
26 {
1import { type Context, Hono } from "https://esm.sh/hono@3.11.7";
2import { blob } from "https://esm.town/v/std/blob";
3import { OpenAI } from "https://esm.town/v/std/openai";
4import { sqlite } from "https://esm.town/v/stevekrouse/sqlite";
5import Groq from "npm:groq-sdk";
16
17const app = new Hono();
18const openai = new OpenAI();
19
20// Get all voice notes (for admin/dashboard)
153async function transcribeAudio(voiceNoteId: string, audioBuffer: ArrayBuffer) {
154 try {
155 // Convert ArrayBuffer to File for OpenAI
156 const audioFile = new File([audioBuffer], "audio.webm", { type: "audio/webm" });
157
6
7- 🎙️ Record voice notes directly in the browser
8- 🤖 AI-powered transcription using OpenAI Whisper
9- 🔗 Share voice notes via unique URLs
10- ⏰ Set expiration by max listens or date
53- **Database**: SQLite for voice note metadata
54- **Storage**: Val Town Blob storage for audio files
55- **AI**: OpenAI Whisper for transcription
56- **Frontend**: React with TypeScript
57- **Styling**: TailwindCSS
94Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
95
96### OpenAI
97
98```ts
99import { OpenAI } from "https://esm.town/v/std/openai";
100const openai = new OpenAI();
101const completion = await openai.chat.completions.create({
102 messages: [
103 { role: "user", content: "Say hello in a creative way" },
6 const { messages, input, handleInputChange, handleSubmit, isLoading, setInput } = useChat({
7 api: "/api/chat",
8 // Tell AI SDK to expect OpenAI format
9 onError: (error) => {
10 console.error("Chat error:", error);
8- ✅ AI Chat powered by custom agent
9- ✅ **Robust streaming proxy** with proper format conversion and error handling
10- ✅ Real-time streaming responses with proper OpenAI-compatible format
11- ✅ Auto-scrolling to latest messages
12- ✅ Enhanced loading indicators with animated dots
43- **Centered layout** - Takes up 1/2 of screen width and full height
44- **useChat hook** from Vercel AI SDK handles message state and streaming
45- **Robust streaming proxy** - Properly converts agent's custom format to OpenAI-compatible SSE
46- **Custom agent integration** - Seamlessly connects to your agent API with full error handling
47- **Real-time streaming** - Word-by-word responses with proper buffering and parsing
66
67The agent should return either:
68- **Streaming**: Custom format (`f:`, `0:"content"`, `e:`/`d:` markers) which gets converted to OpenAI-compatible `text/event-stream`
69- **Non-streaming**: JSON with `content`, `message`, or `choices[0].message.content`
70
72- Properly parses the agent's custom streaming format line by line
73- Handles incomplete chunks and buffering correctly
74- Converts to OpenAI-compatible Server-Sent Events in real-time
75- Provides graceful error handling and recovery
76- Works seamlessly with the Vercel AI SDK
88Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
89
90### OpenAI
91
92```ts
93import { OpenAI } from "https://esm.town/v/std/openai";
94const openai = new OpenAI();
95const completion = await openai.chat.completions.create({
96 messages: [
97 { role: "user", content: "Say hello in a creative way" },
9Configure the following variables in your environment:
10- `AGENT_API_KEY` (This is a secure token that you choose to secure the agent.tsx POST endpoint)
11- `OPENAI_API_KEY` (An OpenAI API Key)
12- `EXA_API_KEY` (Optional, though needed if you use the web search tool)
13
1import { anthropic } from "npm:@ai-sdk/anthropic";
2import { openai } from "npm:@ai-sdk/openai";
3import { generateText, streamText } from "npm:ai";
4import { getSystemPrompt } from "./prompt.tsx";
34 const maxSteps = 10;
35
36 const model = Deno.env.get("ANTHROPIC_API_KEY") ? anthropic("claude-3-7-sonnet-latest") : openai("gpt-4.1");
37
38 const options = {