codex-agent-framework 0.1.86__tar.gz → 0.1.88__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/CHANGELOG.md +23 -0
- {codex_agent_framework-0.1.86/codex_agent_framework.egg-info → codex_agent_framework-0.1.88}/PKG-INFO +2 -2
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/App.test.ts +33 -15
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/App.tsx +92 -42
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/api.ts +17 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/components/ChatArea.tsx +47 -121
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/components/Composer.tsx +44 -14
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/store.test.ts +9 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/store.ts +24 -3
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/agent.py +2 -2
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/agent_runtime.py +49 -8
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/ai.py +1 -1
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/realtime/__init__.py +1 -2
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/realtime/bridge.py +4 -37
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/realtime/manager.py +10 -10
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/realtime/session.py +4 -5
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/subagents/__init__.py +6 -5
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/event.py +1 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/server/app.py +12 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/server/core.py +11 -0
- codex_agent_framework-0.1.88/codex_agent/version.py +1 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88/codex_agent_framework.egg-info}/PKG-INFO +2 -2
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent_framework.egg-info/SOURCES.txt +0 -52
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent_framework.egg-info/requires.txt +1 -1
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/pyproject.toml +2 -2
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/setup.py +3 -2
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_realtime.py +61 -3
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_runtime.py +1 -1
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_subagents.py +4 -1
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_server.py +22 -3
- codex_agent_framework-0.1.86/codex_agent/version.py +0 -1
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/LICENSE +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/MANIFEST.in +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/README.md +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/.gitignore +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/README.md +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/eslint.config.js +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/index.html +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/package.json +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/pnpm-lock.yaml +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/public/favicon.svg +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/public/icons.svg +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/public/pandora-logo.png +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/api.test.ts +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/assets/hero.png +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/assets/pandora-logo.png +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/assets/vite.svg +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/components/Chat.tsx +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/components/Header.tsx +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/components/IconButton.tsx +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/components/InteractionModal.tsx +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/components/SettingsPanel.tsx +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/components/ShowRenderer.tsx +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/components/SidePanel.tsx +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/components/Splash.tsx +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/components/StatusBar.tsx +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/components/icons.tsx +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/index.css +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/main.tsx +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/models.test.ts +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/models.ts +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src/vite-env.d.ts +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src-tauri/Cargo.lock +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src-tauri/Cargo.toml +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src-tauri/build.rs +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src-tauri/capabilities/default.json +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src-tauri/gen/schemas/acl-manifests.json +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src-tauri/gen/schemas/capabilities.json +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src-tauri/gen/schemas/desktop-schema.json +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src-tauri/gen/schemas/linux-schema.json +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src-tauri/icons/icon-32.png +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src-tauri/icons/icon.png +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src-tauri/icons/icon.svg +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src-tauri/src/main.rs +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/src-tauri/tauri.conf.json +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/tsconfig.app.json +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/tsconfig.json +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/tsconfig.node.json +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/apps/desktop/vite.config.ts +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/__main__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/browser.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_commands.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/bash/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/bash/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/browser/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/browser/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/content/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/content/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/content/system.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/content/vision.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/context/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/desktop/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/desktop/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/environment/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/environment/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/files/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/files/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/files/tools.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/image_generation/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/image_generation/image_generation_system_prompt.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/image_generation/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/interface/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/interface/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/memory/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/memory/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/planner/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/planner/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/python/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/python/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/realtime/audio.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/realtime/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/scheduler/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/scheduler/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/subagents/profiles/explorer.json +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/subagents/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/tts/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/tts/requirements.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/builtin_plugins/web_search/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/cli/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/cli/headless.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/cli/main.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/cli/output.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/cli/root.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/cli/runner.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/client.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/command.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/config.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/context.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/desktop.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/dock.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/get_text/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/get_text/default_gitignore +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/get_text/get_text.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/get_text/simpler_get_text.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/hooks.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/image.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/interactions.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/latex.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/mainloop.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/message.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/plugin.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/prompts/compaction_prompt.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/prompts/system_prompt.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/provider.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/runtime.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/scheduler.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/scripts/install-system-dependencies.sh +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/server/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/service.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/sessions.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/status.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/stream.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/stream_utils.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/token_counter.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tool.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tray.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tui/__init__.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tui/app.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tui/chat.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tui/lifecycle.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tui/log.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tui/perf.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tui/state.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tui/status_bar.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tui/stream_debug.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tui/style.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tui/transcript.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/tui/widgets.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/utils.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent/worker.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent_framework.egg-info/dependency_links.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent_framework.egg-info/entry_points.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/codex_agent_framework.egg-info/top_level.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/dependencies.txt +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/setup.cfg +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_audio_hooks.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_commands.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_context.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_desktop.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_environment.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_image_generation.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_observe.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_plugins.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_providers_config.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_response.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_sessions.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_tools.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_agent_turns.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_ai.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_browser.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_builtin_config.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_chat.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_cli.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_cli_headless.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_cli_root.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_client.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_events.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_get_text_browser.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_hooks.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_image_message.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_local_desktop.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_memory.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_messages.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_planner.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_scheduler.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_service.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_token_counter.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_tui.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_utils.py +0 -0
- {codex_agent_framework-0.1.86 → codex_agent_framework-0.1.88}/tests/test_worker.py +0 -0
|
@@ -4,6 +4,29 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
This project loosely follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and uses semantic versioning where practical.
|
|
6
6
|
|
|
7
|
+
## [0.1.88] - 2026-07-11
|
|
8
|
+
### Added
|
|
9
|
+
- Add server-managed Realtime Voice v2 sessions, exposed through runtime/server endpoints and a dock microphone control.
|
|
10
|
+
- Share the text agent's context and executable tools with Realtime, and persist final voice transcripts as regular user and assistant messages.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Render dock system activity from explicit events rather than developer messages, including command output, compaction, scheduler, restart, and Realtime notices.
|
|
14
|
+
- Group subagent tool activity under its parent subagent call and simplify dock lifecycle/persistence handling.
|
|
15
|
+
- Require `codex-backend-sdk>=0.3.6` for the current Voice v2 credential surface.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- Fail Realtime startup synchronously and visibly when no eligible OpenAI API key is available, without advertising a transient active session.
|
|
19
|
+
|
|
20
|
+
### Tests
|
|
21
|
+
- Validate the release with the 705-test Python suite, 25 desktop tests, frontend build, Tauri release build, and forced `.deb` reinstall.
|
|
22
|
+
|
|
23
|
+
## [0.1.87] - 2026-07-10
|
|
24
|
+
### Fixed
|
|
25
|
+
- Package desktop dock sources with relative paths so wheels build correctly from source distributions.
|
|
26
|
+
|
|
27
|
+
### Tests
|
|
28
|
+
- Build and install both source and wheel distributions in isolated environments.
|
|
29
|
+
|
|
7
30
|
## [0.1.86] - 2026-07-10
|
|
8
31
|
### Changed
|
|
9
32
|
- Simplify tool schema token accounting around a shared Responses-tool primitive while preserving local and server tool formats.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codex-agent-framework
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.88
|
|
4
4
|
Summary: A lightweight event-driven Codex agent runtime.
|
|
5
5
|
Author: Baptiste
|
|
6
6
|
License-Expression: MIT
|
|
@@ -16,7 +16,7 @@ Description-Content-Type: text/markdown
|
|
|
16
16
|
License-File: LICENSE
|
|
17
17
|
Requires-Dist: audioop-lts; python_version >= "3.13"
|
|
18
18
|
Requires-Dist: beautifulsoup4
|
|
19
|
-
Requires-Dist: codex-backend-sdk>=0.3.
|
|
19
|
+
Requires-Dist: codex-backend-sdk>=0.3.6
|
|
20
20
|
Requires-Dist: fastapi
|
|
21
21
|
Requires-Dist: filetype
|
|
22
22
|
Requires-Dist: modict
|
|
@@ -50,7 +50,7 @@ describe("dock native SSE event handling", () => {
|
|
|
50
50
|
});
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
it("keeps developer messages
|
|
53
|
+
it("keeps developer messages out of the dock transcript", async () => {
|
|
54
54
|
const { handleSSE } = await import("./App");
|
|
55
55
|
|
|
56
56
|
handleSSE({
|
|
@@ -61,10 +61,7 @@ describe("dock native SSE event handling", () => {
|
|
|
61
61
|
},
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
-
expect(useStore.getState().messages[
|
|
65
|
-
role: "developer",
|
|
66
|
-
content: [{ type: "text", text: "Runtime resumed" }],
|
|
67
|
-
});
|
|
64
|
+
expect(useStore.getState().messages).toEqual([]);
|
|
68
65
|
});
|
|
69
66
|
|
|
70
67
|
it("extracts assistant tool calls from native messages", async () => {
|
|
@@ -205,9 +202,13 @@ describe("dock native SSE event handling", () => {
|
|
|
205
202
|
});
|
|
206
203
|
});
|
|
207
204
|
|
|
208
|
-
it("
|
|
205
|
+
it("nests subagent tools without adding top-level chat blocks", async () => {
|
|
209
206
|
const { handleSSE } = await import("./App");
|
|
210
207
|
|
|
208
|
+
handleSSE({
|
|
209
|
+
type: "tool_call_start_event",
|
|
210
|
+
tool_call: { id: "task-1", name: "subagents_run", input: { profile: "explorer" } },
|
|
211
|
+
});
|
|
211
212
|
handleSSE({
|
|
212
213
|
type: "subagent_event",
|
|
213
214
|
subagent: "explorer",
|
|
@@ -217,29 +218,46 @@ describe("dock native SSE event handling", () => {
|
|
|
217
218
|
tool_call: { id: "sub-tool-1", name: "glob", input: { pattern: "**/*" } },
|
|
218
219
|
},
|
|
219
220
|
});
|
|
221
|
+
handleSSE({
|
|
222
|
+
type: "subagent_event",
|
|
223
|
+
subagent: "explorer",
|
|
224
|
+
parent_tool_use_id: "task-1",
|
|
225
|
+
event: {
|
|
226
|
+
type: "tool_call_done_event",
|
|
227
|
+
tool_call: { id: "sub-tool-1" },
|
|
228
|
+
content: "found files",
|
|
229
|
+
},
|
|
230
|
+
});
|
|
220
231
|
|
|
232
|
+
expect(useStore.getState().messages).toHaveLength(1);
|
|
233
|
+
expect(useStore.getState().messages[0].content).toEqual([
|
|
234
|
+
{ type: "tool_use", id: "task-1", name: "subagents_run", input: { profile: "explorer" } },
|
|
235
|
+
]);
|
|
221
236
|
expect(useStore.getState().toolRegistry["sub-tool-1"]).toMatchObject({
|
|
222
237
|
id: "sub-tool-1",
|
|
223
238
|
name: "glob",
|
|
224
239
|
parentId: "task-1",
|
|
225
240
|
subagentChain: ["explorer"],
|
|
226
|
-
done:
|
|
241
|
+
done: true,
|
|
242
|
+
output: "found files",
|
|
227
243
|
});
|
|
228
244
|
});
|
|
229
245
|
|
|
230
|
-
it("
|
|
246
|
+
it("keeps compaction, commands, and scheduler wakes as UI events", async () => {
|
|
231
247
|
const { handleSSE } = await import("./App");
|
|
232
248
|
|
|
233
|
-
handleSSE({ type: "assistant_turn_start_event" });
|
|
234
|
-
expect(useStore.getState()).toMatchObject({ sending: true, agentPhase: "responding" });
|
|
235
|
-
|
|
236
249
|
handleSSE({ type: "compaction_requested_event" });
|
|
237
250
|
expect(useStore.getState().compacting).toBe(true);
|
|
238
|
-
|
|
239
|
-
handleSSE({ type: "assistant_turn_end_event" });
|
|
240
|
-
expect(useStore.getState()).toMatchObject({ sending: false, agentPhase: "idle" });
|
|
241
|
-
|
|
242
251
|
handleSSE({ type: "compaction_completed_event" });
|
|
252
|
+
handleSSE({ type: "slash_command_done_event", name: "compact", result: "done" });
|
|
253
|
+
handleSSE({ type: "wakeup_triggered_event", job: { title: "Night maintenance" } });
|
|
254
|
+
|
|
243
255
|
expect(useStore.getState().compacting).toBe(false);
|
|
256
|
+
expect(useStore.getState().messages).toEqual([]);
|
|
257
|
+
expect(useStore.getState().uiEvents).toMatchObject([
|
|
258
|
+
{ title: "Contexte compacté", level: "success" },
|
|
259
|
+
{ title: "/compact terminée", output: "done", level: "success" },
|
|
260
|
+
{ title: "Night maintenance déclenché", level: "info" },
|
|
261
|
+
]);
|
|
244
262
|
});
|
|
245
263
|
});
|
|
@@ -48,16 +48,15 @@ async function dockRegistrationState(collapsed: boolean): Promise<DesktopState>
|
|
|
48
48
|
return state;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
async function trackWindowGeo() {
|
|
52
|
-
if (!isTauri) return;
|
|
51
|
+
async function trackWindowGeo(): Promise<() => void> {
|
|
52
|
+
if (!isTauri) return () => {};
|
|
53
53
|
const { getCurrentWindow } = await import("@tauri-apps/api/window");
|
|
54
54
|
const win = getCurrentWindow();
|
|
55
55
|
let lastGeo = "";
|
|
56
56
|
|
|
57
|
-
//
|
|
58
|
-
setInterval(async () => {
|
|
59
|
-
|
|
60
|
-
if (collapsed) return;
|
|
57
|
+
// Skip while collapsed so we don't overwrite the expanded size.
|
|
58
|
+
const interval = window.setInterval(async () => {
|
|
59
|
+
if (useStore.getState().collapsed) return;
|
|
61
60
|
try {
|
|
62
61
|
const f = await win.scaleFactor();
|
|
63
62
|
const pos = await win.outerPosition();
|
|
@@ -70,6 +69,7 @@ async function trackWindowGeo() {
|
|
|
70
69
|
if (key !== lastGeo) { lastGeo = key; cacheDockUI(geo); }
|
|
71
70
|
} catch { /* ignore */ }
|
|
72
71
|
}, 2000);
|
|
72
|
+
return () => window.clearInterval(interval);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
|
|
@@ -126,7 +126,11 @@ export function handleSSE(event: SSEEvent, isReplay = false) {
|
|
|
126
126
|
store.setSending(false);
|
|
127
127
|
store.setAgentPhase("idle");
|
|
128
128
|
store.setLastToolName("");
|
|
129
|
-
store.
|
|
129
|
+
store.addUiEvent({
|
|
130
|
+
title: "Tour interrompu par une erreur",
|
|
131
|
+
detail: textFromContent(event.error),
|
|
132
|
+
level: "error",
|
|
133
|
+
});
|
|
130
134
|
break;
|
|
131
135
|
case "assistant_interrupt_requested_event":
|
|
132
136
|
case "assistant_interrupted_event":
|
|
@@ -147,25 +151,44 @@ export function handleSSE(event: SSEEvent, isReplay = false) {
|
|
|
147
151
|
case "interaction_cancelled_event":
|
|
148
152
|
handleInteractionClosed(event);
|
|
149
153
|
break;
|
|
154
|
+
case "realtime_starting_event":
|
|
155
|
+
store.setRealtimeState("starting");
|
|
156
|
+
break;
|
|
157
|
+
case "realtime_started_event":
|
|
158
|
+
store.setRealtimeState("active");
|
|
159
|
+
break;
|
|
160
|
+
case "realtime_stopped_event":
|
|
161
|
+
store.setRealtimeState("stopped");
|
|
162
|
+
break;
|
|
163
|
+
case "realtime_error_event":
|
|
164
|
+
store.setRealtimeState("error");
|
|
165
|
+
store.addUiEvent({
|
|
166
|
+
title: "Session vocale interrompue",
|
|
167
|
+
detail: typeof event.error === "string" ? event.error : undefined,
|
|
168
|
+
level: "error",
|
|
169
|
+
});
|
|
170
|
+
break;
|
|
150
171
|
case "compaction_requested_event":
|
|
151
172
|
store.setCompacting(true);
|
|
152
173
|
break;
|
|
153
174
|
case "compaction_completed_event":
|
|
154
175
|
store.setCompacting(false);
|
|
155
|
-
store.
|
|
176
|
+
store.addUiEvent({ title: "Contexte compacté", level: "success" });
|
|
156
177
|
break;
|
|
157
178
|
case "compaction_failed_event":
|
|
158
179
|
store.setCompacting(false);
|
|
159
|
-
store.
|
|
180
|
+
store.addUiEvent({
|
|
181
|
+
title: "Compaction échouée",
|
|
182
|
+
detail: textFromContent(event.error || event.reason),
|
|
183
|
+
level: "error",
|
|
184
|
+
});
|
|
160
185
|
break;
|
|
161
186
|
case "session_loaded_event": {
|
|
162
187
|
if (typeof event.session_id === "string") store.setSessionId(event.session_id);
|
|
163
188
|
const session = isRecord(event.session) ? event.session : null;
|
|
164
189
|
const messages = Array.isArray(session?.messages) ? session.messages : [];
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
for (const message of messages) handleMessageEvent({ type: "message_added_event", message });
|
|
168
|
-
}
|
|
190
|
+
store.clearMessages();
|
|
191
|
+
for (const message of messages) handleMessageEvent({ type: "message_added_event", message });
|
|
169
192
|
break;
|
|
170
193
|
}
|
|
171
194
|
case "session_deleted_event":
|
|
@@ -177,9 +200,14 @@ export function handleSSE(event: SSEEvent, isReplay = false) {
|
|
|
177
200
|
case "desktop_control_event":
|
|
178
201
|
handleDesktopControl(event);
|
|
179
202
|
break;
|
|
203
|
+
case "wakeup_triggered_event":
|
|
204
|
+
handleWakeupTriggered(event);
|
|
205
|
+
break;
|
|
206
|
+
case "restart_wakeup_event":
|
|
207
|
+
handleRestartWakeup(event);
|
|
208
|
+
break;
|
|
180
209
|
case "audio_playback_event":
|
|
181
210
|
case "wakeup_scheduled_event":
|
|
182
|
-
case "wakeup_triggered_event":
|
|
183
211
|
case "wakeup_cancelled_event":
|
|
184
212
|
break;
|
|
185
213
|
}
|
|
@@ -251,9 +279,8 @@ function handleMessageEvent(event: SSEEvent) {
|
|
|
251
279
|
return;
|
|
252
280
|
}
|
|
253
281
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
: "assistant";
|
|
282
|
+
if (message.role !== "assistant" && message.role !== "user") return;
|
|
283
|
+
const role = message.role;
|
|
257
284
|
const blocks = [
|
|
258
285
|
...blocksFromContent(message.content),
|
|
259
286
|
...blocksFromToolCalls(message.tool_calls),
|
|
@@ -277,7 +304,7 @@ function handleToolCallStart(
|
|
|
277
304
|
const input = toolCallInput(toolCall);
|
|
278
305
|
if (id) {
|
|
279
306
|
useStore.getState().registerToolUse(id, name, input, opts);
|
|
280
|
-
if (!hasDisplayedToolUse(id)) {
|
|
307
|
+
if (!opts?.parentId && !hasDisplayedToolUse(id)) {
|
|
281
308
|
useStore.getState().addMessage({ role: "assistant", content: [{ type: "tool_use", id, name, input }] });
|
|
282
309
|
}
|
|
283
310
|
}
|
|
@@ -285,13 +312,16 @@ function handleToolCallStart(
|
|
|
285
312
|
useStore.getState().setLastToolName(name);
|
|
286
313
|
}
|
|
287
314
|
|
|
288
|
-
function handleToolCallDone(
|
|
315
|
+
function handleToolCallDone(
|
|
316
|
+
event: SSEEvent,
|
|
317
|
+
opts?: { parentId?: string },
|
|
318
|
+
) {
|
|
289
319
|
const toolCall = toolCallData(event);
|
|
290
320
|
const id = stringField(toolCall, "id") || stringField(toolCall, "call_id") || stringField(event, "call_id");
|
|
291
321
|
const output = textFromContent(event.content ?? event.result ?? objectField(toolCall, "output"));
|
|
292
322
|
const isError = Boolean(event.is_error) || output.startsWith("<error>");
|
|
293
323
|
if (id) useStore.getState().resolveToolResult(id, isError, output);
|
|
294
|
-
if (!id || !hasDisplayedToolResult(id)) {
|
|
324
|
+
if (!opts?.parentId && (!id || !hasDisplayedToolResult(id))) {
|
|
295
325
|
useStore.getState().addMessage({
|
|
296
326
|
role: "assistant",
|
|
297
327
|
content: [{ type: "tool_result", tool_use_id: id, output, is_error: isError }],
|
|
@@ -330,10 +360,27 @@ function handleInteractionClosed(event: SSEEvent) {
|
|
|
330
360
|
}
|
|
331
361
|
|
|
332
362
|
function handleSlashCommandDone(event: SSEEvent) {
|
|
333
|
-
useStore.getState()
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
363
|
+
const store = useStore.getState();
|
|
364
|
+
store.setSending(false);
|
|
365
|
+
store.setAgentPhase("idle");
|
|
366
|
+
const name = stringField(event, "name");
|
|
367
|
+
const output = textFromContent(event.result || event.error);
|
|
368
|
+
store.addUiEvent({
|
|
369
|
+
title: event.error ? `/${name || "command"} échouée` : `/${name || "command"} terminée`,
|
|
370
|
+
output: output || undefined,
|
|
371
|
+
level: event.error ? "error" : "success",
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function handleWakeupTriggered(event: SSEEvent) {
|
|
376
|
+
const job = objectField(event, "job");
|
|
377
|
+
const title = stringField(job, "title") || "Wakeup scheduler";
|
|
378
|
+
useStore.getState().addUiEvent({ title: `${title} déclenché`, level: "info" });
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function handleRestartWakeup(event: SSEEvent) {
|
|
382
|
+
const title = stringField(event, "title") || "Wakeup post-restart";
|
|
383
|
+
useStore.getState().addUiEvent({ title: `${title} déclenché`, level: "info" });
|
|
337
384
|
}
|
|
338
385
|
|
|
339
386
|
function handleSubAgentEvent(event: SSEEvent) {
|
|
@@ -346,9 +393,7 @@ function handleSubAgentEvent(event: SSEEvent) {
|
|
|
346
393
|
if (innerEvent.type === "tool_call_start_event") {
|
|
347
394
|
handleToolCallStart(innerEvent, { parentId, subagentChain: chain });
|
|
348
395
|
} else if (innerEvent.type === "tool_call_done_event") {
|
|
349
|
-
handleToolCallDone(innerEvent);
|
|
350
|
-
} else if (innerEvent.type === "message_added_event") {
|
|
351
|
-
handleMessageEvent(innerEvent);
|
|
396
|
+
handleToolCallDone(innerEvent, { parentId });
|
|
352
397
|
}
|
|
353
398
|
}
|
|
354
399
|
|
|
@@ -511,9 +556,18 @@ export default function App() {
|
|
|
511
556
|
const headerHeight = useStore((s) => s.headerHeight);
|
|
512
557
|
const composerHeight = useStore((s) => s.composerHeight);
|
|
513
558
|
|
|
514
|
-
// Restore window position/size on mount, then track changes
|
|
559
|
+
// Restore window position/size on mount, then track changes.
|
|
515
560
|
useEffect(() => {
|
|
516
|
-
|
|
561
|
+
let disposed = false;
|
|
562
|
+
let stop = () => {};
|
|
563
|
+
trackWindowGeo().then((cleanup) => {
|
|
564
|
+
if (disposed) cleanup();
|
|
565
|
+
else stop = cleanup;
|
|
566
|
+
});
|
|
567
|
+
return () => {
|
|
568
|
+
disposed = true;
|
|
569
|
+
stop();
|
|
570
|
+
};
|
|
517
571
|
}, []);
|
|
518
572
|
// Zoom: read from cache instantly, persist to server file
|
|
519
573
|
const [zoom, setZoom] = useState(() => getCachedDockUI().zoom || 1.0);
|
|
@@ -648,26 +702,22 @@ export default function App() {
|
|
|
648
702
|
};
|
|
649
703
|
}, [setConnected]);
|
|
650
704
|
|
|
651
|
-
// Register the
|
|
652
|
-
|
|
705
|
+
// Register the dock like the TUI: the server uses its PID to discard stale state.
|
|
706
|
+
const dockPidRef = useRef<number | undefined>(undefined);
|
|
653
707
|
useEffect(() => {
|
|
654
|
-
dockRegistrationState(collapsed).then(registerDesktop).catch(() => {});
|
|
655
|
-
}, [collapsed]);
|
|
656
|
-
|
|
657
|
-
useEffect(() => {
|
|
658
|
-
if (!isTauri) return;
|
|
659
|
-
let pid: number | undefined;
|
|
660
708
|
dockRegistrationState(collapsed)
|
|
661
709
|
.then((state) => {
|
|
662
|
-
|
|
710
|
+
dockPidRef.current = state.pid ?? undefined;
|
|
663
711
|
return registerDesktop(state);
|
|
664
712
|
})
|
|
665
713
|
.catch(() => {});
|
|
666
|
-
|
|
667
|
-
|
|
714
|
+
}, [collapsed]);
|
|
715
|
+
useEffect(() => {
|
|
716
|
+
const unregister = () => { unregisterDesktop(dockPidRef.current).catch(() => {}); };
|
|
717
|
+
window.addEventListener("beforeunload", unregister);
|
|
668
718
|
return () => {
|
|
669
|
-
window.removeEventListener("beforeunload",
|
|
670
|
-
|
|
719
|
+
window.removeEventListener("beforeunload", unregister);
|
|
720
|
+
unregister();
|
|
671
721
|
};
|
|
672
722
|
}, []);
|
|
673
723
|
|
|
@@ -42,6 +42,10 @@ const SSE_EVENT_TYPES = [
|
|
|
42
42
|
"interaction_requested_event",
|
|
43
43
|
"interaction_resolved_event",
|
|
44
44
|
"interaction_cancelled_event",
|
|
45
|
+
"realtime_starting_event",
|
|
46
|
+
"realtime_started_event",
|
|
47
|
+
"realtime_stopped_event",
|
|
48
|
+
"realtime_error_event",
|
|
45
49
|
"compaction_requested_event",
|
|
46
50
|
"compaction_completed_event",
|
|
47
51
|
"compaction_failed_event",
|
|
@@ -53,6 +57,7 @@ const SSE_EVENT_TYPES = [
|
|
|
53
57
|
"wakeup_scheduled_event",
|
|
54
58
|
"wakeup_triggered_event",
|
|
55
59
|
"wakeup_cancelled_event",
|
|
60
|
+
"restart_wakeup_event",
|
|
56
61
|
];
|
|
57
62
|
|
|
58
63
|
function parseSSEMessage(event: MessageEvent, fallbackType?: string): SSEEvent | null {
|
|
@@ -206,6 +211,18 @@ export const loadPlugin = (name: string, kind = "auto") => post<unknown>(`/plugi
|
|
|
206
211
|
export const unloadPlugin = (name: string) => post<unknown>(`/plugins/${encodeURIComponent(name)}/unload`);
|
|
207
212
|
export const reloadPlugin = (name: string) => post<unknown>(`/plugins/${encodeURIComponent(name)}/reload`);
|
|
208
213
|
|
|
214
|
+
export interface RealtimeStatus {
|
|
215
|
+
active: boolean;
|
|
216
|
+
state: "stopped" | "starting" | "active" | "stopping" | "error";
|
|
217
|
+
loaded?: boolean;
|
|
218
|
+
session_id?: string;
|
|
219
|
+
error?: string;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export const getRealtimeStatus = () => get<RealtimeStatus>("/realtime");
|
|
223
|
+
export const startRealtimeVoice = () => post<RealtimeStatus>("/realtime/start");
|
|
224
|
+
export const stopRealtimeVoice = () => post<RealtimeStatus>("/realtime/stop");
|
|
225
|
+
|
|
209
226
|
export interface AccountInfo {
|
|
210
227
|
authenticated?: boolean;
|
|
211
228
|
id?: string;
|