Skip to content

agent

agentic_ml.research.agent

Build a Strands agent for a research run (requires the research extra).

AgentConfig dataclass

AgentConfig(
    pin_first: int = 1,
    preserve_recent_messages: int = 4,
    summary_ratio: float = 0.3,
    compression_threshold: float = 0.85,
    offload_max_result_tokens: int = 1500,
    offload_preview_tokens: int = 750,
)

Strands-specific knobs for the research agent's conversation manager and context offloader.

Kept separate from :class:~agentic_ml.core.engine.ResearchConfig, which must stay usable without Strands installed.

pin_first class-attribute instance-attribute

pin_first: int = 1

Number of messages at the very start of the conversation permanently protected from summarization. Message 0 is always the kickoff prompt; message 1 (only if pin_first >= 2) is the agent's first response. The system prompt is sent separately on every model call and is never part of this managed history, so it needs no protection.

preserve_recent_messages class-attribute instance-attribute

preserve_recent_messages: int = 4

Minimum number of most-recent messages the conversation manager always keeps uncompressed.

summary_ratio class-attribute instance-attribute

summary_ratio: float = 0.3

Fraction of the older, non-pinned messages summarized whenever compression triggers.

compression_threshold class-attribute instance-attribute

compression_threshold: float = 0.85

Fraction of the model's context window that triggers proactive summarization.

offload_max_result_tokens class-attribute instance-attribute

offload_max_result_tokens: int = 1500

Tool results larger than this (estimated tokens) are truncated with a retrievable preview.

offload_preview_tokens class-attribute instance-attribute

offload_preview_tokens: int = 750

Size of the truncated preview kept in place of an offloaded tool result.

build_session_manager

build_session_manager(
    ctx: ResearchContext,
) -> SnapshotSessionManager

Create the session manager that persists conversation state under the run's workspace.

Source code in src/agentic_ml/research/agent.py
51
52
53
54
55
56
57
58
def build_session_manager(ctx: ResearchContext) -> SnapshotSessionManager:
    """Create the session manager that persists conversation state under the run's workspace."""
    from strands.session import SnapshotSessionManager
    from strands.storage import LocalFileStorage

    storage = LocalFileStorage(str(ctx.workspace.session_dir))
    # A single fixed id: one research_dir holds exactly one research session.
    return SnapshotSessionManager(session_id="research", storage=storage)

build_research_agent

build_research_agent(
    ctx: ResearchContext,
    model: object,
    session_manager: object,
)

Create a Strands Agent wired with the research tools and the composed prompt.

This reproduces what context_manager="auto" builds (a SummarizingConversationManager with proactive compression plus a ContextOffloader truncating large tool results with a retrievable preview), but tuned via ctx.agent_config (see :class:AgentConfig) — the "auto" defaults (preserve_recent_messages=10) never let summarization act on the short conversations a research run typically has (kickoff + a handful of tool calls; no system message is ever part of this managed history), so it always failed with "insufficient messages for summarization". session_manager persists/restores the conversation across process restarts; see :func:build_session_manager.

Source code in src/agentic_ml/research/agent.py
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
def build_research_agent(ctx: ResearchContext, model: object, session_manager: object):
    """Create a Strands ``Agent`` wired with the research tools and the composed prompt.

    This reproduces what ``context_manager="auto"`` builds (a ``SummarizingConversationManager``
    with proactive compression plus a ``ContextOffloader`` truncating large tool results with a
    retrievable preview), but tuned via ``ctx.agent_config`` (see :class:`AgentConfig`) — the
    "auto" defaults (``preserve_recent_messages=10``) never let summarization act on the short
    conversations a research run typically has (kickoff + a handful of tool calls; no system
    message is ever part of this managed history), so it always failed with "insufficient
    messages for summarization". ``session_manager`` persists/restores the conversation across
    process restarts; see :func:`build_session_manager`.
    """
    from strands import Agent
    from strands.agent.conversation_manager import SummarizingConversationManager
    from strands.hooks import AfterModelCallEvent
    from strands.vended_plugins.context_offloader import ContextOffloader

    agent_config = ctx.agent_config
    system_prompt = build_system_prompt(ctx.task, ctx.profile_text, ctx.config)
    conversation_manager = SummarizingConversationManager(
        summary_ratio=agent_config.summary_ratio,
        proactive_compression={"compression_threshold": agent_config.compression_threshold},
        preserve_recent_messages=agent_config.preserve_recent_messages,
        pin_first=agent_config.pin_first,
    )
    agent = Agent(
        model=model,
        system_prompt=system_prompt,
        tools=build_tools(ctx),
        conversation_manager=conversation_manager,
        plugins=[
            ContextOffloader(
                max_result_tokens=agent_config.offload_max_result_tokens,
                preview_tokens=agent_config.offload_preview_tokens,
            )
        ],
        session_manager=session_manager,
    )
    agent.hooks.add_callback(AfterModelCallEvent, _log_token_usage)
    return agent