Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions packages/bub-acp-server/src/bub_acp_server/client_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def _require_terminal_client(self) -> Client:
def build_client_tools(runtime: ACPClientToolRuntime) -> dict[str, Tool]:
"""Build supported client tools, leaving unsupported tools on the agent intact."""

@partial(Tool.from_callable, name="bash", context=True, preserve=True)
@partial(Tool.from_callable, name="bash", context=True, exposure="direct")
async def bash(
command: str,
cwd: str | None = None,
Expand All @@ -254,7 +254,7 @@ async def bash(
"""Run a shell command through the ACP client terminal."""
return await runtime.bash(command, cwd, timeout_seconds, background, context)

@partial(Tool.from_callable, name="bash.output", context=True, preserve=True)
@partial(Tool.from_callable, name="bash.output", context=True, exposure="direct")
async def bash_output(
shell_id: str,
offset: int = 0,
Expand All @@ -265,12 +265,12 @@ async def bash_output(
"""Read buffered output from an ACP client terminal."""
return await runtime.bash_output(shell_id, offset, limit, context)

@partial(Tool.from_callable, name="bash.kill", context=True, preserve=True)
@partial(Tool.from_callable, name="bash.kill", context=True, exposure="direct")
async def kill_bash(shell_id: str, *, context: ToolContext) -> str:
"""Terminate an ACP client terminal process."""
return await runtime.kill_bash(shell_id, context)

@partial(Tool.from_callable, name="fs.read", context=True, preserve=True)
@partial(Tool.from_callable, name="fs.read", context=True, exposure="direct")
async def fs_read(
path: str,
offset: int = 0,
Expand All @@ -281,7 +281,7 @@ async def fs_read(
"""Read a text file through the ACP client filesystem."""
return await runtime.read_file(path, offset, limit, context)

@partial(Tool.from_callable, name="fs.write", context=True, preserve=True)
@partial(Tool.from_callable, name="fs.write", context=True, exposure="direct")
async def fs_write(
path: str,
content: str,
Expand All @@ -291,7 +291,7 @@ async def fs_write(
"""Write a text file through the ACP client filesystem."""
return await runtime.write_file(path, content, context)

@partial(Tool.from_callable, name="fs.edit", context=True, preserve=True)
@partial(Tool.from_callable, name="fs.edit", context=True, exposure="direct")
async def fs_edit(
path: str,
old: str,
Expand Down
2 changes: 1 addition & 1 deletion packages/bub-acp-server/tests/test_client_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ async def test_initialize_selects_client_tools_by_capability(
}.items():
assert (selected[name] is not originals[name]) == client_backed, name
# Client-backed overrides stay model-facing in code mode like the builtins.
assert selected[name].preserve == originals[name].preserve, name
assert selected[name].exposure == originals[name].exposure, name
assert REGISTRY == originals


Expand Down
2 changes: 1 addition & 1 deletion packages/bub-acp-server/tests/test_subagents.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ async def test_negotiated_session_replaces_only_this_session_tool() -> None:
assert installed.description == REGISTRY["subagent"].description
assert installed.parameters == REGISTRY["subagent"].parameters
assert installed.renderer is REGISTRY["subagent"].renderer
assert installed.preserve == REGISTRY["subagent"].preserve
assert installed.exposure == REGISTRY["subagent"].exposure
assert installed.output_schema == REGISTRY["subagent"].output_schema
assert installed.handler is not REGISTRY["subagent"].handler
assert REGISTRY["subagent"].handler is not installed.handler
Expand Down
2 changes: 1 addition & 1 deletion packages/bub-qq/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ Note: with no configuration, comma commands are unusable in C2C (fail-closed). S

### Ops comma commands

The plugin ships model-invisible comma commands (registered with `agent_use=False`) for authorized senders:
The plugin ships model-invisible comma commands (registered with `exposure="command"`) for authorized senders:

| Command | Description |
| --- | --- |
Expand Down
2 changes: 1 addition & 1 deletion packages/bub-qq/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ export BUB_QQ_RECEIVE_MODE=websocket

### 运维逗号命令

插件内置了对模型不可见(`agent_use=False`)、仅授权发送者可用的逗号命令:
插件内置了对模型不可见(`exposure="command"`)、仅授权发送者可用的逗号命令:

| 命令 | 说明 |
| --- | --- |
Expand Down
4 changes: 2 additions & 2 deletions packages/bub-qq/src/bub_qq/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
``msg_id``/``msg_seq`` targeting, dedupe and the active-message fallback
all behave exactly as in direct mode.

Tools registered with ``agent_use=False`` are ops comma commands: they
Tools registered with ``exposure="command"`` are ops comma commands: they
never appear in the model's tool list and can only be run as ``,name``
by senders who pass the comma-command gate (group owners/admins or
``admin_users``).
Expand Down Expand Up @@ -101,7 +101,7 @@ async def qq_send(content: str, *, context: ToolContext) -> QQSendResult:
return {"status": "sent"}


@tool(name="qq.version", agent_use=False)
@tool(name="qq.version", exposure="command")
def qq_version() -> str:
"""Show the installed bub-qq plugin version (ops comma command)."""

Expand Down
4 changes: 2 additions & 2 deletions packages/bub-qq/tests/test_ops_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
def test_qq_version_is_registered_as_command_only() -> None:
tool = REGISTRY["qq.version"]

assert tool.agent_use is False
assert REGISTRY["qq.send"].agent_use is True
assert tool.exposure == "command"
assert REGISTRY["qq.send"].exposure == "auto"


def test_qq_version_reports_package_version() -> None:
Expand Down
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading