Allow router session tools to read external parquet paths

This commit is contained in:
武阳
2026-05-09 11:55:54 +08:00
parent b87b9c14b7
commit 95c265d2a1
3 changed files with 25 additions and 6 deletions
+2 -2
View File
@@ -254,7 +254,7 @@ def build_data_agent_tools(handlers: Mapping[str, ToolHandler]) -> list[AgentToo
'paths': { 'paths': {
'type': 'array', 'type': 'array',
'items': {'type': 'string'}, 'items': {'type': 'string'},
'description': 'Workspace-relative parquet files or date directories. Use when dates is not enough.', 'description': 'Parquet files or date directories. Relative paths resolve from workspace root; absolute paths are allowed for external online data.',
}, },
'max_files': {'type': 'integer', 'minimum': 1, 'maximum': 200}, 'max_files': {'type': 'integer', 'minimum': 1, 'maximum': 200},
'max_rows_per_file': {'type': 'integer', 'minimum': 1, 'maximum': 100000}, 'max_rows_per_file': {'type': 'integer', 'minimum': 1, 'maximum': 100000},
@@ -280,7 +280,7 @@ def build_data_agent_tools(handlers: Mapping[str, ToolHandler]) -> list[AgentToo
'paths': { 'paths': {
'type': 'array', 'type': 'array',
'items': {'type': 'string'}, 'items': {'type': 'string'},
'description': 'Workspace-relative parquet files or date directories. Use when dates is not enough.', 'description': 'Parquet files or date directories. Relative paths resolve from workspace root; absolute paths are allowed for external online data.',
}, },
'devices': {'type': 'array', 'items': {'type': 'string'}}, 'devices': {'type': 'array', 'items': {'type': 'string'}},
'domains': {'type': 'array', 'items': {'type': 'string'}}, 'domains': {'type': 'array', 'items': {'type': 'string'}},
-4
View File
@@ -278,10 +278,6 @@ def _resolve_parquet_files(
files: list[Path] = [] files: list[Path] = []
for path in requested: for path in requested:
resolved = path.resolve() resolved = path.resolve()
try:
resolved.relative_to(root_path)
except ValueError as exc:
raise DataAgentRouterSessionError(f'path escapes workspace root: {path}') from exc
if not resolved.exists(): if not resolved.exists():
raise DataAgentRouterSessionError(f'path not found: {path}') raise DataAgentRouterSessionError(f'path not found: {path}')
if resolved.is_dir(): if resolved.is_dir():
+23
View File
@@ -123,6 +123,29 @@ class DataAgentRouterSessionTests(unittest.TestCase):
self.assertEqual(candidate['matched_turn']['query'], '导航去公司') self.assertEqual(candidate['matched_turn']['query'], '导航去公司')
self.assertEqual(candidate['prev_turns'][0]['query'], '你好小爱') self.assertEqual(candidate['prev_turns'][0]['query'], '你好小爱')
@unittest.skipUnless(HAS_PYARROW, 'pyarrow is required for parquet tests')
def test_router_session_tools_allow_external_absolute_paths(self) -> None:
with tempfile.TemporaryDirectory() as workspace_dir, tempfile.TemporaryDirectory() as data_dir:
_write_router_parquet(Path(data_dir))
external_partition = Path(data_dir) / 'router_session_parquet' / 'date=20260428'
profile = profile_router_sessions(
workspace_dir,
paths=[str(external_partition)],
max_files=1,
)
search = search_router_sessions(
workspace_dir,
paths=[str(external_partition)],
query_keywords=['导航'],
max_files=1,
max_candidates=5,
)
self.assertEqual(profile['sampled_row_count'], 2)
self.assertEqual(search['candidate_count'], 1)
self.assertEqual(search['candidates'][0]['matched_turn']['query'], '导航去公司')
@unittest.skipUnless(HAS_PYARROW, 'pyarrow is required for parquet tests') @unittest.skipUnless(HAS_PYARROW, 'pyarrow is required for parquet tests')
def test_router_session_tools_execute_against_registry(self) -> None: def test_router_session_tools_execute_against_registry(self) -> None:
with tempfile.TemporaryDirectory() as tmp_dir: with tempfile.TemporaryDirectory() as tmp_dir: