workspace#

class baf.reasoning.workspace.Workspace(path, name='workspace', description=None, writable=True, max_read_bytes=200000)[source]#

Bases: object

A filesystem path the reasoning loop can browse on demand.

A Workspace is a pure data + behaviour holder: it stores a sandboxed root path and exposes list_directory and read_file methods that the reasoning loop invokes through the agent’s universal list_directory and read_file tools (registered automatically by baf.core.agent.Agent.add_workspace() the first time a workspace is added). Tools take a workspace argument that selects which workspace to use, and may omit it when only one workspace is registered.

All paths are resolved relative to root and any attempt to escape the workspace (via .. or absolute paths) is rejected with a WorkspaceError.

Parameters:
  • path (str) – the workspace root path. Must exist and be a directory.

  • name (str) – the workspace identifier the LLM passes as the workspace tool argument. Must be unique within the agent.

  • description (str) – a short human-readable explanation of what the workspace contains. Surfaced to the LLM in the system prompt so it knows when this workspace is relevant — without a description the LLM only sees the name and root path and may not realise it should browse the workspace at all.

  • writable (bool) – if False, the mutating operations (write_file, create_file, delete_file) raise WorkspaceError and the corresponding universal tools are not registered on the agent unless at least one other workspace is writable. Defaults to True.

  • max_read_bytes (int) – the maximum number of bytes read_file will return; the rest is replaced with a clear truncation marker. Defaults to 200_000.

root#

the resolved absolute path to the workspace root.

Type:

Path

name#

the workspace identifier.

Type:

str

description#

the optional human-readable description.

Type:

Optional[str]

writable#

whether mutating operations are allowed.

Type:

bool

max_read_bytes#

cap on read_file output.

Type:

int

_require_writable()[source]#

Guard for mutating operations. Raises if the workspace is read-only.

_safe_resolve(relative_path)[source]#

Resolve relative_path and guard against workspace escape.

Parameters:

relative_path (str) – the user-supplied (LLM-supplied) path.

Returns:

the absolute, resolved path inside the workspace.

Return type:

Path

Raises:

WorkspaceError – if the resolved path escapes the workspace root.

create_file(relative_path, content='')[source]#

Create a new file inside the workspace with the given content.

Fails if the target path already exists (use write_file() to overwrite instead). Missing parent directories are created.

Parameters:
  • relative_path (str) – a path relative to the workspace root.

  • content (str) – the initial contents of the file (UTF-8). Defaults to an empty string for an empty file.

Returns:

a short confirmation including the byte count written.

Return type:

str

Raises:

WorkspaceError – if the workspace is read-only, the path escapes the workspace root, or the target already exists.

delete_file(relative_path)[source]#

Delete a file inside the workspace.

Only deletes regular files — directories are refused (deletion cascades are intentionally not exposed). Fails if the target does not exist so the LLM gets explicit feedback rather than a silent no-op.

Parameters:

relative_path (str) – a path relative to the workspace root.

Returns:

a short confirmation message.

Return type:

str

Raises:

WorkspaceError – if the workspace is read-only, the path escapes the workspace root, the target does not exist, or the target is a directory.

list_directory(relative_path='.')[source]#

List files and subfolders inside the workspace at relative_path.

Parameters:

relative_path (str) – a path relative to the workspace root. Defaults to '.' (the root itself).

Returns:

one entry per line, prefixed by '[DIR] ' or '[FILE] '.

Return type:

str

Raises:

WorkspaceError – if the resolved path escapes the workspace root or does not point at a directory.

read_file(relative_path)[source]#

Read a file inside the workspace.

Output is truncated at self.max_read_bytes with a clear marker so the LLM knows it can ask for a follow-up read.

Parameters:

relative_path (str) – a path relative to the workspace root.

Returns:

the file’s textual content (possibly truncated).

Return type:

str

Raises:

WorkspaceError – if the path escapes the workspace root or the target is not a file.

top_level_listing()[source]#

Return a one-line-per-entry preview of the workspace root.

Used to hint the LLM at what’s inside without forcing a separate list_directory call. Returns '' if the directory is empty or unreadable.

write_file(relative_path, content)[source]#

Write content to a file inside the workspace, overwriting any existing content.

Creates the file (and any missing parent directories) if it does not exist. Use create_file() instead when you want the call to fail if the file already exists.

Parameters:
  • relative_path (str) – a path relative to the workspace root.

  • content (str) – the new contents of the file (UTF-8). May be empty, which truncates an existing file.

Returns:

a short confirmation including the byte count written.

Return type:

str

Raises:

WorkspaceError – if the workspace is read-only, the path escapes the workspace root, or the target points at an existing directory.

exception baf.reasoning.workspace.WorkspaceError[source]#

Bases: Exception

Raised when a Workspace operation fails (path escape, missing file, etc.).

baf.reasoning.workspace._is_within(parent, child)[source]#

Return True if child is at or below parent on the filesystem.

Uses pathlib.Path.is_relative_to() when available (Python 3.9+), and falls back to os.path.commonpath() otherwise so the helper keeps working on older interpreters.