local-operator 0.45.2__tar.gz → 0.45.4__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.
- {local_operator-0.45.2 → local_operator-0.45.4}/PKG-INFO +1 -1
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/compaction/api.py +16 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/compaction/pass_.py +26 -4
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/compaction/pruning.py +58 -1
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/compaction/thresholds.py +170 -3
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/compaction/tokens.py +297 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/incidents.py +22 -2
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/model/discovery.py +193 -6
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/model/registry.py +61 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/controller.py +30 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/failover.py +72 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/frontend_state.py +7 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/session.py +503 -7
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/settings_io.py +33 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/app.py +8 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/model_picker.py +58 -7
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/settings_view.py +1 -1
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator.egg-info/PKG-INFO +1 -1
- {local_operator-0.45.2 → local_operator-0.45.4}/pyproject.toml +1 -1
- {local_operator-0.45.2 → local_operator-0.45.4}/LICENSE +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/README.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/agent_profiles.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/agent_seeds/architect.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/agent_seeds/coder.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/agent_seeds/designer.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/agent_seeds/manager.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/agent_seeds/reviewer.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/agent_seeds/scout.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/agents.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/analytics/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/analytics/model.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/analytics/recorder.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/analytics/store.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/ansi.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/bootstrap.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/browser_bridge/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/browser_bridge/backend.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/browser_bridge/daemon.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/browser_bridge/gen_ts.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/browser_bridge/install.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/browser_bridge/protocol.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/browser_bridge/state.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/callback_page.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/cli.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/cli_style.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/clients/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/clients/_http.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/clients/fal.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/clients/google_client.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/clients/ollama.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/clients/openrouter.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/clients/radient.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/clients/serpapi.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/clients/tavily.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/clipboard.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/compaction/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/compaction/advisor.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/compaction/cutpoint.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/compaction/marker.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/compaction/png.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/compaction/snapcompact.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/config.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/config_watch.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/console.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/context_files.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/credentials.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/env.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/adapters/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/adapters/api.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/adapters/discovery.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/adapters/rpc.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/adapters/supervisor.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/adapters/worker.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/evidence/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/evidence/media.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/evidence/models.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/evidence/store.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/evidence/verify.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/lifecycle.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/protocol.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/receipts.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/runner/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/runner/durable_root.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/runner/episode.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/runner/guards.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/runner/host_secrets.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/runner/model.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/runner/provider_client.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/runner/rescue_sweep.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/runner/responder.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/runner/route_ids.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/evaluation/runner/secrets.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/exec_mode.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/exec_worker.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/fork.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/guides/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/guides/agents/GUIDE.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/guides/browser/GUIDE.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/guides/configuration/GUIDE.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/guides/discovery.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/guides/extensions/GUIDE.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/guides/failover/GUIDE.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/guides/mcp/GUIDE.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/guides/mobile/GUIDE.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/guides/peer-messaging/GUIDE.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/guides/teams/GUIDE.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/harness/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/harness/approval.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/harness/comms.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/harness/intent.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/harness/jobs.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/harness/loop.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/harness/subagent.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/harness/types.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/harness/wake.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/headless_print.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/helpers.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/imaging.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/jobs.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/jsonl.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/logger.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mcp/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mcp/auth.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mcp/config.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mcp/manager.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mcp/resources.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mcp/tool_bridge.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mcp/tool_cache.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/media.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/attach_client.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/auth.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/child.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/command_reservation.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/daemon.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/durable.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/install.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/owned.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/peer_client.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/peer_send.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/projection.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/registrant.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/registry.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/resources.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/seen.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/service.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/static/mark.png +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/tui_handle.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/types.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/dist/assets/index-CuRNCaFt.css +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/dist/assets/index-DkiusxCg.js +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/dist/index.html +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/dist/mark.png +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/index.html +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/package.json +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/pnpm-lock.yaml +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/pnpm-workspace.yaml +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/public/mark.png +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/scripts/generate-theme-css.mjs +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/scripts/inline-mark.mjs +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/scripts/palette-source.mjs +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/agent-view.interaction.test.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/agent-view.test.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/api.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/app.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/agents-sheet.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/composer.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/markdown.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/model-sheet.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/pending-card.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/row-boundary.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/spinner.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/subagents-panel.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/todos-panel.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/tool-row.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/transcript.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/ui/button.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/ui/chip.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/ui/disclosure.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/ui/sheet.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/components/working-line.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/continuation-command.test.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/continuation-command.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/detail-loader.test.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/detail-loader.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/lib/cn.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/lib/format.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/lib/mark.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/main.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/past-sessions.fork.test.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/private-storage.test.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/private-storage.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/router.test.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/router.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/screens/agent-view.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/screens/new-session.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/screens/past-sessions.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/screens/session-list.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/screens/session-view.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/session-list.unread.test.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/session-view.pending.test.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/session-view.seen.test.tsx +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/store.test.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/store.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/store.unread.test.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/styles/index.css +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/styles/themes.generated.css +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/test-setup.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/theme.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/alucard.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/ayu-light.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/ayu-mirage.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/ayu.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/catppuccin-frappe.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/catppuccin-macchiato.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/dracula.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/dune.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/duskfox.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/everforest-light.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/everforest.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/gruvbox-light.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/iceberg.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/kanagawa-lotus.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/kanagawa-wave.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/local-operator.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/monokai.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/neon.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/nightfox.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/obsidian.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/one-light.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/palenight.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/palette-contract.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/radient.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/rose-pine.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/sage.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/synth.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/tokyo-night-day.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/themes/tokyo-night.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/src/types.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/tsconfig.app.json +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/tsconfig.json +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/tsconfig.node.json +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/mobile/web/vite.config.ts +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/model/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/model/catalogue.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/model/configure.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/model/defaults.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/model/effort.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/model/effort_classifier.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/model/ids.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/model/naming.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/model/prices.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/multiplexer/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/multiplexer/broadcast.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/multiplexer/cmux.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/multiplexer/markers.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/multiplexer/registry.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/multiplexer/types.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/optional.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/org_chart.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/paths.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/proc.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/prompts_api.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/prompts_md/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/prompts_md/compaction_summary.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/prompts_md/edit_file_instructions.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/prompts_md/system.md +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/auth_cli.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/auth_store.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/clients.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/login_defaults.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/oauth/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/oauth/anthropic.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/oauth/callback_server.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/oauth/device_code.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/oauth/kimi.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/oauth/openai.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/oauth/pkce.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/oauth/qwencloud.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/oauth/radient.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/oauth/xai.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/oauth/zai.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/registry.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/usage.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/providers/usage_cache.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/reexec.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/resume.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/scheduler_service.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/app.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/dependencies.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/generate_openapi.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/models/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/models/schemas.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/openapi.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/agents.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/chat.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/config.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/credentials.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/health.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/jobs.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/models.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/schedules.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/speech.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/sse.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/static.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/transcription.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/routes/websockets.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/utils/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/utils/attachment_utils.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/utils/event_broker.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/utils/job_processor_queue.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/utils/operator.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/utils/speech_utils.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/utils/sse.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/utils/sse_publisher.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/server/utils/websocket_manager.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/attachments.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/goal.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/mcp_status.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/naming.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/peer.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/protocol.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/remote.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/retention.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/runtime/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/runtime/control.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/runtime/owned.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/runtime/process.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/runtime/registry.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/runtime/server.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/runtime/types.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/search_index.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session/transcript.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session_factory.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/session_lease.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/skills/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/skills/api.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/skills/discovery.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/skills/embeddings.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/skills/index.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/skills/invoke.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/skills/protocol.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/skills/vectors.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/spawn/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/spawn/apple.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/spawn/cmux.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/spawn/fallback.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/spawn/ghostty.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/spawn/kitty.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/spawn/policy.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/spawn/registry.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/spawn/types.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/spawn/wezterm.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/stream.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/teams.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/terminals.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tools/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tools/agent_tool.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tools/builtin.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tools/eval.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tools/eval_worker.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tools/group_reaper.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tools/lsp.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tools/registry.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tools/spill.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tools/team_tool.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/animation.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/autocomplete.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/bindings.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/copy_targets.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/costs.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/events.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/glyphs.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/images.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/local_operator.tcss +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/markdown_theme.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/notify.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/org_layout.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/org_render.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/palettes/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/palettes/classics.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/palettes/companions.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/palettes/lights.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/palettes/modern.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/palettes/nature.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/palettes/neon.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/palettes/radient.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/palettes/rose_pine.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/settings.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/shimmer.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/terminal_title.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/theme.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/_copy_markdown.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/analytics_panel.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/approval.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/aside_panel.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/ask_picker.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/assistant.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/command_picker.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/copy_picker.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/editor.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/image_block.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/key_prompt.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/org_chart_view.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/overlay.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/session_picker.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/status_line.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/subagent_panel.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/subagent_view.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/toast.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/todo_panel.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/tool_card.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/transcript.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/usage_panel.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/wake_panel.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/tui/widgets/welcome.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/types.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/update.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/variables.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/wakes/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/wakes/install.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/wakes/store.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/web_fetch/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/web_fetch/cli.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/web_fetch/models.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/web_fetch/render.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/web_fetch/service.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/web_fetch/tool.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/web_search/__init__.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/web_search/cli.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/web_search/models.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/web_search/providers.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/web_search/service.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator/web_search/tool.py +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator.egg-info/SOURCES.txt +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator.egg-info/dependency_links.txt +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator.egg-info/entry_points.txt +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator.egg-info/requires.txt +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/local_operator.egg-info/top_level.txt +0 -0
- {local_operator-0.45.2 → local_operator-0.45.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: local-operator
|
|
3
|
-
Version: 0.45.
|
|
3
|
+
Version: 0.45.4
|
|
4
4
|
Summary: A team of proactive AI assistants that can work together behind the scenes to help you get mundane tasks done so you can focus on the fun stuff.
|
|
5
5
|
Author-email: Damian Tran <damian@gominerva.com>
|
|
6
6
|
License: MIT License
|
|
@@ -50,16 +50,23 @@ from .pruning import (
|
|
|
50
50
|
_is_useless,
|
|
51
51
|
compute_suffix_tokens,
|
|
52
52
|
prune_tool_outputs,
|
|
53
|
+
shed_frames_to_wire_budget,
|
|
53
54
|
)
|
|
54
55
|
from .thresholds import (
|
|
56
|
+
DEFAULT_WIRE_BYTES_BUDGET,
|
|
57
|
+
DEFAULT_WIRE_BYTES_TRIGGER,
|
|
55
58
|
RECOVERY_BAND,
|
|
59
|
+
WIRE_RECOVERY_BAND,
|
|
56
60
|
CompactionSettings,
|
|
57
61
|
cleared_headroom,
|
|
62
|
+
cleared_wire_headroom,
|
|
58
63
|
compaction_context_tokens,
|
|
59
64
|
effective_reserve_tokens,
|
|
60
65
|
resolve_advisor_floor_tokens,
|
|
61
66
|
resolve_strategy,
|
|
62
67
|
resolve_threshold_tokens,
|
|
68
|
+
resolve_wire_bytes_budget,
|
|
69
|
+
resolve_wire_bytes_trigger,
|
|
63
70
|
should_compact,
|
|
64
71
|
)
|
|
65
72
|
from .tokens import (
|
|
@@ -69,6 +76,7 @@ from .tokens import (
|
|
|
69
76
|
clear_estimate_cache,
|
|
70
77
|
estimate_messages_tokens,
|
|
71
78
|
estimate_tokens,
|
|
79
|
+
estimate_wire_bytes,
|
|
72
80
|
history_chars,
|
|
73
81
|
invalidate_message_cache,
|
|
74
82
|
messages_tokens_upper_bound,
|
|
@@ -87,6 +95,9 @@ __all__ = [
|
|
|
87
95
|
"MIN_PRUNE_TOKENS",
|
|
88
96
|
"PRESERVED_USER_TURN_KEY",
|
|
89
97
|
"RECOVERY_BAND",
|
|
98
|
+
"WIRE_RECOVERY_BAND",
|
|
99
|
+
"DEFAULT_WIRE_BYTES_BUDGET",
|
|
100
|
+
"DEFAULT_WIRE_BYTES_TRIGGER",
|
|
90
101
|
"SUMMARIZATION_SYSTEM_PROMPT",
|
|
91
102
|
"SUPERSEDED_NOTICE",
|
|
92
103
|
"TOOL_ARGS_MAX_CHARS",
|
|
@@ -96,11 +107,13 @@ __all__ = [
|
|
|
96
107
|
"build_compaction_prompt",
|
|
97
108
|
"clear_estimate_cache",
|
|
98
109
|
"cleared_headroom",
|
|
110
|
+
"cleared_wire_headroom",
|
|
99
111
|
"compaction_context_tokens",
|
|
100
112
|
"compute_suffix_tokens",
|
|
101
113
|
"effective_reserve_tokens",
|
|
102
114
|
"estimate_messages_tokens",
|
|
103
115
|
"estimate_tokens",
|
|
116
|
+
"estimate_wire_bytes",
|
|
104
117
|
"extract_file_ops_from_messages",
|
|
105
118
|
"extract_preserved_user_turns",
|
|
106
119
|
"find_cut_point",
|
|
@@ -112,11 +125,14 @@ __all__ = [
|
|
|
112
125
|
"parse_hint",
|
|
113
126
|
"prepare_partitions",
|
|
114
127
|
"prune_tool_outputs",
|
|
128
|
+
"shed_frames_to_wire_budget",
|
|
115
129
|
"register_invalidator",
|
|
116
130
|
"render_file_operations",
|
|
117
131
|
"resolve_advisor_floor_tokens",
|
|
118
132
|
"resolve_strategy",
|
|
119
133
|
"resolve_threshold_tokens",
|
|
134
|
+
"resolve_wire_bytes_budget",
|
|
135
|
+
"resolve_wire_bytes_trigger",
|
|
120
136
|
"serialize_conversation",
|
|
121
137
|
"should_compact",
|
|
122
138
|
"summarize_messages",
|
|
@@ -39,14 +39,15 @@ from .marker import (
|
|
|
39
39
|
build_compaction_marker,
|
|
40
40
|
render_compaction_marker,
|
|
41
41
|
)
|
|
42
|
-
from .pruning import prune_stale_frames, prune_tool_outputs
|
|
42
|
+
from .pruning import prune_stale_frames, prune_tool_outputs, shed_frames_to_wire_budget
|
|
43
43
|
from .thresholds import (
|
|
44
44
|
CompactionSettings,
|
|
45
45
|
compaction_context_tokens,
|
|
46
46
|
resolve_strategy,
|
|
47
|
+
resolve_wire_bytes_budget,
|
|
47
48
|
should_compact,
|
|
48
49
|
)
|
|
49
|
-
from .tokens import estimate_messages_tokens
|
|
50
|
+
from .tokens import estimate_messages_tokens, estimate_wire_bytes
|
|
50
51
|
|
|
51
52
|
logger = logging.getLogger(__name__)
|
|
52
53
|
|
|
@@ -152,11 +153,32 @@ async def run_compaction_pass(
|
|
|
152
153
|
working, frames_dropped = prune_stale_frames(
|
|
153
154
|
working, keep_recent_frames=settings.keep_recent_frames
|
|
154
155
|
)
|
|
156
|
+
else:
|
|
157
|
+
# (2b) Byte shed, for the surface that did NOT opt in. A session is
|
|
158
|
+
# not statically one kind or the other — the session this guard was
|
|
159
|
+
# written for was an ordinary chat for hundreds of turns and then
|
|
160
|
+
# started driving a browser, without any config changing — so the
|
|
161
|
+
# honest discriminator is the observed byte pressure, not a static
|
|
162
|
+
# per-surface guess. Under budget this is one cheap scan that changes
|
|
163
|
+
# nothing; over budget the alternative is a request the provider
|
|
164
|
+
# refuses outright, taking every frame with it.
|
|
165
|
+
working, frames_dropped = shed_frames_to_wire_budget(
|
|
166
|
+
working, budget=resolve_wire_bytes_budget(settings)
|
|
167
|
+
)
|
|
155
168
|
|
|
156
|
-
# (3) Trigger through the single resolver.
|
|
169
|
+
# (3) Trigger through the single resolver. Bytes go in as a second input
|
|
170
|
+
# to the SAME resolver rather than as a second predicate: an image-heavy
|
|
171
|
+
# history can be far under every token threshold and still be too large to
|
|
172
|
+
# send, and two functions free to disagree about when a pass is due is the
|
|
173
|
+
# drift this package forbids.
|
|
157
174
|
local_estimate = estimate_messages_tokens(working)
|
|
158
175
|
tokens_before = compaction_context_tokens(provider_context_tokens, local_estimate)
|
|
159
|
-
if respect_threshold and not should_compact(
|
|
176
|
+
if respect_threshold and not should_compact(
|
|
177
|
+
tokens_before,
|
|
178
|
+
model.context_window,
|
|
179
|
+
settings,
|
|
180
|
+
wire_bytes=estimate_wire_bytes(working),
|
|
181
|
+
):
|
|
160
182
|
return _refused(
|
|
161
183
|
working,
|
|
162
184
|
"below-threshold",
|
|
@@ -40,7 +40,7 @@ from typing import Any, Sequence
|
|
|
40
40
|
from local_operator.harness.types import Content, ImageContent, Message, TextContent
|
|
41
41
|
|
|
42
42
|
from .marker import marker_exists
|
|
43
|
-
from .tokens import estimate_tokens, invalidate_message_cache
|
|
43
|
+
from .tokens import estimate_tokens, estimate_wire_bytes, invalidate_message_cache
|
|
44
44
|
|
|
45
45
|
__all__ = [
|
|
46
46
|
"MIN_PRUNE_TOKENS",
|
|
@@ -52,6 +52,7 @@ __all__ = [
|
|
|
52
52
|
"count_stale_observations",
|
|
53
53
|
"prune_stale_frames",
|
|
54
54
|
"prune_tool_outputs",
|
|
55
|
+
"shed_frames_to_wire_budget",
|
|
55
56
|
"shed_stale_frames",
|
|
56
57
|
]
|
|
57
58
|
|
|
@@ -157,6 +158,62 @@ def prune_stale_frames(
|
|
|
157
158
|
return out, dropped
|
|
158
159
|
|
|
159
160
|
|
|
161
|
+
def shed_frames_to_wire_budget(
|
|
162
|
+
messages: Sequence[Message], *, budget: int
|
|
163
|
+
) -> tuple[list[Message], int]:
|
|
164
|
+
"""Replace the OLDEST frames with notices until the request fits ``budget``
|
|
165
|
+
bytes, keeping as many recent frames as possible.
|
|
166
|
+
|
|
167
|
+
The last-resort transport guard. Ordinary compaction decides what to keep
|
|
168
|
+
by *context* value; this decides by whether the provider will accept the
|
|
169
|
+
request at all, which is a different and strictly narrower question — so
|
|
170
|
+
it engages only when the payload is already over a ceiling set below the
|
|
171
|
+
provider's cap, and does nothing at all below it. The early return is not
|
|
172
|
+
an optimisation detail: it is the guarantee that every session under
|
|
173
|
+
budget behaves byte-identically to one without this function.
|
|
174
|
+
|
|
175
|
+
Built on :func:`prune_stale_frames` rather than as a second
|
|
176
|
+
frame-dropping primitive, so there is ONE definition of "which frames are
|
|
177
|
+
recent" and one set of copy/identity semantics. That also means no message
|
|
178
|
+
is ever removed — user/assistant alternation and tool pairings survive
|
|
179
|
+
untouched, which a transport guard running on arbitrary history must
|
|
180
|
+
guarantee, since it cannot know what is mid-tool-call.
|
|
181
|
+
|
|
182
|
+
The loop mirrors ``_shed_stale_turns`` in the evaluation runner's provider
|
|
183
|
+
client: walk the keep count DOWN and stop when a step frees nothing.
|
|
184
|
+
Termination is structural — ``keep`` strictly decreases toward 0, and
|
|
185
|
+
``keep=0`` drops every image there is — so a payload still over budget
|
|
186
|
+
with no images left exits rather than spinning. That residual case is
|
|
187
|
+
real: a text-only history cannot be shed here, and the caller must be
|
|
188
|
+
prepared for "still over" rather than assuming success (this is what the
|
|
189
|
+
byte-side auto-continue band checks).
|
|
190
|
+
|
|
191
|
+
Sheds the FEWEST frames that fit, not a fixed count, because every frame
|
|
192
|
+
dropped is evidence the user may still need. Returns ``(messages,
|
|
193
|
+
frames_dropped)``; ``frames_dropped`` is 0 and the input list is returned
|
|
194
|
+
unchanged when nothing was over budget.
|
|
195
|
+
"""
|
|
196
|
+
if budget <= 0:
|
|
197
|
+
return list(messages), 0
|
|
198
|
+
if estimate_wire_bytes(messages) <= budget:
|
|
199
|
+
return list(messages), 0
|
|
200
|
+
|
|
201
|
+
keep = count_frame_messages(messages)
|
|
202
|
+
working = list(messages)
|
|
203
|
+
dropped = 0
|
|
204
|
+
while keep > 0:
|
|
205
|
+
keep -= 1
|
|
206
|
+
candidate, candidate_dropped = prune_stale_frames(messages, keep_recent_frames=keep)
|
|
207
|
+
if candidate_dropped <= dropped:
|
|
208
|
+
# This step freed nothing new; another turn of the loop cannot
|
|
209
|
+
# either, since the keep count only shrinks.
|
|
210
|
+
break
|
|
211
|
+
working, dropped = candidate, candidate_dropped
|
|
212
|
+
if estimate_wire_bytes(working) <= budget:
|
|
213
|
+
break
|
|
214
|
+
return working, dropped
|
|
215
|
+
|
|
216
|
+
|
|
160
217
|
def compute_suffix_tokens(messages: Sequence[Message]) -> list[int]:
|
|
161
218
|
"""Per-index sum of estimated tokens of all messages strictly AFTER it.
|
|
162
219
|
|
|
@@ -30,9 +30,15 @@ __all__ = [
|
|
|
30
30
|
"DEFAULT_RESERVE_TOKENS",
|
|
31
31
|
"DEFAULT_THRESHOLD_PERCENT",
|
|
32
32
|
"DEFAULT_THRESHOLD_TOKENS",
|
|
33
|
+
"DEFAULT_WIRE_BYTES_BUDGET",
|
|
34
|
+
"DEFAULT_WIRE_BYTES_TRIGGER",
|
|
33
35
|
"CompactionSettings",
|
|
34
36
|
"RECOVERY_BAND",
|
|
37
|
+
"WIRE_RECOVERY_BAND",
|
|
35
38
|
"cleared_headroom",
|
|
39
|
+
"cleared_wire_headroom",
|
|
40
|
+
"resolve_wire_bytes_budget",
|
|
41
|
+
"resolve_wire_bytes_trigger",
|
|
36
42
|
"compaction_context_tokens",
|
|
37
43
|
"effective_reserve_tokens",
|
|
38
44
|
"resolve_advisor_floor_tokens",
|
|
@@ -58,6 +64,28 @@ DEFAULT_THRESHOLD_PERCENT = 0.80
|
|
|
58
64
|
#: when that is a small fraction of a very large window.
|
|
59
65
|
DEFAULT_THRESHOLD_TOKENS = 600_000
|
|
60
66
|
|
|
67
|
+
#: HARD ceiling on the serialized request, in bytes — the number the render
|
|
68
|
+
#: seam sheds frames to satisfy. NOT a token figure; see
|
|
69
|
+
#: :func:`~.tokens.estimate_wire_bytes` for why the two rulers stay apart.
|
|
70
|
+
#:
|
|
71
|
+
#: 24 MB is Anthropic's 32 MB Messages-API cap minus 25% headroom for the
|
|
72
|
+
#: system prompt, the tool schemas, the ~2.2% JSON envelope, and the growth
|
|
73
|
+
#: the NEXT request adds before another guard runs.
|
|
74
|
+
#:
|
|
75
|
+
#: Calibrated against real traffic rather than guessed: a scan of all **4,738
|
|
76
|
+
#: sessions** in a production session store found exactly **one** above 24 MB
|
|
77
|
+
#: (the session that wedged on HTTP 413), two above 16 MB, ten above 8 MB, and
|
|
78
|
+
#: none above 32 MB. So this budget sheds nothing that works today — it fires
|
|
79
|
+
#: only on the shape that was already failing outright.
|
|
80
|
+
DEFAULT_WIRE_BYTES_BUDGET = 24_000_000
|
|
81
|
+
|
|
82
|
+
#: SOFT trigger: fires a real compaction pass (with a summary) well before the
|
|
83
|
+
#: hard budget forces amputation. ~2/3 of the hard budget, which on the
|
|
84
|
+
#: measured store is above every session but the three largest — the point is
|
|
85
|
+
#: that a screenshot-heavy session compacts *properly and early* instead of
|
|
86
|
+
#: surviving by shedding frames at the wall.
|
|
87
|
+
DEFAULT_WIRE_BYTES_TRIGGER = 16_000_000
|
|
88
|
+
|
|
61
89
|
|
|
62
90
|
class CompactionSettings(BaseModel):
|
|
63
91
|
"""Compaction knobs, mirrored from ``config.yml`` ``values.compaction.*``.
|
|
@@ -123,6 +151,16 @@ class CompactionSettings(BaseModel):
|
|
|
123
151
|
# at $262. So the knob is opt-in per surface, and ``None`` means the frame
|
|
124
152
|
# prune is not even consulted — ``run_compaction_pass`` with the defaults
|
|
125
153
|
# is byte-identical to a pass without it, which a test pins.
|
|
154
|
+
#
|
|
155
|
+
# EXTENDED, not reversed: ``None`` now means "never prune frames for
|
|
156
|
+
# size-of-CONTEXT reasons", and a byte shed engages underneath it when the
|
|
157
|
+
# request would otherwise be REFUSED outright (``wire_bytes_budget``). The
|
|
158
|
+
# argument above assumes pruning frames costs the user content for no
|
|
159
|
+
# forced reason, which is exactly right up to the wall; at the wall the
|
|
160
|
+
# alternative is not "keep every frame", it is losing the whole session —
|
|
161
|
+
# a session that 413s loses all 42 frames, while the shed keeps 28. The
|
|
162
|
+
# default and the distinct-attachments reasoning are both untouched, and a
|
|
163
|
+
# session under budget still performs no work here at all.
|
|
126
164
|
keep_recent_frames: int | None = Field(
|
|
127
165
|
default=None,
|
|
128
166
|
description=(
|
|
@@ -133,6 +171,36 @@ class CompactionSettings(BaseModel):
|
|
|
133
171
|
),
|
|
134
172
|
)
|
|
135
173
|
|
|
174
|
+
# --- Transport size budget (BYTES, not tokens) --------------------------
|
|
175
|
+
#
|
|
176
|
+
# These two are the only knobs in this model measured in bytes, and the
|
|
177
|
+
# separation is deliberate: the token thresholds above answer "how much of
|
|
178
|
+
# the context WINDOW is occupied", these answer "will the HTTP request be
|
|
179
|
+
# accepted". A screenshot-heavy session can sit at 15% of a 1M window and
|
|
180
|
+
# still be over a provider's request cap, because a flat per-image token
|
|
181
|
+
# charge (correct for billing) is blind to base64 length. Never compare a
|
|
182
|
+
# value here against a token figure.
|
|
183
|
+
#
|
|
184
|
+
# Registered in ``settings_io.SETTINGS`` so an operator on a provider with
|
|
185
|
+
# a different cap can move them without editing code.
|
|
186
|
+
wire_bytes_budget: int = Field(
|
|
187
|
+
default=DEFAULT_WIRE_BYTES_BUDGET,
|
|
188
|
+
description=(
|
|
189
|
+
"Hard ceiling on the serialized request in BYTES. Older screenshots"
|
|
190
|
+
" are shed from the rendered history (never from the transcript) to"
|
|
191
|
+
" stay under it. Non-positive disables the shed."
|
|
192
|
+
),
|
|
193
|
+
)
|
|
194
|
+
wire_bytes_trigger: int = Field(
|
|
195
|
+
default=DEFAULT_WIRE_BYTES_TRIGGER,
|
|
196
|
+
description=(
|
|
197
|
+
"Soft trigger in BYTES: a compaction pass fires once the serialized"
|
|
198
|
+
" request passes this, so a screenshot-heavy session summarises"
|
|
199
|
+
" early instead of shedding frames at the hard budget."
|
|
200
|
+
" Non-positive disables the byte trigger."
|
|
201
|
+
),
|
|
202
|
+
)
|
|
203
|
+
|
|
136
204
|
# --- Speculative compaction advisor (BETA, off by default) -------------
|
|
137
205
|
#
|
|
138
206
|
# Every field below is optional with an inert default, so a config written
|
|
@@ -386,6 +454,7 @@ def should_compact(
|
|
|
386
454
|
settings: CompactionSettings,
|
|
387
455
|
*,
|
|
388
456
|
advisory_ok: bool = False,
|
|
457
|
+
wire_bytes: int = 0,
|
|
389
458
|
) -> bool:
|
|
390
459
|
"""Whether the current context exceeds the compaction threshold.
|
|
391
460
|
|
|
@@ -411,15 +480,79 @@ def should_compact(
|
|
|
411
480
|
the disabled/off short-circuit — is untouched, so a future reader citing
|
|
412
481
|
this as precedent should carry those constraints too.
|
|
413
482
|
|
|
414
|
-
|
|
415
|
-
|
|
483
|
+
``wire_bytes`` is the second input with that posture, and it is here for
|
|
484
|
+
the same reason ``advisory_ok`` is: it is a different QUESTION about the
|
|
485
|
+
same decision ("will the request be accepted?" beside "does the context
|
|
486
|
+
fit the window?"), and a separate ``should_compact_for_size()`` beside
|
|
487
|
+
this one would be exactly the trigger drift the module docstring forbids.
|
|
488
|
+
So it is OR-ed into the one resolved answer, where it can only pull the
|
|
489
|
+
trigger EARLIER.
|
|
490
|
+
|
|
491
|
+
The byte term is what makes an image-heavy session compact at all. Its
|
|
492
|
+
token estimate is honest and small — 42 screenshots read as 154,690
|
|
493
|
+
tokens, 15.5% of a 1M window — while the serialized request is 34 MB,
|
|
494
|
+
past the provider's cap. No token threshold can see that, because the
|
|
495
|
+
per-image token charge is flat by design (see
|
|
496
|
+
:func:`~.tokens.estimate_wire_bytes`).
|
|
497
|
+
|
|
498
|
+
Monotonicity is preserved in BOTH numeric arguments, which the session's
|
|
499
|
+
cheap upper-bound pre-gate depends on: raising either can only turn a
|
|
500
|
+
``False`` into a ``True``. Bytes are exact and cheap, so the pre-gate can
|
|
501
|
+
pass the real figure rather than a bound.
|
|
502
|
+
|
|
503
|
+
With ``advisory_ok`` false and ``wire_bytes`` 0 (their defaults, and what
|
|
504
|
+
every caller but the plan gate passes) the function is byte-identical to
|
|
505
|
+
its previous form.
|
|
416
506
|
"""
|
|
417
507
|
if not settings.enabled or settings.strategy == "off" or window_tokens <= 0:
|
|
418
508
|
return False
|
|
419
509
|
threshold = resolve_threshold_tokens(window_tokens, settings)
|
|
420
510
|
if advisory_ok and getattr(settings, "advisor_enabled", False):
|
|
421
511
|
threshold = min(threshold, resolve_advisor_floor_tokens(window_tokens, settings))
|
|
422
|
-
|
|
512
|
+
if context_tokens > threshold:
|
|
513
|
+
return True
|
|
514
|
+
byte_trigger = resolve_wire_bytes_trigger(settings)
|
|
515
|
+
return byte_trigger > 0 and wire_bytes > byte_trigger
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
def resolve_wire_bytes_budget(settings: CompactionSettings) -> int:
|
|
519
|
+
"""THE hard byte ceiling, resolved in one place.
|
|
520
|
+
|
|
521
|
+
Same discipline as :func:`resolve_threshold_tokens`: one resolver, no
|
|
522
|
+
caller re-deriving the number from the settings model. A non-positive
|
|
523
|
+
value means "no byte ceiling" and is returned as ``0`` so every caller can
|
|
524
|
+
test it the same way; a garbage value falls back to the default rather
|
|
525
|
+
than disabling the guard silently, because a typo here is the difference
|
|
526
|
+
between a session that recovers and one that 413s forever.
|
|
527
|
+
"""
|
|
528
|
+
raw = getattr(settings, "wire_bytes_budget", DEFAULT_WIRE_BYTES_BUDGET)
|
|
529
|
+
try:
|
|
530
|
+
value = int(raw)
|
|
531
|
+
except (TypeError, ValueError):
|
|
532
|
+
logger.warning("compaction.wire_bytes_budget is not an integer; using the default")
|
|
533
|
+
return DEFAULT_WIRE_BYTES_BUDGET
|
|
534
|
+
return value if value > 0 else 0
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
def resolve_wire_bytes_trigger(settings: CompactionSettings) -> int:
|
|
538
|
+
"""THE soft byte trigger, resolved in one place.
|
|
539
|
+
|
|
540
|
+
Clamped to the hard budget: a trigger ABOVE the ceiling would mean the
|
|
541
|
+
render seam amputates frames before a proper compaction pass ever fires,
|
|
542
|
+
which inverts the whole design — the soft trigger exists so the session
|
|
543
|
+
summarises with a model call instead of surviving by amputation. Returns
|
|
544
|
+
``0`` when the byte trigger is disabled.
|
|
545
|
+
"""
|
|
546
|
+
raw = getattr(settings, "wire_bytes_trigger", DEFAULT_WIRE_BYTES_TRIGGER)
|
|
547
|
+
try:
|
|
548
|
+
value = int(raw)
|
|
549
|
+
except (TypeError, ValueError):
|
|
550
|
+
logger.warning("compaction.wire_bytes_trigger is not an integer; using the default")
|
|
551
|
+
value = DEFAULT_WIRE_BYTES_TRIGGER
|
|
552
|
+
if value <= 0:
|
|
553
|
+
return 0
|
|
554
|
+
budget = resolve_wire_bytes_budget(settings)
|
|
555
|
+
return min(value, budget) if budget > 0 else value
|
|
423
556
|
|
|
424
557
|
|
|
425
558
|
def compaction_context_tokens(provider_reported: int | None, local_estimate: int) -> int:
|
|
@@ -452,6 +585,40 @@ def cleared_headroom(residual_tokens: int, threshold_tokens: int) -> int:
|
|
|
452
585
|
return threshold_tokens - residual_tokens
|
|
453
586
|
|
|
454
587
|
|
|
588
|
+
#: The byte-side twin of :data:`RECOVERY_BAND`, and it exists because that
|
|
589
|
+
#: constant CANNOT cover the byte trigger. ``RECOVERY_BAND`` is defined on
|
|
590
|
+
#: tokens against the token threshold; a pass fired by byte pressure can leave
|
|
591
|
+
#: the token residual comfortably inside the token band while the request is
|
|
592
|
+
#: still over the byte budget — the token side would then say "headroom
|
|
593
|
+
#: created", schedule an auto-continue, and the next turn would fire the byte
|
|
594
|
+
#: trigger again on a context nothing had shrunk. That is precisely the live
|
|
595
|
+
#: dead-loop ``RECOVERY_BAND`` was added for, arrived at through the new
|
|
596
|
+
#: trigger, so the guard has to be restated in the new trigger's own units.
|
|
597
|
+
#:
|
|
598
|
+
#: Same 0.8 ratio, same meaning: a pass counts as having created byte headroom
|
|
599
|
+
#: only when the residual request lands at or below ``0.8 x`` the soft byte
|
|
600
|
+
#: trigger.
|
|
601
|
+
WIRE_RECOVERY_BAND = 0.8
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
def cleared_wire_headroom(residual_bytes: int, settings: CompactionSettings) -> bool:
|
|
605
|
+
"""Whether a pass created real BYTE headroom, for the auto-continue gate.
|
|
606
|
+
|
|
607
|
+
Returns ``True`` when the byte trigger is disabled, so a session that
|
|
608
|
+
never opted into byte pressure keeps exactly the token-only behaviour it
|
|
609
|
+
has today — this must not become a second veto on ordinary text sessions.
|
|
610
|
+
|
|
611
|
+
Otherwise the residual must sit at or below
|
|
612
|
+
``WIRE_RECOVERY_BAND * trigger``. A pass that shaved a screenshot or two
|
|
613
|
+
and is still near the trigger has NOT recovered, and scheduling a
|
|
614
|
+
continuation on it re-enters the same pass next turn.
|
|
615
|
+
"""
|
|
616
|
+
trigger = resolve_wire_bytes_trigger(settings)
|
|
617
|
+
if trigger <= 0:
|
|
618
|
+
return True
|
|
619
|
+
return residual_bytes <= WIRE_RECOVERY_BAND * trigger
|
|
620
|
+
|
|
621
|
+
|
|
455
622
|
def resolve_strategy(
|
|
456
623
|
settings: CompactionSettings, model: Any
|
|
457
624
|
) -> Literal["context-full", "snapcompact"]:
|