# 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.
1. **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 future rounds of conversation, it will
   be removed from context.
1. **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?"
