| """Analytics tool registry |
| |
| The real registry of the `analyze_*` family, built on the canonical `ToolSpec` |
| (src/tools/contracts.py) and the prompt-style `DESCRIPTION` constants the Planner |
| reads to choose a tool (KM-625). This replaces the agent team's local stub in |
| `src/agents/planner/registry.py` for the analytics slice. |
| |
| Conventions (decided with the agent team, KM-465): |
| - **Pattern A** — `analyze_*` tools do NOT self-fetch by `source_id`. Each takes a |
| `data` argument that is a `"${t<id>}"` placeholder pointing at an upstream |
| `retrieve_data` table output, resolved to a DataFrame at execution time. |
| Column arguments reference the aliases that upstream query produced. |
| - `input_schema` is the lightweight JSON-schema-ish dict the planner validator |
| consumes: `required` (arg names with no default) + `properties` (allowed args). |
| `required` mirrors each compute function's no-default parameters; value-typing of |
| placeholder args is deferred to execution time. |
| - `output_kind` is the `ToolOutput.kind` each tool returns: stats (labelled-metric |
| dict) | table (rows×cols) | series (ordered periods). |
| |
| The four data-access tools (retrieve_data / retrieve_knowledge / check_data / |
| check_knowledge) are registered separately once their wrappers land (KM-465 #4); |
| `default_registry()` composes both slices. |
| """ |
|
|
| from __future__ import annotations |
|
|
| from src.tools.analytics import ( |
| aggregation, |
| comparison, |
| decomposition, |
| descriptive, |
| quality, |
| relationship, |
| segmentation, |
| temporal, |
| ) |
| from src.tools.contracts import ToolRegistry, ToolSpec |
|
|
| |
| ACTIVE_ANALYTICS_TOOLS: list[ToolSpec] = [ |
| ToolSpec( |
| name="analyze_descriptive", |
| category="analytics.descriptive", |
| input_schema={ |
| "required": ["data", "column_ids"], |
| "properties": { |
| "data": {"type": "string"}, |
| "column_ids": {"type": "array"}, |
| "metrics": {"type": "array"}, |
| }, |
| }, |
| output_kind="stats", |
| description=descriptive.DESCRIPTION, |
| ), |
| ToolSpec( |
| name="analyze_aggregate", |
| category="analytics.aggregation", |
| input_schema={ |
| "required": ["data", "aggregations"], |
| "properties": { |
| "data": {"type": "string"}, |
| "aggregations": {"type": "object"}, |
| "group_by": {"type": "array"}, |
| }, |
| }, |
| output_kind="table", |
| description=aggregation.DESCRIPTION, |
| ), |
| ToolSpec( |
| name="analyze_correlation", |
| category="analytics.relationship", |
| input_schema={ |
| "required": ["data"], |
| "properties": { |
| "data": {"type": "string"}, |
| "column_ids": {"type": "array"}, |
| "method": {"type": "string"}, |
| }, |
| }, |
| output_kind="stats", |
| description=relationship.DESCRIPTION, |
| ), |
| ToolSpec( |
| name="analyze_trend", |
| category="analytics.timeseries", |
| input_schema={ |
| "required": ["data", "date_column", "value_column"], |
| "properties": { |
| "data": {"type": "string"}, |
| "date_column": {"type": "string"}, |
| "value_column": {"type": "string"}, |
| "freq": {"type": "string"}, |
| "agg": {"type": "string"}, |
| }, |
| }, |
| output_kind="series", |
| description=temporal.DESCRIPTION, |
| ), |
| ] |
|
|
| |
| |
| |
| |
| |
| |
| DEFERRED_ANALYTICS_TOOLS: list[ToolSpec] = [ |
| ToolSpec( |
| name="analyze_comparison", |
| category="analytics.comparison", |
| input_schema={ |
| "required": ["data", "dimension", "value_column", "group_a", "group_b"], |
| "properties": { |
| "data": {"type": "string"}, |
| "dimension": {"type": "string"}, |
| "value_column": {"type": "string"}, |
| "group_a": {}, |
| "group_b": {}, |
| "agg": {"type": "string"}, |
| }, |
| }, |
| output_kind="stats", |
| description=comparison.DESCRIPTION, |
| ), |
| ToolSpec( |
| name="analyze_contribution", |
| category="analytics.decomposition", |
| input_schema={ |
| "required": ["data", "dimension", "value_column"], |
| "properties": { |
| "data": {"type": "string"}, |
| "dimension": {"type": "string"}, |
| "value_column": {"type": "string"}, |
| "agg": {"type": "string"}, |
| "top_n": {"type": "integer"}, |
| }, |
| }, |
| output_kind="table", |
| description=decomposition.DESCRIPTION, |
| ), |
| ToolSpec( |
| name="analyze_profile", |
| category="analytics.quality", |
| input_schema={ |
| "required": ["data"], |
| "properties": { |
| "data": {"type": "string"}, |
| "column_ids": {"type": "array"}, |
| }, |
| }, |
| output_kind="stats", |
| description=quality.DESCRIPTION, |
| ), |
| ToolSpec( |
| name="analyze_segment", |
| category="analytics.segmentation", |
| input_schema={ |
| "required": ["data", "column", "bins"], |
| "properties": { |
| "data": {"type": "string"}, |
| "column": {"type": "string"}, |
| "bins": {}, |
| "method": {"type": "string"}, |
| "labels": {"type": "array"}, |
| "value_column": {"type": "string"}, |
| "agg": {"type": "string"}, |
| }, |
| }, |
| output_kind="table", |
| description=segmentation.DESCRIPTION, |
| ), |
| ] |
|
|
| |
| |
| ANALYTICS_TOOLS: list[ToolSpec] = [*ACTIVE_ANALYTICS_TOOLS, *DEFERRED_ANALYTICS_TOOLS] |
|
|
|
|
| def analytics_registry() -> ToolRegistry: |
| """The analytics (`analyze_*`) slice of the tool registry (fresh instance). |
| |
| Exposes only `ACTIVE_ANALYTICS_TOOLS`; deferred specs are withheld from the |
| Planner (see `DEFERRED_ANALYTICS_TOOLS`). |
| """ |
| return ToolRegistry(tools=list(ACTIVE_ANALYTICS_TOOLS)) |
|
|