Skip to content

feat(core): compile-time media feature gate (media_generation + image) (#4804)#4840

Merged
M3gA-Mind merged 9 commits into
tinyhumansai:mainfrom
oxoxDev:feat/4804-media-feature-gate
Jul 15, 2026
Merged

feat(core): compile-time media feature gate (media_generation + image) (#4804)#4840
M3gA-Mind merged 9 commits into
tinyhumansai:mainfrom
oxoxDev:feat/4804-media-feature-gate

Conversation

@oxoxDev

@oxoxDev oxoxDev commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

Problem

#4795 wants one compile-time feature gate per subsystem family so slim harness builds drop code + deps; #4796 shipped the runtime DomainSet axis. This PR adds the compile-time half for media. Two scope realities the issue over-stated, confirmed by a full sweep:

  • Sheds no dependencies. Media generation is backend-proxied (image/video via GMI over reqwest, shared) and the image crate is shared with channel media upload — neither is exclusive to the gated domains. This is a surface-only gate (drops the tool code + modules), not a dependency-shedding one. The issue's "sheds media processing dependencies" DoD line is superseded.
  • No controllers / stores / subscribers. Media is agent-tools-only — nothing is tagged DomainGroup::Media in src/core/all.rs beyond the media_generate_* tools. The "controllers unregistered / stores not initialized / subscribers not registered" DoD lines don't apply.
  • image is dead scaffold — added in feat(image): add image tool contracts #2997 ("image tool contracts"), wired to nothing (zero consumers). Folded under the gate per issue scope; gating it is cosmetic.

Solution

  • Cargo.toml: new media = [] feature (no dep: — no exclusive crate), added to default.
  • Facade-free leaf gate: src/openhuman/mod.rs marks pub mod media_generation; and pub mod image; as #[cfg(feature = "media")]; the single consumer (build_media_tools extend in src/openhuman/tools/ops.rs) is #[cfg(feature = "media")]. The remaining media_generation references are doc-comments only (src/openhuman/file_storage/tools.rs), so nothing else needs a cfg.
  • CI: the existing rust-feature-gate-smoke lane already builds --no-default-features --features tokenjuice-treesitter (which turns every default gate off), so it covers this gate too — updated its name + comment; no new step needed.
  • Tests: media_tools_registered_when_feature_on (default build) and media_tools_absent_when_feature_off (disabled build) assert the on/off behavior.
  • Docs: AGENTS.md gains a media row + a "leaf-gate variant" note contrasting it with the voice stub-facade.

When off: the media_generate_image/video + media_list_models agent tools are absent from the tool list; the media_generation + image modules are excluded from the build.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • N/A: no instrumented changed lines — the diff is compile-config only (#[cfg] attrs, a media = [] feature, docs, CI yaml). diff-cover reports no lines with coverage information; the two new registration tests cover the on/off behavior. CI coverage-gate authoritative. — Diff coverage ≥ 80%
  • Coverage matrix updated — N/A: compile-time build-config change, no user-facing feature row
  • All affected feature IDs from the matrix are listed in the PR description under ## RelatedN/A: no matrix rows affected
  • No new external network dependencies introduced (mock backend used per Testing Strategy)
  • N/A: default build is byte-identical; the gate only removes surface when explicitly disabled — Manual smoke checklist
  • Linked issue closed via Closes #NNN in the ## Related section

Impact

  • Desktop / CLI / mobile / web: no behavior change — default build keeps media on and is byte-identical.
  • Slim builds: --no-default-features (without media) drops the media_generate_* tools + the media_generation/image modules. No deps shed (image crate + reqwest are shared).
  • Security / migration: none. Additive, default-preserving.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: feat/4804-media-feature-gate
  • Commit SHA: 910c0877697d73c3dca370f4c0859c287a73d802

Validation Run

  • N/A: no app/ (frontend) changes — pnpm --filter openhuman-app format:check
  • N/A: no TypeScript changes — pnpm typecheck
  • Focused tests: openhuman::tools::ops::tests::media_tools_registered_when_feature_on (default, passed) + ..::media_tools_absent_when_feature_off (disabled build, passed)
  • Rust fmt/check: cargo fmt --check clean · default cargo check exit 0 · disabled cargo check --no-default-features --features tokenjuice-treesitter exit 0 · cargo clippy --lib 0 warnings in changed files (both configs)
  • N/A: no app/src-tauri changes — Tauri fmt/check

Validation Blocked

  • command: cargo test --lib (full)
  • error: OOM on local machine (known)
  • impact: full matrix runs in CI; locally scoped to the two media gate tests + default/disabled cargo check — all green in both feature configs

Behavior Changes

  • Intended behavior change: new default-on media compile-time gate; default unchanged
  • User-visible effect: none by default; slim builds omit the media-generation agent tools + modules

Summary by CodeRabbit

  • New Features

    • Added a compile-time media feature to enable image and media-generation tools.
    • Media capabilities are now enabled by default, and can be excluded from slim/headless builds.
    • Desktop shell builds now properly forward the media capability so media tools show up when enabled.
  • Documentation

    • Updated feature-gate documentation to clarify media vs voice behavior and scope.
  • Tests

    • Added feature-gated test coverage to confirm media tools appear when enabled and are omitted when disabled.
  • Chores

    • Adjusted CI “feature-gate smoke” messaging to reflect both voice and media being disabled together.

@oxoxDev
oxoxDev requested a review from a team July 14, 2026 07:05
@oxoxDev oxoxDev added this to the M1 — Big compile wins milestone Jul 14, 2026
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 21 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2d7d8347-688b-4eb7-9d50-8aa33e77ac7f

📥 Commits

Reviewing files that changed from the base of the PR and between 2174e7c and e4b9b76.

📒 Files selected for processing (3)
  • Cargo.toml
  • app/src-tauri/Cargo.toml
  • tests/raw_coverage/agent_session_round24_raw_coverage_e2e.rs
📝 Walkthrough

Walkthrough

The PR adds a media Cargo feature, enables it by default, gates media modules and tool registration at compile time, forwards the feature to the Tauri shell, updates documentation and CI guidance, and adds enabled/disabled tool-surface tests.

Changes

Media feature gate

Layer / File(s) Summary
Feature contract and build guidance
Cargo.toml, AGENTS.md, .github/workflows/ci-lite.yml
Adds and documents the media feature, enables it by default, and updates CI smoke-lane descriptions for disabled voice and media gates.
Media module compilation
src/openhuman/mod.rs
Compiles the image and media_generation modules only when the media feature is enabled.
Media tool registration and validation
src/openhuman/tools/ops.rs, src/openhuman/tools/ops_tests.rs
Gates media tool registration at compile time and tests tool presence with the feature enabled and absence when disabled.
Desktop feature forwarding
app/src-tauri/Cargo.toml
Forwards the media feature to the embedded core dependency used by the Tauri shell.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested labels: rust-core, feature

Suggested reviewers: github-actions[bot], senamakel, m3ga-mind

Poem

I’m a rabbit with a feature flag,
Media tools hop in when built.
Slim builds leave them in the burrow,
Tests check every gate is shut.
Carrots all around! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the PR's main change: adding a compile-time media feature gate for media_generation and image.
Linked Issues check ✅ Passed The PR implements the default-on media feature, gates media_generation/image and tools, adds tests, CI smoke, and docs, matching #4804.
Out of Scope Changes check ✅ Passed The changes stay focused on the media gate, related docs, tests, CI, and feature forwarding without unrelated scope creep.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. labels Jul 14, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 910c087769

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/openhuman/tools/ops.rs
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 14, 2026
…sai#4804)

The Tauri app consumes openhuman_core with default-features = false, so
the compile-time `media` gate defaults OFF in the desktop build even
though the root crate keeps it in `default`. That would drop the
media_generate_* agent tools from the shipped app. Forward the gate
explicitly to keep the desktop build byte-identical, per AGENTS.md.
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 14, 2026
max_iteration_checkpoint_uses_deterministic_fallback_and_hooks fed the wrap-up
call a non-empty response (tool-call XML text) plus a streamed delta, so
summarize_turn_wrapup returned that text as the checkpoint and the deterministic
fallback the test is named for never ran — the (1 steps) assertion failed under
the FULL instrumented suite. Make the wrap-up yield nothing (empty text, no
deltas) so build_deterministic_checkpoint is the answer, and assert no
iteration-2 wrap-up delta is streamed. Surfaced by tinyhumansai#4804's Cargo.toml change
forcing the full coverage suite; the checkpoint-selection logic predates tinyhumansai#4386.
@M3gA-Mind

Copy link
Copy Markdown
Collaborator

Maintainer fix pass (pushed e4b9b76ed):

CI — Rust Core Coverage was RED (and PR CI Gate red as its aggregator). Root cause was a stale, pre-existing test unrelated to this media gate: agent_session_round24_raw_coverage_e2e::max_iteration_checkpoint_uses_deterministic_fallback_and_hooks. It fed the tool-call-cap wrap-up call a non-empty response (tool-call XML text) plus a streamed "checkpoint delta", so summarize_turn_wrapup returned that text as the checkpoint and the deterministic fallback the test is named for never executed — the (1 steps) assertion failed. The checkpoint-selection logic (response.text() non-empty wins → else streamed → else empty→fallback) predates #4386, so the test only fails in the FULL instrumented suite, which this PR triggers via its Cargo.toml change (media feature); it doesn't gate normal main pushes, so the drift went unnoticed.

Fix (tests/raw_coverage/agent_session_round24_raw_coverage_e2e.rs): make the wrap-up genuinely empty (text_response("", None), no stream deltas) so build_deterministic_checkpoint becomes the answer — restoring the path the test name promises. Updated the trailing progress assertion to expect no iteration-2 wrap-up delta (nothing streams now), and refreshed a stale digest-format comment. Robust by construction: an empty summary always routes to the deterministic fallback regardless of stream plumbing. All other assertions (hooks, requests.len()==2, stream_was_requested, tools-disabled, tool count) are unchanged. No production code touched — the media gate itself is untouched.

Review feedback: none outstanding — reviewDecision is unblocked and CodeRabbit's latest review is APPROVED; no open actionable inline comments.

@M3gA-Mind

Copy link
Copy Markdown
Collaborator

Re @chatgpt-codex-connector's P1 "Keep media enabled for the embedded desktop core"already addressed in current HEAD. app/src-tauri/Cargo.toml:143 now forwards the new gate:

openhuman_core = { path = "../..", package = "openhuman", default-features = false, features = ["media"] }

with a comment explaining that default-features = false (from #1061) means each default-ON gate must be forwarded explicitly. This restores media_generate_image / media_generate_video / media_list_models in the shipped desktop build (pnpm dev:app, cargo tauri build, and the E2E desktop build), so the embedded core's tool surface stays byte-identical to pre-gate. Verified the change is purely additive (main's dep forwarded no features), and Rust Feature-Gate Smoke gates off + Rust Tauri Coverage are both green. Good catch — the fix landed before this pass.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@M3gA-Mind M3gA-Mind 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.

Reviewed — CI green and all CodeRabbit/Codex review threads resolved. Approving.

@Coding-Dev-Tools

Copy link
Copy Markdown

🤖 Council Merge Gate — APPROVE (merge failed)

The model council review gate returned APPROVE (session council-53be7bd7-9205-453f-98cc-0bd0dfb0c8fb), so the change is council-cleared.

However, gh pr merge failed with:

GraphQL: Coding-Dev-Tools does not have the correct permissions to execute `MergePullRequest` (mergePullRequest)

The PR is left OPEN for manual investigation.

Posted automatically by the council_gate_merge cron job.

@M3gA-Mind
M3gA-Mind merged commit 2dcaaba into tinyhumansai:main Jul 15, 2026
28 of 30 checks passed
CodeGhost21 added a commit to CodeGhost21/openhuman that referenced this pull request Jul 15, 2026
Conflict in app/src-tauri/Cargo.toml: the media feature gate (tinyhumansai#4804/tinyhumansai#4840)
landed on main and hit the same trap as tinyhumansai#4901 — `default-features = false`
silently dropping a default-ON core gate from the shipped desktop build. It
forwarded `media`; this branch forwards `voice`. Both are required, so the
resolution keeps both rather than either side.

Merged the two comments into one rule ("every default-ON gate must be
forwarded explicitly, a missing gate vanishes silently") and noted that
`tokenjuice-treesitter` is the remaining un-forwarded default (tinyhumansai#4918).

Verified after merge: `cargo tree -e features -i openhuman` resolves both
`feature "media"` and `feature "voice"`; shell `cargo check` green (so the
VOICE_COMPILED_IN assert passes); 212 related Vitest tests pass; fmt clean.
senamakel pushed a commit to M3gA-Mind/openhuman that referenced this pull request Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(core): feature gate — media generation

3 participants