mirror of
https://github.com/THU-MAIC/OpenMAIC.git
synced 2026-10-30 07:35:16 +08:00
@openmaic/generation@0.3.13
14
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3b4567076f |
refactor(generation): consume the package everywhere and delete lib/generation (#1090)
Part D of #1057 — the switch. All consumers import @openmaic/generation; lib/generation deleted (net -11,900 lines). PBL wiring preserved (single-call -> classified fallback -> injected loop), streaming outline route deduplicated onto buildOutlinePrompt, serverExternalPackages wired, and the change verified by a real-model four-kind end-to-end run against the production build with a rendered-classroom screenshot check. Closes #1057. |
||
|
|
0ae21aa559 |
refactor(pbl): retire v1 write path and dead UI, converge on v2 (#1060)
* refactor(pbl): retire v1 write path and dead UI (#1058) Remove the legacy generator, renderer branches, chat API, and compatibility mirror writes. Keep stored v1 scenes readable through documented legacy adapters, and surface ordinary PBL planner double failures instead of degrading. * fix(pbl): contain planner failure to the scene, support legacy scenes in action regeneration, tighten legacy guards - Contain typed planner failures per scene while preserving retry and skip behavior. - Upgrade legacy PBL content before regenerating scene actions. - Apply video-export import boundaries to legacy readers. - Harden legacy rendering and empty-state handling. - Restore legacy upgrade compatibility coverage. - Remove retired translations and refresh fallback narration and legacy cover documentation. * fix(pbl): keep tolerant legacy configs renderable, guard invalid chat timestamps * chore(dsl): bump to 0.6.3 for README accuracy fix The README no longer references the deleted PBLProjectConfig symbol; the version gate requires a bump for any publishable package input change. * fix(pbl): harden legacy upgrade and persistence contract * fix(pbl): align action prompt with v2 workflow and validate project containers * fix(i18n): remove retired PBL v1 keys from the new fr-FR locale The fr-FR locale landed on main after this branch removed the v1 UI key families; prune the same 38 keys so all 10 locales align with en-US. * fix(generation): sync packaged pbl-actions template with the v2 wording The generation package that landed on main carries a byte-identical copy of the app's pbl-actions template; sync the v2 rewording and bump the package version. * fix(pbl): normalize legacy content and preserve planner status * fix(pbl): propagate provider status and ground action prompts * fix(pbl): classify planner failures for retry, default the project summary prompt input * fix(pbl): fall back to legacy data when v2 payloads are damaged, harden summary building * refactor(pbl): resolve hybrid content through a validity-aware resolver * fix(pbl): keep one v2 acceptance criterion across validator, resolver and persistence Persistence gates on the same container predicate as the validator and the renderer's resolver: payloads the renderer will not treat as v2 are inert bytes everywhere, avoiding runtime side effects for documents the write barrier would reject. An explicit null proficiencyAssessment stays processable. * fix(pbl): require runnable projects and harden legacy fallback * test(pbl): exercise the real save reload and hydration chain * fix(pbl): require an instructor and usable microtasks before v2 takes precedence * fix(pbl): fall back to the loop planner unless the provider failed or the user cancelled * fix(pbl): require role and task identities before v2 takes precedence Runtime normalization can repair status and create the instructor thread, but it cannot synthesize the role id that binds the thread, the microtask ids used by lookup and update paths, or the labels the workspace renders. The runnable predicate and its video-export mirror now require them, so identity-less payloads fall back to usable legacy data. |
||
|
|
61a7154f07 |
feat(pi): add evidence-aware Director context runtime (#971)
* feat(pi): add evidence-aware Director context runtime * fix(web-search): require completed native search * fix(orchestration): preserve whiteboard across agent handoffs * fix(pi): remove wrap-up turn bypass |
||
|
|
4b821272ff |
feat(interactive-actions): feed real HTML element inventory into the prompt (#829)
* feat(interactive-actions): feed real HTML element inventory into the prompt
Teacher actions (highlight/setState/annotation/reveal) for interactive scenes
frequently miss because the model has to guess selectors from the prompt's
naming conventions (e.g. `#{var}-slider`, `#start-btn`) that don't match the
ids the content model actually emits (`#score-val`, `#launch-btn`, …). The
game widget category is the worst hit because its conventions cover almost
nothing.
Extract an inventory of interactable elements (ids + notable classes +
aria/role/data-step-id) from the generated widget HTML and thread it into
`INTERACTIVE_ACTIONS` under an `{{elementInventory}}` variable. The system
prompt now instructs the model to select `target` from the inventory first
and only fall back to conventions when nothing matches.
The inventory is:
- Persisted on the runtime `InteractiveContent` so pro-mode
`regenerate_scene_actions` gets the same real selectors, not a stale guess.
- Refreshed by `edit_interactive_html` — the tool re-runs the extractor on
the post-edit HTML and the client writes it back into `scene.content`, so
a subsequent action regen sees the new dom.
- Computed on the fly in `generateSceneActions` when a legacy scene lacks it,
so pre-existing courses benefit without a data migration.
Tailwind / utility class tokens are filtered so the 30-class inventory cap
keeps semantic hooks like `.pairing-rules`, `.dna-card`, `.btn-launch` from
being crowded out by layout tokens.
* style: prettier format
* fix(interactive-actions): compute element inventory at prompt-build time
Address PR #829 review feedback:
1. Drop the persisted `elementInventory` field on
`InteractiveContent`/`GeneratedInteractiveContent`. `generateSceneActions`
already computes the inventory on the fly from `content.html`; make that
the only path. Removes born-stale mismatches (post-processing rewrite vs
raw-html extraction), same-turn staleness of `sceneContextMap`, and the
silent divergence between `createSceneWithActions` (drops the field) and
`scene-builder.ts` (keeps it) — server-generated classrooms already ran
in recompute-only mode today.
2. Extractor hardening:
- Strip HTML comments alongside `<script>` / `<style>` so commented-out
markup can't forge phantom inventory entries the prompt would prefer.
- Drop content after an unmatched `<script` open so a truncated
generation doesn't inventory ids inside `innerHTML` template strings.
- Parse attributes into a name→value map by walking the tag grammar
instead of per-attribute regex over the flat string. Prevents
`aria-label="try name=alpha or id=fake"` from lifting phantom
`name=alpha` / `id=fake` attributes.
- Collapse whitespace and truncate each attribute value (~120 chars)
when building inventory lines so a multi-line or hostile aria-label
can't fake prompt sections.
- Keep semantic hooks whose names collide with Tailwind category
prefixes (`.grid-cell`, `.fill-blank`, `.text-input`, `.select-btn`,
`.ring-carbon`) when they are declared in the page's own `<style>`
block.
* style: prettier format
* fix(interactive-actions): surface id-less data-attribute targets in inventory
The interactive-actions system prompt tells the model to prefer
`[data-step-id="step-1"]` selectors for procedural-skill widgets whose
step rows typically carry only `data-step-id` (no id, and often no
surviving semantic class). Under the previous extractor those rows were
invisible: `data-step-id` and `data-action` only surfaced as decoration
on id rows, so a widget with all-data-only steps could hit the
"(no interactive elements detected)" sentinel while the system prompt
kept telling the model to prefer the inventory — degrading exactly the
one widget family the conventions already served well.
Add a third `Stable data attributes:` section that emits an
`[data-step-id="step-1"] <li>` line for each id-less element carrying
data-step-id or data-action, deduped on attribute value and capped at 30
entries. Elements that already have an id keep those attributes as row
decoration only (no duplicate row).
|
||
|
|
cec3c6aaea |
Refactor widget actions into the scene action pipeline (#796)
* refactor: align widget actions with scene pipeline * feat(edit): migrate legacy teacherActions off interactive content on load The widget-actions pipeline no longer persists a teacherActions authoring layer; playback reads only scene.actions. Add migrateInteractiveContent to strip the dead field from existing documents as they load through migrateScene (wired into all store/classroom load paths). Satisfies the #794 forward-migration acceptance item. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(generation): default widget_setState.state to {} when the LLM omits it The removed TeacherAction->Action converter always defaulted state to {}. Restore that guard in the structured-output parser so an action missing state can't forward state: undefined into the widget iframe, where SET_WIDGET_STATE handlers dereference it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(edit): also strip nested widgetConfig.teacherActions in migration Legacy WidgetConfig variants each declared their own teacherActions, so existing documents can carry the dead field nested inside content.widgetConfig as well as at the top level. Extend migrateInteractiveContent to drop both, preserving all other widgetConfig fields. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(prompts): document stable widget-action selectors for diagram/game/viz3d The interactive-actions prompt documented stable target selectors only for procedural-skill and simulation widgets. Add the canonical selectors the diagram / game / visualization3d content prompts actually emit (node IDs via revealOrder; #zoom-in-btn / #canvas-container / #speed-slider / ...; #start-btn), plus a rule to use widget_setState or a speech-only beat instead of guessing a target when no stable selector is known (e.g. free-form code widgets). Hardens against widget actions silently no-oping on non-existent selectors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: 杨慎 <117187635+cosarah@users.noreply.github.com> |
||
|
|
09863af421 |
Add PBL v2 core schema and generation path (#795)
* feat: add PBL v2 core planner * chore: restore unrelated lint comments * fix: document PBL v2 scenario outline flags * fix: expose PBL scenario subtype in outlines * chore: clear PBL v2 completion stats lint warning * chore: address PBL instructor code quality comments * fix: address PBL v2 review findings * chore: restore unrelated lint comments |
||
|
|
e6debb093b | fix(vocational): address review feedback | ||
|
|
c58893e76f | feat(vocational): add task engine and procedural skill widgets | ||
|
|
ea049417cd |
fix(prompts): gate media snippets in interactive-outlines template (#626) (#628)
The interactive-outlines template (Ultra Mode) never included the media-generation instructions, so the `mediaGenerations` field was only ever produced by strong cloud models inferring it from context. Weak local models followed the prompt literally and omitted it, so images silently never generated. Mirror requirements-to-outlines by including the same conditional snippet blocks (image / video / media-safety), gated on the imageEnabled / videoEnabled / mediaEnabled variables that both outline paths already pass to buildPrompt. Reuses the existing snippets as the single source of truth rather than duplicating the instructions. Extends media-conditional.test.ts to hold INTERACTIVE_OUTLINES to the same media-gating contract as the standard template. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
2dff6d10be |
feat: add generated video manifest refs (#540)
* feat: add generated video manifest refs * style: format video manifest changes * fix: address video manifest review feedback |
||
|
|
3fafca5f99 |
feat(prompts): conditional media snippets in generation prompts (#490)
* feat(prompts): conditional media snippets in generation prompts (#483) Replace always-included media instructions + negative-override pattern with conditional snippet includes gated on imageEnabled/videoEnabled flags. - Extend prompt loader with {{snippet:name?if=condition}} syntax - Extract 15 media instruction snippets from outline and slide templates - Wire imageEnabled/videoEnabled through outline-generator, scene-generator, and route handler - Remove mediaGenerationPolicy negative-override from all call sites - Close gap: slide content generation now receives media policy - Unify pre-output checklist to labeled bullet format * refactor(prompts): replace ?if= snippet syntax with {{#if}} inline blocks Address review feedback on PR #490 — the file-per-fragment pattern was too fine-grained (6 of 15 new snippets were ≤2 lines). Changes: - Add {{#if name}}...{{/if}} block syntax to the loader (~10 lines) - Inline 9 micro-snippets (≤4 lines each) back into host templates - Keep 3 large instruction snippets as {{snippet:name}} wrapped in {{#if}} at the call site - Drop ?if= syntax and PromptLoadOptions.conditions — conditional blocks read directly from buildPrompt's variables - Update tests and README Processing order: snippets → conditional blocks → variable interpolation * style: format media-conditional test with prettier |
||
|
|
fc6b186929 |
refactor(whiteboard): file-based prompts + geometry conflict detection (#485)
* feat(prompts): declare whiteboard role prompt IDs + whiteboard-reference snippet * feat(prompts): add whiteboard role template skeletons + reference snippet stub * refactor(orchestration): move buildWhiteboardGuidelines to role-specific markdown templates * docs(prompts): whiteboard guidelines now in markdown templates * feat(prompts): whiteboard-reference canvas + JSON output sections * feat(prompts): whiteboard-reference action schemas for text/shape/line * feat(prompts): whiteboard-reference action schemas for latex/chart/table * feat(prompts): whiteboard-reference action schemas for code/delete/clear/close * feat(prompts): whiteboard-reference LaTeX JSON escape section * feat(prompts): whiteboard-reference bounds + overlap section * feat(prompts): whiteboard-reference font + latex height tables * feat(prompts): whiteboard-reference pre-output checklist * feat(prompts): expand teacher whiteboard template * feat(prompts): expand assistant whiteboard template * feat(prompts): expand student whiteboard template * test(prompts): assert whiteboard-reference sections reach every role prompt * tune(prompts): cap teacher element budget at 4/turn, encourage wb_clear on crowded board * tune(prompts): simplify teacher template — single conservative rule + state-awareness emphasis * tune(prompts): add LaTeX-height × text-fontSize pairing table for visual weight consistency * feat(orchestration): preserve image parts from UIMessage to AI SDK ModelMessage * feat(eval): attach prior-turn whiteboard screenshot as user message image part Gated behind EVAL_ATTACH_PRIOR_SCREENSHOT=1 env. When on, captures a screenshot after every turn (not just checkpoints) and attaches it as a file part with mediaType:'image/png' on the next user message. Teacher prompt gets a new 'Prior-state image' section telling the agent to treat it as direct visual feedback. * fix(orchestration): strip data: prefix before passing image to AI SDK Vercel AI SDK's streamText/generateText treats ImagePart.image as a URL to fetch when it's a string. data: URLs fail the http/https scheme check and throw AI_DownloadError. Strip the data URL prefix and pass raw base64 with mediaType separately — AI SDK treats base64 strings as data content. * refactor(whiteboard): add conflict summarizer, drop prior-screenshot feature Eval across flash (image-on vs off × repeat-3) and pro (same) showed the prior-screenshot image-input feature gives ~0 net benefit: +0.4 overall on flash and −0.6 on pro. The image feedback loop's theoretical upside (agent self-correcting from visual) didn't materialize — weak models couldn't act on the image and strong models "found things to fix" and over-corrected. Meanwhile programmatic geometry detection on the raw JSON cleanly lifted overlap from 6.3 → 8.1 on flash. So: remove the image-input plumbing, keep a programmatic equivalent. ## Removed (reverts |
||
|
|
550c43a3f3 |
fix(generation): unify languageDirective across outline + scene pipeline (#472) (#474)
* fix(generation): unify languageDirective across outline + scene pipeline (#472) Root issue: languageDirective was dropped, renamed, or hardcoded at several points in the scene-generation pipeline, silently degrading prompt-level language control. Slide paths survived because their fallback happened to hint requirement-language; widget paths degraded to zh-CN default. Fix plan (all code-only threading + prompt hygiene, no schema changes): 1. Thread languageDirective through every buildPrompt in scene-generator.ts: - Add param to generateSlideContent / generateQuizContent / generatePBLSceneContent - Forward from generateSceneContent's slide / quiz / pbl branches - Include key in the four generateSceneActions buildPrompt calls - Demote generatePBLSceneContent's hardcoded English to a fallback - Drop the dishonest `as 'zh-CN' | 'en-US'` cast on the widget path 2. Unify variable naming across widget templates + callers: - Rename {{language}} → {{languageDirective}} in 6 widget templates (simulation / diagram / code / game / visualization3d / widget-teacher-actions) - generateWidgetContent and generateWidgetTeacherActions now pass `languageDirective: languageDirective || ''` instead of a locale-code shim 3. Make the outline LLM reliably emit the wrapper object: - requirements-to-outlines/system.md + user.md restructured so the "top-level JSON object with languageDirective + outlines" contract is surfaced up-front, short, and unambiguous — drowning-by-scene-examples removed. Important Reminders reordered: top-level shape first. - interactive-outlines/system.md + user.md aligned with main outliner: adds full Language Inference section, requires wrapper output, drops the orphan {{language}} placeholder that never had a value source. 4. Remove lib/prompts/loader.ts prompt/snippet caches: - Disk reads for prompt templates are not on any hot path (LLM call dominates by 5 orders of magnitude). The cache's only observable effect was blocking prompt edits from taking effect without restart — which masked the wrapper bug during this investigation. Verification: - 7 new regression tests in tests/generation cover directive threading at each buildPrompt site plus the PBL caller-forwarding guarantee. - outline-language eval (50 scenarios, gemini-3-flash-preview inference, qwen-3.5-flash judge): 48/50 (96%). The 2 persistent failures are in the proxy-request category (teacher / tutor preparing lessons for students) where the system prompt's rule 5 has genuine ambiguity — orthogonal to this fix. - Curl burst tests: 8/8 runs each for regular-mode and interactive-mode outline endpoints emit the wrapper object and extract a detailed inferred directive. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * style: apply prettier formatting to loader.ts and new test file Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: thread languageDirective in scene-builder and classroom-generation Code review caught two additional sites missing the directive: - lib/server/classroom-generation.ts:371 — generateSceneActions call was missing languageDirective, reproducing the issue #472 symptom in the shareable-classroom server generation path. - lib/generation/scene-builder.ts:114 — buildSceneFromOutline's generateSceneActions call had the same miss; latent (no current live caller) but wrong for consistency. Also renumber duplicate `8.` in requirements-to-outlines/system.md scene-level rules. Extend regression tests with a buildSceneFromOutline end-to-end case that captures both the content and actions prompts via a stub aiCall and asserts the directive reaches both phases — this would have caught the scene-builder miss. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * review: widget-path test + docs + fallback constant (PR #474) Address @cosarah's review feedback: - Add widget-path regression test (tests/generation/...): interactive scene with widgetType=simulation captures both widget content and widget-teacher-actions prompts, asserts the directive reaches each and no `{{language}}` / `{{languageDirective}}` placeholder leaks. This is exactly the path issue #472 was filed for. - Rewrite lib/prompts/README.md "Caching" section: the cache was removed in this PR; README still instructed callers to use a clearPromptCache() function that no longer exists. - Sync interactive-outlines/user.md with the main outliner's "## Language Context" reminder block (line 13-19) so both outline paths give the LLM the same language-inference reminders. - Hoist 'Teach in the language that matches the user requirement.' into DEFAULT_LANGUAGE_DIRECTIVE, exported from outline-generator. Replaces 4 copies across outline-generator, scene-generator, and the scene-outlines-stream route. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
f40c92f1aa |
refactor(orchestration): migrate prompt builders to file-based templates (#459)
* refactor(prompts): move loader to lib/prompts/ Move file-based prompt loader from lib/generation/prompts/ to project-level lib/prompts/ so it can be shared by orchestration and PBL prompts in subsequent commits. - Templates and snippets moved alongside the loader - getPromptsDir() now points at lib/prompts/ - Generation pipeline imports updated to @/lib/prompts (outline-generator, scene-generator, search-query-builder, scene-outlines-stream route) - Add tests/prompts/loader.test.ts as sanity gate Pure file move — no behavior change. * test(orchestration): add baseline snapshots for prompt builders Snapshot tests cover variant matrix: - buildStructuredPrompt: role × scene-type × peer/ledger/discussion/profile - convertMessagesToOpenAI: mixed message kinds - summarizeConversation: truncation - buildDirectorPrompt: Q&A vs discussion, ledger, profile - buildPBLSystemPrompt: default config These lock current output so the body refactor in subsequent commits can be verified byte-equal. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(orchestration): plug snapshot coverage gaps from review - Split convertMessagesToOpenAI test: same-agent (existing) + cross-agent (new). The original test passed currentAgentId matching the message's agentId, so the cross-agent role-conversion branch was never exercised. - Add 'teacher / quiz scene' snapshot to lock the spotlight/laser strip path in getEffectiveActions. The previous variant-7 test (whiteboard-open) only triggered the mutual-exclusion warning, not the strip — renamed it to reflect what it actually tests. - Add assistant-role variant (was uncovered: ROLE_GUIDELINES, buildLengthGuidelines, buildWhiteboardGuidelines all branch on role). * refactor(orchestration): extract summarizers from prompt-builder.ts Move state-context, virtual whiteboard ledger replay, peer context, message converter, and conversation summary out of the 890-line prompt-builder.ts into focused modules under lib/orchestration/summarizers/. prompt-builder.ts now only owns prompt assembly. director-graph imports updated to the new locations. Snapshot tests pass byte-equal — no behavior change. * refactor(orchestration): move agent-system prompt to template file The buildStructuredPrompt template literal is now lib/prompts/templates/agent-system/system.md, assembled by a thin variable-pass through the shared prompt loader. Per-variant ternaries (format example, ordering, spotlight examples, mutual-exclusion note) are kept as module-level constants in prompt-builder.ts. ROLE_GUIDELINES, buildLengthGuidelines, and buildWhiteboardGuidelines stay too (they may further migrate to template partials in Phase 2). Also: PROMPT_IDS gains a 'satisfies Record<string, PromptId>' clause to prevent constant/union drift as more IDs are added. Snapshot tests (12 prompt-builder + 4 director + 1 pbl) pass byte-equal. * refactor(prompts): align agent-system template with project conventions - Rename agent-system placeholders snake_case → camelCase to match the convention already used by slide-actions/user.md and other generation templates. Settles convention before Task 5 lands two more templates that would otherwise inherit drift. - Extract '## Speech Guidelines (CRITICAL)' into lib/prompts/snippets/speech-guidelines.md for reuse by director and PBL prompts in Task 5. Snapshot tests pass byte-equal — placeholder name changes are invisible in rendered output, and snippet inclusion happens at load time. * refactor(orchestration,pbl): move director + PBL prompts to templates director-prompt.ts and pbl-system-prompt.ts now use the shared template loader. Bodies collapse to thin variable assembly. Three orchestration-tier prompts now share one infrastructure: agent-system, director, pbl-design. Snapshot tests pass byte-equal. * refactor(orchestration): extract WhiteboardActionRecord + AgentTurnSummary to types module These two interfaces are imported by 6+ modules including summarizers/ — having them live in director-prompt.ts created an awkward upward import direction (summarizers reaching back to a sibling prompt builder for types). Move them to lib/orchestration/types.ts and update all callers. director-prompt.ts now imports them too. Pure type-location refactor — snapshots pass byte-equal. * test: remove snapshot tests in favor of eval-as-integration-test Per review feedback: byte-equal snapshots were the wrong invariant for this refactor. The goal was a stable substrate for editing prompts, not a frozen contract. Snapshots would have generated maintenance churn (~100-200 line diffs per intentional Phase 2 prompt tweak) without providing value the eval doesn't already. Test posture going forward: - tests/prompts/loader.test.ts (3 tests) — bounds the loader infrastructure (template load, snippet inclusion, variable interpolation, missing-id behavior) - pnpm eval:whiteboard — bounds end-to-end agent loop, template composition, and integration with chat/director/state-manager Removed: 1879 lines of .snap + 320 lines of test scaffolding + fixtures. Net PR diff drops by ~2200 lines. * docs(prompts): add README + structural assertion tests (review feedback) Addresses two items flagged by PR #459 final review: 1. lib/prompts/README.md — conventions, syntax, gotchas, and local-testing recipe for template authors. Previously there was no doc for the stated goal of "non-engineers can edit prompts." 2. tests/prompts/templates.test.ts — 8 structural assertions covering: - no surviving {{...}} placeholders in any rendered template - role dispatch (teacher → LEAD TEACHER, student → not) - scene-type action stripping (quiz scene has no spotlight/laser) - director prompt output spec mentions next_agent These replace the removed byte-equal snapshot suite at much lower maintenance cost — they assert behaviors the refactor must preserve, not exact bytes. * chore(prompts): relocate templates added on main during rebase PR #461 (interactive mode clean) added 7 new templates under lib/generation/prompts/templates/ (the pre-refactor location). Rebase onto origin/main landed them at the old path; git's rename detection didn't forward them through the directory move in db56c40. Manually move them to lib/prompts/templates/ to match the new convention, and fix scene-generator.ts's relative import ('./prompts/types' → '@/lib/prompts/types') since the dir no longer exists as a sibling. No behavior change — templates read from PROMPT_IDS values via getPromptsDir() which already points at lib/prompts/. * refactor(prompts): address review feedback from @cosarah - loadSnippet now throws on missing file instead of silently returning a literal {{snippet:id}} string. A typo like {{snippet:speach-guidelines}} now fails at load time instead of reaching the LLM. - README gains a "Still in TypeScript" section listing the role-conditional content that still lives in prompt-builder.ts (ROLE_GUIDELINES, buildLengthGuidelines, buildWhiteboardGuidelines) so contributors expecting a pure-markdown workflow know where to look. - Expand tests/prompts/templates.test.ts to cover the conditional branches Phase 2 is most likely to touch (9 new assertions): - assistant role dispatch - peer-context section toggles on agentResponses presence - language constraint toggles on stage.languageDirective presence - director Q&A vs discussion mode branching - pbl-design {{issueCount}} substituted at all 3 occurrences - placeholder-naming-convention lint scans every template for non-camelCase placeholders (slide-content grandfathered) - Comment above interpolateVariables regex documents why kebab-case placeholders pass through silently (the lint test now catches them). - New test in loader.test.ts locks the throw-on-missing-snippet behavior. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |