Skip to content

Commit

Permalink
Naming pass
Browse files Browse the repository at this point in the history
  • Loading branch information
epatey committed Mar 8, 2025
1 parent c6e8c33 commit c77f062
Show file tree
Hide file tree
Showing 62 changed files with 132 additions and 132 deletions.
57 changes: 0 additions & 57 deletions src/eric_testing/README.md

This file was deleted.

16 changes: 0 additions & 16 deletions src/eric_testing/src/inspect_multi_tool/__init__.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ WORKDIR /opt/inspect



COPY /inspect_multi_tool-0.1.0.tar.gz /tmp/
RUN pip install /tmp/inspect_multi_tool-0.1.0.tar.gz
COPY /inspect_tool_container-0.1.0.tar.gz /tmp/
RUN pip install /tmp/inspect_tool_container-0.1.0.tar.gz

RUN inspect-tool-install

Expand Down
Binary file not shown.
2 changes: 1 addition & 1 deletion src/inspect_ai/tool/_tools/_web_browser/_web_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from inspect_ai.util._sandbox import SandboxEnvironment, sandbox_with
from inspect_ai.util._sandbox.docker.internal import INSPECT_WEB_BROWSER_IMAGE_DOCKERHUB
from inspect_ai.util._store_model import StoreModel, store_as
from inspect_multi_tool._remote_tools._web_browser.tool_types import (
from inspect_tool_container._remote_tools._web_browser.tool_types import (
CrawlerResult,
NewSessionResult,
)
Expand Down
8 changes: 8 additions & 0 deletions src/inspect_tool_container/.pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[MASTER]
; R - Refactorings
; C - Convention
; W - Warning
; E - Error
enable=C,R,W,E
disable=R0903,C0114,C0115,C0116,C0301,C0411,C1804,C1805,W0120,W0511,W0718,W1203,E0401,E1101,E0611,E1128
score=no
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
include README.md
include LICENSE
recursive-include src/inspect_multi_tool *.py *.svg *.md
recursive-include src/inspect_tool_container *.py *.svg *.md
recursive-exclude * __pycache__
recursive-exclude * *.py[cod]
recursive-exclude * *$py.class
40 changes: 40 additions & 0 deletions src/inspect_tool_container/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Multi-tool Shared Image

![diagram](shared_tool_container_design.svg)

## Stateless / Stateful Design

Inspect calls into the sandboxed image are done statelessly via `docker exec python multi-tool.py`.

Some tools can be implemented without the need for any in-process state. For those tools, the tool code will be executed within the `multi-tool.py` process.

For tools that require the maintenance of state over the lifetime of and sandbox, this image marshals tool calls into a long running process via JSON RPC to an http server process. That server then dispatches tool calls to tool specific `@method` handlers.

### Stateful Tool Design Pattern

Each stateful tool should have its own subdirectory that contains the following files:

- `json_rpc_methods.py`

This module contains all of the JSON RPC `@method` functions — one for each tool (e.g. the web browser tool is actually a set of distinct tools). It is responsible for unpacking the JSON RPC request and forwarding the call to a transport-agnostic, strongly typed, stateful controller.

- `tool_types.py`

This module includes the `pydantic` models representing the types for tool call parameters and results.

- `controller.py`

This is transport-agnostic, strongly typed code that manages the tool specific in-process state and performs requested commands.

## Compatibility

The Inspect framework will insure that the most recently published image of a particular tag will be downloaded when an eval is executed. This means that, from a cross-version perspective, we only have to worry about old tool code interacting with newer container code. The inverse is not possible.

Because of this, when publishing new _major version_ images, care must be taken to retain the old version entrypoint called by tools.

For example, older versions of the `web_browser_tool()` performed `docker exec`'s against `/app/web_browser/web_client.py` and `/app/web_browser/web_client_new_session.py`. A newer version of the image changed the entry point to `/opt/inspect/multi-tool-v1.py`.

This means that newer versions of the image **must** retain the old entry points in a backwardly compatible way. Typically, the implementation of those old entry points will be updated to adapt and call the new version of the code.

> [!TIP]
> For this reason, it is a best practice to include a version number in the filename of the `docker exec` entry points.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"name": "Python: Debug multi_tool cli",
"type": "python",
"request": "launch",
"module": "inspect_multi_tool",
"module": "inspect_tool_container",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}/src/eric_testing/src",
"args": ["${input:requestArg}"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"

[tool.setuptools.packages.find]
where = ["src"]
include = ["inspect_multi_tool*"]
include = ["inspect_tool_container*"]

[tool.setuptools.package-data]
"inspect_multi_tool" = ["**/*.svg", "**/*.md"]
"inspect_tool_container" = ["**/*.svg", "**/*.md"]


[tool.ruff]
Expand Down Expand Up @@ -64,9 +64,9 @@ disable_error_code = "unused-ignore"
ignore = ["W002", "W009"]

[project]
name = "inspect_multi_tool"
name = "inspect_tool_container"
version = "0.1.0"
description = "Multi-tool sandbox container code for inspect_ai"
description = "Sandbox container tool code for inspect_ai"
authors = [{ name = "UK AI Security Institute" }]
readme = "README.md"
requires-python = ">=3.10"
Expand Down Expand Up @@ -97,9 +97,9 @@ dependencies = [
[project.urls]

[project.scripts]
inspect-tool-exec = "inspect_multi_tool._cli.main:main"
inspect-tool-install = "inspect_multi_tool._cli.post_install:main"
inspect-tool-server = "inspect_multi_tool._cli.server:main"
inspect-tool-exec = "inspect_tool_container._cli.main:main"
inspect-tool-install = "inspect_tool_container._cli.post_install:main"
inspect-tool-server = "inspect_tool_container._cli.server:main"

[project.optional-dependencies]

Expand Down
16 changes: 16 additions & 0 deletions src/inspect_tool_container/src/inspect_tool_container/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
Sandbox container tool code for inspect_ai.
Contains tools for web browser, bash, and editor functionality.
"""

__version__ = "0.1.0"

from inspect_tool_container._util._constants import SERVER_PORT
from inspect_tool_container._util._load_tools import load_tools

__all__ = [
"__version__",
"SERVER_PORT",
"load_tools",
]
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
from jsonrpcserver import async_dispatch
from pydantic import BaseModel

from inspect_multi_tool import SERVER_PORT
from inspect_multi_tool._util._common_types import JSONRPCResponseJSON
from inspect_multi_tool._util._json_rpc_helpers import json_rpc_http_call
from inspect_multi_tool._util._load_tools import load_tools
from inspect_tool_container import SERVER_PORT
from inspect_tool_container._util._common_types import JSONRPCResponseJSON
from inspect_tool_container._util._json_rpc_helpers import json_rpc_http_call
from inspect_tool_container._util._load_tools import load_tools

_SERVER_URL = f"http://localhost:{SERVER_PORT}/"

Expand All @@ -31,7 +31,7 @@ def main() -> None:
async def async_main() -> None:
_ensure_daemon_is_running()

in_process_tools = load_tools("inspect_multi_tool._in_process_tools")
in_process_tools = load_tools("inspect_tool_container._in_process_tools")

args: argparse.Namespace = parser.parse_args()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from aiohttp.web import Application, Request, Response, run_app
from jsonrpcserver import async_dispatch

from inspect_multi_tool import SERVER_PORT, load_tools
from inspect_tool_container import SERVER_PORT, load_tools


def main() -> None:
load_tools("inspect_multi_tool._remote_tools")
load_tools("inspect_tool_container._remote_tools")

async def handle_request(request: Request) -> Response:
return Response(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from pathlib import Path
from typing import Literal

from inspect_multi_tool._in_process_tools._editor._run import maybe_truncate, run
from inspect_multi_tool._util._common_types import ToolException
from inspect_tool_container._in_process_tools._editor._run import maybe_truncate, run
from inspect_tool_container._util._common_types import ToolException

DEFAULT_HISTORY_PATH = "/tmp/inspect_editor_history.pkl"
SNIPPET_LINES: int = 4
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
from jsonrpcserver import method

from inspect_multi_tool._in_process_tools._editor.editor import (
from inspect_tool_container._in_process_tools._editor.editor import (
create,
insert,
str_replace,
undo_edit,
view,
)
from inspect_multi_tool._in_process_tools._editor.tool_types import (
from inspect_tool_container._in_process_tools._editor.tool_types import (
CreateParams,
EditorParams,
InsertParams,
StrReplaceParams,
UndoEditParams,
ViewParams,
)
from inspect_multi_tool._util._json_rpc_helpers import with_validated_rpc_method_params
from inspect_tool_container._util._json_rpc_helpers import (
with_validated_rpc_method_params,
)


@method
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from asyncio import Task
from asyncio.subprocess import Process

from inspect_multi_tool._remote_tools._bash.tool_types import (
from inspect_tool_container._remote_tools._bash.tool_types import (
BashCommandResult,
BashRestartResult,
)
Expand Down Expand Up @@ -148,6 +148,3 @@ async def _close(self) -> None:
except asyncio.TimeoutError:
process.kill()
await process.wait()
except asyncio.TimeoutError:
process.kill()
await process.wait()
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import jsonrpcserver

from inspect_multi_tool._remote_tools._bash.controller import Controller
from inspect_multi_tool._remote_tools._bash.tool_types import (
from inspect_tool_container._remote_tools._bash.controller import Controller
from inspect_tool_container._remote_tools._bash.tool_types import (
BashCommandResult,
BashParams,
BashRestartResult,
CommandParams,
RestartParams,
)
from inspect_multi_tool._util._json_rpc_helpers import with_validated_rpc_method_params
from inspect_tool_container._util._json_rpc_helpers import (
with_validated_rpc_method_params,
)

controller = Controller()

Expand All @@ -24,4 +26,3 @@ async def _bash(params: BashParams) -> BashCommandResult | BashRestartResult:
return await controller.execute_command(command)
case RestartParams():
return await controller.restart()
return await controller.restart()
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
from functools import reduce
from typing import Iterable, TypedDict

from inspect_multi_tool._remote_tools._web_browser.accessibility_tree_node import (
from inspect_tool_container._remote_tools._web_browser.accessibility_tree_node import (
AccessibilityTreeNode,
)
from inspect_multi_tool._remote_tools._web_browser.cdp.a11y import AXNode, AXNodeId
from inspect_multi_tool._remote_tools._web_browser.cdp.dom_snapshot import (
from inspect_tool_container._remote_tools._web_browser.cdp.a11y import AXNode, AXNodeId
from inspect_tool_container._remote_tools._web_browser.cdp.dom_snapshot import (
DOMSnapshot,
create_snapshot_context,
)
from inspect_multi_tool._remote_tools._web_browser.rectangle import Rectangle
from inspect_tool_container._remote_tools._web_browser.rectangle import Rectangle

_AccType = tuple[
AXNode | None,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
from functools import reduce
from typing import Optional

from inspect_multi_tool._remote_tools._web_browser.cdp.a11y import (
from inspect_tool_container._remote_tools._web_browser.cdp.a11y import (
AXNode,
AXNodeId,
AXProperty,
AXPropertyName,
node_has_property,
string_from_ax_value,
)
from inspect_multi_tool._remote_tools._web_browser.cdp.dom_snapshot import (
from inspect_tool_container._remote_tools._web_browser.cdp.dom_snapshot import (
DOMSnapshotContext,
bounds_for_node_index,
current_url_src_for_node_index,
index_for_node_id,
text_value_for_node_index,
)
from inspect_multi_tool._remote_tools._web_browser.rectangle import Rectangle
from inspect_tool_container._remote_tools._web_browser.rectangle import Rectangle

# Properties to ignore when printing out the accessibility tree.
_IGNORED_AT_PROPERTIES: set[AXPropertyName] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from pydantic import BaseModel

from inspect_multi_tool._remote_tools._web_browser.cdp.dom import DOMBackendNodeId
from inspect_tool_container._remote_tools._web_browser.cdp.dom import DOMBackendNodeId

# brand these str's so that we don't confuse them with other str's
PageFrameId = NewType("PageFrameId", str)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from pydantic import BaseModel

from inspect_multi_tool._remote_tools._web_browser.cdp.dom import DOMBackendNodeId
from inspect_tool_container._remote_tools._web_browser.cdp.dom import DOMBackendNodeId

StringIndex = NewType("StringIndex", int)
Rectangle = tuple[float, ...]
Expand Down
Loading

0 comments on commit c77f062

Please sign in to comment.