Files
infiplot-web/lib/engine/vision.ts
T
Zonghao Yuan dc5ecd60f6 refactor: flatten monorepo to single web package (#12)
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>
2026-06-03 00:55:45 +08:00

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,
};
}