9cedfa66e4
Engine - Split /api/vision out from /api/interact so client can drive prefetch + cache lookup independently of click interpretation - Image client switched to chat-completions+modalities API (OpenRouter/ provider style), supporting markdown image URL responses - annotateClick now resizes to 768w before composite to keep vision payloads small and avoid CDN timeouts - Prompts updated to mention "JSON" in user messages (required by Gemini's strict JSON mode) - Shared fetchWithRetry helper: 2 retries for chat/image, 0 for vision (with 60s hard timeout) Client - Parallel prefetch of all three choice branches on each new frame - Effect deliberately excludes phase from deps so user-click doesn't abort in-flight prefetches - Cache hit/miss/free-form fallback handled in handleClick - PlayCanvas reads img naturalWidth/Height and adapts container to whatever aspect AI returns (no more cropped third choice) - max-width raised to 560px, max-height calc(100dvh - 200px) Misc - README env-path corrected to apps/web/.env.local - users.md: BGM/TTS idea note - .env.example moved into apps/web alongside next config Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
33 lines
928 B
TypeScript
33 lines
928 B
TypeScript
import { takeTurn } from "@dada/engine";
|
|
import type { InteractRequest } from "@dada/types";
|
|
import { NextResponse } from "next/server";
|
|
import { loadEngineConfig } from "@/lib/config";
|
|
|
|
export const runtime = "nodejs";
|
|
export const maxDuration = 60;
|
|
|
|
export async function POST(req: Request) {
|
|
let body: InteractRequest;
|
|
try {
|
|
body = (await req.json()) as InteractRequest;
|
|
} catch {
|
|
return NextResponse.json({ error: "Invalid JSON" }, { status: 400 });
|
|
}
|
|
|
|
if (!body.session || !body.intent) {
|
|
return NextResponse.json(
|
|
{ error: "session and intent are required" },
|
|
{ status: 400 },
|
|
);
|
|
}
|
|
|
|
try {
|
|
const config = loadEngineConfig();
|
|
const result = await takeTurn(config, body);
|
|
return NextResponse.json(result);
|
|
} catch (err) {
|
|
const message = err instanceof Error ? err.message : "Unknown error";
|
|
return NextResponse.json({ error: message }, { status: 500 });
|
|
}
|
|
}
|