Context handed to every tool execution.
Carries the working directory the loop should treat as root, the current
permission mode, the session id (if any), and a free-form assigns map for
custom tools to stash arbitrary data the consumer needs (project id,
conversation id, ticket id — whatever the host cares about).
Tools that don't care about context can ignore it, but cwd and phase
are load-bearing for any tool that touches the filesystem or checks
permissions.
Summary
Functions
Whether this context confines tools to allowed_roots.
Build a context. :cwd is required; everything else defaults.
Resolve a user-supplied path against ctx.cwd.
Whether an absolute path lies within one of roots. Compares on path
segments (not string prefixes) so /foo never matches /foobar. A path equal
to a root counts as inside it.
Types
Functions
Whether this context confines tools to allowed_roots.
Build a context. :cwd is required; everything else defaults.
Resolve a user-supplied path against ctx.cwd.
Unconfined (allowed_roots: nil, the default) keeps the historical behaviour:
relative paths are expanded against cwd, .. traversal is rejected, and
absolute paths pass through untouched.
Confined (allowed_roots is a list) expands the path to an absolute one
(handling ../~ lexically) and requires the result to fall inside one of
the roots, returning {:error, {:path_outside_roots, abs}} otherwise — so
neither /etc/passwd nor ../../secret can escape.
Whether an absolute path lies within one of roots. Compares on path
segments (not string prefixes) so /foo never matches /foobar. A path equal
to a root counts as inside it.