Skip to content

fix(graphics): consolidate backend readiness and cache identity - #786

Merged
calesthio merged 32 commits into
OpenMontageInc:mainfrom
rudycelekli:fix/diagram-render-cache-identity-20261013
Nov 8, 2026
Merged

calesthio merged 32 commits into
OpenMontageInc:mainfrom
rudycelekli:fix/diagram-render-cache-identity-20261013

Conversation

@rudycelekli

@rudycelekli rudycelekli commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Diagram generation must report backend readiness honestly and avoid reusing outputs across different rendering inputs. This branch combines strict Mermaid fallback, CLI-version compatibility and diagram/code-snippet cache fixes.

This canonical PR consolidates #640, #786 and #872. Original contributor commits remain in the merge ancestry; duplicate implementations are excluded. This consolidation is part of the maintainer-requested approved-PR integration.

Validation: 23 focused tests pass. Cache keys preserve connections/title/theme/dimensions/fallback and normalize omitted/false fallback for both cache paths.

A separate draft integration PR, #910, runs the full combined Python suite before these canonical PRs land. Main remains protected by code-owner approval and the Validate Python check. No live generation or model downloads were used.

Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
@rudycelekli rudycelekli changed the title fix(graphics): include rendering inputs in diagram cache identity fix(graphics): retain rendering controls in local image cache identity Oct 13, 2026
calesthio and others added 25 commits October 16, 2026 08:01
…penMontageInc#790)

* fix(audio): pass ducking attack and release in milliseconds

Signed-off-by: Rudy Celekli <rudy@gradiahq.com>

* fix(audio): invalidate cached renders for corrected ducking timing

Signed-off-by: Rudy Celekli <rudy@gradiahq.com>

---------

Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
…geInc#795)

* fix(reframe): crop anamorphic input in display coordinates

Signed-off-by: Rudy Celekli <rudy@gradiahq.com>

* fix(reframe): invalidate cached encoded-pixel crops

Signed-off-by: Rudy Celekli <rudy@gradiahq.com>

---------

Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
…MontageInc#796)

* fix(video): include local rendering controls in cache identity

Signed-off-by: Rudy Celekli <rudy@gradiahq.com>

* fix(video): retain scene analysis controls in processing cache identity

Signed-off-by: Rudy Celekli <rudy@gradiahq.com>

---------

Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
…penMontageInc#805)

execute() called get_genai_client().interactions.create(...) on a
temporary Client. With google-genai 2.31 the Client is garbage-collected
(closing its HTTP session) before the request is sent, so every call
failed with "Cannot send a request, as the client has been closed."
Hold the client in a local variable for the duration of the call.

Adds an offline regression test whose fake client's interactions only
weakly reference the client.

Co-authored-by: FaqsCCE <facundonatale@cceindustrial.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…eInc#832)

Co-authored-by: naitik0009 <your_naitik0009_email@example.com>
…geInc#813)

edit-director.md §8b instructs recording `edit_decisions.end_tag` and
compose-director.md §4b reads `edit_decisions.end_tag.offset_seconds`,
but edit_decisions.schema.json declared `additionalProperties: false`
without an `end_tag` property, so writing it exactly as documented failed
validation with "Additional properties are not allowed ('end_tag' was
unexpected)". The compose stage could therefore never see offset_seconds.

Declare `end_tag` ({ offset_seconds >= 0, notes }) matching the documented
shape. It stays optional, so concat mode (which omits it) is unaffected.

Addresses part 3 of OpenMontageInc#575.

Co-authored-by: SilverArget <196021214+SilverArget@users.noreply.github.com>
CaptionOverlay lays each word out as an inline-block span. Inline-blocks are
bidi-neutral, so with no base direction the page defaults to LTR and Arabic,
Hebrew, Persian and Urdu captions are placed left to right (sentence reads
backwards, karaoke highlight walks the wrong way).

Add a direction prop (ltr | rtl | auto, default auto). auto picks RTL when
most words are RTL, so a caption that opens with a Latin brand name still
reads right to left. The page wrapper gets dir + CSS direction. English and
other LTR captions render unchanged.

Co-authored-by: AmroA <266593117+AmroAlemam@users.noreply.github.com>
…tageInc#840)

Co-authored-by: Hermes Video Production <hermes@localhost>
…penMontageInc#839)

`_search` never asked the Freesound API for the `license` field, so
`execute` had nothing to read and hardcoded the generic string
"Creative Commons (check individual sound license)" instead. Every
Freesound sound carries its own license (CC0, CC BY, CC BY-NC...), and
whether attribution is required or the track may be used commercially
depends on it, so the agent had no way to decide. The author was only
reachable by parsing `freesound_url`.

- add `license` to the requested `fields`
- return `sound["license"]`, falling back to the generic string when a
  (partial) response omits it, so behaviour degrades rather than
  handing the agent a bare `None`
- surface `author` as a first-class result field

The fallback string moves to a `_GENERIC_LICENSE` class constant so the
test and the implementation cannot drift apart.

Closes OpenMontageInc#736

Co-authored-by: Amy Zhao <pseudodream@users.noreply.github.com>
* fix(video): prevent ffmpeg filtergraph injection in drawtext and subtitle force_style (GHSA-cg89-3297-mwhg)

* Close remaining filtergraph injection; preserve literal text

Addresses review on this PR:

1. [P1] title_color (and background_color) were still interpolated
   directly into the filtergraph (showcase_card.py:182) - a crafted color
   literal could close the fontcolor option list and append a second
   drawtext filter that reads an arbitrary local file into the output.
   Adds _validate_color() (named color or 0x/#-hex literal only) and
   applies it to both fields, plus _validate_font_file() for title_font
   (bare filename, no path/quote/colon characters) and
   _validate_int_range() for output_width/output_height/font sizes.

2. [P2] _drawtext_safe destroyed literal punctuation in user text
   (stripped backslash/percent, turned ':' into ' —'). Replaced with
   _write_drawtext_textfile(): text is written verbatim to a temp file and
   read back via drawtext's textfile=+expansion=none, which needs no
   escaping of the text content at all. Only the (internally generated)
   temp-file path is embedded in the filtergraph, via _safe_filter_path().

Adds tests/tools/test_showcase_card_security.py: unit tests for the three
validators and the textfile writer, plus FFmpeg integration tests
reproducing the reviewer's title_color canary-file-read attack (now
rejected) and verifying tricky punctuation (%, :, backslash, apostrophe,
comma) now renders unchanged.

* fix(video): escape temporary text paths across FFmpeg parsers

---------

Co-authored-by: Filip Kulisiewicz <nisustawa@gmail.com>
Co-authored-by: calesthio <celesthioailabs@gmail.com>
…oice

The subtitle force_style regression test added with the GHSA-cg89-3297-mwhg
fix compared a frame rendered with the attack payload against a frame
rendered with `FontName=Arial`, requiring them to be byte-identical.

Those two frames differ for a benign reason: `_build_subtitle_style`
strips `' \ : , ; [ ] =` from the value, so the payload collapses into a
single inert font family (`Arialdrawtextfontsize30...`). fontconfig
resolves "Arial" to an installed metric-compatible face and falls back to
its default family for the sanitised payload, so the comparison measured
typeface selection rather than filtergraph injection -- and failed on
ubuntu-latest, which ships those aliases.

Replace it with two assertions that test the property the advisory is
about:

1. Structural: the generated force_style string gains no extra style
   entries from the payload, and every value is free of the characters
   that could close the quoted literal or open a new filter/option.
2. Behavioural: render the payload frame with the named canary file
   present, remove the file, and render again. Injection of a
   `drawtext=textfile=` filter would change the frame or make FFmpeg
   fail; identical frames prove the output cannot depend on local file
   contents. A payload naming a never-existent file is checked the same
   way, and a lit-pixel assertion keeps this from passing on two blank
   frames.

The production fix is unchanged; only the test was measuring the wrong
thing.
…le-security-test

test(security): fix the subtitle force_style regression test (unblocks main CI)
mermaid-cli 12 removed -w/--width in favour of --size, so diagram_gen failed
with "unknown option '-w'" whenever the current mmdc was installed. Detect the
installed major version once and pass the matching flag.
…t model (OpenMontageInc#897)

* fix(local_diffusion): use MPS on Apple Silicon and a reachable default model

Device selection only checked CUDA, so Macs fell back to CPU in fp32.
Pick cuda, then mps (fp16), then cpu, and share that with image_gen's
local backend. The default stabilityai/stable-diffusion-2-1-base repo was
removed from the Hub and returns 401; default to the sd2-community mirror.

Fixes OpenMontageInc#886

* fix(local_diffusion): seed MPS runs with a CPU generator

torch.Generator(device="mps") isn't supported on older PyTorch, which requirements still allow, so seeded requests on Apple Silicon failed. Create the generator on CPU when the pipeline runs on MPS.
calesthio
calesthio previously approved these changes Nov 7, 2026

@calesthio calesthio left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for fixing these incomplete image-cache identities. Reviewed the complete diff against current main (63d1087a) and checked the actual producer inputs: diagram dimensions/theme/title/connections and code-card padding/line numbers/title now participate in cache keys, while output destinations remain reusable.

Validation: python -m pytest tests/tools/test_code_snippet_cache_identity.py tests/tools/test_diagram_gen_cache_identity.py -q --tb=short -p no:cacheprovider — 10 passed, comparing actual Pillow output pixels/dimensions with uncached renders and checking output-path-only hits. Existing CI is successful.

@calesthio calesthio changed the title fix(graphics): retain rendering controls in local image cache identity fix(graphics): consolidate backend readiness and cache identity Nov 8, 2026
calesthio
calesthio previously approved these changes Nov 8, 2026

@calesthio calesthio left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for these contributions. Re-reviewed the consolidated head after preserving the original commits from #640, #786 and #872. 23 focused tests pass. Cache keys preserve connections/title/theme/dimensions/fallback and normalize omitted/false fallback for both cache paths.

The fresh exact-head Validate Python workflow passed: https://github.com/calesthio/OpenMontage/actions/runs/42428629572. Approved at adbad3e. The combined integration batch remains gated on its separate full-suite validation; no failing tests were skipped or disabled and no live provider generation was used.

@rudycelekli
rudycelekli dismissed calesthio’s stale review November 8, 2026 00:17

The merge-base changed after approval.

calesthio pushed a commit that referenced this pull request Nov 8, 2026
calesthio
calesthio previously approved these changes Nov 8, 2026

@calesthio calesthio left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reconfirmed the unchanged reviewed head and preserved unique fixes/tests. This exact head has passing Validate Python CI. The complete ordered integration also passes: 2,814 tests, 17 skipped, 1 subtest passed (https://github.com/calesthio/OpenMontage/actions/runs/42429872644). Approved for the requested ordered integration.

@rudycelekli
rudycelekli dismissed calesthio’s stale review November 8, 2026 00:35

The merge-base changed after approval.

@calesthio
calesthio merged commit 752a481 into OpenMontageInc:main Nov 8, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.