Skip to content

trading_agent.memory.session_keeper

Starts, resumes and rolls over a desk's sessions.

When the desk starts, the keeper asks the model router to pick up the session saved before a restart. Before each turn it checks the India date: on the first turn of a new day it asks the desk to summarise the old session and fold the day's notes into Memory.md, saves that summary, and starts a fresh session. The first message of every new session carries the most recent summary, so the desk knows what happened last.

Typical usage example:

keeper = SessionKeeper('main', router, store, event_bus) await keeper.start() trigger = await keeper.prepare(trigger)

SessionKeeper

SessionKeeper(desk_name, router, store, event_bus, curator=None)

Looks after one desk's sessions.

Creates the keeper.

Parameters:

Name Type Description Default
desk_name str

The desk.

required
router ModelRouter

The desk's router, built with the same store.

required
store SessionStore

The desk's sessions folder.

required
event_bus EventBus

Where new sessions are announced.

required
curator SkillCurator | None

Reviews the desk's own skills after the day's summary, or None to skip the review.

None
Source code in src/trading_agent/memory/session_keeper.py
def __init__(
    self,
    desk_name: str,
    router: model_router_module.ModelRouter,
    store: session_store_module.SessionStore,
    event_bus: event_bus_module.EventBus,
    curator: skill_curator_module.SkillCurator | None = None,
):
    """Creates the keeper.

    Args:
        desk_name (str): The desk.
        router (model_router_module.ModelRouter): The desk's router, built with the same store.
        store (session_store_module.SessionStore): The desk's sessions folder.
        event_bus (event_bus_module.EventBus): Where new sessions are announced.
        curator (skill_curator_module.SkillCurator | None): Reviews the desk's own skills after the day's summary, or None to skip the review.
    """
    self._desk_name = desk_name
    self._router = router
    self._store = store
    self._event_bus = event_bus
    self._curator = curator

start async

start()

Picks up the saved session, or starts the first one, when the desk starts.

Source code in src/trading_agent/memory/session_keeper.py
async def start(self) -> None:
    """Picks up the saved session, or starts the first one, when the desk starts."""
    resumed = await self._router.restore_session()
    reason = 'first'
    if resumed:
        reason = 'resumed'
    self._publish_session_started(reason, None, None)

prepare async

prepare(trigger)

Rolls over to a new session on a new day, and seeds a new session's first message.

Parameters:

Name Type Description Default
trigger Trigger

The trigger about to run.

required

Returns:

Type Description
Trigger

The trigger, with the previous session's summary in front when the session is new.

Source code in src/trading_agent/memory/session_keeper.py
async def prepare(
    self,
    trigger: trigger_module.Trigger,
) -> trigger_module.Trigger:
    """Rolls over to a new session on a new day, and seeds a new session's first message.

    Args:
        trigger (trigger_module.Trigger): The trigger about to run.

    Returns:
        trigger_module.Trigger: The trigger, with the previous session's summary in front when the session is new.
    """
    if self._router.trading_date != self._store.today():
        await self.roll_over()
    if self._router.exchanges:
        return trigger
    summary = self._store.latest_summary()
    if summary is None:
        return trigger
    text = '\n'.join(
        [
            f'[This is the first message of a new session. Summary of your previous session, from {summary.trading_date.isoformat()}:]',
            summary.text,
            '[End of the summary. Your lasting lessons are in Memory.md. The message follows.]',
            '',
            trigger.text,
        ]
    )
    return dataclasses.replace(trigger, text=text)

roll_over async

roll_over()

Ends the current session with a summary and starts a fresh one for today.

Returns:

Type Description
str | None

The new session's identifier.

Source code in src/trading_agent/memory/session_keeper.py
async def roll_over(self) -> str | None:
    """Ends the current session with a summary and starts a fresh one for today.

    Returns:
        str | None: The new session's identifier.
    """
    previous_session_id = self._router.session_id
    previous_date = self._router.trading_date
    summary_path = None
    if self._router.exchanges and previous_date is not None:
        summary = await self._summary(previous_date)
        summary_path = self._store.write_summary(previous_date, summary)
        await self._review_skills(previous_date)
    await self._router.reset()
    self._publish_session_started(
        'daily_rollover',
        previous_session_id,
        summary_path,
    )
    return self._router.session_id