dc5ecd60f6
Flatten the pnpm monorepo (apps/web + packages/*) into a single web package at the repo root. - Move app/lib/components/scripts/public to root; drop apps/web and packages/* wrappers - Rewrite tsconfig paths (@infiplot/*) to ./lib/*; turbopack.root = __dirname - Update Vercel (no root-directory) and Cloudflare (pnpm build:cf at root) deploy paths - Regenerate pnpm-lock.yaml to drop stale workspace importers - Bump engines.node to >=22 to match wrangler Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
40 lines
1.1 KiB
TypeScript
40 lines
1.1 KiB
TypeScript
import { interpretClick } from "@infiplot/ai-client";
|
|
import type {
|
|
ClickIntent,
|
|
ProviderConfig,
|
|
Scene,
|
|
VisionClassify,
|
|
} from "@infiplot/types";
|
|
import { parseJsonLoose } from "./jsonParser";
|
|
import { VISION_SYSTEM_PROMPT, buildVisionUserPrompt } from "./prompts";
|
|
|
|
export type VisionInterpretation = {
|
|
intent: ClickIntent;
|
|
classify: VisionClassify;
|
|
};
|
|
|
|
export async function interpret(
|
|
config: ProviderConfig,
|
|
annotatedImageBase64: string,
|
|
scene: Scene | null,
|
|
): Promise<VisionInterpretation> {
|
|
const userPrompt = `${VISION_SYSTEM_PROMPT}\n\n${buildVisionUserPrompt(scene)}`;
|
|
const raw = await interpretClick(config, annotatedImageBase64, userPrompt);
|
|
const parsed = parseJsonLoose<{
|
|
freeformAction?: string;
|
|
classify?: string;
|
|
reasoning?: string;
|
|
}>(raw);
|
|
|
|
const classify: VisionClassify =
|
|
parsed.classify === "change-scene" ? "change-scene" : "insert-beat";
|
|
|
|
return {
|
|
intent: {
|
|
freeformAction: parsed.freeformAction?.trim() || "玩家点了画面,但意图不明",
|
|
reasoning: parsed.reasoning?.trim() || "",
|
|
},
|
|
classify,
|
|
};
|
|
}
|