4 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e244ee5240 |
feat: modifying a deck can see it
Some checks failed
Forgejo Android APK / Root app tests (push) Successful in 1m0s
Forgejo Docker Build / Root app tests (push) Successful in 47s
Forgejo Android APK / Build signed APK (push) Successful in 2m13s
Forgejo Docker Build / Build Docker image (push) Successful in 24s
Forgejo Docker Build / Deploy to the host (push) Failing after 0s
The model editing a deck could not see it, which made most of what people actually ask for unanswerable: "that slide is too crowded", "the diagram is in the wrong place", "this one looks empty" are facts about the rendered page, not about the JSON. When a vision model is configured, modifying now renders the current deck — with its figures, unlike the review pass, which runs while they are still being drawn — and hands the model one image per slide alongside the JSON. Same pipeline as review, reused rather than reimplemented: pptx, Gotenberg, PDF, pdftoppm, capped at MAX_SLIDES. The vision model then does the editing, which is a second and separately measured benefit. On a real 20-slide deck, ds-deepseek-v4-flash returned the deck unchanged for "make it better" — the echo reported yesterday — while openrouter-gemini-3.8-flash applied it. So the stronger model fixes the echo even without sight. A model the author picks explicitly still wins over both. The result is rendered and reviewed again. Generation-only was the old rule, on the reasoning that refining is a text edit; it is not. The edit is made against how the deck looked before it, so a slide that gains two bullets only overflows once it is rendered again. The reviewer may reposition but is held to the same words, so a verification pass cannot quietly undo what was just asked for. Whether an instruction achieved anything is judged on the model's edit, before the reviewer runs, or a reviewer nudging a slide into two columns would mask an instruction that did nothing. Sight is an upgrade, never a dependency: no vision model, Gotenberg down, a render that fails — each falls through to editing blind, and a test covers each of those paths. Verified against two mutations: keeping the text model when images are attached, and dropping the verification pass, each fail exactly one test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU |
||
|
|
491a2b0811 |
fix: the My Resources diagnostics survive a deploy
Some checks failed
Forgejo Android APK / Root app tests (push) Successful in 47s
Forgejo Docker Build / Root app tests (push) Successful in 52s
Forgejo Android APK / Build signed APK (push) Successful in 2m5s
Forgejo Docker Build / Build Docker image (push) Successful in 17s
Forgejo Docker Build / Deploy to the host (push) Failing after 0s
logRefine writes the one line that answers "did that modification change anything" — path, before and after size, CHANGED=yes/no, figures, model, instruction. It went to console, so it lived in the container's stdout and was destroyed the next time the container was recreated. That cost a diagnosis today: a modification came back unchanged, the user asked why, and the evidence had already been deleted by a deploy. The deck-fallback warnings and the deck-vocabulary gaps had the same problem, and those exist specifically to be read later — the vocabulary gaps are meant to show which shapes to build next, which is a question about weeks, not about one container. All of them now go through logger, which writes the dated file in the scribe-logs volume and ships to Loki when it is configured, and carries the event as structured data rather than only as a formatted string. console.error is left alone: those are failures, and logger.error already echoes to the console. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU |
||
|
|
07d1c541a0 |
fix: a deck the model fumbles once is asked for again, not abandoned
Some checks failed
Forgejo Android APK / Root app tests (push) Successful in 50s
Forgejo Docker Build / Root app tests (push) Successful in 48s
Forgejo Android APK / Build signed APK (push) Successful in 2m2s
Forgejo Docker Build / Build Docker image (push) Successful in 23s
Forgejo Docker Build / Deploy to the host (push) Failing after 0s
A presentation is generated as a typed deck — the model chooses each slide's layout — and that deck is what scripts/render_pptx.py renders. When the reply did not parse as a deck, the route fell straight back to asking for markdown, and slideSpec.build() then inferred slides from it. Both paths go through python-pptx, but the fallback's layout is guessed from heading and list structure rather than chosen, so everything lands as title-and-bullets. Measured on the stored library: since decks landed, 7 of 8 generations produced one and 1 did not. Models are stochastic, so one unlucky reply was costing the whole layout. It now asks a second time with the same prompt before giving up. The fallback was also invisible. It warned to the console, where the person who would simply have generated again could not see it, so they kept the plainer deck without knowing a better one was one click away. The response now carries deckFallback and the UI says it came out as plain slides, and why. Fixed the reason heuristic while adding tests for it: truncation was claimed for any reply not ending in "}", which is every prose refusal. It is now only claimed for a reply that began as JSON and stopped. The four generate tests run the handler. Verified against a mutation: removing the retry fails tests 6 and 7 and nothing else. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU |
||
|
|
e69eb9a9f7 |
fix: modifying a presentation failed whenever illustration was ticked
Some checks failed
Forgejo Android APK / Root app tests (push) Successful in 53s
Forgejo Docker Build / Root app tests (push) Successful in 54s
Forgejo Android APK / Build signed APK (push) Successful in 1m56s
Forgejo Docker Build / Build Docker image (push) Successful in 22s
Forgejo Docker Build / Deploy to the host (push) Failing after 0s
existingDeck was declared below the branch that reads it, so `var` hoisting made it undefined there. With illustration on, a deck modification therefore appended the *markdown* instruction — "Returning the markdown is still required; a tool call is not a substitute for it" — to a prompt whose body asked for deck JSON. The model was told to produce two different artifacts in one reply, the reply parsed as neither, and deckBuild.parse returned null, so the handler answered 502 "That change could not be applied." Moved the declaration above its first reader. Same class of fault as the savedFigureIds one, in the same file. Two things made it hard to see, both fixed: - The library row read created_at, so a modification that did apply left the visible timestamp on the generation time. That timestamp is what led to "modification doesn't work" — it was the only signal available, and it was reading the wrong column. Rows now show the modified time when there is one. - A model can also return the document back unchanged. That was logged server-side and answered "Applied. Download it to see the result", which sent people to download an identical file. The response now carries `unchanged` and the UI says so, keeping the instruction in the box so it can be reworded. Also surfaced has_deck on the library list: 28 of 38 stored presentations have no deck and go through the weaker flat-markdown path, and nothing in the UI distinguished them. They now read "plain text, no slide layout". test/my-resources-refine.test.js runs the handler rather than reading it, since all three faults were invisible to source reading. Verified against a mutation: putting the declaration back where it was fails test 1 and nothing else. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU |