Commit ·
37b8384
1
Parent(s): 148e33b
[KM-630] Data-Access Tools: review fixes
Browse files- describe_source: add table_row_count column (the registry tool
description advertises row counts; output now matches the contract).
- retrieve_documents: coerce top_k to int with a fallback to 5, so a
non-int top_k from the Planner can't reach the retriever unguarded.
- Refresh the module docstring to list all four tools (query_structured
and retrieve_documents were missing).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- src/tools/data_access.py +21 -9
src/tools/data_access.py
CHANGED
|
@@ -1,15 +1,22 @@
|
|
| 1 |
-
"""DataAccessToolInvoker —
|
| 2 |
|
| 3 |
Implements the `ToolInvoker` Protocol (src/agents/slow_path/invoker.py) for the
|
| 4 |
-
data-access
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
|
| 10 |
Tools implemented here:
|
| 11 |
-
- `list_sources`
|
| 12 |
-
- `describe_source`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
Frozen guarantee (§8.4): **never throws.** Any failure returns
|
| 15 |
`ToolOutput(kind="error", error=...)`.
|
|
@@ -132,6 +139,7 @@ class DataAccessToolInvoker:
|
|
| 132 |
[
|
| 133 |
t.table_id,
|
| 134 |
t.name,
|
|
|
|
| 135 |
c.column_id,
|
| 136 |
c.name,
|
| 137 |
c.data_type,
|
|
@@ -147,6 +155,7 @@ class DataAccessToolInvoker:
|
|
| 147 |
columns=[
|
| 148 |
"table_id",
|
| 149 |
"table_name",
|
|
|
|
| 150 |
"column_id",
|
| 151 |
"column_name",
|
| 152 |
"data_type",
|
|
@@ -249,7 +258,10 @@ class DataAccessToolInvoker:
|
|
| 249 |
error="missing 'query' argument",
|
| 250 |
)
|
| 251 |
|
| 252 |
-
|
|
|
|
|
|
|
|
|
|
| 253 |
source_id = args.get("source_id")
|
| 254 |
|
| 255 |
retriever = self._retriever
|
|
|
|
| 1 |
+
"""DataAccessToolInvoker — the data-access tool family (KM-465 / KM-630).
|
| 2 |
|
| 3 |
Implements the `ToolInvoker` Protocol (src/agents/slow_path/invoker.py) for the
|
| 4 |
+
data-access family. Unlike the stateless `AnalyticsToolInvoker`, these tools
|
| 5 |
+
read the user's catalog / sources, so the invoker is constructed per-request
|
| 6 |
+
with the authenticated `user_id` and its dependencies (dependency injection —
|
| 7 |
+
the runtime/Coordinator supplies them; INV-7 keeps the agent layer
|
| 8 |
+
tool-agnostic).
|
| 9 |
|
| 10 |
Tools implemented here:
|
| 11 |
+
- `list_sources` — the user's data sources (id, name, type, table count).
|
| 12 |
+
- `describe_source` — tables/columns of one source (one row per column,
|
| 13 |
+
metadata only — exposes `pii_flag`, never sample values).
|
| 14 |
+
- `query_structured` — runs a pre-built `QueryIR` (validate -> dispatch ->
|
| 15 |
+
execute, skipping the planner) and returns rows as
|
| 16 |
+
`ToolOutput(kind="table")` — the Pattern A handoff the
|
| 17 |
+
`analyze_*` tools consume.
|
| 18 |
+
- `retrieve_documents` — dense retrieval over unstructured sources, returns
|
| 19 |
+
`ToolOutput(kind="documents")`.
|
| 20 |
|
| 21 |
Frozen guarantee (§8.4): **never throws.** Any failure returns
|
| 22 |
`ToolOutput(kind="error", error=...)`.
|
|
|
|
| 139 |
[
|
| 140 |
t.table_id,
|
| 141 |
t.name,
|
| 142 |
+
t.row_count,
|
| 143 |
c.column_id,
|
| 144 |
c.name,
|
| 145 |
c.data_type,
|
|
|
|
| 155 |
columns=[
|
| 156 |
"table_id",
|
| 157 |
"table_name",
|
| 158 |
+
"table_row_count",
|
| 159 |
"column_id",
|
| 160 |
"column_name",
|
| 161 |
"data_type",
|
|
|
|
| 258 |
error="missing 'query' argument",
|
| 259 |
)
|
| 260 |
|
| 261 |
+
try:
|
| 262 |
+
top_k = int(args.get("top_k", 5))
|
| 263 |
+
except (TypeError, ValueError):
|
| 264 |
+
top_k = 5
|
| 265 |
source_id = args.get("source_id")
|
| 266 |
|
| 267 |
retriever = self._retriever
|