monkeybot 3.3.0__tar.gz → 3.5.0__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.3.0 → monkeybot-3.5.0}/CHANGELOG.md +52 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/PKG-INFO +2 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/pyproject.toml +1 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold.py +12 -3
- monkeybot-3.5.0/cli/src/monkeybot_cli/scaffold_defaults/goal/SKILL.md +31 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/monkeybot.example.yaml +11 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_scaffold.py +8 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/features.md +4 -2
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/sse-gateway-ui.md +2 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/verifier-agent-design.md +14 -11
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/pyproject.toml +1 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/app.py +4 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/tab_ops.py +22 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/tabs.py +32 -14
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_act.py +30 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_playbook_flows.py +40 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_tabs.py +64 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/uv.lock +1 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/pyproject.toml +4 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/computer/safety.py +138 -16
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/computer/tools.py +15 -8
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/attachments/config.py +10 -0
- monkeybot-3.5.0/src/monkeybot/core/attachments/image_preview.py +126 -0
- monkeybot-3.5.0/src/monkeybot/core/attachments/resolve.py +156 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/attachments/store.py +0 -7
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/config/runtime_env.py +2 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/config/settings.py +82 -21
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/config/snapshot.py +2 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/context/__init__.py +44 -0
- monkeybot-3.5.0/src/monkeybot/core/context/slash_skills.py +54 -0
- monkeybot-3.5.0/src/monkeybot/core/goals/__init__.py +15 -0
- monkeybot-3.5.0/src/monkeybot/core/goals/service.py +242 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/captions.py +8 -4
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/backends.py +11 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/firestore.indexes.json +8 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/firestore_scheduled_loops.py +179 -80
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/postgres.py +154 -52
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/scheduled_loops.py +283 -56
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/sqlite.py +59 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/prompts/harness_prompt.py +1 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/prompts/headings.py +4 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/prompts/prompt.py +18 -2
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/events.py +93 -17
- monkeybot-3.5.0/src/monkeybot/core/runtime/input_admission.py +305 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/loop.py +32 -21
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/loop_messages.py +10 -9
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/realtime_loop.py +9 -2
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/tool_dispatch.py +35 -16
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/turn_loop.py +54 -37
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/core_tool_executor.py +149 -12
- monkeybot-3.5.0/src/monkeybot/core/verifier/actuator.py +89 -0
- monkeybot-3.5.0/src/monkeybot/core/verifier/binding.py +81 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/verifier/classify.py +89 -27
- monkeybot-3.5.0/src/monkeybot/core/verifier/intervention.py +54 -0
- monkeybot-3.5.0/src/monkeybot/core/verifier/judge.py +572 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/verifier/ledger.py +92 -23
- monkeybot-3.5.0/src/monkeybot/core/verifier/mailbox.py +551 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/verifier/port.py +6 -2
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/verifier/tracker.py +60 -8
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/realtime/app.py +1 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/realtime/deps.py +3 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/realtime/routes.py +7 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/sse/app.py +187 -68
- monkeybot-3.5.0/src/monkeybot/gateway/sse/goal_routes.py +75 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/sse/models.py +5 -1
- monkeybot-3.5.0/src/monkeybot/gateway/sse/request_storage.py +23 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/sse/routes.py +135 -2
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/sse/scheduler_routes.py +35 -18
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/_openai_compat.py +274 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/bedrock.py +10 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/claude.py +8 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/gemini.py +8 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/huggingface.py +8 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/nvidia.py +8 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/ollama.py +20 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/openai.py +26 -2
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/openrouter.py +8 -1
- monkeybot-3.5.0/src/monkeybot/providers/request_budget.py +238 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/vertex_claude.py +9 -3
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/scheduler/engine.py +20 -5
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/computer/test_computer_tools.py +39 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/computer/test_path_policy.py +140 -1
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_attachment_store.py +14 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_config_extensions.py +74 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_context.py +2 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_core_tool_executor.py +74 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_events.py +48 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_firestore_scheduled_loops.py +177 -6
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_goal_ledger.py +152 -2
- monkeybot-3.5.0/tests/core/test_goal_persistence.py +494 -0
- monkeybot-3.5.0/tests/core/test_goals.py +464 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_harness_prompt.py +2 -0
- monkeybot-3.5.0/tests/core/test_image_preview.py +169 -0
- monkeybot-3.5.0/tests/core/test_input_admission.py +922 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_media.py +43 -4
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_loop.py +135 -3
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_loop_hooks.py +5 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_progress_tracker.py +90 -32
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_runtime_config_snapshot.py +40 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_scheduled_loops.py +87 -0
- monkeybot-3.5.0/tests/core/test_slash_skills.py +95 -0
- monkeybot-3.5.0/tests/core/test_verifier_binding.py +62 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_verifier_inspector.py +10 -4
- monkeybot-3.5.0/tests/core/test_verifier_judge.py +673 -0
- monkeybot-3.5.0/tests/core/test_verifier_mailbox_lifecycle.py +348 -0
- monkeybot-3.5.0/tests/core/test_verifier_sticky_nudge.py +466 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/realtime/test_deps.py +2 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/sse/test_attachments.py +28 -0
- monkeybot-3.5.0/tests/gateway/sse/test_gateway_runtime.py +817 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/sse/test_scheduler_routes.py +1 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/test_sse_events.py +17 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_anthropic_cache.py +4 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_ollama.py +26 -0
- monkeybot-3.5.0/tests/providers/test_openai_byte_budget.py +415 -0
- monkeybot-3.5.0/tests/providers/test_request_budget.py +204 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/scheduler/test_engine.py +56 -2
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/test_packaging_config.py +1 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/uv.lock +7 -4
- monkeybot-3.3.0/src/monkeybot/core/attachments/resolve.py +0 -70
- monkeybot-3.3.0/src/monkeybot/core/runtime/input_admission.py +0 -170
- monkeybot-3.3.0/src/monkeybot/core/verifier/actuator.py +0 -39
- monkeybot-3.3.0/src/monkeybot/core/verifier/judge.py +0 -187
- monkeybot-3.3.0/src/monkeybot/core/verifier/mailbox.py +0 -107
- monkeybot-3.3.0/tests/core/test_input_admission.py +0 -404
- monkeybot-3.3.0/tests/core/test_verifier_judge.py +0 -260
- monkeybot-3.3.0/tests/gateway/sse/test_gateway_runtime.py +0 -101
- {monkeybot-3.3.0 → monkeybot-3.5.0}/.dockerignore +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/.github/workflows/ci.yml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/.github/workflows/live-eval-smoke.yml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/.github/workflows/prepare-release.yml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/.github/workflows/publish-release.yml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/.gitignore +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/.pre-commit-config.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/BACKLOG.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/CONTRIBUTING.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/LICENSE +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/README.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/skills/monkeybot/SKILL.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/skills/monkeybot/references/config-sections.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/chat_file_index.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/chat_local_shell.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/chat_renderer.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/chat_session.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/chat_status_bar.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/chat_theme.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/chat_tool_display.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/chat_tui.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/chat_tui_widgets.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/commands/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/commands/chat.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/commands/doctor.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/commands/loop.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/commands/new.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/commands/refresh.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/commands/run_cmd.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/commands/talk.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/commands/validate.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/compat.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/config_resolve.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/exit_commands.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/extras_catalog.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/gateway_health.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/main.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/opensandbox_lifecycle.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/output.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/process_tree.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/providers.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/realtime/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/realtime/audio_io.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/realtime/client.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/realtime/gateway_manager.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/realtime/push_to_talk.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/realtime/session.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/realtime/session_controller.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/realtime/talk_ui.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/realtime/wire_encode.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/runtime_python.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/AGENT.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/Dockerfile +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/browser/SKILL.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/command_allowlist.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/dockerignore +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/env.example +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/image-generator/SKILL.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/image-generator/generate_image.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/loop/SKILL.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/mcp.json +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/opensandbox.docker.toml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/otel-collector.example.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/permissions.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/session_controller.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/terminal_markdown.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_chat_continue.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_chat_e2e.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_chat_errors.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_chat_file_index.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_chat_grounding.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_chat_local_shell.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_chat_renderer_parity.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_chat_session.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_chat_status_bar.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_chat_theme.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_chat_tool_display.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_chat_tui.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_cli.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_config_resolve.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_doctor.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_extras_catalog.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_gateway_health.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_opensandbox_lifecycle.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_realtime_session_controller.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_run_cmd.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_runtime_python.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/tests/test_terminal_markdown.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/cli/uv.lock +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docker/Dockerfile +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docker/demo-model.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docker/demo.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docker/docker-compose.sandbox.yml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docker/opensandbox.docker.toml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docker/sandbox.Dockerfile +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docker-compose.yml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/agent-layout.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/assets/logo.png +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/browser-mcp-perf-baseline.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/browser-mcp-performance-plan.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/browser-mcp.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/cloud-deployment-design.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/deploy-aws-agentcore.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/deploy-pattern-a-container.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/deploy-pattern-b-serverless.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/deploy-pattern-c-agent-platform.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/deploy-pattern-d-realtime.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/getting-started.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/knowledge-layer-fixes.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/live-evals.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/mcp.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/memory-graph-split-plan.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/migrations/agent-scope-namespacing.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/migrations/memory-outbox.sql +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/observability-runbook.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/ollama-local.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/otel-collector.example.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/progressive-loop-tools.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/progressive-mcp-tools.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/skills.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/spill-dynamic-design.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/docs/workspace-index-design.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/TEST_COVERAGE.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/assertions.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/baselines/smoke.json +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/baselines/smoke.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/diff.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/eval_config.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/models.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/persistence.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/report.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/runner.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenario_loader.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/context/summarization_trigger.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/drift/declares_done.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/drift/path_constraint.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/drift/preempt.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/drift/repeat_correction.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/drift/supersession.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/mcp/get_prompt.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/mcp/list_resources.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/mcp/tool_invoke.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/memory/recall_cross_session.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/memory/recall_single_session.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/multi_turn/task_tracking.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/skills/skill_invocation.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/subagents/dispatch_complete.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/tools/core_read.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/tools/core_read_error.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/tools/core_run_command.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/tools/core_run_command_sandbox.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scenarios/tools/core_write.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/scorer.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/.env.example +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/.gitignore +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/fixture_mcp_server.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/monkeybot_config/AGENT.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/monkeybot_config/command_allowlist.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/monkeybot_config/mcp.json +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/monkeybot_config/monkeybot.verifier-on.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/monkeybot_config/monkeybot.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/monkeybot_config/permissions.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/pyproject.toml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/skills/browser/SKILL.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/uv.lock +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/workspace/.gitkeep +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/smoke_agent/workspace/skills/browser/playbooks/.gitkeep +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/suites/drift.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/suites/smoke.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/test_assertions.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/test_diff.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/test_judge.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/test_report.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/test_runner_sse.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/evals/test_scorer.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/README.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/agentcore/handler.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/agentcore/runtime_app.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/agentengine/handler.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/cloud-functions/main.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/lambda/handler.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/ollama/PrefixStable.Modelfile +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/skills/browser/SKILL.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/skills/browser/playbooks/.gitkeep +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/skills/diagnostics/README.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/skills/diagnostics/SKILL.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/skills/diagnostics/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/skills/diagnostics/diagnostics.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/skills/image-generator/SKILL.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/examples/skills/image-generator/generate_image.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/scripts/agentcore_smoke.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/scripts/dump_tool_surface.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/scripts/perf_bench.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/actions.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/agentcore.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/assets/NOTICE.md +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/assets/dom_tree.js +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/assets/pa_driver.js +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/backend.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/chat_scope.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/dom_indexing.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/in_app_cdp.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/login.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/observe.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/perf.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/playbooks.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/playwright_helpers.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/results.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/screenshots.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/server.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/tools/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/tools/batch.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/tools/capture.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/tools/interact.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/tools/navigate.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/tools/playbook.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/tools/read.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/src/browser_mcp/tools/tab_control.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/fixtures/api.json +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/fixtures/article.html +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/fixtures/cards.html +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/fixtures/form.html +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/fixtures/long_list.html +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/fixtures/spa.html +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/fixtures/tool_surface.json +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/integration/conftest.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/integration/test_act_observe.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/integration/test_driver_persist.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/integration/test_intent_tools.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/integration/test_multi_tab.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/integration/test_observation.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/integration/test_run_playbook.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/integration/test_wait_for.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_agentcore.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_chat_scope.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_dom_indexing.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_fill_form.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_in_app_cdp.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_indexed_tools.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_observe.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_observe_after.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_perf.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_playbooks.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_playwright_helpers.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_screenshots.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_server_shutdown.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_tool_surface.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/integrations/browser-mcp/tests/test_wait_tools.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/pytest.ini +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/scripts/create_schema.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/scripts/precommit-pytest.sh +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/scripts/release.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/scripts/smoke_global_cli.sh +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/cli/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/cli/__main__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/cli/audio_io.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/cli/gateway_manager.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/cli/main.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/cli/push_to_talk.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/cli/realtime_client.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/computer/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/computer/approvals.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/computer/permissions.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/attachments/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/attachments/catalog.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/attachments/freeze.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/attachments/text.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/attachments/tools.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/bootstrap.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/config/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/config/realtime_config.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/config/validation.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/config/yaml_loader.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/context/campaign_context.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/context/common.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/context/epoch.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/context/secret_egress.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/context/tool_output_policy.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/context/tool_result_ingress.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/context/tool_shapers.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/hooks/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/chunking.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/config.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/embeddings/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/embeddings/base.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/embeddings/factory.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/embeddings/gemini.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/embeddings/nvidia.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/embeddings/openai_compat.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/embeddings/sanitize.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/evidence_guard.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/extractors.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/fusion.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/hook.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/indexer.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/links.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/salience.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/sqlite_index.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/subsystem.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/tool.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/knowledge/types.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/layout.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/llm/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/llm/provider.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/llm/realtime_provider.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/llm/usage.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/lockfile_names.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/logging_utils.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/mcp/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/mcp/mcp_client.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/mcp/ports_mcp.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/memory/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/memory/config.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/memory/hook.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/memory/ids.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/memory/ingest.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/memory/migrate_layout.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/memory/observability.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/memory/outbox.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/memory/palace.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/memory/subsystem.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/memory/uri.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/memory/writer.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/messages/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/messages/convert_provider.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/messages/tool_integrity.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/messages/transform_context.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/path_safety.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/db.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/durable_runs.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/errors.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/firestore.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/goal_ledger.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/history.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/runs.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/session_turn_locks.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/sqlite_backend.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/sqlite_vector.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/thread_summary.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/transcript.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/usage.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/persistence/usage_buckets.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/prompts/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/context_budget.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/doom_loop.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/history_compaction.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/loop_hooks.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/loop_ports.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/loop_usage.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/provider_stream_mapper.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/tool_batch.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/runtime/utterance_buffer.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/subagents/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/subagents/progress_publish.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/subagents/subagent_proto.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/subagents/subagent_worker.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/subagents/worker_pool.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/subprocess_groups.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/testing/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/testing/mocks_provider.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/testing/mocks_realtime_provider.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/fs_isolation.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/grant_store.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/inspector.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/loop_inspector.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/patch.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/path_grant_inspector.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/permission.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/sandbox_executor.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/spill_inventory.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/terminal.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/text_normalize.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/tool_hint.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/tool_kind.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/types.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/tools/workspace_service.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/types/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/types/content_blocks.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/types/interfaces.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/types/types_tools.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/verifier/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/verifier/inspector.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/verifier/match.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/verifier/severity.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/workspace/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/workspace/factory.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/workspace/gcs.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/workspace/local.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/workspace/protocol.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/workspace/s3.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/core/workspace_layout.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/bootstrap.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/main.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/pending_response_bus.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/realtime/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/realtime/errors.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/realtime/guardrails.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/realtime/manager.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/realtime/metrics.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/realtime/session.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/realtime/wire.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/realtime_main.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/sse/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/sse/loop_port.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/sse/reload.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/sse/reply_body.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/sse/scheduler_wiring.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/sse/session_bus.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/sse/sse.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/gateway/sse/workspace_layout.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/observability/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/observability/_state.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/observability/instrumentation.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/observability/propagation.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/observability/spans.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/observability/sqlite_exporter.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/_bedrock_converse.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/_utils.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/gemini_live.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/model_capabilities.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/pricing.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/providers/sampling.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/scaffold/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/scheduler/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/scheduler/__main__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/scheduler/http_invoker.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/scheduler/interval.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/scheduler/tick_result.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/scheduler/worker.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/subagents/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/subagents/worker/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/subagents/worker/__main__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/todo_list/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/todo_list/store.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/todo_list/tool.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/web_search/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/web_search/backends/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/web_search/backends/duckduckgo.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/web_search/backends/firecrawl.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/web_search/backends/tavily.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/web_search/protocol.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/src/monkeybot/web_search/tool.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/acceptance/test_observability_acceptance.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/cli/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/cli/test_gateway_manager.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/cli/test_main.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/cli/test_push_to_talk.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/cli/test_realtime_client.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/computer/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/computer/test_approvals.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/computer/test_package_init.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/computer/test_permissions.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/computer/test_subagent_exclusion.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/computer/test_wiring.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/conftest.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/fixtures/bitbucket_dc_style_pr.diff +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/memory/helpers.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/memory/in_memory_palace.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/memory/test_mempalace.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/memory/test_review_fixes.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_agent_layout.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_attachment_freeze.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_bootstrap.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_content_blocks.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_context_budget.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_context_epoch.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_doom_loop.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_durable_events.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_durable_runs.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_empty_completion.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_env_map_grep_gates.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_evidence_guard.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_firestore_history.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_firestore_usage.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_fs_isolation.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_gemini_history_replay.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_grant_store.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_history.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_history_compaction_split.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_hooks.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_inspector.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_chunking.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_chunking_rank.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_config.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_embeddings.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_fts.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_fusion.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_fusion_ann.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_hook.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_indexer.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_links.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_salience.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_single_writer.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_subsystem.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_knowledge_vectors.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_layout.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_logging_utils.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_loop_observability.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_loop_transcript.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_mcp_client.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_memory_layout_migrate.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_message_pipeline.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_mocks_realtime_provider.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_patch.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_path_grant_inspector.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_path_safety.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_permission.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_pricing.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_progress_publish.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_prompt.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_provider_contract.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_provider_stream_mapper.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_realtime_loop.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_replace_fuzzy.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_run_command_parse.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_runs.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_runtime_env.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_sandbox_executor.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_secret_egress.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_session_turn_locks.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_settlement.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_spill_dynamic.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_spill_inventory.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_storage_backends.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_subagent_proto.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_subagent_trace_propagation.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_subagent_worker_paths.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_terminal.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_thread_summary_wire.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_tool_def_schema.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_tool_integrity.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_tool_result_ingress.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_tool_shapers.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_transcript.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_truncated_tool_batch.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_usage.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_usage_migration.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_utterance_buffer.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_worker_pool.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_workspace_extra_read_roots.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_workspace_layout.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_workspace_symlinks.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/test_workspace_write_scope.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/workspace/test_factory.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/workspace/test_local_storage.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/core/workspace/test_protocol_contract.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/eval_hook.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenario_runner.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/memory_wake_up_large.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/memory_write_inject.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/subagent_roundtrip.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/tool_glob_grep.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/tool_load_file.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/tool_loops.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/tool_read.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/tool_replace_apply_patch.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/tool_run_command.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/tool_search_knowledge.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/tool_search_memory.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/tool_todo_list.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/tool_web_search.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/tool_write.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/scenarios/turn_completion.yaml +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/test_agent_behavior.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/test_memory_knowledge_routing.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/evals/test_verifier_port.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/realtime/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/realtime/test_app.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/realtime/test_guardrails.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/realtime/test_manager.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/realtime/test_metrics.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/realtime/test_routes_client_text.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/realtime/test_session.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/realtime/test_wire.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/sse/test_config_reload.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/sse/test_create_session_model.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/sse/test_routes.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/sse/test_session_bus.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/sse/test_transcript_wiring.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/test_otel_fastapi.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/test_otel_lifespan.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/test_pending_response_endpoints.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/test_realtime_main.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/test_resolve_provider.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/gateway/test_subagent_event_publisher.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/integration/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/integration/test_mb_e2e_simple_reply.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/integration/test_observability_integration.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/integration/test_prompt_caching_integration.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/observability/conftest.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/observability/test_init.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/observability/test_instrumentation.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/observability/test_loop_hook_spans.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/observability/test_propagation.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/observability/test_span_contract.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/observability/test_spans.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/observability/test_sqlite_exporter.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/observability/test_truncate.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/observability/test_turn_complete_trace.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/conftest.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_anthropic_history.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_bedrock_converse.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_bedrock_estimate.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_gemini_history.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_gemini_live.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_gemini_usage.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_huggingface.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_model_capabilities.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_nvidia.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_openai_compat_usage.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_openai_history.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_pricing.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_safe_parse_tool_args.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_sampling.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_sonnet5_sampling.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_source_grep_gates.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/providers/test_vertex_claude_history.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/scheduler/test_interval.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/skills/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/skills/test_generate_image_script.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/test_cold_start.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/test_release_script.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/todo_list/test_todo_list.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/web_search/__init__.py +0 -0
- {monkeybot-3.3.0 → monkeybot-3.5.0}/tests/web_search/test_web_search.py +0 -0
|
@@ -6,6 +6,58 @@ the project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [core v3.5.0] - 2026-09-20
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Native durable goals beside scheduled loops (`create_goal` / `update_goal`, plus `/goals` pause/resume/stop). Continuations are scheduled automatically until the goal completes or is stopped.
|
|
14
|
+
- `FileBlock` SSE for generated documents (path/filename/mime — clients load from disk). Workspace open/export stays inside the workspace and still denies nested credential directories.
|
|
15
|
+
- HTML (`text/html`) uploads for Files preview, and `text/plain` attachments inlined at resolve.
|
|
16
|
+
- Promote a queued follow-up into the live turn (`POST /sessions/{id}/queue/{request_id}/steer`) or drop it (`DELETE`) so it never drains.
|
|
17
|
+
- Verifier: request-scoped mailbox, sticky nudge until the tracker recovers, nudge armed on judge deposit, concurrent session-bound `ProviderJudge` jobs with scoped budgets and fencing, and staged reload so live workers stay intact.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- `verifier.enabled: true` turns on omitted nested `ledger` / `tracker` flags. Omitted `judge.enabled` turns on only when the tracker is on. Explicit `enabled: false` still opts a nested section out.
|
|
22
|
+
- Omitted `verifier.ledger.model` / `verifier.judge.model` inherit the agent model (`model.name` / `MODEL_NAME`, then `gemini-2.5-flash`). The live judge worker is session-bound `ProviderJudge`.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Provider requests that exceed the multimodal byte budget drop media rather than sending an oversized body; remaining oversize fails closed. In-flight media is frozen on abort.
|
|
27
|
+
- Promoted follow-ups no longer vanish if the turn ends before they inject — they restore to the front of the follow-up queue.
|
|
28
|
+
|
|
29
|
+
### Notes
|
|
30
|
+
|
|
31
|
+
- Existing configs that set only `verifier.enabled: true` (or `enabled: true` plus `ledger.enabled: true`) now also get the tracker, and the judge if the tracker stays on. Opt out with `tracker.enabled: false` / `judge.enabled: false`.
|
|
32
|
+
|
|
33
|
+
## [cli v0.7.0] - 2026-09-20
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- New agents install a packaged `skills/goal/SKILL.md` for explicit `/goal` invocations. `monkeybot refresh` adds it when missing.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- Example YAML documents verifier nested enable-flag inheritance and optional model inherit.
|
|
42
|
+
|
|
43
|
+
## [browser v0.7.2] - 2026-09-13
|
|
44
|
+
|
|
45
|
+
#### Fixed
|
|
46
|
+
|
|
47
|
+
- Reuse the focused `about:blank` tab when opening a URL so agent `Target.createTarget` does not stack a leftover New tab next to the first real page.
|
|
48
|
+
|
|
49
|
+
## [browser v0.7.1] - 2026-09-12
|
|
50
|
+
|
|
51
|
+
#### Fixed
|
|
52
|
+
|
|
53
|
+
- Empty in-app browsers report `no page target` so `browser_act` / `run_playbook` can `goto` instead of aborting. Stale sessions still fail closed when other tabs exist.
|
|
54
|
+
|
|
55
|
+
## [core v3.4.0] - 2026-09-12
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
|
|
59
|
+
- A leading `/slug` in the user turn pins that installed skill for the turn (`## Invoked skill`) without rewriting persisted chat text.
|
|
60
|
+
|
|
9
61
|
## [browser v0.7.0] - 2026-09-10
|
|
10
62
|
|
|
11
63
|
#### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: monkeybot
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.5.0
|
|
4
4
|
Summary: monkeybot agent harness — FastAPI SSE gateway, owned loop, SQLite, and MCP.
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -11,6 +11,7 @@ Requires-Dist: google-genai>=1.0.0
|
|
|
11
11
|
Requires-Dist: httpx>=0.27.0
|
|
12
12
|
Requires-Dist: mcp<2,>=1.27.1
|
|
13
13
|
Requires-Dist: numpy<2.5,>=1.26.0
|
|
14
|
+
Requires-Dist: pillow>=10.0.0
|
|
14
15
|
Requires-Dist: pydantic>=2.10.0
|
|
15
16
|
Requires-Dist: python-dotenv>=1.0.0
|
|
16
17
|
Requires-Dist: python-ulid>=2.0.0
|
|
@@ -176,6 +176,13 @@ def install_loop_skill(dest: Path, *, force: bool) -> str:
|
|
|
176
176
|
return _install_file(target, resources.files(_DEFAULTS_PKG) / "loop" / "SKILL.md", force=force)
|
|
177
177
|
|
|
178
178
|
|
|
179
|
+
def install_goal_skill(dest: Path, *, force: bool) -> str:
|
|
180
|
+
"""Install the bundled native-goal procedure into ``skills/goal``."""
|
|
181
|
+
target = dest / "skills" / "goal" / "SKILL.md"
|
|
182
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
183
|
+
return _install_file(target, resources.files(_DEFAULTS_PKG) / "goal" / "SKILL.md", force=force)
|
|
184
|
+
|
|
185
|
+
|
|
179
186
|
def install_env_example(dest: Path, *, force: bool) -> str:
|
|
180
187
|
env_example = dest / ".env.example"
|
|
181
188
|
if env_example.exists() and not force:
|
|
@@ -399,6 +406,7 @@ def run_refresh(*, dest: Path) -> list[str]:
|
|
|
399
406
|
report.append(refresh_permissions_if_default(cfg_dir))
|
|
400
407
|
report.append(refresh_monkeybot_yaml(cfg_dir))
|
|
401
408
|
report.extend(ensure_memory(dest, force=False))
|
|
409
|
+
report.append(f" skills/goal/SKILL.md: {install_goal_skill(dest, force=False)}")
|
|
402
410
|
return report
|
|
403
411
|
|
|
404
412
|
|
|
@@ -412,11 +420,12 @@ def run_new(
|
|
|
412
420
|
) -> list[str]:
|
|
413
421
|
"""Full scaffold: config bundle, empty skills root, writable state, and image files.
|
|
414
422
|
|
|
415
|
-
|
|
423
|
+
Optional capability skills (``browser``, ``image-generator``, ``loop``) are packaged
|
|
416
424
|
under ``scaffold_defaults`` but not installed into new agents for now —
|
|
417
425
|
the Mac Main Agent loads them from ``~/.monkeybot/.internal/skills``
|
|
418
426
|
instead. Re-enable via ``install_*_skill`` when custom agents should get
|
|
419
|
-
them again.
|
|
427
|
+
them again. The ``goal`` skill is installed because native goal tools are
|
|
428
|
+
intentionally exposed only for explicit ``/goal`` invocations.
|
|
420
429
|
"""
|
|
421
430
|
cfg_dir = dest / "monkeybot_config"
|
|
422
431
|
report = install_config_bundle(cfg_dir, force=force)
|
|
@@ -426,7 +435,7 @@ def run_new(
|
|
|
426
435
|
)
|
|
427
436
|
report.extend(ensure_memory(dest, force=force))
|
|
428
437
|
report.extend(ensure_workspace(dest, force=force))
|
|
429
|
-
report.append(" skills
|
|
438
|
+
report.append(f" skills/goal/SKILL.md: {install_goal_skill(dest, force=force)}")
|
|
430
439
|
report.append(f" .env.example: {install_env_example(dest, force=force)}")
|
|
431
440
|
report.extend(install_container_files(dest, force=force))
|
|
432
441
|
report.append(
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: goal
|
|
3
|
+
description: Create one durable objective that continues across scheduled turns until completed.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Goal
|
|
7
|
+
|
|
8
|
+
Use this skill only when the user explicitly invokes `/goal` with an objective
|
|
9
|
+
that may require multiple turns.
|
|
10
|
+
|
|
11
|
+
## Start
|
|
12
|
+
|
|
13
|
+
1. Preserve the user's complete objective without narrowing its scope.
|
|
14
|
+
2. Call `create_goal` exactly once with that objective.
|
|
15
|
+
3. Do the first concrete increment of work in the same turn.
|
|
16
|
+
4. Keep the returned goal id; every `update_goal` call must include it.
|
|
17
|
+
|
|
18
|
+
## Continue
|
|
19
|
+
|
|
20
|
+
- Goal continuations are scheduled automatically.
|
|
21
|
+
- Treat the stored objective as authoritative.
|
|
22
|
+
- Make measurable progress and verify results before declaring completion.
|
|
23
|
+
- Temporary session-busy deferrals are normal and are not goal failures.
|
|
24
|
+
- Persistent execution failures stop the goal after the retry limit so it
|
|
25
|
+
cannot consume resources indefinitely.
|
|
26
|
+
|
|
27
|
+
## Complete
|
|
28
|
+
|
|
29
|
+
Call `update_goal` with the returned `goal_id` and `status="complete"` only
|
|
30
|
+
after evidence proves every requirement is satisfied. Otherwise leave the goal
|
|
31
|
+
active. Use the `/goals` control plane to pause, resume, or stop it manually.
|
{monkeybot-3.3.0 → monkeybot-3.5.0}/cli/src/monkeybot_cli/scaffold_defaults/monkeybot.example.yaml
RENAMED
|
@@ -253,6 +253,17 @@ scheduler:
|
|
|
253
253
|
# Env override: MONKEYBOT_SCHEDULER_ENABLED (1 | true | yes | on).
|
|
254
254
|
enabled: false
|
|
255
255
|
|
|
256
|
+
# Background verifier (YAML-only). Off by default: ledger costs one model call
|
|
257
|
+
# per human message. `enabled: true` turns on omitted ledger/tracker flags;
|
|
258
|
+
# omitted judge.enabled turns on only when the tracker is on. Explicit
|
|
259
|
+
# `enabled: false` still opts a nested section out. Omitted ledger.model /
|
|
260
|
+
# judge.model inherit model.name (same fallback as the agent). The live
|
|
261
|
+
# worker is session-bound ProviderJudge. Realtime loops ignore this block.
|
|
262
|
+
# verifier:
|
|
263
|
+
# enabled: true
|
|
264
|
+
# escalation:
|
|
265
|
+
# max_severity: nudge
|
|
266
|
+
|
|
256
267
|
# Optional JSON for model.provider: fake tests (env: MONKEYBOT_FAKE_PROVIDER_EVENTS)
|
|
257
268
|
# fake_provider:
|
|
258
269
|
# events_json: '[[]]'
|
|
@@ -34,6 +34,7 @@ def test_run_new_creates_bundle(tmp_path: Path) -> None:
|
|
|
34
34
|
assert not (tmp_path / "skills" / "browser").exists()
|
|
35
35
|
assert not (tmp_path / "skills" / "image-generator").exists()
|
|
36
36
|
assert not (tmp_path / "skills" / "loop").exists()
|
|
37
|
+
assert (tmp_path / "skills" / "goal" / "SKILL.md").is_file()
|
|
37
38
|
assert (tmp_path / "workspace" / ".gitkeep").is_file()
|
|
38
39
|
assert (tmp_path / "workspace" / "browser" / "playbooks").is_dir()
|
|
39
40
|
assert (tmp_path / "workspace" / "generated-media" / "images").is_dir()
|
|
@@ -153,6 +154,8 @@ def test_run_refresh_adds_template_commands_and_keeps_extras(tmp_path: Path) ->
|
|
|
153
154
|
doc = yaml.safe_load(yaml_path.read_text(encoding="utf-8")) or {}
|
|
154
155
|
doc.pop("memory", None)
|
|
155
156
|
yaml_path.write_text(yaml.safe_dump(doc, sort_keys=False), encoding="utf-8")
|
|
157
|
+
goal_skill = tmp_path / "skills" / "goal" / "SKILL.md"
|
|
158
|
+
goal_skill.unlink()
|
|
156
159
|
|
|
157
160
|
report = run_refresh(dest=tmp_path)
|
|
158
161
|
text = allow.read_text(encoding="utf-8")
|
|
@@ -166,6 +169,7 @@ def test_run_refresh_adds_template_commands_and_keeps_extras(tmp_path: Path) ->
|
|
|
166
169
|
refreshed_yaml = yaml_path.read_text(encoding="utf-8")
|
|
167
170
|
assert "enabled: true" in refreshed_yaml
|
|
168
171
|
assert "custom persona" not in refreshed_yaml
|
|
172
|
+
assert goal_skill.is_file()
|
|
169
173
|
joined = "\n".join(report)
|
|
170
174
|
assert "command_allowlist.yaml: updated" in joined
|
|
171
175
|
assert "monkeybot.yaml: updated" in joined
|
|
@@ -174,7 +178,10 @@ def test_run_refresh_adds_template_commands_and_keeps_extras(tmp_path: Path) ->
|
|
|
174
178
|
def test_run_refresh_skips_custom_permissions_and_model(tmp_path: Path) -> None:
|
|
175
179
|
run_new(dest=tmp_path, force=False, provider="nvidia", model="keep-me")
|
|
176
180
|
perms = tmp_path / "monkeybot_config" / "permissions.yaml"
|
|
177
|
-
perms.write_text(
|
|
181
|
+
perms.write_text(
|
|
182
|
+
"default: deny\nrules:\n - tool: '*'\n pattern: '*'\n effect: deny\n",
|
|
183
|
+
encoding="utf-8",
|
|
184
|
+
)
|
|
178
185
|
yaml_path = tmp_path / "monkeybot_config" / "monkeybot.yaml"
|
|
179
186
|
before = yaml_path.read_text(encoding="utf-8")
|
|
180
187
|
|
|
@@ -97,8 +97,10 @@ One **user message** may span multiple **inner turns** (model → tools → mode
|
|
|
97
97
|
| Reply | `POST /sessions/{id}/reply` | Session idle | Starts a turn immediately (`SESSION_BUSY` if busy) |
|
|
98
98
|
| Steer | `POST /sessions/{id}/steer` | Session busy | Injected after current tool batch / before next provider call |
|
|
99
99
|
| Follow-up | `POST /sessions/{id}/queue` | Busy → enqueue; idle → start | FIFO drain after `TurnComplete` / lock release |
|
|
100
|
+
| Promote | `POST /sessions/{id}/queue/{request_id}/steer` | A turn is live and the item is still queued. 409 `SESSION_IDLE` otherwise — promote is not meaningful between turns (including while a follow-up is waiting on the lock-retry path); those items drain automatically. | Atomic move from follow-up → steer; injected at the next inner-turn boundary. If the turn ends first, the item is restored to the front of the follow-up FIFO and starts its own turn. `QueuedInputAccepted.request_id` is the in-flight turn (same as `POST /steer`); the follow-up id is `UserSteered.queued_request_id`. |
|
|
101
|
+
| Drop | `DELETE /sessions/{id}/queue/{request_id}` | Item still in the follow-up queue (or popped by drain but not yet started) | Removes it so it will not drain or promote |
|
|
100
102
|
|
|
101
|
-
Do **not** conflate with HITL `ToolConfirmationRequest`. Cancel clears pending steer; follow-ups survive. Caps: `MONKEYBOT_STEER_QUEUE_MAX` (default 8), `MONKEYBOT_FOLLOW_UP_QUEUE_MAX` (default 16).
|
|
103
|
+
Do **not** conflate with HITL `ToolConfirmationRequest`. Cancel clears pending steer; follow-ups survive (including follow-ups that had been promoted and not yet injected). Caps: `MONKEYBOT_STEER_QUEUE_MAX` (default 8), `MONKEYBOT_FOLLOW_UP_QUEUE_MAX` (default 16). `UserSteered.request_id` is always the in-flight turn; `queued_request_id` is set when the injected steer came from a promoted follow-up.
|
|
102
104
|
|
|
103
105
|
**Process-local only:** steer/follow-up queues live on the in-process `SessionBus` (same constraint as the SSE registry). Multi-replica gateways do not share admission queues across instances — pin sticky sessions to one replica, or treat `/queue` as best-effort for single-process deployments. If drain cannot acquire the durable turn lock (another replica / stale claim), the item is requeued and retried on an interval (`MONKEYBOT_FOLLOW_UP_LOCK_RETRY_S`, default 1s) until the lock frees or the wait budget expires (`MONKEYBOT_FOLLOW_UP_LOCK_WAIT_MS`, default = session-turn stale window), after which that follow-up is dropped so the queue cannot wedge forever.
|
|
104
106
|
|
|
@@ -657,7 +659,7 @@ Before spawning the gateway, the CLI probes that interpreter for MonkeyBot `>=3.
|
|
|
657
659
|
|
|
658
660
|
**How it works:**
|
|
659
661
|
- Off by default, macOS-only: `computer.enabled: true` in `monkeybot.yaml` → `MONKEYBOT_COMPUTER_TOOLS` env, combined with a hard `sys.platform == "darwin"` check (`should_enable_computer_tools()`). The desktop app sets the env var when it spawns a gateway with the feature turned on in Settings; no other deployment should ever set it.
|
|
660
|
-
- **Hard security boundary lives in the tool bodies, not in `permissions.yaml`** (`safety.py`): every path is resolved and validated against the user's home directory after following symlinks; a fixed denylist blocks credential directories (`.ssh`, `.aws`, keychains, browser profiles, the app's own config) both at their canonical location *and* by directory-name anywhere in the tree; filenames matching credential patterns (`.env`, `*.pem`, `id_rsa*`, …) are always refused; `computer_open` refuses any path/app that would make `open` execute code (`.command`, `.app`, `.sh`, Terminal, script editors, …); trash never hard-deletes. `permissions.yaml` is fail-open (a broken file silently disables it), so none of this can depend on it. `_denied_dirs()` also always includes `MONKEYBOT_WORKSPACE_ROOT` (not only under `MONKEYBOT_APP_HOME`, which only the desktop app sets) — a CLI-scaffolded agent's workspace can sit anywhere under `$HOME` the user chose
|
|
662
|
+
- **Hard security boundary lives in the tool bodies, not in `permissions.yaml`** (`safety.py`): every path is resolved and validated against the user's home directory after following symlinks; a fixed denylist blocks credential directories (`.ssh`, `.aws`, keychains, browser profiles, the app's own config) both at their canonical location *and* by directory-name anywhere in the tree; filenames matching credential patterns (`.env`, `*.pem`, `id_rsa*`, …) are always refused; `computer_open` refuses any path/app that would make `open` execute code (`.command`, `.app`, `.sh`, Terminal, script editors, …); trash never hard-deletes. `permissions.yaml` is fail-open (a broken file silently disables it), so none of this can depend on it. `_denied_dirs()` also always includes `MONKEYBOT_WORKSPACE_ROOT` (not only under `MONKEYBOT_APP_HOME`, which only the desktop app sets) — a CLI-scaffolded agent's workspace can sit anywhere under `$HOME` the user chose. Destinations and `computer_trash` still cannot write into it. A workspace *source* may be copied (not moved) out only when it is a generated document (PDF, images, office files); `computer_open` of workspace exec surfaces (`.terminal`, `.webloc`, `.fileloc`, …) is denied. `computer_move`'s own description now says so, so the model doesn't reach for it as a `read_file`/`run_command` workaround.
|
|
661
663
|
- **Every `computer_*` call asks by default**, via a built-in baseline rule (`COMPUTER_BASELINE_RULES` in `permissions.py`) — not a line in `permissions.yaml`, so it can't be silently defeated by a missing/broken config file. `ComputerAwarePermissionInspector` layers, last-match-wins: baseline `ask` < durable approvals overlay `allow` < the user's `permissions.yaml` (highest authority — a hand-written `deny` always wins).
|
|
662
664
|
- **"Always allow" is durable and narrow**: `monkeybot_config/approvals.json` (machine-written, JSON — deliberately *not* appended into `permissions.yaml`, which is a comment-heavy file the app's Advanced settings save wholesale) stores one exact `(tool, resource)` pair per rule. Mutating tools (`computer_move`, `computer_trash`) are excluded from `ALWAYS_SCOPE` — their resource is the *source* path only, so an "always" rule would cover any destination — every call to them asks. The inspector re-`stat`s the overlay file on every check and reloads on change; on a genuine change it also clears the session-level approval cache, so a revoke in the app's Settings takes effect immediately rather than waiting for a gateway restart.
|
|
663
665
|
- Registered via the standard `extra_tools` extension point in both the SSE (`gateway/sse/app.py`) and realtime (`gateway/realtime/routes.py`) gateways — same mechanism as `web_search`/`todo_list`. Never registered for subagents (`subagent_worker.py` builds its own `extra_tools` independently and never imports this package).
|
|
@@ -104,7 +104,8 @@ Common types you will handle in a chat UI:
|
|
|
104
104
|
| `ToolCallStarted` / `ToolCallResult` | Tool name, args, result text / error. |
|
|
105
105
|
| `TurnComplete` | Turn finished; includes `usage` (`input_tokens`, `output_tokens`, `cached_tokens`, `cost_usd`, `duration_ms`, `estimated_prompt_tokens` — see [Session usage endpoint](#session-usage-endpoint)). |
|
|
106
106
|
| `Error` | Recoverable stream error string in `error`. |
|
|
107
|
-
| `ImageBlock` | Inline image (`mime_type`, base64 `data`). |
|
|
107
|
+
| `ImageBlock` | Inline image (`mime_type`, workspace `path`, or base64 `data` when no path). |
|
|
108
|
+
| `FileBlock` | Generated document (`mime_type`, workspace `path`, `filename`, `file_id`). Path-only — clients load from disk; raw PDF bytes are never sent on the wire. |
|
|
108
109
|
| `ThinkingBlockDelta` / `ThinkingBlockComplete` / `RedactedThinkingBlock` | Extended thinking blocks where the model exposes them. |
|
|
109
110
|
| `ToolConfirmationRequest` | User must approve/deny; POST to `tool-confirmations` with `tool_call_id`. Carries `tool_name`, `arguments` (the tool's raw call args — e.g. `path`/`url`/`app` for `computer_*` tools, useful for showing *what* is being approved), and an optional human-readable `prompt`. The reference Textual client can auto-answer these client-side in `auto-approve`/`deny-confirms` mode (`Shift+Tab` in `monkeybot chat`) — this is purely a UI convenience, no gateway change; `ActionRequiredEvent` elicitations are never auto-answered. |
|
|
110
111
|
| `ActionRequiredEvent` | e.g. `action_type: "elicitation"` with `id` and `payload`; POST to `elicitations/{id}`. |
|
|
@@ -70,8 +70,9 @@ A new session should read this section, then Part 8. Phases 0–6 are in the tre
|
|
|
70
70
|
- `NudgeActuator` on `PRE_TOOL`; drain caps severity and stashes one nudge.
|
|
71
71
|
- `tail_grace_s` on the turn-tail drain only, and only while the judge has a call in flight
|
|
72
72
|
(`mailbox.pending`) — an idle turn never pays the grace.
|
|
73
|
-
-
|
|
74
|
-
whose request has already finished is dropped, not applied to
|
|
73
|
+
- Sticky nudges (`activate_nudge`/`peek_nudge`) and replan notes (`put_replan`/`take_replan`)
|
|
74
|
+
are request-scoped: a note whose request has already finished is dropped, not applied to
|
|
75
|
+
the next user message.
|
|
75
76
|
- Judge rate limits are charged at `enqueue` and refunded when no verdict lands, so a slow port
|
|
76
77
|
cannot slip past `max_verdicts_per_message` while a call is in flight.
|
|
77
78
|
- Tests: `tests/core/test_progress_tracker.py` (`test_nudge_reaches_next_system_message_once`), `tests/evals/test_verifier_port.py`.
|
|
@@ -725,16 +726,16 @@ New `verifier:` block in `monkeybot.yaml`, defaulted off. The section is **YAML-
|
|
|
725
726
|
verifier:
|
|
726
727
|
enabled: false # master switch; when false, NOTHING below runs
|
|
727
728
|
ledger:
|
|
728
|
-
enabled: false #
|
|
729
|
-
model: gemini-2.5-flash
|
|
729
|
+
enabled: false # omitted → follows verifier.enabled
|
|
730
|
+
# model: # omitted / null → inherit model.name (then gemini-2.5-flash)
|
|
730
731
|
max_entries_per_thread: 64
|
|
731
732
|
tracker:
|
|
732
|
-
enabled: false #
|
|
733
|
+
enabled: false # omitted → follows verifier.enabled
|
|
733
734
|
suspicion_threshold: 3
|
|
734
735
|
min_turn_before_verdict: 3
|
|
735
736
|
judge:
|
|
736
|
-
enabled: false #
|
|
737
|
-
model:
|
|
737
|
+
enabled: false # omitted → on only when parent and tracker are on
|
|
738
|
+
# model: # reserved; SignalJudge ignores it today
|
|
738
739
|
max_verdicts_per_message: 3
|
|
739
740
|
min_turns_between_verdicts: 2
|
|
740
741
|
max_spend_ratio: 0.25 # of main-agent tokens for this message
|
|
@@ -743,16 +744,18 @@ verifier:
|
|
|
743
744
|
max_severity: nudge # nudge | replan | steer | block
|
|
744
745
|
```
|
|
745
746
|
|
|
746
|
-
**Gating is
|
|
747
|
+
**Gating is hierarchical.** Precedence, highest first:
|
|
747
748
|
|
|
748
749
|
1. **`verifier.enabled` is the master switch.** When `false`, nothing below runs — not the ledger, not the tracker, not the judge, and not actuation — regardless of child `enabled` flags or `escalation.max_severity`. That is the one switch an operator needs to turn the whole feature off.
|
|
749
|
-
2. **
|
|
750
|
-
3. **`judge` requires `tracker
|
|
750
|
+
2. **When the master is on, omitted child `enabled` flags inherit on** for `ledger` and `tracker`. Omitted `judge.enabled` inherits on only if the tracker is on. Explicit `enabled: false` still opts a nested section out. A child set `true` while the master is `false` is a no-op, not an override.
|
|
751
|
+
3. **`judge` requires `tracker` at runtime.** `build_verifier` skips an explicit `judge.enabled: true` when the tracker is off and logs that skip. `tracker` without `ledger` runs only the ledger-independent signals (`error_streak`, `no_progress`, `write_without_read`, `budget_burn`, `rewrite_churn`). `ledger` can run alone (Phase 1 ships this way).
|
|
751
752
|
4. **`escalation.max_severity` caps actuation, it does not enable anything.** `enabled: true` plus `max_severity: none` is "on but muted": observe/record verdicts at `none`, never nudge/replan/steer/block. Raising the cap cannot turn on a disabled child. The smoke fixture `evals/smoke_agent/monkeybot_config/monkeybot.verifier-on.yaml` uses this shape on purpose.
|
|
752
753
|
|
|
753
754
|
The parser does not rewrite child flags when the master is off; readers must check `verifier.enabled` first. `max_severity` values are `none | nudge | replan | steer | block` in that rank order (`VERIFIER_SEVERITY_ORDER` in `core/config/settings.py`). `steer` is reserved for a later optional phase; Phases 4–6 ship nudge/replan/block.
|
|
754
755
|
|
|
755
|
-
The
|
|
756
|
+
The dataclass default for every nested `enabled` is still `false` so an absent `verifier:` section stays off. The inheritance rule above is the upgrade hazard: an existing file that set only `verifier.enabled: true` plus `ledger.enabled: true` now also gets the tracker (and the judge if the tracker stays on). Opt out with `tracker.enabled: false` / `judge.enabled: false`.
|
|
757
|
+
|
|
758
|
+
Omitted `ledger.model` / `judge.model` resolve through `effective_verifier_model` — the same `model.name` / `MODEL_NAME` / `gemini-2.5-flash` chain as `get_provider_config`. `judge.model` is reserved; today's worker is the deterministic `SignalJudge`.
|
|
756
759
|
|
|
757
760
|
**Plumbing is a typed snapshot field, not an env map.** Mirror `subagents:`:
|
|
758
761
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "monkeybot-browser-mcp"
|
|
7
|
-
version = "0.7.
|
|
7
|
+
version = "0.7.2"
|
|
8
8
|
description = "monkeybot MCP server wrapping browser-harness for real-browser control and site playbooks."
|
|
9
9
|
requires-python = ">=3.11"
|
|
10
10
|
dependencies = [
|
|
@@ -151,7 +151,10 @@ def prepare_action(
|
|
|
151
151
|
)
|
|
152
152
|
except tabs.UnknownTabError as exc:
|
|
153
153
|
return PreparedAction(error=results.unknown_tab_result(exc), mode=mode)
|
|
154
|
-
before_url =
|
|
154
|
+
before_url = ""
|
|
155
|
+
if capture_url:
|
|
156
|
+
info = handle.page_info()
|
|
157
|
+
before_url = str(info.get("url") or "") if isinstance(info, dict) else ""
|
|
155
158
|
return PreparedAction(
|
|
156
159
|
error=None, helpers=helpers, handle=handle, mode=mode, before_url=before_url
|
|
157
160
|
)
|
|
@@ -76,8 +76,30 @@ def _close_target(helpers: Any, target_id: str) -> None:
|
|
|
76
76
|
raise tabs.SingleTabBackendError()
|
|
77
77
|
|
|
78
78
|
|
|
79
|
+
def _blank_target_id(helpers: Any) -> str | None:
|
|
80
|
+
"""Reuse the focused about:blank tab instead of stacking a New tab."""
|
|
81
|
+
if not callable(getattr(helpers, "current_tab", None)):
|
|
82
|
+
return None
|
|
83
|
+
try:
|
|
84
|
+
row = helpers.current_tab()
|
|
85
|
+
except Exception:
|
|
86
|
+
logger.debug("current_tab failed while looking for a blank tab", exc_info=True)
|
|
87
|
+
return None
|
|
88
|
+
if not isinstance(row, dict):
|
|
89
|
+
return None
|
|
90
|
+
if not actions._is_blank_url(str(row.get("url") or "")):
|
|
91
|
+
return None
|
|
92
|
+
tid = row.get("targetId") or row.get("target_id")
|
|
93
|
+
return str(tid) if tid else None
|
|
94
|
+
|
|
95
|
+
|
|
79
96
|
def _create_blank_target(helpers: Any, *, focus: bool, url: str = "about:blank") -> bool:
|
|
80
97
|
"""Create a tab. Returns True if ``url`` was already loaded by the helper."""
|
|
98
|
+
existing = _blank_target_id(helpers)
|
|
99
|
+
if existing:
|
|
100
|
+
if focus:
|
|
101
|
+
helpers.switch_tab(existing)
|
|
102
|
+
return actions._is_blank_url(url)
|
|
81
103
|
if callable(getattr(helpers, "cdp", None)):
|
|
82
104
|
try:
|
|
83
105
|
result = helpers.cdp(
|
|
@@ -19,7 +19,9 @@ from typing import Any
|
|
|
19
19
|
|
|
20
20
|
_ALIAS_RE = re.compile(r"^[a-z][a-z0-9_-]{0,23}$")
|
|
21
21
|
_CHROME_INTERNAL = ("chrome://", "chrome-untrusted://", "devtools://", "chrome-extension://")
|
|
22
|
-
|
|
22
|
+
# Chrome: "Session with given id not found". Monkeyapp's flatten CDP bridge:
|
|
23
|
+
# "unknown session" when the harness still holds a detached sessionId.
|
|
24
|
+
_SESSION_GONE_MARKERS = ("session with given id", "unknown session")
|
|
23
25
|
logger = logging.getLogger(__name__)
|
|
24
26
|
_SINGLE_TAB_MARKERS = (
|
|
25
27
|
"not allowed",
|
|
@@ -96,8 +98,18 @@ def _has_helper(helpers: Any, name: str) -> bool:
|
|
|
96
98
|
return callable(getattr(helpers, name, None))
|
|
97
99
|
|
|
98
100
|
|
|
101
|
+
def _message_has_marker(exc: BaseException, markers: tuple[str, ...]) -> bool:
|
|
102
|
+
text = str(exc).lower()
|
|
103
|
+
return any(marker in text for marker in markers)
|
|
104
|
+
|
|
105
|
+
|
|
99
106
|
def _session_gone(exc: BaseException) -> bool:
|
|
100
|
-
return
|
|
107
|
+
return _message_has_marker(exc, _SESSION_GONE_MARKERS)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def is_missing_page_error(exc: BaseException) -> bool:
|
|
111
|
+
"""True when CDP has no live page (empty tabs). Fail-closed on unknown session."""
|
|
112
|
+
return "no page target" in str(exc).lower()
|
|
101
113
|
|
|
102
114
|
|
|
103
115
|
def _log_detach_failure(session_id: str, exc: BaseException) -> None:
|
|
@@ -271,19 +283,25 @@ class TabHandle:
|
|
|
271
283
|
return self.helpers.goto_url(url, target_id=self.state.target_id)
|
|
272
284
|
|
|
273
285
|
def page_info(self) -> dict[str, Any]:
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
286
|
+
try:
|
|
287
|
+
if self.focused or self.state is None:
|
|
288
|
+
info = self.helpers.page_info()
|
|
289
|
+
return info if isinstance(info, dict) else {}
|
|
290
|
+
raw = self.evaluate(_PAGE_INFO_JS)
|
|
291
|
+
if isinstance(raw, dict):
|
|
292
|
+
return raw
|
|
293
|
+
if isinstance(raw, str):
|
|
294
|
+
try:
|
|
295
|
+
parsed = json.loads(raw)
|
|
296
|
+
except json.JSONDecodeError:
|
|
297
|
+
return {}
|
|
298
|
+
return parsed if isinstance(parsed, dict) else {}
|
|
299
|
+
return {}
|
|
300
|
+
except Exception as exc:
|
|
301
|
+
if is_missing_page_error(exc):
|
|
302
|
+
logger.debug("page_info: no live page yet", exc_info=True)
|
|
284
303
|
return {}
|
|
285
|
-
|
|
286
|
-
return {}
|
|
304
|
+
raise
|
|
287
305
|
|
|
288
306
|
def capture_screenshot(
|
|
289
307
|
self, path: str | None = None, full: bool = False, max_dim: int | None = None
|
|
@@ -119,6 +119,36 @@ def test_act_stop_on_error_returns_completed_and_observation() -> None:
|
|
|
119
119
|
assert result["observation"]["mode"] in {"diff", "full"}
|
|
120
120
|
|
|
121
121
|
|
|
122
|
+
def test_act_goto_opens_tab_when_page_info_has_no_page() -> None:
|
|
123
|
+
"""Empty in-app browser must not abort act/goto."""
|
|
124
|
+
helpers = MagicMock()
|
|
125
|
+
helpers.list_tabs.return_value = []
|
|
126
|
+
helpers.current_tab.return_value = None
|
|
127
|
+
helpers.js.return_value = True
|
|
128
|
+
|
|
129
|
+
def page_info() -> dict[str, str]:
|
|
130
|
+
if helpers.new_tab.called:
|
|
131
|
+
return {"url": "https://a.test/", "title": "A", "w": "800", "h": "600"}
|
|
132
|
+
raise RuntimeError("no page target")
|
|
133
|
+
|
|
134
|
+
helpers.page_info.side_effect = page_info
|
|
135
|
+
with (
|
|
136
|
+
_patch_harness(helpers),
|
|
137
|
+
patch.object(dom_indexing, "settle", return_value={"quiet": True, "navigated": False}),
|
|
138
|
+
patch.object(dom_indexing, "_register_driver_for_new_documents"),
|
|
139
|
+
patch.object(dom_indexing, "get_elements") as get_elements,
|
|
140
|
+
):
|
|
141
|
+
result = json.loads(
|
|
142
|
+
server.browser_act(
|
|
143
|
+
[{"do": "goto", "url": "https://a.test/"}],
|
|
144
|
+
observe="none",
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
assert result["ok"] is True
|
|
148
|
+
helpers.new_tab.assert_called_once_with("https://a.test/")
|
|
149
|
+
get_elements.assert_not_called()
|
|
150
|
+
|
|
151
|
+
|
|
122
152
|
def test_act_observe_none_skips_snapshot() -> None:
|
|
123
153
|
helpers = _helpers()
|
|
124
154
|
with (
|
|
@@ -144,6 +144,46 @@ def test_list_playbooks_includes_flows() -> None:
|
|
|
144
144
|
assert listed["flows"] == [{"host": "a.test", "name": "signup", "params": ["nickname"]}]
|
|
145
145
|
|
|
146
146
|
|
|
147
|
+
def test_run_playbook_opens_tab_when_page_info_has_no_page() -> None:
|
|
148
|
+
playbooks.write_playbook("a.test", _SIGNUP)
|
|
149
|
+
helpers = MagicMock()
|
|
150
|
+
helpers.list_tabs.return_value = []
|
|
151
|
+
helpers.current_tab.return_value = None
|
|
152
|
+
helpers.js.return_value = True
|
|
153
|
+
|
|
154
|
+
def page_info() -> dict[str, str]:
|
|
155
|
+
if helpers.new_tab.called:
|
|
156
|
+
return {"url": "https://a.test/form.html", "title": "A"}
|
|
157
|
+
raise RuntimeError("no page target")
|
|
158
|
+
|
|
159
|
+
helpers.page_info.side_effect = page_info
|
|
160
|
+
with (
|
|
161
|
+
_patch_harness(helpers),
|
|
162
|
+
patch.object(dom_indexing, "settle", return_value={"quiet": True, "navigated": False}),
|
|
163
|
+
patch.object(dom_indexing, "_register_driver_for_new_documents"),
|
|
164
|
+
patch.object(
|
|
165
|
+
actions,
|
|
166
|
+
"do_fill_form",
|
|
167
|
+
return_value={
|
|
168
|
+
"ok": True,
|
|
169
|
+
"filled": [{"label": "Nickname", "index": 1, "how": "label_for"}],
|
|
170
|
+
"unresolved": [],
|
|
171
|
+
"submitted": True,
|
|
172
|
+
},
|
|
173
|
+
),
|
|
174
|
+
patch.object(playbooks, "check_expect", return_value=None),
|
|
175
|
+
):
|
|
176
|
+
result = json.loads(
|
|
177
|
+
server.browser_run_playbook(
|
|
178
|
+
"a.test", "signup", {"nickname": "ada"}, observe="none"
|
|
179
|
+
)
|
|
180
|
+
)
|
|
181
|
+
assert result["ok"] is True
|
|
182
|
+
helpers.new_tab.assert_called_once_with("https://a.test/form.html")
|
|
183
|
+
assert result["name"] == "signup"
|
|
184
|
+
assert len(result["completed"]) == 2
|
|
185
|
+
|
|
186
|
+
|
|
147
187
|
def test_run_playbook_success_and_expect() -> None:
|
|
148
188
|
playbooks.write_playbook("a.test", _SIGNUP)
|
|
149
189
|
helpers = _helpers()
|
|
@@ -149,6 +149,27 @@ def test_user_opened_untouched_tabs_do_not_count_toward_cap(
|
|
|
149
149
|
)
|
|
150
150
|
|
|
151
151
|
|
|
152
|
+
def test_open_tab_reuses_focused_blank_instead_of_creating() -> None:
|
|
153
|
+
helpers = _helpers(tabs_list=[_tab("blank", "about:blank")], focused="blank")
|
|
154
|
+
helpers.cdp = MagicMock()
|
|
155
|
+
|
|
156
|
+
def goto_url(url: str, **_k: object) -> str:
|
|
157
|
+
helpers.current_tab.return_value = _tab("blank", url)
|
|
158
|
+
helpers.page_info.return_value = {"url": url, "title": "t", "w": 800, "h": 600}
|
|
159
|
+
return url
|
|
160
|
+
|
|
161
|
+
helpers.goto_url.side_effect = goto_url
|
|
162
|
+
with _patch_harness(helpers):
|
|
163
|
+
json.loads(server.browser_tabs())
|
|
164
|
+
result = json.loads(server.browser_open_tab("https://ex.test/new"))
|
|
165
|
+
assert result["ok"] is True
|
|
166
|
+
assert result["url"] == "https://ex.test/new"
|
|
167
|
+
assert all(
|
|
168
|
+
not (c.args and c.args[0] == "Target.createTarget")
|
|
169
|
+
for c in helpers.cdp.call_args_list
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
|
|
152
173
|
def test_close_tab_then_retry_succeeds(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
153
174
|
monkeypatch.setenv("BROWSER_MCP_MAX_TABS", "1")
|
|
154
175
|
user = _tab("user", "https://user.test/")
|
|
@@ -208,6 +229,49 @@ def test_browser_stop_closes_agent_opened_tabs_at_cap(
|
|
|
208
229
|
assert helpers.close_tab.call_count == 5
|
|
209
230
|
|
|
210
231
|
|
|
232
|
+
def test_session_for_reattaches_on_unknown_session() -> None:
|
|
233
|
+
helpers = MagicMock()
|
|
234
|
+
helpers.cdp.side_effect = [
|
|
235
|
+
{"sessionId": "sid-1"},
|
|
236
|
+
{},
|
|
237
|
+
{},
|
|
238
|
+
RuntimeError("{'code': -32000, 'message': 'unknown session'}"),
|
|
239
|
+
{"sessionId": "sid-2"},
|
|
240
|
+
{},
|
|
241
|
+
{},
|
|
242
|
+
{"result": {"type": "string", "value": "ok"}},
|
|
243
|
+
]
|
|
244
|
+
state = TabState(target_id="aaa", tab="t1", alias="t1")
|
|
245
|
+
tabs.reset_registry()
|
|
246
|
+
tabs.registry()._tabs["aaa"] = state
|
|
247
|
+
tabs.registry()._aliases["t1"] = "aaa"
|
|
248
|
+
handle = tabs.TabHandle(helpers, state, focused=False)
|
|
249
|
+
assert handle.evaluate("1+1") == "ok"
|
|
250
|
+
methods = [c.args[0] for c in helpers.cdp.call_args_list]
|
|
251
|
+
assert methods.count("Target.attachToTarget") == 2
|
|
252
|
+
assert state.session_id == "sid-2"
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def test_focused_page_info_returns_empty_on_no_page() -> None:
|
|
256
|
+
helpers = MagicMock()
|
|
257
|
+
helpers.page_info.side_effect = RuntimeError("no page target")
|
|
258
|
+
handle = tabs.TabHandle(helpers, None, focused=True)
|
|
259
|
+
assert handle.page_info() == {}
|
|
260
|
+
assert tabs.is_missing_page_error(RuntimeError("no page target"))
|
|
261
|
+
assert not tabs.is_missing_page_error(RuntimeError("unknown session"))
|
|
262
|
+
assert not tabs.is_missing_page_error(RuntimeError("tab sealed"))
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def test_focused_page_info_raises_on_unknown_session() -> None:
|
|
266
|
+
helpers = MagicMock()
|
|
267
|
+
helpers.page_info.side_effect = RuntimeError(
|
|
268
|
+
"{'code': -32000, 'message': 'unknown session'}"
|
|
269
|
+
)
|
|
270
|
+
handle = tabs.TabHandle(helpers, None, focused=True)
|
|
271
|
+
with pytest.raises(RuntimeError, match="unknown session"):
|
|
272
|
+
handle.page_info()
|
|
273
|
+
|
|
274
|
+
|
|
211
275
|
def test_session_for_attaches_once_and_reattaches_on_lost_session() -> None:
|
|
212
276
|
helpers = MagicMock()
|
|
213
277
|
helpers.cdp.side_effect = [
|