# Sales Assistant Agent with Context Offloading

This agent acts as a sales assistant, capable of generating and retrieving large
sales reports for different regions (North America, EMEA, APAC).

## The Challenge: Large Context Windows

Storing large pieces of data, like full sales reports, directly in conversation
history consumes valuable LLM context window space. This limits how much
conversation history the model can see, potentially degrading response quality
in longer conversations and increasing token costs.

## The Solution: Context Offloading with Artifacts

This agent demonstrates how to use ADK's artifact feature to offload large data
from the main conversation context, while still making it available to the agent
on-demand. Large reports are generated by the `query_large_data` tool but are
immediately saved as artifacts instead of being returned in the function call
response. This keeps the turn events small, saving context space.

### How it Works

1.  **Saving Artifacts**: When the user asks for a sales report (e.g., "Get EMEA
    sales report"), the `query_large_data` tool is called. It generates a mock
    report, saves it as an artifact (`EMEA_sales_report_q3_2025.txt`), and saves
    a brief description in the artifact's metadata (e.g., `{'summary': 'Sales
    report for EMEA Q3 2025'}`). The tool returns only a confirmation message to
    the agent, not the large report itself.
2.  **Immediate Loading**: The `QueryLargeDataTool` then runs its
    `process_llm_request` hook. It detects that `query_large_data` was just
    called, loads the artifact that was just saved, and injects its content into
    the *next* request to the LLM. This makes the report data available
    immediately, allowing the agent to summarize it or answer questions in the
    same turn, as seen in the logs. This artifact is only appended for that
    round and not saved to session. For furtuer rounds of conversation, it will
    be removed from context.
3.  **Loading on Demand**: The `CustomLoadArtifactsTool` enhances the default
    `load_artifacts` behavior.
    *   It reads the `summary` metadata from all available artifacts and includes
        these summaries in the instructions sent to the LLM (e.g., `You have
        access to artifacts: ["APAC_sales_report_q3_2025.txt: Sales report for
        APAC Q3 2025", ...]`). This lets the agent know *what* data is
        available in artifacts, without having to load the full content.
    *   It instructs the agent to use data from the most recent turn if
        available, but to call `load_artifacts` if it needs to access data from
        an *older* turn that is no longer in the immediate context (e.g., if
        comparing North America data after having discussed EMEA and APAC).
    *   When `load_artifacts` is called, this tool intercepts it and injects the
        requested artifact content into the LLM request.
    *   Note that artifacts are never saved to session.

This pattern ensures that large data is only loaded into the LLM's context
window when it is immediately relevant—either just after being generated or when
explicitly requested later—thereby managing context size more effectively.

### How to Run

```bash
adk web
```

Then, ask the agent:

*   "Hi, help me query the North America sales report"
*   "help me query EMEA and APAC sales report"
*   "Summarize sales report for North America?"
