diff --git a/pageindex/filesystem/agent.py b/pageindex/filesystem/agent.py index 291fb9c..1b342eb 100644 --- a/pageindex/filesystem/agent.py +++ b/pageindex/filesystem/agent.py @@ -51,6 +51,8 @@ cat --node 0009. You may also use file_ref or document_id when a path is ambiguous. After structure identifies a relevant section node, prefer cat --node ; use cat --page when the user asks for page-level evidence, no suitable node exists, or exact page text is needed. +For questions about metadata fields, available summaries, or whether metadata +was provided, inspect stat --schema and stat before making claims. """ AGENT_TOOL_POLICY = """ @@ -69,6 +71,8 @@ Tool policy: - Use cat --page - when the user explicitly asks for pages/page ranges, when no suitable node_id exists, or when you need exact page text to verify page-level evidence. - Avoid fetching a broad page span after a matching node is available unless page-level citation or verification is required. - Do not call cat --page ; if you need a page span, use cat --page -. +- For metadata or summary-field questions, run stat --schema and stat for relevant files before answering; do not infer metadata presence or absence from ls/find output alone. +- Distinguish default/register metadata from caller-provided custom metadata when the evidence supports it. """ STREAM_MODE_ALIASES = { @@ -361,6 +365,8 @@ class PIFSAgentStreamObserver: print(text, end="", file=self.output, flush=True) def emit_tool_call(self, command: str, *, force: bool = False) -> None: + if not command.strip(): + return if self.stream_log is not None: self.stream_log.append({"kind": "tool_call", "command": command}) if not (force or self.wants_tool_stream): diff --git a/tests/test_pifs_agent_stream.py b/tests/test_pifs_agent_stream.py index 5e0787a..4beaf6c 100644 --- a/tests/test_pifs_agent_stream.py +++ b/tests/test_pifs_agent_stream.py @@ -79,6 +79,17 @@ class PIFSAgentStreamTest(unittest.TestCase): self.assertEqual(stream_log[1]["kind"], "tool_result") self.assertEqual(stream_log[2], {"kind": "tool_args", "text": '{"command":"ls /"}'}) + def test_empty_tool_command_is_not_printed_or_logged(self): + output = io.StringIO() + stream_log = [] + observer = PIFSAgentStreamObserver("tools", stream_log=stream_log, output=output) + + observer.emit_tool_call("") + observer.emit_tool_call(" ") + + self.assertEqual(output.getvalue(), "") + self.assertEqual(stream_log, []) + def test_tool_result_preview_compacts_large_outputs(self): output = io.StringIO() observer = PIFSAgentStreamObserver("tools", output=output) @@ -188,6 +199,11 @@ class PIFSAgentStreamTest(unittest.TestCase): self.assertIn("page-level evidence", AGENT_TOOL_POLICY) self.assertIn("prefer\ncat --node ", BASH_TOOL_DESCRIPTION) + def test_prompt_requires_stat_for_metadata_questions(self): + self.assertIn("stat --schema and stat ", AGENT_TOOL_POLICY) + self.assertIn("do not infer metadata presence or absence", AGENT_TOOL_POLICY) + self.assertIn("questions about metadata fields", BASH_TOOL_DESCRIPTION) + def test_system_prompt_sets_workspace_identity_and_scope(self): self.assertIn("PageIndex FileSystem Demo Agent", AGENT_SYSTEM_PROMPT) self.assertIn("VectifyAI Team", AGENT_SYSTEM_PROMPT)