LLM refine: 2dp prompt, mixed 64/32 frames, full proxy log, low reasoning

- spec.js: round all songSpec + extended summary/tempo/normalization to
  r2 (2dp) so high-precision 0.6607… stops wasting tokens; hoist r2/r3
  above specForPrompt to fix ReferenceError; FULL control wording kept.
- thumbs.js: border detection — first/last + 0.5s of any section start
  → 64×64 (borders), interior → 32×32 (between). Back-compat shim for
  old {size:N} callers. Returns size+role per frame for attachFrames.
- vite.config.js: raise sanitizeBodyForLog to 64k for __llm so 8×
  vision frames aren't truncated (was 16384, only 2 images logged).
  Also log reasoningEffort via providerOptions.
- llmTweak.js: set providerOptions reasoningEffort:'low' for both
  streamObject and generateObject fallback to cut 2459 → faster
  streaming progress, temperature 0.7 kept for variety.

Verification: build+lint:scenes green, tests 18/18.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Dejvino
2026-09-13 22:21:09 +02:00
co-authored by Claude
parent b0989169e2
commit 49914fd4ad
4 changed files with 66 additions and 30 deletions
+16 -20
View File
@@ -70,30 +70,26 @@ export function clampEdits(edits) {
* either `look` (no-op here) or `lookDigest`.
*/
export function buildTweakPrompt({ spec, track, look, lookDigest = null, hint = '', frames = [] } = {}) {
const summary = track ? track.summary : null;
const digest = lookDigest ?? (look ? look : null);
const specForPrompt = spec ? {
bpm: spec.bpm ?? null,
brightness: spec.brightness ?? null,
noise: spec.noise ?? null,
noiseColour: spec.noiseColour ?? null,
dynamics: spec.dynamics ?? null,
transition: spec.transition ?? null,
arrangement: spec.arrangement ?? null,
duration: spec.duration ?? null,
seed: spec.seed ?? null,
} : null;
// --- helpers for richer context ---
const r2 = (v) => {
const n = Number(v);
return Number.isFinite(n) ? Math.round(n * 100) / 100 : 0;
};
const r3 = (v) => {
const n = Number(v);
return Number.isFinite(n) ? Math.round(n * 1000) / 1000 : 0;
};
const r3 = r2;
const summary = track ? track.summary : null;
const digest = lookDigest ?? (look ? look : null);
const specForPrompt = spec ? {
bpm: spec.bpm != null ? Math.round(Number(spec.bpm)) : null,
brightness: spec.brightness != null ? r2(spec.brightness) : null,
noise: spec.noise != null ? r2(spec.noise) : null,
noiseColour: spec.noiseColour != null ? r2(spec.noiseColour) : null,
dynamics: spec.dynamics != null ? r2(spec.dynamics) : null,
transition: spec.transition != null ? r2(spec.transition) : null,
arrangement: spec.arrangement ?? null,
duration: spec.duration != null ? r2(spec.duration) : null,
seed: spec.seed ?? null,
} : null;
const sectionsDetailed = track ? (track.sections || []).map((s, i) => ({
index: Number.isFinite(s.index) ? s.index : i,