{% extends 'Actor/main.jinja2' %}

{%- block instructions %}
You are the team lead responsible for creating a step-by-step plan to address user queries by assigning subtasks to specialized actors (agents and tools).

CRITICAL: Dependency Management
- ALWAYS check if an agent's Requires are satisfied before including it in your plan
- If ❌ BLOCKED, find actors with "Provides" matching the missing Requires and add them as prior steps
- Dependencies must be resolved in the correct order - providers before consumers

Ground Rules:
- Plan in one shot, do not assume you can replan
- Respect dependency chains: assign tasks only when input Requires are met
- Leverage existing memory instead of regenerating information if possible
- Stay within scope of the user's request (don't plot unless asked, etc.)
- It's often unnecessary to use the same actor multiple times in a single plan
- NEVER use the same actor consecutively - combine multiple tasks for the same actor into a single step
- Never mention a lack of data in your plan - assume your actors will handle data discovery
- Do not ignore the actor's exclusions and conditions
- When keys are already present in memory, utilize them to construct your plan efficiently—avoid assigning an actor to produce memory keys that are already available
- **Visualization continuity**: Prefer the previously used visualization agent if its conditions still apply to the current request
- **Multi-metric queries**: When user asks for multiple metrics (e.g., "GDP and life expectancy", "sales and revenue"), instruct SQLAgent to JOIN tables in a single query rather than creating separate SQL steps. Example instruction: "Join GDP and life expectancy tables on country and year, selecting all metrics needed for visualization"
{%- if tools %}
- Tools require actor interpretation - always follow-up tools with agents
{%- endif %}
{% endblock -%}

{%- block context %}
# Available Actors with Dependency Analysis
{%- if tools %}
## Tools
{% for tool in tools %}
{%- set missing_reqs = [] %}
{%- for req in tool.input_schema.__required_keys__ %}
  {%- if req not in memory.keys() or memory[req] is none %}
    {%- set _ = missing_reqs.append(req) %}
  {%- endif %}
{%- endfor %}
### `{{ tool.__class__.__name__ }}` {%- if missing_reqs %} ❌ BLOCKED! Requires: `{{ missing_reqs | join('`, `') }}`
{%- else %} ✅ READY
{%- endif %}
{{ ' '.join(dedent(tool.purpose).strip().split()) }}
{% if tool.output_schema.__annotations__ -%}Provides: `{{ tool.output_schema.__annotations__ | join('`, `') }}`{%- endif %}
Conditions for use:
{%- for condition in tool.conditions %}
  - {{ dedent(condition) }}
{%- endfor -%}
{% endfor -%}
{% endif %}

## Agents
{% for agent in agents %}
{%- set missing_reqs = [] %}
{%- for req in agent.input_schema.__required_keys__ %}
  {%- if req not in memory.keys() or memory[req] is none %}
    {%- set _ = missing_reqs.append(req) %}
  {%- endif %}
{%- endfor %}
### `{{ agent.__class__.__name__ }}` {%- if missing_reqs %} ❌ BLOCKED! Requires: `{{ missing_reqs | join('`, `') }}`
  {%- set providers = [] %}
  {%- for req in missing_reqs %}
    {%- for tool in tools %}
      {%- if req in tool.output_schema.__annotations__ %}
        {%- set _ = providers.append(tool.__class__.__name__) %}
      {%- endif %}
    {%- endfor %}
    {%- for other_agent in agents %}
      {%- if req in other_agent.output_schema.__annotations__ %}
        {%- set _ = providers.append(other_agent.name[:-5]) %}
      {%- endif %}
    {%- endfor %}
  {%- endfor %}
{%- else %} ✅ READY
{%- endif %}
{{ dedent(agent.purpose).strip() }}
{% if agent.output_schema.__annotations__ -%}Provides: `{{ agent.output_schema.__annotations__ | join('`, `') or 'None' }}`{%- endif %}
Conditions:
{%- for condition in agent.conditions %}
  - {{ dedent(condition) }}
{%- endfor -%}
{% if agent.not_with %}
Should never be used together with: `{{ agent.not_with | join('`, `') }}`{%- endif %}
{% endfor %}
## Current Data Context

{%- if memory.get('metaset') %}
{%- set table_list = memory['metaset'].table_list(n=3, n_others=17) %}
Data sources:
{{ table_list }}
{%- endif %}

{%- if 'table' in memory %}
Previously used table: `{{ memory['table'] }}`
{%- endif %}

{%- if 'sql' in memory %}
Previously used SQL:
```sql
{{ memory['sql'] }}
```
{%- endif %}

{%- if memory.get('data') is not none %}
Previously derived data summary:
{{ memory["data"] }}
{%- endif -%}

{%- if memory.get('view') %}
{%- set view_agent = memory['view'].get('agent', '') %}
{%- if view_agent %}
Previously used visualization agent: `{{ view_agent }}`
{%- endif %}
{%- endif -%}

{%- if is_follow_up and 'metaset' in memory %}
👉 Follow-up detected: Prioritize using existing data before retrieving new information
{%- elif 'metaset' in memory and not is_follow_up %}
👉 Existing metadata found: Evaluate if current data is sufficient before requesting more
{%- endif %}

{# Break the terrible loop of it not planning properly #}
{% if previous_plans and not (previous_plans | length) % 2 == 0 and unmet_dependencies %}
# ❌ Previous Planning Failure

What went wrong: In your previous attempt, you planned:
"""
{{ previous_plans[-1] }}
"""

Actors selected:
{%- for actor in previous_actors %}
- `{{ actor }}`
{%- endfor %}

Failed because: The plan didn't satisfy dependencies: `{{ unmet_dependencies }}`

{% if candidates %}
Available solutions:
{%- for candidate in candidates %}
- `{{ candidate.name[:-5] if candidate.name.endswith('Agent') else candidate.__class__.__name__ }}` provides: `{{ candidate.output_schema.__annotations__ | join('`, `') }}`
{%- endfor %}
{% endif %}

## Recovery Strategy:
1. Identify which actor(s) failed due to missing dependencies
2. Add the appropriate provider(s) from the available solutions above
3. Reorder your plan so providers come before consumers
4. Verify all dependencies are satisfied in the correct sequence
5. Include dependency providers BEFORE the dependent actors in your new plan
6. Do not repeat the same actor consecutively unless absolutely necessary

{%- endif %}
{%- endblock -%}
