mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-06 17:57:43 +02:00
[eric] agents: read-only session flag for the unattended onboarding audit (Edit/Bash hard-blocked)
This commit is contained in:
@@ -17,6 +17,10 @@ class AgentConfig(BaseModel):
|
||||
workflow_edit_id: Optional[str] = None
|
||||
# App cards the user picked to edit. When exactly one resolves, launch binds the chat's cwd to that app instead of seeding a new "Untitled App".
|
||||
selected_app_output_ids: Optional[list[str]] = None
|
||||
# Onboarding auto-launches an audit over the user's REAL files with nobody watching, so it runs
|
||||
# read-only: Read/Grep/Glob + Write (its one report) allowed, Edit/Bash/NotebookEdit hard-blocked
|
||||
# so "modify or delete an existing file" is unrepresentable, not just discouraged by the prompt.
|
||||
read_only: bool = False
|
||||
|
||||
class ApprovalRequest(BaseModel):
|
||||
id: str = Field(default_factory=lambda: uuid4().hex)
|
||||
@@ -84,6 +88,8 @@ class AgentSession(BaseModel):
|
||||
sdk_session_id: Optional[str] = None
|
||||
system_prompt: Optional[str] = None
|
||||
allowed_tools: list[str] = Field(default_factory=list)
|
||||
# Hard-block the mutation/exec tools for this session (onboarding's unattended audit); see AgentConfig.read_only.
|
||||
read_only: bool = False
|
||||
max_turns: Optional[int] = None
|
||||
cwd: Optional[str] = None
|
||||
# Resolved at session start so resume reattaches to the same repo even after the user cd's elsewhere.
|
||||
|
||||
@@ -110,6 +110,7 @@ class AgentLaunch(AgentManagerProtocol):
|
||||
mode=config.mode,
|
||||
system_prompt=config.system_prompt,
|
||||
allowed_tools=tools,
|
||||
read_only=config.read_only,
|
||||
max_turns=config.max_turns,
|
||||
cwd=effective_cwd,
|
||||
repo_url=repo_url,
|
||||
|
||||
@@ -19,6 +19,10 @@ from backend.apps.tools_lib.tools_lib import (
|
||||
sanitize_server_name as sanitize_server_name,
|
||||
)
|
||||
|
||||
# Mutation/exec tools a read-only session must never reach: Edit (rewrites files), Bash (rm/mv/overwrite),
|
||||
# NotebookEdit (rewrites notebooks). Write is intentionally NOT here, the audit needs its one report.
|
||||
READ_ONLY_BLOCKED_TOOLS = ("Edit", "Bash", "NotebookEdit")
|
||||
|
||||
|
||||
@typechecked
|
||||
def build_effective_tool_lists(
|
||||
@@ -108,4 +112,13 @@ def build_effective_tool_lists(
|
||||
# The claude_code preset ships its own bare `Skill` tool that reads ~/.claude/skills directly; always withhold it so skills only ever load through our provider-agnostic mcp__openswarm-skill__Skill (or not at all).
|
||||
if "Skill" not in effective_disallowed:
|
||||
effective_disallowed.append("Skill")
|
||||
# Read-only session (onboarding's unattended audit over the user's real files): the mutation/exec
|
||||
# tools are HARD-blocked, not just left out of allowed, so a background agent can never modify or
|
||||
# delete an existing file. Write stays permitted for its single report. Also drop them from allowed
|
||||
# in case a preset seeded them, disallowed wins in the SDK but keep the two lists coherent.
|
||||
if getattr(session, "read_only", False):
|
||||
for dt in READ_ONLY_BLOCKED_TOOLS:
|
||||
if dt not in effective_disallowed:
|
||||
effective_disallowed.append(dt)
|
||||
effective_allowed = [t for t in effective_allowed if t not in READ_ONLY_BLOCKED_TOOLS]
|
||||
return effective_allowed, effective_disallowed
|
||||
|
||||
@@ -137,6 +137,8 @@ export interface AgentConfig {
|
||||
target_directory?: string;
|
||||
dashboard_id?: string;
|
||||
selected_app_output_ids?: string[];
|
||||
// Onboarding's unattended audit runs read-only over the user's real files (Edit/Bash hard-blocked).
|
||||
read_only?: boolean;
|
||||
}
|
||||
|
||||
export interface HistorySession {
|
||||
|
||||
Reference in New Issue
Block a user