Skip to main content

CommandBackend

Struct CommandBackend 

Source
pub struct CommandBackend { /* private fields */ }
Expand description

A subprocess backend: prompt on stdin, completion on stdout.

Implementations§

Source§

impl CommandBackend

Source

pub fn new(argv: Vec<String>, timeout: Duration) -> Self

A backend named by its own command line.

The named constructors below are the production path; this is for a backend with nothing better to call itself, which in practice means a test double.

Source

pub fn with_working_dir(self, dir: &Path) -> Self

Run the child in dir.

The repository root, for any backend whose prompt names repo-relative paths — which the default one does. See the field for what goes wrong without it, and why it goes wrong silently.

Source

pub fn with_cancel(self, flag: Arc<AtomicBool>) -> Self

Kill the child as soon as flag is set.

Source

pub fn with_timeout(self, timeout: Duration) -> Self

Source

pub fn claude_cli(fetch: &str) -> Self

The default: headless, text output, and read-only tools (ADR 0022).

ADR 0010 denied tools outright, because the evaluated grouping tool kept exiting 1 on stop_reason: "tool_use". Denying them cured it by sending no tool definitions at all, so the model could not ask. An allowlist is the other cure: it can ask, and the answer is yes.

fetch is the executable the prompt tells the model to run — normally this process. The allowlist is derived from it, so the two cannot disagree about what the model is allowed to invoke.

Nothing here can write. The fetch command reads the document the engine just wrote; the rest read the repository. git log and git show are what reach the reason a change was made, which no prompt can carry.

git diff is advertised; the rest are not. The prompt names the fetch command and git diff, and nothing else.

That is a change of rule, and it is worth saying why. git diff is advertised because it is now the only way to see what a hunk says: the fetch command’s diff query is gone, having duplicated class except for the text. A tool the model must use and is not told about is a tool it will not use.

It costs an invitation to read the whole repository, and the prompt is what pays for that: it says to read what decides a label and then stop.

It no longer costs a route around the generated content this stage folds away, though it did when it was written. generated is part of the shape-class key now (ADR 0004), so no class the model is given contains a generated file and there is nothing folded left for it to ask git diff about by accident. The prompt still says not to go looking.

Read, Grep, Glob, git log and git show stay unadvertised for the original reason: a model that needs the code around a hunk can go and read it, but it is not sent looking. If you add a tool here, do not add a line about it to the prompt.

The allowlist is this function’s business, not the user’s, and there is no config that replaces it. [grouping].agent picks between agents by name; it used to take a free argv, which handed a stranger’s process the prompt and none of the allowlist, fetch command or read path the prompt is written for.

fetch is where a binary lives, so it is the one part of this argv that says nothing about what the model will do. The cache identity stands a placeholder in its place: change the allowlist and every cached grouping is rightly invalidated, move the binary and none of them are.

Trait Implementations§

Source§

impl LlmBackend for CommandBackend

Source§

fn name(&self) -> &str

What to call this agent on screen, for a reviewer waiting on it. Read more
Source§

fn identity(&self) -> &str

Everything about this backend that could change the grouping, and nothing that could not. The grouping cache key hashes this (ADR 0009). Read more
Source§

fn complete(&self, prompt: &str) -> Result<String, LlmError>

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.