You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up from #2269 / #2270, requested by @lionello: "we need a read-only mode, agent without mutable tools."
#2270 makes each write-capable agent tool handler (deploy, destroy, set_config, remove_config) refuse up front when elicitations.Controller.IsSupported() is false — i.e. when there's no user to confirm with. The tools are still registered and offered to the model; they just no-op-and-report an error at call time. That fixes the specific incident (unattended CI debugger silently mutating production) but isn't the same thing as a read-only mode.
This issue is about the broader ask: a mode where mutable tools are never registered/offered to the model at all, so the model can't even attempt a write — closer to the "gate registration in agent.go" variant that was considered and set aside for #2270 in favor of the narrower per-handler-refusal fix (see #2269's plan comment).
Where this would live
src/pkg/agent/agent.go's New() builds the tool list unconditionally:
tools.CollectDefangTools (src/pkg/agent/tools/tools.go) returns one flat []ai.Tool including deploy, destroy, set_config, remove_config alongside read-only tools (services, logs, estimate, list_configs, current_stack, ...).
Proposed shape
Add a ReadOnly bool (or similar) to StackConfig, or a new agent.Option (e.g. WithReadOnly()), that CollectDefangTools uses to skip the four write-capable tool constructors entirely.
Decide how it's exposed: a CLI flag on the debugger invocation, an MCP integration setting, or both — the sibling hook session that flagged this noted it could be reusable beyond the CI-debugger path (e.g. for MCP).
WithNonInteractive() (used only by the CI debugger) and a future WithReadOnly() are orthogonal: the CI debugger today wants non-interactive and now has per-handler refusal (agent: refuse debugger writes when there is no one to confirm them #2270); a read-only mode might be requested independently by an interactive session too (e.g. someone deliberately wants read-only chat access).
Describe the issue
Follow-up from #2269 / #2270, requested by @lionello: "we need a read-only mode, agent without mutable tools."
#2270 makes each write-capable agent tool handler (
deploy,destroy,set_config,remove_config) refuse up front whenelicitations.Controller.IsSupported()is false — i.e. when there's no user to confirm with. The tools are still registered and offered to the model; they just no-op-and-report an error at call time. That fixes the specific incident (unattended CI debugger silently mutating production) but isn't the same thing as a read-only mode.This issue is about the broader ask: a mode where mutable tools are never registered/offered to the model at all, so the model can't even attempt a write — closer to the "gate registration in
agent.go" variant that was considered and set aside for #2270 in favor of the narrower per-handler-refusal fix (see #2269's plan comment).Where this would live
src/pkg/agent/agent.go'sNew()builds the tool list unconditionally:tools.CollectDefangTools(src/pkg/agent/tools/tools.go) returns one flat[]ai.Toolincludingdeploy,destroy,set_config,remove_configalongside read-only tools (services,logs,estimate,list_configs,current_stack, ...).Proposed shape
ReadOnly bool(or similar) toStackConfig, or a newagent.Option(e.g.WithReadOnly()), thatCollectDefangToolsuses to skip the four write-capable tool constructors entirely.WithNonInteractive()(used only by the CI debugger) and a futureWithReadOnly()are orthogonal: the CI debugger today wants non-interactive and now has per-handler refusal (agent: refuse debugger writes when there is no one to confirm them #2270); aread-onlymode might be requested independently by an interactive session too (e.g. someone deliberately wants read-only chat access).Not decided yet
Referenced from #2269.