Skip to content

trading_agent.workspace.workspace_layout

Where every file in the agent's workspace lives, and creating the missing ones from templates.

The workspace has a shared part that belongs to the user, and one folder per desk:

workspace/ shared/ Agents.md User.md TradingRules.md shared/skills/installed/ the user's imported skills shared/knowledge/ the user's documents, searched with search_knowledge shared/agents/ the user's subagent definitions, starting with four starters shared/hooks// the user's hook scripts shared/packages// installed packages desks// Persona.md Memory.md notes/ sessions/ skills/ proposals/ requests/ scratch/ uploads/ .checkpoints/.git snapshots of each desk's own files

Typical usage example:

layout = WorkspaceLayout(Path('workspace')) layout.create_missing(['main']) text = layout.trading_rules_file.read_text()

SHARED_FILE_NAMES module-attribute

SHARED_FILE_NAMES = ('Agents.md', 'User.md', 'TradingRules.md')

DESK_FILE_NAMES module-attribute

DESK_FILE_NAMES = ('Persona.md', 'Memory.md')

USER_OWNED_FILE_NAMES module-attribute

USER_OWNED_FILE_NAMES = ('Agents.md', 'User.md', 'TradingRules.md', 'Persona.md')

TEMPLATE_STATUS_LINE module-attribute

TEMPLATE_STATUS_LINE = 'Status: template, not filled in yet.'

WorkspaceLayout

WorkspaceLayout(root)

The paths of one workspace.

Attributes:

Name Type Description
root

The workspace folder.

shared_directory

The folder of the files every desk shares.

agents_file

The operating manual every desk follows.

user_file

What the agent knows about the user.

trading_rules_file

The strategies and hard limits.

Describes a workspace without touching the disk.

Parameters:

Name Type Description Default
root Path

The workspace folder.

required
Source code in src/trading_agent/workspace/workspace_layout.py
def __init__(self, root: Path):
    """Describes a workspace without touching the disk.

    Args:
        root (Path): The workspace folder.
    """
    self.root = root
    self.shared_directory = root / 'shared'
    self.agents_file = self.shared_directory / 'Agents.md'
    self.user_file = self.shared_directory / 'User.md'
    self.trading_rules_file = self.shared_directory / 'TradingRules.md'

risk_ledger_file property

risk_ledger_file

The risk engine's SQLite ledger, shared by every desk.

desk_orders_file property

desk_orders_file

The SQLite record of which desk placed which order.

desk_directory

desk_directory(desk_name)

The folder that belongs to one desk.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's folder.

Source code in src/trading_agent/workspace/workspace_layout.py
def desk_directory(self, desk_name: str) -> Path:
    """The folder that belongs to one desk.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's folder.
    """
    return self.root / 'desks' / desk_name

persona_file

persona_file(desk_name)

The desk's persona, which belongs to the user.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's Persona.md.

Source code in src/trading_agent/workspace/workspace_layout.py
def persona_file(self, desk_name: str) -> Path:
    """The desk's persona, which belongs to the user.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's Persona.md.
    """
    return self.desk_directory(desk_name) / 'Persona.md'

memory_file

memory_file(desk_name)

The desk's lasting lessons, which the desk itself maintains.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's Memory.md.

Source code in src/trading_agent/workspace/workspace_layout.py
def memory_file(self, desk_name: str) -> Path:
    """The desk's lasting lessons, which the desk itself maintains.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's Memory.md.
    """
    return self.desk_directory(desk_name) / 'Memory.md'

agents_directory property

agents_directory

The user's subagent definitions, one Markdown file each.

hooks_directory property

hooks_directory

The user's hook scripts, one folder per event.

packages_directory property

packages_directory

The installed packages, one folder each.

knowledge_directory property

knowledge_directory

The user's documents that every desk can search.

knowledge_index_file property

knowledge_index_file

The SQLite full-text index of the knowledge folder.

installed_skills_directory property

installed_skills_directory

The user's imported skills, shared by every desk and read-only to them.

agent_skills_directory

agent_skills_directory(desk_name)

The skills the desk wrote for itself.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's skills/agent folder.

Source code in src/trading_agent/workspace/workspace_layout.py
def agent_skills_directory(self, desk_name: str) -> Path:
    """The skills the desk wrote for itself.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's skills/agent folder.
    """
    return self.desk_directory(desk_name) / 'skills' / 'agent'

skill_usage_file

skill_usage_file(desk_name)

The record of each time the desk loaded a skill.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's skills/usage.jsonl.

Source code in src/trading_agent/workspace/workspace_layout.py
def skill_usage_file(self, desk_name: str) -> Path:
    """The record of each time the desk loaded a skill.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's skills/usage.jsonl.
    """
    return self.desk_directory(desk_name) / 'skills' / 'usage.jsonl'

skill_ledger_file

skill_ledger_file(desk_name)

The record of every change to the desk's own skills.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's skills/ledger.jsonl.

Source code in src/trading_agent/workspace/workspace_layout.py
def skill_ledger_file(self, desk_name: str) -> Path:
    """The record of every change to the desk's own skills.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's skills/ledger.jsonl.
    """
    return self.desk_directory(desk_name) / 'skills' / 'ledger.jsonl'

notes_directory

notes_directory(desk_name)

Where the desk records its daily improvement notes.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's notes folder.

Source code in src/trading_agent/workspace/workspace_layout.py
def notes_directory(self, desk_name: str) -> Path:
    """Where the desk records its daily improvement notes.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's notes folder.
    """
    return self.desk_directory(desk_name) / 'notes'

alerts_file

alerts_file(desk_name)

The desk's price alerts.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's alerts.json.

Source code in src/trading_agent/workspace/workspace_layout.py
def alerts_file(self, desk_name: str) -> Path:
    """The desk's price alerts.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's alerts.json.
    """
    return self.desk_directory(desk_name) / 'alerts.json'

market_watcher_state_file property

market_watcher_state_file

The ids of broker orders the market watcher has already reported.

telegram_pairing_file property

telegram_pairing_file

The Telegram chats allowed to command the desks, and the pairing codes waiting for approval.

phone_devices_file property

phone_devices_file

The phones running the Android app that receive push notifications.

cron_directory

cron_directory(desk_name)

Where the desk's scheduled jobs and their run record are kept.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's cron folder.

Source code in src/trading_agent/workspace/workspace_layout.py
def cron_directory(self, desk_name: str) -> Path:
    """Where the desk's scheduled jobs and their run record are kept.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's cron folder.
    """
    return self.desk_directory(desk_name) / 'cron'

sessions_directory

sessions_directory(desk_name)

Where the desk's session logs, session state and daily summaries are kept.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's sessions folder.

Source code in src/trading_agent/workspace/workspace_layout.py
def sessions_directory(self, desk_name: str) -> Path:
    """Where the desk's session logs, session state and daily summaries are kept.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's sessions folder.
    """
    return self.desk_directory(desk_name) / 'sessions'

checkpoint_repository

checkpoint_repository(desk_name)

The git directory holding snapshots of the desk's own files.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The repository, such as workspace/.checkpoints/main.git.

Source code in src/trading_agent/workspace/workspace_layout.py
def checkpoint_repository(self, desk_name: str) -> Path:
    """The git directory holding snapshots of the desk's own files.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The repository, such as workspace/.checkpoints/main.git.
    """
    return self.root / '.checkpoints' / f'{desk_name}.git'

proposals_directory

proposals_directory(desk_name)

Where the desk's proposed changes to the user's files wait.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's proposals folder.

Source code in src/trading_agent/workspace/workspace_layout.py
def proposals_directory(self, desk_name: str) -> Path:
    """Where the desk's proposed changes to the user's files wait.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's proposals folder.
    """
    return self.desk_directory(desk_name) / 'proposals'

requests_directory

requests_directory(desk_name)

Where the desk's questions, plans and permission requests to the user are kept.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's requests folder.

Source code in src/trading_agent/workspace/workspace_layout.py
def requests_directory(self, desk_name: str) -> Path:
    """Where the desk's questions, plans and permission requests to the user are kept.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's requests folder.
    """
    return self.desk_directory(desk_name) / 'requests'

scratch_directory

scratch_directory(desk_name)

The desk's working folder for temporary files.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's scratch folder.

Source code in src/trading_agent/workspace/workspace_layout.py
def scratch_directory(self, desk_name: str) -> Path:
    """The desk's working folder for temporary files.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's scratch folder.
    """
    return self.desk_directory(desk_name) / 'scratch'

uploads_directory

uploads_directory(desk_name)

The desk's folder of files the user sent with messages.

Parameters:

Name Type Description Default
desk_name str

The desk's name.

required

Returns:

Type Description
Path

The desk's uploads folder.

Source code in src/trading_agent/workspace/workspace_layout.py
def uploads_directory(self, desk_name: str) -> Path:
    """The desk's folder of files the user sent with messages.

    Args:
        desk_name (str): The desk's name.

    Returns:
        Path: The desk's uploads folder.
    """
    return self.desk_directory(desk_name) / 'uploads'

user_owned_file

user_owned_file(desk_name, file_name)

Finds one of the user's files by name.

Parameters:

Name Type Description Default
desk_name str

The desk whose Persona.md is meant, for that file name.

required
file_name str

One of USER_OWNED_FILE_NAMES.

required

Returns:

Type Description
Path

The file's path.

Raises:

Type Description
ValueError

The name is not one of the user's files.

Source code in src/trading_agent/workspace/workspace_layout.py
def user_owned_file(self, desk_name: str, file_name: str) -> Path:
    """Finds one of the user's files by name.

    Args:
        desk_name (str): The desk whose Persona.md is meant, for that file name.
        file_name (str): One of USER_OWNED_FILE_NAMES.

    Returns:
        Path: The file's path.

    Raises:
        ValueError: The name is not one of the user's files.
    """
    if file_name == 'Persona.md':
        return self.persona_file(desk_name)
    if file_name in SHARED_FILE_NAMES:
        return self.shared_directory / file_name
    raise ValueError(f'Not one of the user files: {file_name!r}')

create_missing

create_missing(desk_names)

Creates the folders, and writes each missing file from its template.

Existing files are never overwritten. The intraday, scalper and positional desks get their own starter Persona.md; other desks get the general template. The starter subagents are written only when the agents folder does not exist yet, so one the user deleted stays deleted.

Parameters:

Name Type Description Default
desk_names Sequence[str]

The desks to prepare.

required

Returns:

Type Description
list[Path]

The files that were created.

Source code in src/trading_agent/workspace/workspace_layout.py
def create_missing(self, desk_names: Sequence[str]) -> list[Path]:
    """Creates the folders, and writes each missing file from its template.

    Existing files are never overwritten. The intraday, scalper and positional desks get their own starter Persona.md; other desks get the general template. The starter subagents are written only when the agents folder does not exist yet, so one the user deleted stays deleted.

    Args:
        desk_names (Sequence[str]): The desks to prepare.

    Returns:
        list[Path]: The files that were created.
    """
    created = []
    self.shared_directory.mkdir(parents=True, exist_ok=True)
    self.knowledge_directory.mkdir(parents=True, exist_ok=True)
    for file_name in SHARED_FILE_NAMES:
        target = self.shared_directory / file_name
        if self._write_template_if_missing(target, file_name):
            created.append(target)
    if not self.agents_directory.exists():
        created.extend(self._write_starter_agents())
    for desk_name in desk_names:
        self.proposals_directory(desk_name).mkdir(
            parents=True, exist_ok=True
        )
        self.scratch_directory(desk_name).mkdir(parents=True, exist_ok=True)
        self.notes_directory(desk_name).mkdir(parents=True, exist_ok=True)
        for file_name in DESK_FILE_NAMES:
            target = self.desk_directory(desk_name) / file_name
            template_name = file_name
            if file_name == 'Persona.md' and self._has_persona_template(
                desk_name
            ):
                template_name = f'personas/{desk_name}.md'
            if self._write_template_if_missing(target, template_name):
                created.append(target)
    return created

template_text

template_text(template_name)

Reads one of the templates shipped with the package.

Parameters:

Name Type Description Default
template_name str

The template's file name, such as "Agents.md".

required

Returns:

Type Description
str

The template's text.

Source code in src/trading_agent/workspace/workspace_layout.py
def template_text(self, template_name: str) -> str:
    """Reads one of the templates shipped with the package.

    Args:
        template_name (str): The template's file name, such as "Agents.md".

    Returns:
        str: The template's text.
    """
    templates = (
        importlib.resources.files('trading_agent.workspace') / 'templates'
    )
    resource = templates
    for part in template_name.split('/'):
        resource = resource / part
    return resource.read_text(encoding='utf-8')

is_template

is_template(path)

Says whether a file is still an unfilled template.

Parameters:

Name Type Description Default
path Path

The file.

required

Returns:

Type Description
bool

True when the file is missing or still holds the template's status line.

Source code in src/trading_agent/workspace/workspace_layout.py
def is_template(self, path: Path) -> bool:
    """Says whether a file is still an unfilled template.

    Args:
        path (Path): The file.

    Returns:
        bool: True when the file is missing or still holds the template's status line.
    """
    if not path.is_file():
        return True
    return TEMPLATE_STATUS_LINE in path.read_text(encoding='utf-8')