monkeybot 3.0.2__tar.gz → 3.0.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.
- {monkeybot-3.0.2 → monkeybot-3.0.4}/.github/workflows/ci.yml +1 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/CHANGELOG.md +27 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/PKG-INFO +8 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/README.md +7 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/skills/monkeybot/SKILL.md +3 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/skills/monkeybot/references/config-sections.md +1 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/chat_local_shell.py +7 -43
- monkeybot-3.0.4/cli/src/monkeybot_cli/commands/run_cmd.py +197 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/extras_catalog.py +2 -1
- monkeybot-3.0.4/cli/src/monkeybot_cli/process_tree.py +44 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/providers.py +11 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold.py +1 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/env.example +4 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/monkeybot.example.yaml +13 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_chat_local_shell.py +16 -15
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_extras_catalog.py +5 -0
- monkeybot-3.0.4/cli/tests/test_run_cmd.py +277 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_scaffold.py +1 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/features.md +27 -2
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/sse-gateway-ui.md +2 -2
- {monkeybot-3.0.2 → monkeybot-3.0.4}/pyproject.toml +1 -1
- monkeybot-3.0.4/src/monkeybot/computer/__init__.py +116 -0
- monkeybot-3.0.4/src/monkeybot/computer/approvals.py +194 -0
- monkeybot-3.0.4/src/monkeybot/computer/permissions.py +220 -0
- monkeybot-3.0.4/src/monkeybot/computer/safety.py +683 -0
- monkeybot-3.0.4/src/monkeybot/computer/tools.py +406 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/attachments/store.py +16 -6
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/bootstrap.py +7 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/config/runtime_env.py +2 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/config/settings.py +17 -5
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/config/validation.py +8 -12
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/context/__init__.py +12 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/__init__.py +2 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/config.py +15 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/layout.py +23 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/llm/usage.py +18 -2
- monkeybot-3.0.4/src/monkeybot/core/path_safety.py +82 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/backends.py +3 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/firestore.indexes.json +8 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/firestore.py +47 -16
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/history.py +56 -18
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/postgres.py +64 -24
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/sqlite.py +7 -2
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/transcript.py +22 -7
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/usage.py +47 -16
- monkeybot-3.0.4/src/monkeybot/core/persistence/usage_buckets.py +77 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/loop_usage.py +6 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/realtime_loop.py +174 -99
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/tool_batch.py +23 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/tool_dispatch.py +40 -19
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/turn_loop.py +64 -9
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/subagents/subagent_worker.py +3 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/core_tool_executor.py +15 -2
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/permission.py +68 -4
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/sandbox_executor.py +21 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/spill_inventory.py +115 -28
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/workspace_service.py +17 -0
- monkeybot-3.0.4/src/monkeybot/gateway/pending_response_bus.py +8 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/realtime/app.py +2 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/realtime/deps.py +3 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/realtime/routes.py +22 -2
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/realtime/session.py +14 -6
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/sse/app.py +52 -19
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/sse/loop_port.py +4 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/sse/models.py +23 -2
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/sse/routes.py +38 -21
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/sse/session_bus.py +32 -18
- monkeybot-3.0.4/src/monkeybot/providers/_bedrock_converse.py +604 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/_openai_compat.py +327 -27
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/_utils.py +94 -26
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/bedrock.py +64 -4
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/model_capabilities.py +22 -11
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/ollama.py +86 -16
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/pricing.py +13 -4
- monkeybot-3.0.4/tests/computer/test_approvals.py +191 -0
- monkeybot-3.0.4/tests/computer/test_computer_tools.py +317 -0
- monkeybot-3.0.4/tests/computer/test_package_init.py +72 -0
- monkeybot-3.0.4/tests/computer/test_path_policy.py +368 -0
- monkeybot-3.0.4/tests/computer/test_permissions.py +342 -0
- monkeybot-3.0.4/tests/computer/test_subagent_exclusion.py +34 -0
- monkeybot-3.0.4/tests/computer/test_wiring.py +174 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_agent_layout.py +42 -1
- monkeybot-3.0.4/tests/core/test_attachment_store.py +43 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_config_extensions.py +22 -0
- monkeybot-3.0.4/tests/core/test_firestore_usage.py +72 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_history.py +40 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_config.py +23 -19
- monkeybot-3.0.4/tests/core/test_layout.py +47 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_loop.py +353 -0
- monkeybot-3.0.4/tests/core/test_path_safety.py +59 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_permission.py +99 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_realtime_loop.py +245 -28
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_runtime_env.py +23 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_sandbox_executor.py +47 -0
- monkeybot-3.0.4/tests/core/test_spill_inventory.py +248 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_transcript.py +12 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_usage.py +109 -3
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_workspace_symlinks.py +53 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/sse/test_create_session_model.py +2 -2
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/sse/test_routes.py +41 -2
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/sse/test_session_bus.py +16 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/sse/test_transcript_wiring.py +1 -1
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/test_pending_response_endpoints.py +45 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/test_resolve_provider.py +30 -2
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_anthropic_cache.py +9 -9
- monkeybot-3.0.4/tests/providers/test_bedrock_converse.py +605 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_model_capabilities.py +7 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_ollama.py +102 -0
- monkeybot-3.0.4/tests/providers/test_openai_compat_usage.py +1195 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_pricing.py +8 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_sampling.py +4 -4
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_sonnet5_sampling.py +78 -0
- monkeybot-3.0.4/tests/web_search/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/uv.lock +1 -1
- monkeybot-3.0.2/cli/src/monkeybot_cli/commands/run_cmd.py +0 -63
- monkeybot-3.0.2/cli/tests/test_run_cmd.py +0 -90
- monkeybot-3.0.2/src/monkeybot/core/path_safety.py +0 -11
- monkeybot-3.0.2/tests/core/test_spill_inventory.py +0 -81
- monkeybot-3.0.2/tests/providers/test_openai_compat_usage.py +0 -514
- {monkeybot-3.0.2 → monkeybot-3.0.4}/.dockerignore +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/.github/workflows/live-eval-smoke.yml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/.github/workflows/prepare-release.yml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/.github/workflows/publish-release.yml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/.gitignore +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/.pre-commit-config.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/BACKLOG.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/CONTRIBUTING.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/LICENSE +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/pyproject.toml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/chat_file_index.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/chat_renderer.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/chat_session.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/chat_status_bar.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/chat_theme.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/chat_tool_display.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/chat_tui.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/chat_tui_widgets.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/commands/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/commands/chat.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/commands/doctor.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/commands/loop.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/commands/new.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/commands/refresh.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/commands/talk.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/commands/validate.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/compat.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/config_resolve.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/exit_commands.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/gateway_health.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/main.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/opensandbox_lifecycle.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/output.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/realtime/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/realtime/audio_io.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/realtime/client.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/realtime/gateway_manager.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/realtime/push_to_talk.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/realtime/session.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/realtime/session_controller.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/realtime/talk_ui.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/realtime/wire_encode.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/runtime_python.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/AGENT.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/Dockerfile +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/browser/SKILL.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/command_allowlist.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/dockerignore +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/image-generator/SKILL.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/image-generator/generate_image.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/loop/SKILL.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/mcp.json +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/opensandbox.docker.toml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/otel-collector.example.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/permissions.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/session_controller.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/terminal_markdown.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_chat_continue.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_chat_e2e.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_chat_errors.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_chat_file_index.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_chat_grounding.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_chat_renderer_parity.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_chat_session.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_chat_status_bar.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_chat_theme.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_chat_tool_display.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_chat_tui.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_cli.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_config_resolve.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_doctor.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_gateway_health.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_opensandbox_lifecycle.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_realtime_session_controller.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_runtime_python.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/tests/test_terminal_markdown.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/cli/uv.lock +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docker/Dockerfile +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docker/docker-compose.sandbox.yml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docker/opensandbox.docker.toml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docker/sandbox.Dockerfile +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docker-compose.yml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/agent-layout.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/assets/logo.png +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/browser-mcp.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/cloud-deployment-design.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/deploy-aws-agentcore.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/deploy-pattern-a-container.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/deploy-pattern-b-serverless.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/deploy-pattern-c-agent-platform.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/deploy-pattern-d-realtime.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/getting-started.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/knowledge-layer-fixes.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/live-evals.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/mcp.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/memory-graph-split-plan.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/migrations/agent-scope-namespacing.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/migrations/memory-outbox.sql +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/observability-runbook.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/otel-collector.example.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/progressive-loop-tools.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/progressive-mcp-tools.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/skills.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/spill-dynamic-design.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/docs/workspace-index-design.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/TEST_COVERAGE.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/assertions.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/diff.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/eval_config.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/models.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/persistence.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/report.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/runner.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenario_loader.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/context/summarization_trigger.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/mcp/get_prompt.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/mcp/list_resources.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/mcp/tool_invoke.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/memory/recall_cross_session.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/memory/recall_single_session.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/multi_turn/task_tracking.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/skills/skill_invocation.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/subagents/dispatch_complete.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/tools/core_read.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/tools/core_read_error.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/tools/core_run_command.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/tools/core_run_command_sandbox.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scenarios/tools/core_write.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/scorer.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/smoke_agent/.env.example +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/smoke_agent/.gitignore +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/smoke_agent/fixture_mcp_server.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/smoke_agent/monkeybot_config/AGENT.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/smoke_agent/monkeybot_config/command_allowlist.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/smoke_agent/monkeybot_config/mcp.json +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/smoke_agent/monkeybot_config/monkeybot.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/smoke_agent/monkeybot_config/permissions.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/smoke_agent/pyproject.toml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/smoke_agent/skills/browser/SKILL.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/smoke_agent/uv.lock +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/smoke_agent/workspace/.gitkeep +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/smoke_agent/workspace/skills/browser/playbooks/.gitkeep +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/suites/smoke.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/test_assertions.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/test_diff.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/test_judge.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/test_report.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/test_runner_sse.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/evals/test_scorer.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/README.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/agentcore/handler.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/agentcore/runtime_app.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/agentengine/handler.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/cloud-functions/main.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/lambda/handler.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/skills/browser/SKILL.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/skills/browser/playbooks/.gitkeep +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/skills/diagnostics/README.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/skills/diagnostics/SKILL.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/skills/diagnostics/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/skills/diagnostics/diagnostics.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/skills/image-generator/SKILL.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/examples/skills/image-generator/generate_image.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/pyproject.toml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/scripts/agentcore_smoke.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/src/browser_mcp/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/src/browser_mcp/agentcore.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/src/browser_mcp/assets/NOTICE.md +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/src/browser_mcp/assets/dom_tree.js +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/src/browser_mcp/assets/pa_driver.js +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/src/browser_mcp/dom_indexing.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/src/browser_mcp/playbooks.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/src/browser_mcp/playwright_helpers.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/src/browser_mcp/screenshots.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/src/browser_mcp/server.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/tests/test_agentcore.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/tests/test_dom_indexing.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/tests/test_in_app_cdp.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/tests/test_indexed_tools.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/tests/test_playbooks.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/tests/test_playwright_helpers.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/tests/test_screenshots.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/tests/test_server_shutdown.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/integrations/browser-mcp/uv.lock +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/pytest.ini +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/scripts/create_schema.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/scripts/precommit-pytest.sh +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/scripts/release.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/scripts/smoke_global_cli.sh +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/cli/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/cli/__main__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/cli/audio_io.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/cli/gateway_manager.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/cli/main.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/cli/push_to_talk.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/cli/realtime_client.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/attachments/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/attachments/catalog.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/attachments/config.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/attachments/freeze.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/attachments/resolve.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/attachments/text.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/attachments/tools.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/config/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/config/realtime_config.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/config/yaml_loader.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/context/campaign_context.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/context/common.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/context/epoch.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/context/tool_output_policy.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/context/tool_result_ingress.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/context/tool_shapers.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/hooks/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/captions.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/chunking.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/embeddings/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/embeddings/base.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/embeddings/factory.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/embeddings/gemini.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/embeddings/nvidia.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/embeddings/openai_compat.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/embeddings/sanitize.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/evidence_guard.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/extractors.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/fusion.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/hook.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/indexer.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/links.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/salience.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/sqlite_index.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/subsystem.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/tool.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/knowledge/types.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/llm/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/llm/provider.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/llm/realtime_provider.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/lockfile_names.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/logging_utils.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/mcp/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/mcp/mcp_client.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/mcp/ports_mcp.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/memory/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/memory/config.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/memory/hook.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/memory/ids.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/memory/ingest.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/memory/migrate_layout.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/memory/observability.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/memory/outbox.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/memory/palace.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/memory/subsystem.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/memory/uri.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/memory/writer.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/messages/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/messages/convert_provider.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/messages/tool_integrity.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/messages/transform_context.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/db.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/durable_runs.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/errors.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/firestore_scheduled_loops.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/runs.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/scheduled_loops.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/session_turn_locks.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/sqlite_backend.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/sqlite_vector.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/thread_summary.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/persistence/transcript_analyzer.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/prompts/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/prompts/harness_prompt.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/prompts/headings.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/prompts/prompt.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/context_budget.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/doom_loop.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/events.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/history_compaction.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/input_admission.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/loop.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/loop_hooks.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/loop_messages.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/loop_ports.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/provider_stream_mapper.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/runtime/utterance_buffer.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/subagents/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/subagents/progress_publish.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/subagents/subagent_proto.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/subagents/worker_pool.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/testing/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/testing/mocks_provider.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/testing/mocks_realtime_provider.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/fs_isolation.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/inspector.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/loop_inspector.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/patch.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/terminal.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/text_normalize.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/tool_hint.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/tool_kind.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/tools/types.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/types/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/types/content_blocks.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/types/interfaces.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/types/types_tools.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/workspace/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/workspace/factory.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/workspace/gcs.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/workspace/local.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/workspace/protocol.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/workspace/s3.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/core/workspace_layout.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/bootstrap.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/main.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/realtime/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/realtime/errors.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/realtime/guardrails.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/realtime/manager.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/realtime/metrics.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/realtime/wire.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/realtime_main.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/sse/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/sse/reply_body.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/sse/scheduler_routes.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/sse/scheduler_wiring.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/sse/sse.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/gateway/sse/workspace_layout.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/observability/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/observability/_state.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/observability/instrumentation.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/observability/propagation.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/observability/spans.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/observability/sqlite_exporter.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/claude.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/gemini.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/gemini_live.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/huggingface.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/nvidia.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/openai.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/openrouter.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/sampling.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/providers/vertex_claude.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/scaffold/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/scheduler/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/scheduler/__main__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/scheduler/engine.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/scheduler/http_invoker.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/scheduler/interval.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/scheduler/tick_result.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/scheduler/worker.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/subagents/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/subagents/worker/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/subagents/worker/__main__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/todo_list/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/todo_list/store.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/todo_list/tool.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/web_search/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/web_search/backends/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/web_search/backends/duckduckgo.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/web_search/backends/firecrawl.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/web_search/backends/tavily.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/web_search/protocol.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/src/monkeybot/web_search/tool.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/acceptance/test_observability_acceptance.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/cli/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/cli/test_gateway_manager.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/cli/test_main.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/cli/test_push_to_talk.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/cli/test_realtime_client.py +0 -0
- {monkeybot-3.0.2/tests/gateway/realtime → monkeybot-3.0.4/tests/computer}/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/conftest.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/fixtures/bitbucket_dc_style_pr.diff +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/memory/helpers.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/memory/in_memory_palace.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/memory/test_mempalace.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/memory/test_review_fixes.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_attachment_freeze.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_bootstrap.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_content_blocks.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_context.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_context_budget.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_context_epoch.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_core_tool_executor.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_doom_loop.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_durable_events.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_durable_runs.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_empty_completion.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_events.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_evidence_guard.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_firestore_history.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_firestore_scheduled_loops.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_fs_isolation.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_gemini_history_replay.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_harness_prompt.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_history_compaction_split.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_hooks.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_input_admission.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_inspector.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_chunking.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_chunking_rank.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_embeddings.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_fts.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_fusion.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_fusion_ann.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_hook.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_indexer.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_links.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_media.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_salience.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_single_writer.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_subsystem.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_knowledge_vectors.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_logging_utils.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_loop_hooks.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_loop_observability.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_loop_transcript.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_mcp_client.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_memory_layout_migrate.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_message_pipeline.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_mocks_realtime_provider.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_patch.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_pricing.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_progress_publish.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_prompt.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_provider_contract.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_provider_stream_mapper.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_replace_fuzzy.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_run_command_parse.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_runs.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_scheduled_loops.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_session_turn_locks.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_settlement.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_spill_dynamic.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_storage_backends.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_subagent_proto.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_subagent_trace_propagation.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_subagent_worker_paths.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_terminal.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_thread_summary_wire.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_tool_def_schema.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_tool_integrity.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_tool_result_ingress.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_tool_shapers.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_transcript_analyzer.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_truncated_tool_batch.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_usage_migration.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_utterance_buffer.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_worker_pool.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_workspace_layout.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/test_workspace_write_scope.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/workspace/test_factory.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/workspace/test_local_storage.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/core/workspace/test_protocol_contract.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/eval_hook.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenario_runner.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/context_curation.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/memory_write_inject.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/subagent_roundtrip.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/tool_glob_grep.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/tool_load_file.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/tool_loops.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/tool_read.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/tool_replace_apply_patch.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/tool_run_command.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/tool_search_knowledge.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/tool_search_memory.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/tool_todo_list.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/tool_web_search.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/tool_write.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/scenarios/turn_completion.yaml +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/test_agent_behavior.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/evals/test_memory_knowledge_routing.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/__init__.py +0 -0
- {monkeybot-3.0.2/tests/web_search → monkeybot-3.0.4/tests/gateway/realtime}/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/realtime/test_app.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/realtime/test_deps.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/realtime/test_guardrails.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/realtime/test_manager.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/realtime/test_metrics.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/realtime/test_routes_client_text.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/realtime/test_session.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/realtime/test_wire.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/sse/test_attachments.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/sse/test_scheduler_routes.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/test_otel_fastapi.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/test_otel_lifespan.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/test_realtime_main.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/test_sse_events.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/gateway/test_subagent_event_publisher.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/integration/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/integration/test_mb_e2e_simple_reply.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/integration/test_observability_integration.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/integration/test_prompt_caching_integration.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/observability/conftest.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/observability/test_init.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/observability/test_instrumentation.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/observability/test_loop_hook_spans.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/observability/test_propagation.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/observability/test_span_contract.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/observability/test_spans.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/observability/test_sqlite_exporter.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/observability/test_truncate.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/observability/test_turn_complete_trace.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/conftest.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_anthropic_history.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_bedrock_estimate.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_gemini_live.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_gemini_usage.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_huggingface.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_nvidia.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_openai_history.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_safe_parse_tool_args.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_source_grep_gates.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/providers/test_vertex_claude_history.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/scheduler/test_engine.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/scheduler/test_interval.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/skills/__init__.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/skills/test_generate_image_script.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/test_cold_start.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/test_packaging_config.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/test_release_script.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/todo_list/test_todo_list.py +0 -0
- {monkeybot-3.0.2 → monkeybot-3.0.4}/tests/web_search/test_web_search.py +0 -0
|
@@ -19,7 +19,7 @@ jobs:
|
|
|
19
19
|
version: "latest"
|
|
20
20
|
|
|
21
21
|
- name: Sync dependencies
|
|
22
|
-
run: uv sync --extra claude --extra vertex-claude --extra bedrock
|
|
22
|
+
run: uv sync --extra claude --extra vertex-claude --extra bedrock --extra firestore
|
|
23
23
|
|
|
24
24
|
- name: Mypy
|
|
25
25
|
run: uv run mypy src/monkeybot
|
|
@@ -6,6 +6,30 @@ the project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
### CLI
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- CLI extras catalog / `monkeybot new` provider menu lists `ollama-cloud` and `ollama-local` instead of a single `ollama` row. `--with ollama` and `--provider ollama` still work.
|
|
14
|
+
|
|
15
|
+
## [core v3.0.4] - 2026-08-28
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Explicit `ollama-cloud` and `ollama-local` provider ids so Cloud always hits `https://ollama.com` even when a leftover local `OLLAMA_BASE_URL` is set. Legacy `ollama` still auto-routes from env.
|
|
20
|
+
|
|
21
|
+
## [core v3.0.3] - 2026-08-23
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Local computer control: nine opt-in, macOS-only `computer_*` tools (`computer/`) let the agent open/reveal files and folders, launch apps, open URLs, read/write the clipboard, and list/find/move/trash files under the user's home directory. Off by default (`computer.enabled: false` / `MONKEYBOT_COMPUTER_TOOLS`); intended for the Monkeybot desktop app, never a server deployment. Every call asks for approval by default via a built-in ruleset baseline (not `permissions.yaml`, which is fail-open); "Always allow" is scoped to the exact `(tool, resource)` approved and persists durably to `monkeybot_config/approvals.json` (a new machine-written file — never hand-edit). Hard security limits (home-directory confinement, credential-path denylist, exec-surface refusal on `open`, trash-not-delete) live in the tool bodies and cannot be bypassed by permission rules. See `docs/features.md` §22.
|
|
26
|
+
- `permissions.yaml`'s `tool-confirmations` approval now supports a durable `persist` hook (`remember_always_approval(..., persist=...)`) in addition to the existing in-session `SessionApprovals` cache; `resource_for_call` gained `url`/`app` argument lookups for readable permission resource strings on tools with no `path` arg.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Anthropic SDK 1.0 removed `temperature` / `top_p` / `top_k` from `messages.stream()`. Filter stream kwargs to the callable signature and retry `TypeError: unexpected keyword argument` so Claude/Bedrock streams no longer die before the request.
|
|
31
|
+
- Stop during a tool confirmation sets the turn cancel Event in `POST /cancel` (and on realtime interrupt) before pending futures are cancelled, so completed tool results settle into history instead of racing a 50ms poller. Session DELETE and websocket teardown leave the Event unset and propagate cancellation. Spill writes refuse an uncontained `_` symlink fallback; transcript and attachment dirs reuse a safe pre-sanitization folder when it still exists on disk. Attachment reads also reject symlinked attachment ids that resolve outside the workspace.
|
|
32
|
+
|
|
9
33
|
## [core v3.0.2] - 2026-08-18
|
|
10
34
|
|
|
11
35
|
### Fixed
|
|
@@ -37,6 +61,9 @@ the project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
37
61
|
|
|
38
62
|
### Fixed
|
|
39
63
|
|
|
64
|
+
- Stop during a tool confirmation now settles completed tool results into history (and synthesizes cancel envelopes for the rest) instead of escaping before abort settlement; the realtime confirm path does the same. Cancel after a finished provider stream also persists already-shown assistant text so follow-ups match what the user saw, and settles any finalized tool calls with cancel envelopes.
|
|
65
|
+
- SQLite `history.reset` (compaction / load-max truncate) runs delete+reinsert in one transaction, matching Postgres, so a crash mid-reset cannot wipe or partially rewrite a thread.
|
|
66
|
+
- Tool spill paths sanitize client `session_id` / `thread_id` components and refuse to write or delete outside `.monkeybot/spill`; `POST /sessions` rejects path-traversal session ids; session DELETE quiesces the active turn before removing spill dirs. The same path-component sanitizer also applies to transcript and attachment directories, so legacy ids containing glob metacharacters map to a sanitized on-disk folder (reads still find a pre-sanitization folder when it exists).
|
|
40
67
|
- Streamable HTTP MCP connects accept both 2-tuple and 3-tuple transport yields from the MCP Python SDK.
|
|
41
68
|
- Stop mid-reply now cancels the in-flight provider token stream (instead of waiting for the full LLM call) and persists any already-streamed assistant text to history so follow-up turns keep matching what the user saw.
|
|
42
69
|
- Chunking improvements now reach existing workspaces: a chunker version bump re-chunks indexed files even when their modification time never changed, so upgrades no longer require deleting `.monkeybot/knowledge/`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: monkeybot
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.4
|
|
4
4
|
Summary: monkeybot agent harness — FastAPI SSE gateway, owned loop, SQLite, and MCP.
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -191,6 +191,13 @@ Clone only if you are changing the harness. Setup, checks, and the release workf
|
|
|
191
191
|
|
|
192
192
|
Search or open an issue in the [GitHub issue tracker](https://github.com/human-plus-machine/monkeybot/issues).
|
|
193
193
|
|
|
194
|
+
## Credits
|
|
195
|
+
|
|
196
|
+
MonkeyBot builds on two open-source projects:
|
|
197
|
+
|
|
198
|
+
- [Browser Use](https://github.com/browser-use/browser-use) — browser automation for the [browser MCP](docs/browser-mcp.md) (via [browser-harness](https://github.com/browser-use/browser-harness) and the interactive-element DOM walker). MIT licensed.
|
|
199
|
+
- [OpenSandbox](https://github.com/opensandbox-group/OpenSandbox) — sandbox runtime used for isolated `run_command` / code execution. Apache-2.0 licensed.
|
|
200
|
+
|
|
194
201
|
## License
|
|
195
202
|
|
|
196
203
|
MIT — see [`LICENSE`](LICENSE).
|
|
@@ -93,6 +93,13 @@ Clone only if you are changing the harness. Setup, checks, and the release workf
|
|
|
93
93
|
|
|
94
94
|
Search or open an issue in the [GitHub issue tracker](https://github.com/human-plus-machine/monkeybot/issues).
|
|
95
95
|
|
|
96
|
+
## Credits
|
|
97
|
+
|
|
98
|
+
MonkeyBot builds on two open-source projects:
|
|
99
|
+
|
|
100
|
+
- [Browser Use](https://github.com/browser-use/browser-use) — browser automation for the [browser MCP](docs/browser-mcp.md) (via [browser-harness](https://github.com/browser-use/browser-harness) and the interactive-element DOM walker). MIT licensed.
|
|
101
|
+
- [OpenSandbox](https://github.com/opensandbox-group/OpenSandbox) — sandbox runtime used for isolated `run_command` / code execution. Apache-2.0 licensed.
|
|
102
|
+
|
|
96
103
|
## License
|
|
97
104
|
|
|
98
105
|
MIT — see [`LICENSE`](LICENSE).
|
|
@@ -111,7 +111,9 @@ uv sync
|
|
|
111
111
|
| `vertex-claude` | `GCP_PROJECT_ID` / `GOOGLE_CLOUD_PROJECT` / `ANTHROPIC_VERTEX_PROJECT_ID` (ADC) | `monkeybot[vertex-claude]` |
|
|
112
112
|
| `aws_bedrock` | `AWS_ACCESS_KEY_ID` / `AWS_PROFILE` + `AWS_REGION` | `monkeybot[bedrock]` |
|
|
113
113
|
| `huggingface` | `HF_TOKEN` (or `HUGGINGFACE_API_KEY`) | `monkeybot[huggingface]` |
|
|
114
|
-
| `ollama` |
|
|
114
|
+
| `ollama-cloud` | `OLLAMA_API_KEY` | `monkeybot[ollama]` |
|
|
115
|
+
| `ollama-local` | None required — `OLLAMA_BASE_URL` (default `http://localhost:11434`) | `monkeybot[ollama]` |
|
|
116
|
+
| `ollama` | Legacy auto-route (key + blank URL = cloud; explicit URL wins) | `monkeybot[ollama]` |
|
|
115
117
|
|
|
116
118
|
**Agent-first dependencies.** The CLI is thin — it does **not** install provider/storage extras globally. `monkeybot new` scaffolds a `pyproject.toml` with the selected provider (and any `--with` extras). Run plain `uv sync` in the agent directory. `monkeybot run` / `chat` spawn the gateway from that project's interpreter (`.venv/bin/python`, else `uv run python`), and `doctor` checks extras in that same interpreter. For a config-only tree (just `monkeybot_config/`, no `pyproject.toml`) the gateway uses the CLI's interpreter when it already has MonkeyBot 3.x (and MemPalace if memory is on). If memory is enabled and that interpreter cannot import MemPalace, `run` / `chat` provision a cached CLI-managed venv under `~/.cache/monkeybot/runtimes/` holding `monkeybot[memory]` pinned to the running core (never rewrites a `pyproject.toml`). `doctor` reuses that cache when it is already present. Otherwise extras must be installed in the CLI env (`uv tool install --with 'monkeybot[<extra>]' monkeybot-cli`).
|
|
117
119
|
|
|
@@ -45,7 +45,7 @@ Validate check ids: `paths.agent_md.exists`, `paths.skills_path.exists`, `paths.
|
|
|
45
45
|
| `max_turns` | `1000` | Hard cap on turns per run |
|
|
46
46
|
| `summarization_model` | (main model) | Cheaper model for history summarization (env `CONTEXT_SUMMARIZATION_MODEL`) |
|
|
47
47
|
|
|
48
|
-
Validate check ids: `model.provider.supported`, `model.name.present`. Supported YAML providers: `gemini`/`vertex`, `openai`, `anthropic`, `vertex-claude`, `huggingface`, `ollama`, `aws_bedrock`, `fake`.
|
|
48
|
+
Validate check ids: `model.provider.supported`, `model.name.present`. Supported YAML providers: `gemini`/`vertex`, `openai`, `anthropic`, `vertex-claude`, `huggingface`, `ollama-cloud`, `ollama-local`, `ollama`, `aws_bedrock`, `fake`.
|
|
49
49
|
|
|
50
50
|
## `gcp` / `anthropic_vertex` (non-secret identifiers)
|
|
51
51
|
|
|
@@ -5,54 +5,18 @@ Output is local-only — never sent to the agent.
|
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
-
import os
|
|
9
|
-
import signal
|
|
10
8
|
import subprocess
|
|
11
9
|
import sys
|
|
12
10
|
import threading
|
|
13
11
|
from pathlib import Path
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
from monkeybot_cli.process_tree import IS_WINDOWS, kill_process_tree, popen_kwargs_for_platform
|
|
16
14
|
|
|
17
15
|
# Cap capture before TUI truncation so `!yes`-style floods cannot OOM the process.
|
|
18
16
|
_MAX_CAPTURE_CHARS = 100_000
|
|
19
17
|
_READ_CHUNK = 4_096
|
|
20
18
|
|
|
21
19
|
|
|
22
|
-
def _popen_kwargs_for_platform() -> dict[str, object]:
|
|
23
|
-
if _IS_WINDOWS:
|
|
24
|
-
# getattr fallback: this constant only exists on Windows builds of
|
|
25
|
-
# `subprocess`, so a plain attribute access breaks importing/testing
|
|
26
|
-
# this module on POSIX even though the branch never runs there.
|
|
27
|
-
return {"creationflags": getattr(subprocess, "CREATE_NEW_PROCESS_GROUP", 0)}
|
|
28
|
-
return {"start_new_session": True}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def _kill_process_tree(pid: int) -> None:
|
|
32
|
-
"""Best-effort kill of the shell process group/tree.
|
|
33
|
-
|
|
34
|
-
Swallow lookup/permission races — leader exit can make killpg raise
|
|
35
|
-
``PermissionError`` even though descendants still need a signal.
|
|
36
|
-
"""
|
|
37
|
-
if _IS_WINDOWS:
|
|
38
|
-
try:
|
|
39
|
-
subprocess.run(
|
|
40
|
-
["taskkill", "/F", "/T", "/PID", str(pid)],
|
|
41
|
-
capture_output=True,
|
|
42
|
-
check=False,
|
|
43
|
-
)
|
|
44
|
-
except OSError:
|
|
45
|
-
pass
|
|
46
|
-
return
|
|
47
|
-
try:
|
|
48
|
-
os.killpg(pid, signal.SIGKILL)
|
|
49
|
-
except (ProcessLookupError, PermissionError, OSError):
|
|
50
|
-
try:
|
|
51
|
-
os.kill(pid, signal.SIGKILL)
|
|
52
|
-
except (ProcessLookupError, PermissionError, OSError):
|
|
53
|
-
pass
|
|
54
|
-
|
|
55
|
-
|
|
56
20
|
def _append_capped(chunks: list[str], total: int, data: str) -> tuple[int, bool]:
|
|
57
21
|
"""Append ``data`` up to the capture cap. Returns (new_total, hit_cap)."""
|
|
58
22
|
remain = _MAX_CAPTURE_CHARS - total
|
|
@@ -84,7 +48,7 @@ def run_local_shell(command: str, cwd: Path, *, timeout: float = 120.0) -> tuple
|
|
|
84
48
|
stdout=subprocess.PIPE,
|
|
85
49
|
stderr=subprocess.STDOUT,
|
|
86
50
|
text=True,
|
|
87
|
-
**
|
|
51
|
+
**popen_kwargs_for_platform(),
|
|
88
52
|
)
|
|
89
53
|
assert proc.stdout is not None
|
|
90
54
|
|
|
@@ -104,7 +68,7 @@ def run_local_shell(command: str, cwd: Path, *, timeout: float = 120.0) -> tuple
|
|
|
104
68
|
state["total"], hit = _append_capped(chunks, state["total"], chunk)
|
|
105
69
|
if hit:
|
|
106
70
|
state["capped"] = True
|
|
107
|
-
|
|
71
|
+
kill_process_tree(proc.pid)
|
|
108
72
|
break
|
|
109
73
|
except (ValueError, OSError):
|
|
110
74
|
# stdout closed from the main thread to unblock a stuck read.
|
|
@@ -119,12 +83,12 @@ def run_local_shell(command: str, cwd: Path, *, timeout: float = 120.0) -> tuple
|
|
|
119
83
|
proc.wait(timeout=timeout)
|
|
120
84
|
except subprocess.TimeoutExpired:
|
|
121
85
|
timed_out = True
|
|
122
|
-
|
|
86
|
+
kill_process_tree(proc.pid)
|
|
123
87
|
|
|
124
88
|
# Shell may have exited while a descendant still holds the pipe —
|
|
125
89
|
# kill the tree and close stdout so the reader cannot block forever.
|
|
126
90
|
if reader.is_alive():
|
|
127
|
-
|
|
91
|
+
kill_process_tree(proc.pid)
|
|
128
92
|
stop_reader.set()
|
|
129
93
|
try:
|
|
130
94
|
proc.stdout.close()
|
|
@@ -139,7 +103,7 @@ def run_local_shell(command: str, cwd: Path, *, timeout: float = 120.0) -> tuple
|
|
|
139
103
|
reader.join(timeout=0.1)
|
|
140
104
|
except Exception:
|
|
141
105
|
timed_out = True
|
|
142
|
-
|
|
106
|
+
kill_process_tree(proc.pid)
|
|
143
107
|
stop_reader.set()
|
|
144
108
|
try:
|
|
145
109
|
proc.stdout.close()
|
|
@@ -149,7 +113,7 @@ def run_local_shell(command: str, cwd: Path, *, timeout: float = 120.0) -> tuple
|
|
|
149
113
|
|
|
150
114
|
try:
|
|
151
115
|
if proc.poll() is None:
|
|
152
|
-
|
|
116
|
+
kill_process_tree(proc.pid)
|
|
153
117
|
try:
|
|
154
118
|
proc.wait(timeout=1)
|
|
155
119
|
except Exception:
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"""monkeybot run — launch the SSE gateway as a subprocess."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import os
|
|
7
|
+
import signal
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
import time
|
|
11
|
+
from collections.abc import Callable
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from types import FrameType
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from monkeybot_cli.config_resolve import (
|
|
17
|
+
load_agent_dotenv,
|
|
18
|
+
load_config_doc,
|
|
19
|
+
resolve_agent_root,
|
|
20
|
+
resolve_config,
|
|
21
|
+
)
|
|
22
|
+
from monkeybot_cli.opensandbox_lifecycle import (
|
|
23
|
+
ensure_opensandbox_for_agent,
|
|
24
|
+
is_sandbox_enabled,
|
|
25
|
+
server_url_from_config,
|
|
26
|
+
)
|
|
27
|
+
from monkeybot_cli.process_tree import IS_WINDOWS, kill_process_tree, popen_kwargs_for_platform
|
|
28
|
+
from monkeybot_cli.runtime_python import gateway_argv, prepare_runtime_python
|
|
29
|
+
|
|
30
|
+
_SHUTDOWN_TIMEOUT_SECS = 5.0
|
|
31
|
+
_KILL_TIMEOUT_SECS = 1.0
|
|
32
|
+
_Handler = Callable[[int, FrameType | None], Any] | int | None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _cli_exit_status(rc: int | None, received: int | None) -> int:
|
|
36
|
+
"""Map a child ``wait()`` status to a CLI exit code.
|
|
37
|
+
|
|
38
|
+
``wait()`` returns a negative signal number when the child dies from a
|
|
39
|
+
signal; ``SystemExit(-15)`` becomes shell status 241. Unix convention is
|
|
40
|
+
``128 + signal`` (143 for SIGTERM, 130 for SIGINT).
|
|
41
|
+
|
|
42
|
+
When the shim received SIGINT, return 130 even if the child exited 0 —
|
|
43
|
+
that matches the conventional Ctrl-C exit status.
|
|
44
|
+
"""
|
|
45
|
+
if received == signal.SIGINT:
|
|
46
|
+
return 130
|
|
47
|
+
if rc is None:
|
|
48
|
+
return 1
|
|
49
|
+
if rc < 0:
|
|
50
|
+
return 128 + (-rc)
|
|
51
|
+
return rc
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _signal_process_group(proc: subprocess.Popen[bytes], signum: int) -> None:
|
|
55
|
+
if proc.poll() is not None:
|
|
56
|
+
return
|
|
57
|
+
if IS_WINDOWS:
|
|
58
|
+
try:
|
|
59
|
+
proc.send_signal(signum)
|
|
60
|
+
except OSError as exc:
|
|
61
|
+
print(f"failed to signal gateway: {exc}", file=sys.stderr)
|
|
62
|
+
return
|
|
63
|
+
try:
|
|
64
|
+
os.killpg(proc.pid, signum)
|
|
65
|
+
return
|
|
66
|
+
except ProcessLookupError:
|
|
67
|
+
return
|
|
68
|
+
except OSError as exc:
|
|
69
|
+
try:
|
|
70
|
+
proc.send_signal(signum)
|
|
71
|
+
except OSError:
|
|
72
|
+
print(f"failed to signal gateway: {exc}", file=sys.stderr)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def run_gateway_process(
|
|
76
|
+
cmd: list[str],
|
|
77
|
+
*,
|
|
78
|
+
env: dict[str, str],
|
|
79
|
+
cwd: Path,
|
|
80
|
+
shutdown_timeout: float = _SHUTDOWN_TIMEOUT_SECS,
|
|
81
|
+
kill_timeout: float = _KILL_TIMEOUT_SECS,
|
|
82
|
+
) -> int:
|
|
83
|
+
"""Start the gateway and forward stop signals to its process group.
|
|
84
|
+
|
|
85
|
+
Electron sends SIGTERM only to this CLI shim. ``subprocess.run`` dies on
|
|
86
|
+
that signal and leaves uvicorn holding the port. On POSIX the child is
|
|
87
|
+
started in a new session so SIGTERM/SIGINT reach the whole tree (``uv run``
|
|
88
|
+
plus the gateway grandchild), then escalate to SIGKILL if it ignores the
|
|
89
|
+
signal for ``shutdown_timeout`` seconds.
|
|
90
|
+
|
|
91
|
+
``start_new_session`` also detaches the gateway from the terminal's
|
|
92
|
+
foreground process group (stdin reads would raise SIGTTIN). That is fine
|
|
93
|
+
for uvicorn today and required for ``killpg``.
|
|
94
|
+
|
|
95
|
+
On Windows, ``send_signal(SIGTERM)`` only terminates the immediate child;
|
|
96
|
+
grandchildren may still be orphaned.
|
|
97
|
+
|
|
98
|
+
Interactive Ctrl-C already hits the foreground process group; forwarding
|
|
99
|
+
SIGINT matters here because the child is in a new session and would
|
|
100
|
+
otherwise keep running.
|
|
101
|
+
"""
|
|
102
|
+
received: int | None = None
|
|
103
|
+
proc: subprocess.Popen[bytes] | None = None
|
|
104
|
+
signal_forwarded = False
|
|
105
|
+
deadline: float | None = None
|
|
106
|
+
|
|
107
|
+
def _forward(signum: int, _frame: object | None) -> None:
|
|
108
|
+
nonlocal received, signal_forwarded, deadline
|
|
109
|
+
if received is None:
|
|
110
|
+
received = signum
|
|
111
|
+
if proc is not None:
|
|
112
|
+
_signal_process_group(proc, signum)
|
|
113
|
+
signal_forwarded = True
|
|
114
|
+
if deadline is None:
|
|
115
|
+
deadline = time.monotonic() + shutdown_timeout
|
|
116
|
+
|
|
117
|
+
restored: dict[int, _Handler] = {}
|
|
118
|
+
forwarded = [signal.SIGINT, signal.SIGTERM]
|
|
119
|
+
if not IS_WINDOWS:
|
|
120
|
+
forwarded.append(signal.SIGHUP)
|
|
121
|
+
for sig in forwarded:
|
|
122
|
+
try:
|
|
123
|
+
restored[sig] = signal.signal(sig, _forward)
|
|
124
|
+
except (ValueError, OSError) as exc:
|
|
125
|
+
print(f"failed to install {sig.name} handler: {exc}", file=sys.stderr)
|
|
126
|
+
try:
|
|
127
|
+
proc = subprocess.Popen(
|
|
128
|
+
cmd,
|
|
129
|
+
env=env,
|
|
130
|
+
cwd=cwd,
|
|
131
|
+
**popen_kwargs_for_platform(),
|
|
132
|
+
)
|
|
133
|
+
if received is not None and not signal_forwarded:
|
|
134
|
+
_signal_process_group(proc, received)
|
|
135
|
+
if deadline is None:
|
|
136
|
+
deadline = time.monotonic() + shutdown_timeout
|
|
137
|
+
while True:
|
|
138
|
+
try:
|
|
139
|
+
rc = proc.wait(timeout=0.25)
|
|
140
|
+
except subprocess.TimeoutExpired:
|
|
141
|
+
if deadline is None or time.monotonic() < deadline:
|
|
142
|
+
continue
|
|
143
|
+
print(
|
|
144
|
+
"gateway did not exit after signal; killing process tree",
|
|
145
|
+
file=sys.stderr,
|
|
146
|
+
)
|
|
147
|
+
kill_process_tree(proc.pid)
|
|
148
|
+
try:
|
|
149
|
+
proc.wait(timeout=kill_timeout)
|
|
150
|
+
except subprocess.TimeoutExpired:
|
|
151
|
+
print("gateway still running after kill", file=sys.stderr)
|
|
152
|
+
rc = proc.returncode
|
|
153
|
+
return _cli_exit_status(rc, received)
|
|
154
|
+
finally:
|
|
155
|
+
for sig, handler in restored.items():
|
|
156
|
+
try:
|
|
157
|
+
signal.signal(sig, handler)
|
|
158
|
+
except (ValueError, OSError) as exc:
|
|
159
|
+
print(f"failed to restore {sig.name} handler: {exc}", file=sys.stderr)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def run_run(args: argparse.Namespace) -> int:
|
|
163
|
+
cwd = Path(args.cwd).expanduser().resolve() if args.cwd else None
|
|
164
|
+
config_path = resolve_config(args.config, cwd=cwd)
|
|
165
|
+
load_agent_dotenv(cwd=cwd, config_path=config_path)
|
|
166
|
+
env = os.environ.copy()
|
|
167
|
+
if config_path is not None:
|
|
168
|
+
env["MONKEYBOT_CONFIG"] = str(config_path)
|
|
169
|
+
if args.port:
|
|
170
|
+
env["PORT"] = str(args.port)
|
|
171
|
+
# --cwd intentionally pins the subprocess and runtime directory. Without
|
|
172
|
+
# it, an explicit config determines the agent root.
|
|
173
|
+
agent_root = resolve_agent_root(cwd=cwd, config_path=config_path)
|
|
174
|
+
if config_path is not None:
|
|
175
|
+
_, cfg_doc = load_config_doc(config_path)
|
|
176
|
+
if is_sandbox_enabled(cfg_doc):
|
|
177
|
+
if not ensure_opensandbox_for_agent(
|
|
178
|
+
agent_root,
|
|
179
|
+
server_url=server_url_from_config(cfg_doc),
|
|
180
|
+
# Fail fast: Mac app health-checks the gateway immediately.
|
|
181
|
+
docker_wait_secs=2.0,
|
|
182
|
+
):
|
|
183
|
+
print(
|
|
184
|
+
"Continuing without a healthy OpenSandbox — run_command may fail.",
|
|
185
|
+
flush=True,
|
|
186
|
+
)
|
|
187
|
+
runtime = prepare_runtime_python(agent_root, config_path)
|
|
188
|
+
cmd = gateway_argv(runtime)
|
|
189
|
+
return run_gateway_process(cmd, env=env, cwd=agent_root)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
|
|
193
|
+
p = subparsers.add_parser("run", help="Start the monkeybot SSE gateway")
|
|
194
|
+
p.add_argument("--config", help="Path to monkeybot.yaml (sets MONKEYBOT_CONFIG)")
|
|
195
|
+
p.add_argument("--port", type=int, help="Listen port (sets PORT)")
|
|
196
|
+
p.add_argument("--cwd", help="Working directory for the gateway process")
|
|
197
|
+
p.set_defaults(func=run_run)
|
|
@@ -24,7 +24,8 @@ PROVIDER_CHOICES: tuple[ExtraChoice, ...] = (
|
|
|
24
24
|
ExtraChoice("vertex-claude", "Claude on Vertex AI"),
|
|
25
25
|
ExtraChoice("aws_bedrock", "AWS Bedrock"),
|
|
26
26
|
ExtraChoice("huggingface", "Hugging Face"),
|
|
27
|
-
ExtraChoice("ollama", "Ollama
|
|
27
|
+
ExtraChoice("ollama-cloud", "Ollama Cloud"),
|
|
28
|
+
ExtraChoice("ollama-local", "Ollama (local)"),
|
|
28
29
|
ExtraChoice("nvidia", "NVIDIA NIM"),
|
|
29
30
|
ExtraChoice("openrouter", "OpenRouter"),
|
|
30
31
|
)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Shared helpers for spawning and tearing down process groups/trees."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import signal
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
IS_WINDOWS = sys.platform == "win32"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def popen_kwargs_for_platform() -> dict[str, object]:
|
|
14
|
+
if IS_WINDOWS:
|
|
15
|
+
# getattr fallback: this constant only exists on Windows builds of
|
|
16
|
+
# `subprocess`, so a plain attribute access breaks importing/testing
|
|
17
|
+
# this module on POSIX even though the branch never runs there.
|
|
18
|
+
return {"creationflags": getattr(subprocess, "CREATE_NEW_PROCESS_GROUP", 0)}
|
|
19
|
+
return {"start_new_session": True}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def kill_process_tree(pid: int) -> None:
|
|
23
|
+
"""Best-effort kill of the shell process group/tree.
|
|
24
|
+
|
|
25
|
+
Swallow lookup/permission races — leader exit can make killpg raise
|
|
26
|
+
``PermissionError`` even though descendants still need a signal.
|
|
27
|
+
"""
|
|
28
|
+
if IS_WINDOWS:
|
|
29
|
+
try:
|
|
30
|
+
subprocess.run(
|
|
31
|
+
["taskkill", "/F", "/T", "/PID", str(pid)],
|
|
32
|
+
capture_output=True,
|
|
33
|
+
check=False,
|
|
34
|
+
)
|
|
35
|
+
except OSError:
|
|
36
|
+
pass
|
|
37
|
+
return
|
|
38
|
+
try:
|
|
39
|
+
os.killpg(pid, signal.SIGKILL)
|
|
40
|
+
except (ProcessLookupError, PermissionError, OSError):
|
|
41
|
+
try:
|
|
42
|
+
os.kill(pid, signal.SIGKILL)
|
|
43
|
+
except (ProcessLookupError, PermissionError, OSError):
|
|
44
|
+
pass
|
|
@@ -59,6 +59,17 @@ PROVIDER_SPECS: dict[str, ProviderSpec] = {
|
|
|
59
59
|
(),
|
|
60
60
|
credentials_optional=True,
|
|
61
61
|
),
|
|
62
|
+
"ollama-cloud": ProviderSpec(
|
|
63
|
+
("ollama-cloud", "ollama_cloud"),
|
|
64
|
+
"ollama",
|
|
65
|
+
("OLLAMA_API_KEY",),
|
|
66
|
+
),
|
|
67
|
+
"ollama-local": ProviderSpec(
|
|
68
|
+
("ollama-local", "ollama_local"),
|
|
69
|
+
"ollama",
|
|
70
|
+
(),
|
|
71
|
+
credentials_optional=True,
|
|
72
|
+
),
|
|
62
73
|
"fake": ProviderSpec(("fake",), None, (), credentials_optional=True),
|
|
63
74
|
}
|
|
64
75
|
|
|
@@ -28,7 +28,10 @@ DB_URL=sqlite:///data/monkeybot.db
|
|
|
28
28
|
# Hugging Face
|
|
29
29
|
# HF_TOKEN=
|
|
30
30
|
|
|
31
|
-
# Ollama (
|
|
31
|
+
# Ollama Cloud (model.provider: ollama-cloud) — key from ollama.com/settings/keys
|
|
32
|
+
# OLLAMA_API_KEY=
|
|
33
|
+
|
|
34
|
+
# Ollama local (model.provider: ollama-local) — no API key needed
|
|
32
35
|
# OLLAMA_BASE_URL=http://localhost:11434
|
|
33
36
|
|
|
34
37
|
# Optional web search
|
{monkeybot-3.0.2 → monkeybot-3.0.4}/cli/src/monkeybot_cli/scaffold_defaults/monkeybot.example.yaml
RENAMED
|
@@ -87,7 +87,7 @@ paths:
|
|
|
87
87
|
workspace_root: ./workspace
|
|
88
88
|
|
|
89
89
|
model:
|
|
90
|
-
# gemini | openai | anthropic | vertex-claude | huggingface | ollama | nvidia | openrouter | aws_bedrock | fake
|
|
90
|
+
# gemini | openai | anthropic | vertex-claude | huggingface | ollama-cloud | ollama-local | ollama | nvidia | openrouter | aws_bedrock | fake
|
|
91
91
|
provider: gemini
|
|
92
92
|
name: gemini-3.1-flash-live-preview
|
|
93
93
|
temperature: 0.7
|
|
@@ -214,6 +214,18 @@ todo_list:
|
|
|
214
214
|
enabled: true
|
|
215
215
|
mirror_to_disk: true
|
|
216
216
|
|
|
217
|
+
# Desktop-only, macOS-only local computer control (open/reveal files & folders,
|
|
218
|
+
# launch apps, read/write the clipboard, browse/move/trash files) via
|
|
219
|
+
# computer_* tools. Off by default — server/Cloud Run deployments should never
|
|
220
|
+
# set this. The Monkeybot desktop app sets MONKEYBOT_COMPUTER_TOOLS when it
|
|
221
|
+
# spawns a gateway with this feature turned on in its settings; every computer_*
|
|
222
|
+
# call still asks for approval by default (a built-in permissions.yaml baseline,
|
|
223
|
+
# not configurable here) and "Always allow" is scoped to the exact action, not
|
|
224
|
+
# the whole tool. See monkeybot_config/permissions.yaml and
|
|
225
|
+
# monkeybot_config/approvals.json (machine-written, do not hand-edit).
|
|
226
|
+
computer:
|
|
227
|
+
enabled: false
|
|
228
|
+
|
|
217
229
|
sandbox:
|
|
218
230
|
# Opt-in: requires Docker Desktop (OpenSandbox). Leave false for normal Mac
|
|
219
231
|
# installs so the gateway starts without Docker. When enabled, ``monkeybot run``
|
|
@@ -8,6 +8,7 @@ import time
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
|
|
10
10
|
import monkeybot_cli.chat_local_shell as chat_local_shell
|
|
11
|
+
import monkeybot_cli.process_tree as process_tree
|
|
11
12
|
from monkeybot_cli.chat_local_shell import run_local_shell, truncate_output
|
|
12
13
|
|
|
13
14
|
|
|
@@ -30,7 +31,7 @@ def test_run_local_shell_uses_cwd(tmp_path: Path) -> None:
|
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
def test_kill_process_tree_swallows_permission_error(monkeypatch) -> None:
|
|
33
|
-
monkeypatch.setattr(
|
|
34
|
+
monkeypatch.setattr(process_tree, "IS_WINDOWS", False)
|
|
34
35
|
|
|
35
36
|
def _boom_killpg(pid: int, sig: int) -> None:
|
|
36
37
|
raise PermissionError("race")
|
|
@@ -38,9 +39,9 @@ def test_kill_process_tree_swallows_permission_error(monkeypatch) -> None:
|
|
|
38
39
|
def _boom_kill(pid: int, sig: int) -> None:
|
|
39
40
|
raise ProcessLookupError()
|
|
40
41
|
|
|
41
|
-
monkeypatch.setattr(
|
|
42
|
-
monkeypatch.setattr(
|
|
43
|
-
|
|
42
|
+
monkeypatch.setattr(process_tree.os, "killpg", _boom_killpg)
|
|
43
|
+
monkeypatch.setattr(process_tree.os, "kill", _boom_kill)
|
|
44
|
+
process_tree.kill_process_tree(4321) # must not raise
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
def test_run_local_shell_timeout(tmp_path: Path) -> None:
|
|
@@ -104,22 +105,22 @@ def test_run_local_shell_timeout_kills_grandchildren(tmp_path: Path) -> None:
|
|
|
104
105
|
|
|
105
106
|
|
|
106
107
|
def test_popen_kwargs_use_process_group_on_posix(monkeypatch) -> None:
|
|
107
|
-
monkeypatch.setattr(
|
|
108
|
-
assert
|
|
108
|
+
monkeypatch.setattr(process_tree, "IS_WINDOWS", False)
|
|
109
|
+
assert process_tree.popen_kwargs_for_platform() == {"start_new_session": True}
|
|
109
110
|
|
|
110
111
|
|
|
111
112
|
def test_popen_kwargs_use_new_process_group_on_windows(monkeypatch) -> None:
|
|
112
|
-
monkeypatch.setattr(
|
|
113
|
-
kwargs =
|
|
113
|
+
monkeypatch.setattr(process_tree, "IS_WINDOWS", True)
|
|
114
|
+
kwargs = process_tree.popen_kwargs_for_platform()
|
|
114
115
|
assert set(kwargs) == {"creationflags"}
|
|
115
116
|
|
|
116
117
|
|
|
117
118
|
def test_kill_process_tree_uses_killpg_on_posix(monkeypatch) -> None:
|
|
118
|
-
monkeypatch.setattr(
|
|
119
|
+
monkeypatch.setattr(process_tree, "IS_WINDOWS", False)
|
|
119
120
|
calls: list[tuple[int, int]] = []
|
|
120
|
-
monkeypatch.setattr(
|
|
121
|
-
|
|
122
|
-
assert calls == [(4321,
|
|
121
|
+
monkeypatch.setattr(process_tree.os, "killpg", lambda pid, sig: calls.append((pid, sig)))
|
|
122
|
+
process_tree.kill_process_tree(4321)
|
|
123
|
+
assert calls == [(4321, process_tree.signal.SIGKILL)]
|
|
123
124
|
|
|
124
125
|
|
|
125
126
|
def test_kill_process_tree_uses_taskkill_on_windows(monkeypatch) -> None:
|
|
@@ -128,14 +129,14 @@ def test_kill_process_tree_uses_taskkill_on_windows(monkeypatch) -> None:
|
|
|
128
129
|
os.killpg doesn't exist on Windows, so the POSIX-only kill path would
|
|
129
130
|
crash a timed-out `!` command instead of finishing the tool block there.
|
|
130
131
|
"""
|
|
131
|
-
monkeypatch.setattr(
|
|
132
|
+
monkeypatch.setattr(process_tree, "IS_WINDOWS", True)
|
|
132
133
|
calls: list[list[str]] = []
|
|
133
134
|
monkeypatch.setattr(
|
|
134
|
-
|
|
135
|
+
process_tree.subprocess,
|
|
135
136
|
"run",
|
|
136
137
|
lambda argv, **kwargs: calls.append(list(argv)),
|
|
137
138
|
)
|
|
138
|
-
|
|
139
|
+
process_tree.kill_process_tree(4321)
|
|
139
140
|
assert calls == [["taskkill", "/F", "/T", "/PID", "4321"]]
|
|
140
141
|
|
|
141
142
|
|
|
@@ -21,6 +21,8 @@ def test_normalize_extra_token_features_and_providers() -> None:
|
|
|
21
21
|
assert normalize_extra_token("anthropic") == "claude"
|
|
22
22
|
assert normalize_extra_token("aws_bedrock") == "bedrock"
|
|
23
23
|
assert normalize_extra_token("claude") == "claude"
|
|
24
|
+
assert normalize_extra_token("ollama-cloud") == "ollama"
|
|
25
|
+
assert normalize_extra_token("ollama-local") == "ollama"
|
|
24
26
|
assert normalize_extra_token("fake") is None
|
|
25
27
|
assert normalize_extra_token("not-a-real-extra") is None
|
|
26
28
|
|
|
@@ -42,6 +44,9 @@ def test_extra_module_covers_catalog_extras() -> None:
|
|
|
42
44
|
def test_provider_extra_name() -> None:
|
|
43
45
|
assert provider_extra_name("openai") == "openai"
|
|
44
46
|
assert provider_extra_name("anthropic") == "claude"
|
|
47
|
+
assert provider_extra_name("ollama-cloud") == "ollama"
|
|
48
|
+
assert provider_extra_name("ollama-local") == "ollama"
|
|
49
|
+
assert provider_extra_name("ollama") == "ollama"
|
|
45
50
|
assert provider_extra_name("fake") is None
|
|
46
51
|
|
|
47
52
|
|