Skip to content

feat(voice): add in-tree lifecycle hooks#5552

Draft
MADPANDA3D wants to merge 1 commit into
odysseus-dev:devfrom
MADPANDA3D:codex/upstream-voice-static-hooks
Draft

feat(voice): add in-tree lifecycle hooks#5552
MADPANDA3D wants to merge 1 commit into
odysseus-dev:devfrom
MADPANDA3D:codex/upstream-voice-static-hooks

Conversation

@MADPANDA3D

Copy link
Copy Markdown

Summary

Adds a small core-owned browser contract for in-tree voice experiments: a hidden app-owned mount, bounded versioned lifecycle signals for capture/chat/TTS, and a fixed same-origin module map for the existing recorder and TTS modules. This does not add a Voice Orb UI, runtime discovery, arbitrary script loading, a plugin wheel, or an external compatibility promise.

Target branch

  • This PR targets dev, not main.

Linked Issue

Part of #5549. Related to #4118 and the direction discussion #4439.

Type of Change

  • Bug fix (non-breaking — fixes a confirmed issue)
  • New feature (non-breaking — adds new behaviour)
  • Breaking change (changes or removes existing behaviour)
  • Refactor / cleanup (behaviour unchanged)
  • Documentation only
  • CI / tooling / configuration

Checklist

  • I searched open issues and pull requests; no existing foreground/lifecycle seam duplicates this proposal.
  • This PR targets dev.
  • Changes are limited to the app-owned voice lifecycle/static contract and its direct recorder/chat/TTS wiring.
  • I ran the app from this branch with an isolated temporary data directory and verified the contract in headless Chromium with zero page errors.

How to Test

  1. Run node tests/voice_lifecycle.test.mjs. It exercises fail-closed payload validation, the fixed module allowlist, recorder-unavailable signaling, and TTS start/idle signaling.
  2. Run python -m pytest -q tests/test_voice_lifecycle_hooks.py tests/test_app_static_mime.py.
  3. Start uvicorn app:app, load /, and import /static/js/voiceLifecycle.js from DevTools. Confirm getVoiceSurfaceRoot() returns the hidden app-owned root, listVoiceStaticModules() returns only recorder and tts, and an emitted event has the frozen v1 payload.

Local validation also ran node --check on every changed JavaScript module, git diff --check, direct HTTP readback of the app shell/module, and a headless Chromium page load with no page errors. The full Python suite produced 4,618 passes, 4 skips, and four failures; an untouched c80462e worktree reproduced the exact same four failures with 4,615 passes. Three failures are caused by the reused virtualenv path containing spaces, and one is the existing order-sensitive src.agent_tools.admin_tools import-state failure.

Visual / UI changes

The only HTML change is an empty hidden mount with aria-hidden="true"; it has no visible rendering, CSS, spacing, mobile, or interaction change. Headless Chromium confirmed the root remained hidden and the page raised no JavaScript errors.

  • Screenshot or short clip attached — no visible pixels change because the mount is empty and hidden.
  • Style match — no new visual styling or component values.
  • No new component pattern — this is a lifecycle/static host seam only.
  • I am not an LLM agent submitting a bulk PR — this contribution is coding-agent assisted, disclosed in Proposal: bounded in-tree host seams for voice and UI composition #5549, and intentionally split from the other independent seams.

@github-actions github-actions Bot added the ready for review Description complete — ready for maintainer review label Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for review Description complete — ready for maintainer review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant