monkeybot 3.2.0__tar.gz → 3.3.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.
Files changed (741) hide show
  1. {monkeybot-3.2.0 → monkeybot-3.3.0}/CHANGELOG.md +24 -1
  2. {monkeybot-3.2.0 → monkeybot-3.3.0}/PKG-INFO +2 -2
  3. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/browser-mcp.md +33 -0
  4. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/features.md +19 -14
  5. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/pyproject.toml +1 -1
  6. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/app.py +8 -9
  7. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/backend.py +33 -2
  8. monkeybot-3.3.0/integrations/browser-mcp/src/browser_mcp/chat_scope.py +139 -0
  9. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/in_app_cdp.py +5 -0
  10. monkeybot-3.3.0/integrations/browser-mcp/tests/test_chat_scope.py +276 -0
  11. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/uv.lock +1 -1
  12. {monkeybot-3.2.0 → monkeybot-3.3.0}/pyproject.toml +2 -2
  13. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/computer/safety.py +35 -7
  14. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/computer/tools.py +8 -1
  15. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/bootstrap.py +9 -0
  16. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/config/runtime_env.py +4 -3
  17. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/config/snapshot.py +2 -0
  18. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/context/__init__.py +30 -2
  19. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/layout.py +23 -0
  20. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/mcp/mcp_client.py +4 -1
  21. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/mcp/ports_mcp.py +2 -0
  22. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/prompts/harness_prompt.py +7 -3
  23. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/realtime_loop.py +10 -2
  24. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/tool_dispatch.py +12 -2
  25. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/subagents/subagent_worker.py +12 -1
  26. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/core_tool_executor.py +115 -64
  27. monkeybot-3.3.0/src/monkeybot/core/tools/fs_isolation.py +695 -0
  28. monkeybot-3.3.0/src/monkeybot/core/tools/grant_store.py +259 -0
  29. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/inspector.py +124 -23
  30. monkeybot-3.3.0/src/monkeybot/core/tools/path_grant_inspector.py +115 -0
  31. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/sandbox_executor.py +39 -6
  32. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/terminal.py +140 -42
  33. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/workspace_service.py +173 -28
  34. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/realtime/app.py +1 -0
  35. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/realtime/deps.py +2 -0
  36. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/realtime/routes.py +2 -0
  37. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/sse/app.py +17 -1
  38. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/computer/test_path_policy.py +16 -0
  39. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_core_tool_executor.py +264 -3
  40. monkeybot-3.3.0/tests/core/test_fs_isolation.py +650 -0
  41. monkeybot-3.3.0/tests/core/test_grant_store.py +183 -0
  42. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_inspector.py +32 -2
  43. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_loop.py +106 -0
  44. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_mcp_client.py +12 -1
  45. monkeybot-3.3.0/tests/core/test_path_grant_inspector.py +230 -0
  46. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_realtime_loop.py +65 -0
  47. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_run_command_parse.py +1 -1
  48. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_terminal.py +183 -0
  49. monkeybot-3.3.0/tests/core/test_workspace_extra_read_roots.py +253 -0
  50. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/realtime/test_deps.py +2 -0
  51. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/sse/test_gateway_runtime.py +1 -0
  52. {monkeybot-3.2.0 → monkeybot-3.3.0}/uv.lock +3 -3
  53. monkeybot-3.2.0/src/monkeybot/core/tools/fs_isolation.py +0 -316
  54. monkeybot-3.2.0/tests/core/test_fs_isolation.py +0 -242
  55. {monkeybot-3.2.0 → monkeybot-3.3.0}/.dockerignore +0 -0
  56. {monkeybot-3.2.0 → monkeybot-3.3.0}/.github/workflows/ci.yml +0 -0
  57. {monkeybot-3.2.0 → monkeybot-3.3.0}/.github/workflows/live-eval-smoke.yml +0 -0
  58. {monkeybot-3.2.0 → monkeybot-3.3.0}/.github/workflows/prepare-release.yml +0 -0
  59. {monkeybot-3.2.0 → monkeybot-3.3.0}/.github/workflows/publish-release.yml +0 -0
  60. {monkeybot-3.2.0 → monkeybot-3.3.0}/.gitignore +0 -0
  61. {monkeybot-3.2.0 → monkeybot-3.3.0}/.pre-commit-config.yaml +0 -0
  62. {monkeybot-3.2.0 → monkeybot-3.3.0}/BACKLOG.md +0 -0
  63. {monkeybot-3.2.0 → monkeybot-3.3.0}/CONTRIBUTING.md +0 -0
  64. {monkeybot-3.2.0 → monkeybot-3.3.0}/LICENSE +0 -0
  65. {monkeybot-3.2.0 → monkeybot-3.3.0}/README.md +0 -0
  66. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/pyproject.toml +0 -0
  67. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/skills/monkeybot/SKILL.md +0 -0
  68. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/skills/monkeybot/references/config-sections.md +0 -0
  69. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/__init__.py +0 -0
  70. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/chat_file_index.py +0 -0
  71. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/chat_local_shell.py +0 -0
  72. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/chat_renderer.py +0 -0
  73. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/chat_session.py +0 -0
  74. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/chat_status_bar.py +0 -0
  75. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/chat_theme.py +0 -0
  76. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/chat_tool_display.py +0 -0
  77. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/chat_tui.py +0 -0
  78. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/chat_tui_widgets.py +0 -0
  79. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/commands/__init__.py +0 -0
  80. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/commands/chat.py +0 -0
  81. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/commands/doctor.py +0 -0
  82. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/commands/loop.py +0 -0
  83. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/commands/new.py +0 -0
  84. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/commands/refresh.py +0 -0
  85. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/commands/run_cmd.py +0 -0
  86. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/commands/talk.py +0 -0
  87. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/commands/validate.py +0 -0
  88. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/compat.py +0 -0
  89. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/config_resolve.py +0 -0
  90. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/exit_commands.py +0 -0
  91. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/extras_catalog.py +0 -0
  92. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/gateway_health.py +0 -0
  93. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/main.py +0 -0
  94. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/opensandbox_lifecycle.py +0 -0
  95. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/output.py +0 -0
  96. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/process_tree.py +0 -0
  97. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/providers.py +0 -0
  98. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/realtime/__init__.py +0 -0
  99. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/realtime/audio_io.py +0 -0
  100. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/realtime/client.py +0 -0
  101. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/realtime/gateway_manager.py +0 -0
  102. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/realtime/push_to_talk.py +0 -0
  103. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/realtime/session.py +0 -0
  104. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/realtime/session_controller.py +0 -0
  105. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/realtime/talk_ui.py +0 -0
  106. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/realtime/wire_encode.py +0 -0
  107. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/runtime_python.py +0 -0
  108. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold.py +0 -0
  109. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/AGENT.md +0 -0
  110. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/Dockerfile +0 -0
  111. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/__init__.py +0 -0
  112. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/browser/SKILL.md +0 -0
  113. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/command_allowlist.yaml +0 -0
  114. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/dockerignore +0 -0
  115. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/env.example +0 -0
  116. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/image-generator/SKILL.md +0 -0
  117. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/image-generator/generate_image.py +0 -0
  118. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/loop/SKILL.md +0 -0
  119. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/mcp.json +0 -0
  120. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/monkeybot.example.yaml +0 -0
  121. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/opensandbox.docker.toml +0 -0
  122. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/otel-collector.example.yaml +0 -0
  123. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/scaffold_defaults/permissions.yaml +0 -0
  124. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/session_controller.py +0 -0
  125. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/src/monkeybot_cli/terminal_markdown.py +0 -0
  126. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_chat_continue.py +0 -0
  127. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_chat_e2e.py +0 -0
  128. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_chat_errors.py +0 -0
  129. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_chat_file_index.py +0 -0
  130. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_chat_grounding.py +0 -0
  131. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_chat_local_shell.py +0 -0
  132. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_chat_renderer_parity.py +0 -0
  133. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_chat_session.py +0 -0
  134. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_chat_status_bar.py +0 -0
  135. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_chat_theme.py +0 -0
  136. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_chat_tool_display.py +0 -0
  137. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_chat_tui.py +0 -0
  138. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_cli.py +0 -0
  139. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_config_resolve.py +0 -0
  140. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_doctor.py +0 -0
  141. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_extras_catalog.py +0 -0
  142. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_gateway_health.py +0 -0
  143. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_opensandbox_lifecycle.py +0 -0
  144. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_realtime_session_controller.py +0 -0
  145. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_run_cmd.py +0 -0
  146. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_runtime_python.py +0 -0
  147. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_scaffold.py +0 -0
  148. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/tests/test_terminal_markdown.py +0 -0
  149. {monkeybot-3.2.0 → monkeybot-3.3.0}/cli/uv.lock +0 -0
  150. {monkeybot-3.2.0 → monkeybot-3.3.0}/docker/Dockerfile +0 -0
  151. {monkeybot-3.2.0 → monkeybot-3.3.0}/docker/demo-model.yaml +0 -0
  152. {monkeybot-3.2.0 → monkeybot-3.3.0}/docker/demo.yaml +0 -0
  153. {monkeybot-3.2.0 → monkeybot-3.3.0}/docker/docker-compose.sandbox.yml +0 -0
  154. {monkeybot-3.2.0 → monkeybot-3.3.0}/docker/opensandbox.docker.toml +0 -0
  155. {monkeybot-3.2.0 → monkeybot-3.3.0}/docker/sandbox.Dockerfile +0 -0
  156. {monkeybot-3.2.0 → monkeybot-3.3.0}/docker-compose.yml +0 -0
  157. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/agent-layout.md +0 -0
  158. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/assets/logo.png +0 -0
  159. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/browser-mcp-perf-baseline.md +0 -0
  160. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/browser-mcp-performance-plan.md +0 -0
  161. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/cloud-deployment-design.md +0 -0
  162. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/deploy-aws-agentcore.md +0 -0
  163. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/deploy-pattern-a-container.md +0 -0
  164. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/deploy-pattern-b-serverless.md +0 -0
  165. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/deploy-pattern-c-agent-platform.md +0 -0
  166. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/deploy-pattern-d-realtime.md +0 -0
  167. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/getting-started.md +0 -0
  168. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/knowledge-layer-fixes.md +0 -0
  169. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/live-evals.md +0 -0
  170. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/mcp.md +0 -0
  171. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/memory-graph-split-plan.md +0 -0
  172. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/migrations/agent-scope-namespacing.md +0 -0
  173. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/migrations/memory-outbox.sql +0 -0
  174. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/observability-runbook.md +0 -0
  175. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/ollama-local.md +0 -0
  176. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/otel-collector.example.yaml +0 -0
  177. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/progressive-loop-tools.md +0 -0
  178. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/progressive-mcp-tools.md +0 -0
  179. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/skills.md +0 -0
  180. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/spill-dynamic-design.md +0 -0
  181. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/sse-gateway-ui.md +0 -0
  182. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/verifier-agent-design.md +0 -0
  183. {monkeybot-3.2.0 → monkeybot-3.3.0}/docs/workspace-index-design.md +0 -0
  184. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/TEST_COVERAGE.md +0 -0
  185. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/assertions.py +0 -0
  186. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/baselines/smoke.json +0 -0
  187. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/baselines/smoke.md +0 -0
  188. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/diff.py +0 -0
  189. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/eval_config.yaml +0 -0
  190. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/models.py +0 -0
  191. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/persistence.py +0 -0
  192. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/report.py +0 -0
  193. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/runner.py +0 -0
  194. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenario_loader.py +0 -0
  195. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/context/summarization_trigger.yaml +0 -0
  196. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/drift/declares_done.yaml +0 -0
  197. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/drift/path_constraint.yaml +0 -0
  198. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/drift/preempt.yaml +0 -0
  199. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/drift/repeat_correction.yaml +0 -0
  200. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/drift/supersession.yaml +0 -0
  201. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/mcp/get_prompt.yaml +0 -0
  202. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/mcp/list_resources.yaml +0 -0
  203. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/mcp/tool_invoke.yaml +0 -0
  204. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/memory/recall_cross_session.yaml +0 -0
  205. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/memory/recall_single_session.yaml +0 -0
  206. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/multi_turn/task_tracking.yaml +0 -0
  207. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/skills/skill_invocation.yaml +0 -0
  208. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/subagents/dispatch_complete.yaml +0 -0
  209. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/tools/core_read.yaml +0 -0
  210. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/tools/core_read_error.yaml +0 -0
  211. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/tools/core_run_command.yaml +0 -0
  212. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/tools/core_run_command_sandbox.yaml +0 -0
  213. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scenarios/tools/core_write.yaml +0 -0
  214. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/scorer.py +0 -0
  215. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/.env.example +0 -0
  216. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/.gitignore +0 -0
  217. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/fixture_mcp_server.py +0 -0
  218. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/monkeybot_config/AGENT.md +0 -0
  219. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/monkeybot_config/command_allowlist.yaml +0 -0
  220. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/monkeybot_config/mcp.json +0 -0
  221. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/monkeybot_config/monkeybot.verifier-on.yaml +0 -0
  222. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/monkeybot_config/monkeybot.yaml +0 -0
  223. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/monkeybot_config/permissions.yaml +0 -0
  224. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/pyproject.toml +0 -0
  225. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/skills/browser/SKILL.md +0 -0
  226. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/uv.lock +0 -0
  227. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/workspace/.gitkeep +0 -0
  228. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/smoke_agent/workspace/skills/browser/playbooks/.gitkeep +0 -0
  229. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/suites/drift.yaml +0 -0
  230. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/suites/smoke.yaml +0 -0
  231. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/test_assertions.py +0 -0
  232. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/test_diff.py +0 -0
  233. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/test_judge.py +0 -0
  234. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/test_report.py +0 -0
  235. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/test_runner_sse.py +0 -0
  236. {monkeybot-3.2.0 → monkeybot-3.3.0}/evals/test_scorer.py +0 -0
  237. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/README.md +0 -0
  238. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/agentcore/handler.py +0 -0
  239. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/agentcore/runtime_app.py +0 -0
  240. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/agentengine/handler.py +0 -0
  241. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/cloud-functions/main.py +0 -0
  242. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/lambda/handler.py +0 -0
  243. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/ollama/PrefixStable.Modelfile +0 -0
  244. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/skills/browser/SKILL.md +0 -0
  245. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/skills/browser/playbooks/.gitkeep +0 -0
  246. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/skills/diagnostics/README.md +0 -0
  247. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/skills/diagnostics/SKILL.md +0 -0
  248. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/skills/diagnostics/__init__.py +0 -0
  249. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/skills/diagnostics/diagnostics.py +0 -0
  250. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/skills/image-generator/SKILL.md +0 -0
  251. {monkeybot-3.2.0 → monkeybot-3.3.0}/examples/skills/image-generator/generate_image.py +0 -0
  252. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/scripts/agentcore_smoke.py +0 -0
  253. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/scripts/dump_tool_surface.py +0 -0
  254. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/scripts/perf_bench.py +0 -0
  255. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/__init__.py +0 -0
  256. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/actions.py +0 -0
  257. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/agentcore.py +0 -0
  258. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/assets/NOTICE.md +0 -0
  259. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/assets/dom_tree.js +0 -0
  260. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/assets/pa_driver.js +0 -0
  261. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/dom_indexing.py +0 -0
  262. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/login.py +0 -0
  263. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/observe.py +0 -0
  264. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/perf.py +0 -0
  265. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/playbooks.py +0 -0
  266. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/playwright_helpers.py +0 -0
  267. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/results.py +0 -0
  268. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/screenshots.py +0 -0
  269. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/server.py +0 -0
  270. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/tab_ops.py +0 -0
  271. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/tabs.py +0 -0
  272. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/tools/__init__.py +0 -0
  273. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/tools/batch.py +0 -0
  274. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/tools/capture.py +0 -0
  275. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/tools/interact.py +0 -0
  276. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/tools/navigate.py +0 -0
  277. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/tools/playbook.py +0 -0
  278. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/tools/read.py +0 -0
  279. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/src/browser_mcp/tools/tab_control.py +0 -0
  280. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/fixtures/api.json +0 -0
  281. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/fixtures/article.html +0 -0
  282. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/fixtures/cards.html +0 -0
  283. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/fixtures/form.html +0 -0
  284. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/fixtures/long_list.html +0 -0
  285. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/fixtures/spa.html +0 -0
  286. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/fixtures/tool_surface.json +0 -0
  287. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/integration/conftest.py +0 -0
  288. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/integration/test_act_observe.py +0 -0
  289. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/integration/test_driver_persist.py +0 -0
  290. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/integration/test_intent_tools.py +0 -0
  291. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/integration/test_multi_tab.py +0 -0
  292. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/integration/test_observation.py +0 -0
  293. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/integration/test_run_playbook.py +0 -0
  294. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/integration/test_wait_for.py +0 -0
  295. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_act.py +0 -0
  296. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_agentcore.py +0 -0
  297. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_dom_indexing.py +0 -0
  298. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_fill_form.py +0 -0
  299. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_in_app_cdp.py +0 -0
  300. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_indexed_tools.py +0 -0
  301. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_observe.py +0 -0
  302. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_observe_after.py +0 -0
  303. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_perf.py +0 -0
  304. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_playbook_flows.py +0 -0
  305. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_playbooks.py +0 -0
  306. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_playwright_helpers.py +0 -0
  307. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_screenshots.py +0 -0
  308. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_server_shutdown.py +0 -0
  309. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_tabs.py +0 -0
  310. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_tool_surface.py +0 -0
  311. {monkeybot-3.2.0 → monkeybot-3.3.0}/integrations/browser-mcp/tests/test_wait_tools.py +0 -0
  312. {monkeybot-3.2.0 → monkeybot-3.3.0}/pytest.ini +0 -0
  313. {monkeybot-3.2.0 → monkeybot-3.3.0}/scripts/create_schema.py +0 -0
  314. {monkeybot-3.2.0 → monkeybot-3.3.0}/scripts/precommit-pytest.sh +0 -0
  315. {monkeybot-3.2.0 → monkeybot-3.3.0}/scripts/release.py +0 -0
  316. {monkeybot-3.2.0 → monkeybot-3.3.0}/scripts/smoke_global_cli.sh +0 -0
  317. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/__init__.py +0 -0
  318. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/cli/__init__.py +0 -0
  319. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/cli/__main__.py +0 -0
  320. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/cli/audio_io.py +0 -0
  321. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/cli/gateway_manager.py +0 -0
  322. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/cli/main.py +0 -0
  323. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/cli/push_to_talk.py +0 -0
  324. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/cli/realtime_client.py +0 -0
  325. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/computer/__init__.py +0 -0
  326. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/computer/approvals.py +0 -0
  327. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/computer/permissions.py +0 -0
  328. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/__init__.py +0 -0
  329. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/attachments/__init__.py +0 -0
  330. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/attachments/catalog.py +0 -0
  331. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/attachments/config.py +0 -0
  332. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/attachments/freeze.py +0 -0
  333. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/attachments/resolve.py +0 -0
  334. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/attachments/store.py +0 -0
  335. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/attachments/text.py +0 -0
  336. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/attachments/tools.py +0 -0
  337. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/config/__init__.py +0 -0
  338. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/config/realtime_config.py +0 -0
  339. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/config/settings.py +0 -0
  340. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/config/validation.py +0 -0
  341. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/config/yaml_loader.py +0 -0
  342. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/context/campaign_context.py +0 -0
  343. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/context/common.py +0 -0
  344. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/context/epoch.py +0 -0
  345. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/context/secret_egress.py +0 -0
  346. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/context/tool_output_policy.py +0 -0
  347. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/context/tool_result_ingress.py +0 -0
  348. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/context/tool_shapers.py +0 -0
  349. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/hooks/__init__.py +0 -0
  350. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/__init__.py +0 -0
  351. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/captions.py +0 -0
  352. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/chunking.py +0 -0
  353. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/config.py +0 -0
  354. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/embeddings/__init__.py +0 -0
  355. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/embeddings/base.py +0 -0
  356. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/embeddings/factory.py +0 -0
  357. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/embeddings/gemini.py +0 -0
  358. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/embeddings/nvidia.py +0 -0
  359. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/embeddings/openai_compat.py +0 -0
  360. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/embeddings/sanitize.py +0 -0
  361. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/evidence_guard.py +0 -0
  362. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/extractors.py +0 -0
  363. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/fusion.py +0 -0
  364. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/hook.py +0 -0
  365. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/indexer.py +0 -0
  366. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/links.py +0 -0
  367. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/salience.py +0 -0
  368. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/sqlite_index.py +0 -0
  369. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/subsystem.py +0 -0
  370. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/tool.py +0 -0
  371. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/knowledge/types.py +0 -0
  372. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/llm/__init__.py +0 -0
  373. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/llm/provider.py +0 -0
  374. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/llm/realtime_provider.py +0 -0
  375. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/llm/usage.py +0 -0
  376. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/lockfile_names.py +0 -0
  377. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/logging_utils.py +0 -0
  378. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/mcp/__init__.py +0 -0
  379. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/memory/__init__.py +0 -0
  380. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/memory/config.py +0 -0
  381. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/memory/hook.py +0 -0
  382. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/memory/ids.py +0 -0
  383. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/memory/ingest.py +0 -0
  384. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/memory/migrate_layout.py +0 -0
  385. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/memory/observability.py +0 -0
  386. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/memory/outbox.py +0 -0
  387. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/memory/palace.py +0 -0
  388. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/memory/subsystem.py +0 -0
  389. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/memory/uri.py +0 -0
  390. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/memory/writer.py +0 -0
  391. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/messages/__init__.py +0 -0
  392. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/messages/convert_provider.py +0 -0
  393. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/messages/tool_integrity.py +0 -0
  394. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/messages/transform_context.py +0 -0
  395. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/path_safety.py +0 -0
  396. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/__init__.py +0 -0
  397. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/backends.py +0 -0
  398. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/db.py +0 -0
  399. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/durable_runs.py +0 -0
  400. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/errors.py +0 -0
  401. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/firestore.indexes.json +0 -0
  402. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/firestore.py +0 -0
  403. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/firestore_scheduled_loops.py +0 -0
  404. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/goal_ledger.py +0 -0
  405. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/history.py +0 -0
  406. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/postgres.py +0 -0
  407. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/runs.py +0 -0
  408. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/scheduled_loops.py +0 -0
  409. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/session_turn_locks.py +0 -0
  410. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/sqlite.py +0 -0
  411. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/sqlite_backend.py +0 -0
  412. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/sqlite_vector.py +0 -0
  413. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/thread_summary.py +0 -0
  414. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/transcript.py +0 -0
  415. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/usage.py +0 -0
  416. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/persistence/usage_buckets.py +0 -0
  417. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/prompts/__init__.py +0 -0
  418. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/prompts/headings.py +0 -0
  419. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/prompts/prompt.py +0 -0
  420. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/__init__.py +0 -0
  421. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/context_budget.py +0 -0
  422. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/doom_loop.py +0 -0
  423. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/events.py +0 -0
  424. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/history_compaction.py +0 -0
  425. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/input_admission.py +0 -0
  426. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/loop.py +0 -0
  427. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/loop_hooks.py +0 -0
  428. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/loop_messages.py +0 -0
  429. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/loop_ports.py +0 -0
  430. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/loop_usage.py +0 -0
  431. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/provider_stream_mapper.py +0 -0
  432. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/tool_batch.py +0 -0
  433. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/turn_loop.py +0 -0
  434. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/runtime/utterance_buffer.py +0 -0
  435. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/subagents/__init__.py +0 -0
  436. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/subagents/progress_publish.py +0 -0
  437. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/subagents/subagent_proto.py +0 -0
  438. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/subagents/worker_pool.py +0 -0
  439. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/subprocess_groups.py +0 -0
  440. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/testing/__init__.py +0 -0
  441. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/testing/mocks_provider.py +0 -0
  442. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/testing/mocks_realtime_provider.py +0 -0
  443. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/__init__.py +0 -0
  444. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/loop_inspector.py +0 -0
  445. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/patch.py +0 -0
  446. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/permission.py +0 -0
  447. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/spill_inventory.py +0 -0
  448. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/text_normalize.py +0 -0
  449. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/tool_hint.py +0 -0
  450. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/tool_kind.py +0 -0
  451. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/tools/types.py +0 -0
  452. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/types/__init__.py +0 -0
  453. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/types/content_blocks.py +0 -0
  454. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/types/interfaces.py +0 -0
  455. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/types/types_tools.py +0 -0
  456. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/verifier/__init__.py +0 -0
  457. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/verifier/actuator.py +0 -0
  458. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/verifier/classify.py +0 -0
  459. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/verifier/inspector.py +0 -0
  460. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/verifier/judge.py +0 -0
  461. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/verifier/ledger.py +0 -0
  462. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/verifier/mailbox.py +0 -0
  463. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/verifier/match.py +0 -0
  464. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/verifier/port.py +0 -0
  465. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/verifier/severity.py +0 -0
  466. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/verifier/tracker.py +0 -0
  467. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/workspace/__init__.py +0 -0
  468. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/workspace/factory.py +0 -0
  469. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/workspace/gcs.py +0 -0
  470. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/workspace/local.py +0 -0
  471. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/workspace/protocol.py +0 -0
  472. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/workspace/s3.py +0 -0
  473. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/core/workspace_layout.py +0 -0
  474. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/__init__.py +0 -0
  475. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/bootstrap.py +0 -0
  476. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/main.py +0 -0
  477. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/pending_response_bus.py +0 -0
  478. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/realtime/__init__.py +0 -0
  479. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/realtime/errors.py +0 -0
  480. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/realtime/guardrails.py +0 -0
  481. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/realtime/manager.py +0 -0
  482. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/realtime/metrics.py +0 -0
  483. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/realtime/session.py +0 -0
  484. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/realtime/wire.py +0 -0
  485. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/realtime_main.py +0 -0
  486. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/sse/__init__.py +0 -0
  487. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/sse/loop_port.py +0 -0
  488. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/sse/models.py +0 -0
  489. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/sse/reload.py +0 -0
  490. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/sse/reply_body.py +0 -0
  491. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/sse/routes.py +0 -0
  492. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/sse/scheduler_routes.py +0 -0
  493. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/sse/scheduler_wiring.py +0 -0
  494. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/sse/session_bus.py +0 -0
  495. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/sse/sse.py +0 -0
  496. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/gateway/sse/workspace_layout.py +0 -0
  497. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/observability/__init__.py +0 -0
  498. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/observability/_state.py +0 -0
  499. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/observability/instrumentation.py +0 -0
  500. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/observability/propagation.py +0 -0
  501. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/observability/spans.py +0 -0
  502. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/observability/sqlite_exporter.py +0 -0
  503. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/__init__.py +0 -0
  504. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/_bedrock_converse.py +0 -0
  505. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/_openai_compat.py +0 -0
  506. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/_utils.py +0 -0
  507. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/bedrock.py +0 -0
  508. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/claude.py +0 -0
  509. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/gemini.py +0 -0
  510. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/gemini_live.py +0 -0
  511. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/huggingface.py +0 -0
  512. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/model_capabilities.py +0 -0
  513. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/nvidia.py +0 -0
  514. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/ollama.py +0 -0
  515. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/openai.py +0 -0
  516. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/openrouter.py +0 -0
  517. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/pricing.py +0 -0
  518. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/sampling.py +0 -0
  519. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/providers/vertex_claude.py +0 -0
  520. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/scaffold/__init__.py +0 -0
  521. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/scheduler/__init__.py +0 -0
  522. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/scheduler/__main__.py +0 -0
  523. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/scheduler/engine.py +0 -0
  524. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/scheduler/http_invoker.py +0 -0
  525. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/scheduler/interval.py +0 -0
  526. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/scheduler/tick_result.py +0 -0
  527. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/scheduler/worker.py +0 -0
  528. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/subagents/__init__.py +0 -0
  529. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/subagents/worker/__init__.py +0 -0
  530. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/subagents/worker/__main__.py +0 -0
  531. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/todo_list/__init__.py +0 -0
  532. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/todo_list/store.py +0 -0
  533. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/todo_list/tool.py +0 -0
  534. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/web_search/__init__.py +0 -0
  535. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/web_search/backends/__init__.py +0 -0
  536. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/web_search/backends/duckduckgo.py +0 -0
  537. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/web_search/backends/firecrawl.py +0 -0
  538. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/web_search/backends/tavily.py +0 -0
  539. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/web_search/protocol.py +0 -0
  540. {monkeybot-3.2.0 → monkeybot-3.3.0}/src/monkeybot/web_search/tool.py +0 -0
  541. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/__init__.py +0 -0
  542. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/acceptance/test_observability_acceptance.py +0 -0
  543. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/cli/__init__.py +0 -0
  544. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/cli/test_gateway_manager.py +0 -0
  545. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/cli/test_main.py +0 -0
  546. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/cli/test_push_to_talk.py +0 -0
  547. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/cli/test_realtime_client.py +0 -0
  548. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/computer/__init__.py +0 -0
  549. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/computer/test_approvals.py +0 -0
  550. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/computer/test_computer_tools.py +0 -0
  551. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/computer/test_package_init.py +0 -0
  552. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/computer/test_permissions.py +0 -0
  553. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/computer/test_subagent_exclusion.py +0 -0
  554. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/computer/test_wiring.py +0 -0
  555. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/conftest.py +0 -0
  556. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/__init__.py +0 -0
  557. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/fixtures/bitbucket_dc_style_pr.diff +0 -0
  558. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/memory/helpers.py +0 -0
  559. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/memory/in_memory_palace.py +0 -0
  560. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/memory/test_mempalace.py +0 -0
  561. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/memory/test_review_fixes.py +0 -0
  562. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_agent_layout.py +0 -0
  563. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_attachment_freeze.py +0 -0
  564. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_attachment_store.py +0 -0
  565. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_bootstrap.py +0 -0
  566. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_config_extensions.py +0 -0
  567. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_content_blocks.py +0 -0
  568. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_context.py +0 -0
  569. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_context_budget.py +0 -0
  570. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_context_epoch.py +0 -0
  571. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_doom_loop.py +0 -0
  572. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_durable_events.py +0 -0
  573. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_durable_runs.py +0 -0
  574. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_empty_completion.py +0 -0
  575. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_env_map_grep_gates.py +0 -0
  576. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_events.py +0 -0
  577. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_evidence_guard.py +0 -0
  578. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_firestore_history.py +0 -0
  579. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_firestore_scheduled_loops.py +0 -0
  580. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_firestore_usage.py +0 -0
  581. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_gemini_history_replay.py +0 -0
  582. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_goal_ledger.py +0 -0
  583. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_harness_prompt.py +0 -0
  584. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_history.py +0 -0
  585. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_history_compaction_split.py +0 -0
  586. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_hooks.py +0 -0
  587. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_input_admission.py +0 -0
  588. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_chunking.py +0 -0
  589. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_chunking_rank.py +0 -0
  590. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_config.py +0 -0
  591. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_embeddings.py +0 -0
  592. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_fts.py +0 -0
  593. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_fusion.py +0 -0
  594. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_fusion_ann.py +0 -0
  595. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_hook.py +0 -0
  596. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_indexer.py +0 -0
  597. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_links.py +0 -0
  598. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_media.py +0 -0
  599. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_salience.py +0 -0
  600. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_single_writer.py +0 -0
  601. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_subsystem.py +0 -0
  602. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_knowledge_vectors.py +0 -0
  603. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_layout.py +0 -0
  604. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_logging_utils.py +0 -0
  605. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_loop_hooks.py +0 -0
  606. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_loop_observability.py +0 -0
  607. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_loop_transcript.py +0 -0
  608. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_memory_layout_migrate.py +0 -0
  609. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_message_pipeline.py +0 -0
  610. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_mocks_realtime_provider.py +0 -0
  611. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_patch.py +0 -0
  612. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_path_safety.py +0 -0
  613. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_permission.py +0 -0
  614. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_pricing.py +0 -0
  615. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_progress_publish.py +0 -0
  616. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_progress_tracker.py +0 -0
  617. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_prompt.py +0 -0
  618. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_provider_contract.py +0 -0
  619. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_provider_stream_mapper.py +0 -0
  620. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_replace_fuzzy.py +0 -0
  621. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_runs.py +0 -0
  622. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_runtime_config_snapshot.py +0 -0
  623. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_runtime_env.py +0 -0
  624. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_sandbox_executor.py +0 -0
  625. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_scheduled_loops.py +0 -0
  626. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_secret_egress.py +0 -0
  627. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_session_turn_locks.py +0 -0
  628. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_settlement.py +0 -0
  629. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_spill_dynamic.py +0 -0
  630. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_spill_inventory.py +0 -0
  631. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_storage_backends.py +0 -0
  632. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_subagent_proto.py +0 -0
  633. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_subagent_trace_propagation.py +0 -0
  634. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_subagent_worker_paths.py +0 -0
  635. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_thread_summary_wire.py +0 -0
  636. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_tool_def_schema.py +0 -0
  637. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_tool_integrity.py +0 -0
  638. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_tool_result_ingress.py +0 -0
  639. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_tool_shapers.py +0 -0
  640. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_transcript.py +0 -0
  641. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_truncated_tool_batch.py +0 -0
  642. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_usage.py +0 -0
  643. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_usage_migration.py +0 -0
  644. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_utterance_buffer.py +0 -0
  645. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_verifier_inspector.py +0 -0
  646. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_verifier_judge.py +0 -0
  647. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_worker_pool.py +0 -0
  648. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_workspace_layout.py +0 -0
  649. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_workspace_symlinks.py +0 -0
  650. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/test_workspace_write_scope.py +0 -0
  651. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/workspace/test_factory.py +0 -0
  652. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/workspace/test_local_storage.py +0 -0
  653. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/core/workspace/test_protocol_contract.py +0 -0
  654. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/__init__.py +0 -0
  655. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/eval_hook.py +0 -0
  656. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenario_runner.py +0 -0
  657. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/memory_wake_up_large.yaml +0 -0
  658. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/memory_write_inject.yaml +0 -0
  659. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/subagent_roundtrip.yaml +0 -0
  660. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/tool_glob_grep.yaml +0 -0
  661. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/tool_load_file.yaml +0 -0
  662. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/tool_loops.yaml +0 -0
  663. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/tool_read.yaml +0 -0
  664. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/tool_replace_apply_patch.yaml +0 -0
  665. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/tool_run_command.yaml +0 -0
  666. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/tool_search_knowledge.yaml +0 -0
  667. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/tool_search_memory.yaml +0 -0
  668. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/tool_todo_list.yaml +0 -0
  669. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/tool_web_search.yaml +0 -0
  670. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/tool_write.yaml +0 -0
  671. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/scenarios/turn_completion.yaml +0 -0
  672. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/test_agent_behavior.py +0 -0
  673. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/test_memory_knowledge_routing.py +0 -0
  674. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/evals/test_verifier_port.py +0 -0
  675. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/__init__.py +0 -0
  676. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/realtime/__init__.py +0 -0
  677. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/realtime/test_app.py +0 -0
  678. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/realtime/test_guardrails.py +0 -0
  679. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/realtime/test_manager.py +0 -0
  680. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/realtime/test_metrics.py +0 -0
  681. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/realtime/test_routes_client_text.py +0 -0
  682. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/realtime/test_session.py +0 -0
  683. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/realtime/test_wire.py +0 -0
  684. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/sse/test_attachments.py +0 -0
  685. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/sse/test_config_reload.py +0 -0
  686. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/sse/test_create_session_model.py +0 -0
  687. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/sse/test_routes.py +0 -0
  688. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/sse/test_scheduler_routes.py +0 -0
  689. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/sse/test_session_bus.py +0 -0
  690. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/sse/test_transcript_wiring.py +0 -0
  691. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/test_otel_fastapi.py +0 -0
  692. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/test_otel_lifespan.py +0 -0
  693. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/test_pending_response_endpoints.py +0 -0
  694. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/test_realtime_main.py +0 -0
  695. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/test_resolve_provider.py +0 -0
  696. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/test_sse_events.py +0 -0
  697. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/gateway/test_subagent_event_publisher.py +0 -0
  698. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/integration/__init__.py +0 -0
  699. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/integration/test_mb_e2e_simple_reply.py +0 -0
  700. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/integration/test_observability_integration.py +0 -0
  701. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/integration/test_prompt_caching_integration.py +0 -0
  702. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/observability/conftest.py +0 -0
  703. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/observability/test_init.py +0 -0
  704. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/observability/test_instrumentation.py +0 -0
  705. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/observability/test_loop_hook_spans.py +0 -0
  706. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/observability/test_propagation.py +0 -0
  707. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/observability/test_span_contract.py +0 -0
  708. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/observability/test_spans.py +0 -0
  709. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/observability/test_sqlite_exporter.py +0 -0
  710. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/observability/test_truncate.py +0 -0
  711. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/observability/test_turn_complete_trace.py +0 -0
  712. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/conftest.py +0 -0
  713. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_anthropic_cache.py +0 -0
  714. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_anthropic_history.py +0 -0
  715. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_bedrock_converse.py +0 -0
  716. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_bedrock_estimate.py +0 -0
  717. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_gemini_history.py +0 -0
  718. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_gemini_live.py +0 -0
  719. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_gemini_usage.py +0 -0
  720. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_huggingface.py +0 -0
  721. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_model_capabilities.py +0 -0
  722. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_nvidia.py +0 -0
  723. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_ollama.py +0 -0
  724. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_openai_compat_usage.py +0 -0
  725. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_openai_history.py +0 -0
  726. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_pricing.py +0 -0
  727. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_safe_parse_tool_args.py +0 -0
  728. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_sampling.py +0 -0
  729. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_sonnet5_sampling.py +0 -0
  730. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_source_grep_gates.py +0 -0
  731. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/providers/test_vertex_claude_history.py +0 -0
  732. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/scheduler/test_engine.py +0 -0
  733. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/scheduler/test_interval.py +0 -0
  734. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/skills/__init__.py +0 -0
  735. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/skills/test_generate_image_script.py +0 -0
  736. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/test_cold_start.py +0 -0
  737. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/test_packaging_config.py +0 -0
  738. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/test_release_script.py +0 -0
  739. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/todo_list/test_todo_list.py +0 -0
  740. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/web_search/__init__.py +0 -0
  741. {monkeybot-3.2.0 → monkeybot-3.3.0}/tests/web_search/test_web_search.py +0 -0
@@ -6,7 +6,30 @@ the project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
- ### Browser MCP
9
+ ## [browser v0.7.0] - 2026-09-10
10
+
11
+ #### Added
12
+
13
+ - Announces the chat it is acting for to the Spaces in-app bridge (`Monkeybot.setChatScope`) so tabs stay attached to their chat; silently no-op on older apps.
14
+
15
+ #### Fixed
16
+
17
+ - Chat-switch tab drop now fires on real tool calls (`browser_harness()` reuse no longer forgets the last scoped chat).
18
+
19
+ ## [core v3.3.0] - 2026-09-11
20
+
21
+ ### Breaking
22
+
23
+ - `run_command` now runs inside a deny-by-default OS filesystem jail (macOS `sandbox-exec`; Linux mount-namespace, unvalidated on a real host as part of this change) on top of the existing binary/path allowlist. The user's home directory is denied by default; the workspace, artifacts, memory palace, and OS temp dirs stay read+write, and skills/the interpreter prefix/granted folders stay read-only, including when they sit inside the denied home directory (the normal case for a desktop app). This closes a real gap: the old argv-string path screen never caught indirect path expressions a shell or interpreter builds at runtime (`bash -c 'cp "$HOME/Desktop/x" .'`, or a Python `os.path.expanduser(...)` call), so a command that depended on reading/writing somewhere under `$HOME` outside the workspace — by accident or on purpose — will now fail where it previously succeeded. `git` keeps working via a narrow, explicit `~/.gitconfig`/`~/.config/git/ignore` read carve-out (needed even for `--version`); `gh` does not — its own auth config is credential-adjacent and is not carved out, matching the credential-path denylist already established for `computer_*` tools. If the OS jail mechanism itself is unavailable on a host (older kernels without unprivileged user namespaces, some hardened/CI Linux configs), `run_command` falls back to running **unconfined** (logged once, not per call) rather than refusing every command — a deliberate difference from the existing memory-off hide mechanism, which still fails closed, since this is default-on hardening for every deployment rather than a narrow, deliberate opt-out.
24
+
25
+ ### Added
26
+
27
+ - MCP tool calls now carry `_meta.monkeybot` (`thread_id`, `request_id`, `run_id`) so servers can attribute work to a chat. Requires `mcp>=1.27.1` so `ClientSession.call_tool(meta=)` is always available.
28
+ - **Command grants:** an unlisted `run_command` binary now surfaces a "Needs your OK" approval card (`Decision.grant_key`/`grant_kind` on `CommandTierInspector`) instead of silently falling through to a hard `SecurityError` at the executor. "Allow once" covers the rest of the turn; "Always allow" writes a durable rule to a new home-level store, `grants.json` (`core/tools/grant_store.py`), shared by every agent on the machine — deliberately separate from the per-agent, `computer_*`-only `approvals.json`. Same on-disk contract (JSON, `0600`, atomic replace, cross-process exclusive-create locking matched with the Electron side).
29
+ - **Folder read grants:** `read_file`/`load_file`/`glob`/`grep` on an absolute path outside the workspace now ask via a new `PathGrantInspector` rather than rejecting outright — denying credential paths and anything outside `$HOME` hard, never promotable. An approved folder is read in place through `WorkspaceFileService.extra_read_roots` (symlink-escape-protected, read-only — never widens what `write_file`/`replace_in_file` can touch); the same granted folders feed the `run_command` jail's read-only set so the shell tool and the file tools agree on what's reachable. Fixes the failure mode where the model, unable to read a file outside its workspace and told only "use a relative path," would narrate copying the file into the workspace to route around the boundary — tool descriptions, the harness prompt, and the `workspace_error_envelope` hint for this case now say to ask for access instead, explicitly calling relocating-to-route-around-the-boundary a policy violation.
30
+ - Settings → Privacy & access gained **Allowed commands** and **Folder access** sections listing/revoking these new grants, alongside the existing per-agent `computer_*` rules.
31
+
32
+ ## [browser v0.6.0] - 2026-09-07
10
33
 
11
34
  #### Added
12
35
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: monkeybot
3
- Version: 3.2.0
3
+ Version: 3.3.0
4
4
  Summary: monkeybot agent harness — FastAPI SSE gateway, owned loop, SQLite, and MCP.
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -9,7 +9,7 @@ Requires-Dist: aiosqlite>=0.20.0
9
9
  Requires-Dist: fastapi>=0.115.0
10
10
  Requires-Dist: google-genai>=1.0.0
11
11
  Requires-Dist: httpx>=0.27.0
12
- Requires-Dist: mcp<2,>=1.0.0
12
+ Requires-Dist: mcp<2,>=1.27.1
13
13
  Requires-Dist: numpy<2.5,>=1.26.0
14
14
  Requires-Dist: pydantic>=2.10.0
15
15
  Requires-Dist: python-dotenv>=1.0.0
@@ -189,6 +189,39 @@ other ephemeral-workspace targets they reset when the instance is recycled. Use
189
189
  the memory storage contract for durable knowledge rather than adding a workspace
190
190
  synchronization layer.
191
191
 
192
+ ## In-app bridge extensions
193
+
194
+ When the Spaces in-app browser is bound, each tool call may announce which chat
195
+ it is acting for so new tabs stay attached to that chat. AgentCore and Browser
196
+ Use Cloud backends never send this.
197
+
198
+ ### MCP request meta
199
+
200
+ The gateway includes `_meta` on every `call_tool`:
201
+
202
+ ```json
203
+ { "monkeybot": { "thread_id": "<gateway thread id>", "request_id": "<turn request id>", "run_id": "<MONKEYBOT_RUN_ID or null>" } }
204
+ ```
205
+
206
+ Servers that ignore `_meta` are unaffected. Older gateways send nothing; this
207
+ server then announces `chatKey` as `null`.
208
+
209
+ ### `Monkeybot.setChatScope`
210
+
211
+ On every in-app tool call, after the harness binds and before other CDP
212
+ commands, the backend sends:
213
+
214
+ ```json
215
+ { "id": 7, "method": "Monkeybot.setChatScope", "params": { "chatKey": "<thread_id or null>" } }
216
+ ```
217
+
218
+ `chatKey` is the gateway `thread_id` from `_meta.monkeybot`, which equals the
219
+ app's session ID. The bridge stores it on the WebSocket client until changed. An
220
+ older app replies with an error; this server treats that as unsupported, stops
221
+ sending the method for the rest of the connection, and continues normally.
222
+ Rebinding the in-app daemon (including after Spaces `warmBrowserOnLaunch`)
223
+ clears that disabled flag so a newer app gets a fresh attempt.
224
+
192
225
  ## Tools
193
226
 
194
227
  Navigation, interaction, screenshots, tabs, waits, playbooks (`browser_list_playbooks`, `browser_read_playbook`, `browser_write_playbook`, `browser_run_playbook`), `browser_login` for Spaces-saved passwords (returns `{ok, loggedIn, origin, mfa?, mode?}` — never the password), and `browser_stop` for daemon cleanup.
@@ -259,20 +259,20 @@ Each section follows: **Purpose** · **Key files** · **How it works** · **Depe
259
259
 
260
260
  **Purpose:** Default `ToolExecutorPort` — built-ins, MCP, custom tools, subagents.
261
261
 
262
- **Key files:** `core/tools/core_tool_executor.py`, `terminal.py`, `workspace_service.py`, `patch.py`, `sandbox_executor.py`, `spill_inventory.py`
262
+ **Key files:** `core/tools/core_tool_executor.py`, `terminal.py`, `workspace_service.py`, `patch.py`, `sandbox_executor.py`, `spill_inventory.py`, `fs_isolation.py`, `grant_store.py`
263
263
 
264
264
  **Built-in tools** (from `context._core_tool_defs`):
265
265
 
266
266
  | Tool | Role |
267
267
  |------|------|
268
- | `read_file` / `write_file` | `skills/...` read-only or workspace-relative paths |
268
+ | `read_file` / `write_file` | `skills/...` read-only or workspace-relative paths; `read_file`/`load_file` also accept an absolute path outside the workspace once the user grants that folder (see §5) — read in place, never copied in |
269
269
  | `replace_in_file` | Unique (or `replace_all`) substring edit; exact then light fuzzy match |
270
- | `glob` / `grep` | Path discovery / content regex search (prefer over shell) |
270
+ | `glob` / `grep` | Path discovery / content regex search (prefer over shell); `root` accepts a granted external folder the same way `read_file` does |
271
271
  | `apply_patch` | Multi-file Codex-style Add/Update/Delete/Move; fail-closed before any write |
272
272
  | `search_memory` | Keyword search in memory tree |
273
273
  | `search` / `recall` | Local knowledge index (workspace + notes); **parallel-safe**. Gateway owns writes; subagents open the index **read-only**. Harness-as-library (Pattern B/C) callers can opt into read-only via `MONKEYBOT_KNOWLEDGE_READ_ONLY=1`; the gateway always ignores this flag and stays the writer |
274
274
  | `list_skills` | Skill discovery |
275
- | `run_command` | Allowlisted shell (host or OpenSandbox) |
275
+ | `run_command` | Allowlisted **and OS-confined** shell (host or OpenSandbox) — see the workspace jail below |
276
276
  | `task` | Subagent subprocess (parent only) |
277
277
  | `enable_mcp` / `disable_mcp` | Catalog connect / disconnect (success includes status) |
278
278
  | `enable_loops` | Progressive advertise scheduled-loop tools |
@@ -296,6 +296,8 @@ Each section follows: **Purpose** · **Key files** · **How it works** · **Depe
296
296
  - Nested `task` disabled inside subagents.
297
297
  - Custom tools must not collide with core or MCP names.
298
298
  - `MONKEYBOT_KNOWLEDGE_READ_ONLY` (default off) opens the knowledge index read-only for `create_harness_deps` (Pattern B/C) callers; subagent workers are always read-only regardless of the flag. The gateway SSE app is the sole writer per workspace and ignores this flag, logging a warning if it is set.
299
+ - **The workspace jail:** `run_command` runs under a deny-by-default OS filesystem policy (`fs_isolation.py::JailRoots`/`jailed_argv`), not just the `allowed_path_prefixes` argv screen (which a shell or interpreter defeats trivially — `bash -c 'cp "$HOME/Desktop/x" .'` never contains a literal `~`/`/` token an argv scanner can catch). The jail denies the user's home directory by default, then allows the workspace/artifacts/memory-palace/OS-temp-dirs back on top (read+write) and skills/interpreter-prefix/granted folders (read-only) — including when those sit inside the denied home directory, the normal case for a desktop app. Implemented for macOS `sandbox-exec`; the Linux mount-namespace path follows the same structure but is unvalidated on a real Linux host — both fail *closed* (refuse to run) if the OS mechanism can't be established, except that the jail itself (unlike the older memory-hide mechanism) fails *open*, once, with a logged warning, if neither OS mechanism is available at all — a default-on hardening that must not turn into "run_command stops working" on unsupported hosts.
300
+ - **Folder read grants:** `read_file`/`load_file`/`glob`/`grep` on an absolute path outside the workspace ask via `PathGrantInspector` (§5) rather than dead-ending; an approved folder is read in place through `WorkspaceFileService.extra_read_roots` — nothing is copied into the workspace, and the same granted folders feed the jail's read-only set above so `run_command` and the file tools agree on what's reachable.
299
301
 
300
302
  ---
301
303
 
@@ -303,13 +305,14 @@ Each section follows: **Purpose** · **Key files** · **How it works** · **Depe
303
305
 
304
306
  **Purpose:** Pre-flight policy gates; supports user confirmation via SSE.
305
307
 
306
- **Key files:** `core/tools/inspector.py`, `core/tools/permission.py`, `core/tools/loop_inspector.py`
308
+ **Key files:** `core/tools/inspector.py`, `core/tools/permission.py`, `core/tools/loop_inspector.py`, `core/tools/path_grant_inspector.py`, `core/tools/grant_store.py`
307
309
 
308
310
  **Inspectors wired at gateway startup (order matters — first deny/confirm wins):**
309
- 1. `CommandTierInspector` — `command_allowlist.yaml` deny-regex preflight; execution allowlists stay on the executor
310
- 2. `RulesInspector` — `MONKEYBOT_TOOL_DENIED_PATTERNS` substring deny list (backward compat)
311
- 3. `PermissionInspector` — `permissions.yaml` last-match-wins `allow` / `ask` / `deny` ruleset (`PERMISSION_CONFIG`)
312
- 4. `LoopStartInspector` — `start_loop` always asks for confirmation (rich plan preview)
311
+ 1. `CommandTierInspector` — `command_allowlist.yaml` deny-regex preflight (hard, never promotable), then a binary allow/ask gate: a binary already on the static allowlist, in `grants.json`, or granted "Allow once" earlier this turn is allowed and the chain continues (`permissions.yaml` can still ask/deny a finer-grained pattern on top, unchanged); any other binary asks (`confirm`, carrying `grant_key`=the binary) instead of silently falling through to a hard rejection at the executor
312
+ 2. `PathGrantInspector` — for `read_file`/`load_file`/`glob`/`grep`, an absolute/`~` path inside the workspace is a no-op (allow); on the credential denylist or outside `$HOME` it's a hard deny; already covered by a `grants.json`/turn-scoped folder grant it's allow; otherwise it asks (`confirm`, `grant_key`=the containing folder, `grant_kind="path"`)
313
+ 3. `RulesInspector` — `MONKEYBOT_TOOL_DENIED_PATTERNS` substring deny list (backward compat)
314
+ 4. `PermissionInspector` — `permissions.yaml` last-match-wins `allow` / `ask` / `deny` ruleset (`PERMISSION_CONFIG`)
315
+ 5. `LoopStartInspector` — `start_loop` always asks for confirmation (rich plan preview)
313
316
 
314
317
  **Permission ruleset (`permissions.yaml`):**
315
318
  - Rules are ordered; **last match wins** (OpenCode-style).
@@ -318,15 +321,17 @@ Each section follows: **Purpose** · **Key files** · **How it works** · **Depe
318
321
  - `default:` applies when nothing matches (shipped default: `allow`).
319
322
  - Session approvals: POST tool-confirmation with `{approved: true, always: true}` remembers tool+resource for the rest of the session (`SessionBus.session_approvals`).
320
323
 
321
- **Decision kinds:** `allow` | `deny` | `confirm` (requires `ctx.sse_bus` for pending UI response).
324
+ **Decision kinds:** `allow` | `deny` | `confirm` (requires `ctx.sse_bus` for pending UI response). A `confirm` may carry `grant_key`/`grant_kind` (`"command"` | `"path"`) — what an "Allow once"/"Always allow" click actually remembers (a binary name or a folder, never the full resource string `resource_for_call()` would otherwise use, which would make a durable rule cover exactly one invocation). `tool_dispatch.py` routes an "always" approval to `ctx.grants_persist` (writing `grants.json`, shared by every agent) when `grant_kind` is set, instead of the `computer_*`-only `ctx.approvals_persist`; either way, "Allow once" also records the grant on `ctx.turn_command_grants`/`ctx.turn_path_grants` so a repeat call later in the same turn does not ask again even without a durable write.
322
325
 
323
- **Hard constraints underneath soft asks:** `allowed_commands` / `allowed_path_prefixes` + sandbox still enforce at execution time — permission `ask`/`allow` cannot bypass them.
326
+ **`grants.json`** (`core/tools/grant_store.py`) is a home-level store — one file shared by every agent on the machine, deliberately distinct from the per-agent, `computer_*`-only `approvals.json` (§21). Same on-disk contract: JSON, mode `0600`, atomic replace, cross-process exclusive-create locking matched byte-for-byte with the Electron side (`electron/main/grants.ts`).
327
+
328
+ **Hard constraints underneath soft asks:** `allowed_commands` / `allowed_path_prefixes` + sandbox still enforce at execution time — permission `ask`/`allow` cannot bypass them. Beyond the argv allowlist, `run_command` additionally runs inside a deny-by-default OS filesystem jail (§4) that a shell/interpreter cannot argue its way around by rewriting a path.
324
329
 
325
330
  **Invariants:**
326
331
  - Missing allowlist file → tier inspector skipped (logged); executor falls back to code defaults.
327
332
  - Missing `permissions.yaml` → soft ruleset disabled (logged).
328
- - Default deny patterns block package installs (`pip install`, `npm install`, etc.).
329
- - Confirm without `sse_bus` → deny.
333
+ - Default deny patterns block package installs (`pip install`, `npm install`, etc.) and are never promotable to a confirm by any grant.
334
+ - Confirm without `sse_bus` → deny (this is why a subagent, which has no interactive session, can use an already-durably-granted command/folder transparently but can never ask for a new one).
330
335
 
331
336
  ---
332
337
 
@@ -652,7 +657,7 @@ Before spawning the gateway, the CLI probes that interpreter for MonkeyBot `>=3.
652
657
 
653
658
  **How it works:**
654
659
  - 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.
655
- - **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.
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, and `computer_move`/`computer_trash` must not be able to relocate a file straight into or out of it, one click away from smuggling exactly what the workspace boundary (§4) exists to prevent. `computer_move`'s own description now says so, so the model doesn't reach for it as a `read_file`/`run_command` workaround.
656
661
  - **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).
657
662
  - **"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.
658
663
  - 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).
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "monkeybot-browser-mcp"
7
- version = "0.5.0"
7
+ version = "0.7.0"
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 = [
@@ -93,15 +93,14 @@ def _public_tool(fn: Callable[_P, str]) -> Callable[_P, str]:
93
93
 
94
94
  @functools.wraps(fn)
95
95
  def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> str:
96
- with _TOOL_LOCK:
97
- with perf.timed_tool(fn.__name__) as rec:
98
- try:
99
- result = fn(*args, **kwargs)
100
- rec.observe(result)
101
- return result
102
- except Exception as exc:
103
- rec.fail()
104
- in_app_cdp._reraise_public_harness_error(exc)
96
+ with _TOOL_LOCK, perf.timed_tool(fn.__name__) as rec:
97
+ try:
98
+ result = fn(*args, **kwargs)
99
+ rec.observe(result)
100
+ return result
101
+ except Exception as exc:
102
+ rec.fail()
103
+ in_app_cdp._reraise_public_harness_error(exc)
105
104
 
106
105
  # FastMCP copies fn.__doc__ as-is (not inspect.getdoc), so without this the
107
106
  # model sees the 4-space body indent from the source. @mcp.tool() wraps
@@ -6,7 +6,7 @@ import contextlib
6
6
  import logging
7
7
  from typing import Any
8
8
 
9
- from browser_mcp import agentcore, dom_indexing, in_app_cdp, perf, tabs
9
+ from browser_mcp import agentcore, chat_scope, dom_indexing, in_app_cdp, perf, tabs
10
10
 
11
11
  logger = logging.getLogger(__name__)
12
12
 
@@ -23,6 +23,24 @@ def mark_unbound() -> None:
23
23
  _bound_cdp = None
24
24
 
25
25
 
26
+ def in_app_backend_active() -> bool:
27
+ """True when the live binding is Monkeyapp's in-app CDP bridge."""
28
+ return (
29
+ _bh is not None
30
+ and _bound_cdp not in (None, "agentcore")
31
+ and in_app_cdp._env_set_from_in_app_file
32
+ )
33
+
34
+
35
+ def in_app_helpers() -> Any | None:
36
+ """Return in-app CDP helpers when the in-app backend is bound, else None."""
37
+ if not in_app_backend_active():
38
+ return None
39
+ assert _bh is not None
40
+ helpers, _ = _bh
41
+ return helpers
42
+
43
+
26
44
  def teardown_bound_backend() -> None:
27
45
  """Tear down whatever backend _bh is currently bound to, if any.
28
46
 
@@ -42,6 +60,7 @@ def teardown_bound_backend() -> None:
42
60
  tabs.registry().detach_all(helpers)
43
61
  _bh = None
44
62
  dom_indexing.clear_registered_targets()
63
+ chat_scope.reset()
45
64
  if is_agentcore:
46
65
  admin.stop_session()
47
66
  from browser_mcp import playwright_helpers
@@ -58,6 +77,12 @@ def _with_perf_helpers(bh: tuple[Any, Any]) -> tuple[Any, Any]:
58
77
  return perf.wrap_helpers(helpers), admin
59
78
 
60
79
 
80
+ def _announce_in_app(helpers: Any) -> None:
81
+ """Scope the in-app bridge after bind. Playbook/login skip this by not binding."""
82
+ if in_app_cdp._env_set_from_in_app_file:
83
+ chat_scope.announce_current(helpers)
84
+
85
+
61
86
  def _reconnect_agentcore() -> tuple[str, dict[str, str]]:
62
87
  """Force a fresh AgentCore session (stop + restart) and return new ws creds.
63
88
 
@@ -105,7 +130,9 @@ def browser_harness() -> tuple[Any, Any]:
105
130
  return _with_perf_helpers(_agentcore_browser_harness())
106
131
 
107
132
  if _bh is not None and cdp == _bound_cdp:
108
- return _with_perf_helpers(_bh)
133
+ wrapped = _with_perf_helpers(_bh)
134
+ _announce_in_app(wrapped[0])
135
+ return wrapped
109
136
 
110
137
  if _bound_cdp == "agentcore":
111
138
  teardown_bound_backend()
@@ -126,6 +153,9 @@ def browser_harness() -> tuple[Any, Any]:
126
153
  admin.ensure_daemon()
127
154
  _bh = (helpers, admin)
128
155
  _bound_cdp = cdp
156
+ if in_app_cdp._env_set_from_in_app_file:
157
+ chat_scope.reset()
158
+ _announce_in_app(helpers)
129
159
  return _with_perf_helpers(_bh)
130
160
 
131
161
 
@@ -153,6 +183,7 @@ def stop_active_backend_best_effort() -> None:
153
183
  with contextlib.suppress(Exception):
154
184
  tab_ops._close_agent_opened_tabs(helpers)
155
185
  _bh = None
186
+ chat_scope.reset()
156
187
  from browser_harness import admin
157
188
 
158
189
  admin.restart_daemon()
@@ -0,0 +1,139 @@
1
+ """Chat identity for the Spaces in-app CDP bridge.
2
+
3
+ The gateway may pass ``_meta.monkeybot.thread_id`` on each MCP tool call.
4
+ When driving the in-app browser, we announce that id as ``Monkeybot.setChatScope``
5
+ before other CDP commands so new tabs attach to the right chat.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import logging
11
+ import re
12
+ from typing import Any
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ # JSON-RPC "Method not found" — Chrome's reply when the app has no setChatScope.
17
+ _JSONRPC_METHOD_NOT_FOUND = -32601
18
+ _CDP_ERROR_CODE_RE = re.compile(r"""['"]code['"]\s*:\s*(-?\d+)""")
19
+
20
+ _UNSET: object = object()
21
+ _last_chat: object = _UNSET
22
+ _unsupported: bool = False
23
+
24
+
25
+ def reset() -> None:
26
+ """Clear last-chat / unsupported flags after a daemon (re)bind."""
27
+ global _last_chat, _unsupported
28
+ _last_chat = _UNSET
29
+ _unsupported = False
30
+
31
+
32
+ def current_thread_id() -> str | None:
33
+ """Return the gateway thread id from this request's ``_meta``, if any.
34
+
35
+ Never raises. Returns ``None`` outside a request or when the extra is absent.
36
+ """
37
+ try:
38
+ from browser_mcp.app import mcp
39
+
40
+ ctx = mcp.get_context()
41
+ meta = getattr(getattr(ctx, "request_context", None), "meta", None)
42
+ return _thread_id_from_meta(meta)
43
+ except LookupError:
44
+ return None
45
+ except Exception:
46
+ logger.debug("browser-mcp: current_thread_id failed", exc_info=True)
47
+ return None
48
+
49
+
50
+ def _thread_id_from_meta(meta: object) -> str | None:
51
+ """Read ``monkeybot.thread_id`` from FastMCP's pydantic ``RequestParams.Meta``."""
52
+ if meta is None:
53
+ return None
54
+ monkeybot: Any = getattr(meta, "monkeybot", None)
55
+ if not isinstance(monkeybot, dict):
56
+ return None
57
+ thread_id = monkeybot.get("thread_id")
58
+ if thread_id is None:
59
+ return None
60
+ text = str(thread_id).strip()
61
+ return text or None
62
+
63
+
64
+ def _forget_other_chat_tabs() -> None:
65
+ """Drop this process's tab registry: those targets belong to the chat we left.
66
+
67
+ Spaces owns the previous chat's tabs and keeps them in that chat's panel.
68
+ Forgetting ``opened_by_agent`` here is intentional: ``browser_stop`` in the
69
+ new chat must not close the previous chat's tabs.
70
+ """
71
+ from browser_mcp import tabs
72
+
73
+ tabs.reset_registry()
74
+
75
+
76
+ def _cdp_error_code(exc: BaseException) -> int | None:
77
+ """Best-effort CDP/JSON-RPC error code from a harness ``RuntimeError``."""
78
+ payload = exc.args[0] if exc.args else None
79
+ if isinstance(payload, dict):
80
+ code = payload.get("code")
81
+ if isinstance(code, int):
82
+ return code
83
+ match = _CDP_ERROR_CODE_RE.search(str(exc))
84
+ if match:
85
+ return int(match.group(1))
86
+ return None
87
+
88
+
89
+ def _looks_like_unknown_method(exc: BaseException) -> bool:
90
+ if _cdp_error_code(exc) == _JSONRPC_METHOD_NOT_FOUND:
91
+ return True
92
+ text = str(exc).lower()
93
+ return "unknown method" in text or "method not found" in text
94
+
95
+
96
+ def announce_current(helpers: object) -> None:
97
+ """Announce this request's thread id. Never raises."""
98
+ announce(helpers, current_thread_id())
99
+
100
+
101
+ def announce(helpers: object, thread_id: str | None) -> None:
102
+ """Send ``Monkeybot.setChatScope`` for this request. Never raises.
103
+
104
+ CDP is sent on every call (idempotent) so a reconnected WebSocket still gets
105
+ ``chatKey``. The tab registry is dropped only when the non-None thread id
106
+ changes. ``_last_chat`` is updated even when the app does not support the
107
+ method, so a chat switch still drops tabs owned by the previous chat.
108
+ """
109
+ global _last_chat, _unsupported
110
+ previous = _last_chat
111
+ switched = (
112
+ thread_id is not None and previous is not _UNSET and previous != thread_id
113
+ )
114
+ if thread_id is not None:
115
+ _last_chat = thread_id
116
+ if switched:
117
+ _forget_other_chat_tabs()
118
+ logger.info(
119
+ "browser-mcp: chat scope changed %s -> %s; dropping tabs",
120
+ previous,
121
+ thread_id,
122
+ )
123
+ if _unsupported:
124
+ return
125
+ cdp = getattr(helpers, "cdp", None)
126
+ if not callable(cdp):
127
+ _unsupported = True
128
+ logger.warning("browser-mcp: helpers have no cdp(); disabling setChatScope")
129
+ return
130
+ try:
131
+ cdp("Monkeybot.setChatScope", chatKey=thread_id)
132
+ except Exception as exc:
133
+ if _looks_like_unknown_method(exc):
134
+ _unsupported = True
135
+ logger.warning(
136
+ "browser-mcp: Monkeybot.setChatScope unsupported; disabling for this connection"
137
+ )
138
+ else:
139
+ logger.warning("browser-mcp: Monkeybot.setChatScope failed", exc_info=True)
@@ -9,6 +9,8 @@ from pathlib import Path
9
9
  from typing import NoReturn
10
10
  from urllib.parse import parse_qsl, urlencode, urlparse, urlunparse
11
11
 
12
+ from browser_mcp import chat_scope
13
+
12
14
  logger = logging.getLogger(__name__)
13
15
 
14
16
  # Written by Monkeyapp when the in-app Electron CDP bridge is live. Prefer this over
@@ -150,9 +152,12 @@ def _redact_cdp_token(message: str) -> str:
150
152
  def _bind_in_app_endpoint(url: str, token: str | None) -> str:
151
153
  global _env_set_from_in_app_file
152
154
  endpoint = _in_app_ws_url(url, token)
155
+ prev = os.environ.get("BU_CDP_WS")
153
156
  os.environ["BU_CDP_WS"] = endpoint
154
157
  os.environ.pop("BU_CDP_URL", None)
155
158
  _env_set_from_in_app_file = True
159
+ if prev != endpoint:
160
+ chat_scope.reset()
156
161
  return endpoint
157
162
 
158
163