From 3d0dfa154b57846187cc18772987a96ea1c90c31 Mon Sep 17 00:00:00 2001 From: jp170na Date: Sat, 7 Nov 2026 16:16:05 +0100 Subject: [PATCH] =?UTF-8?q?Na=C4=8D=C3=ADtanie=20n=C3=A1strojov?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/claude/dist/packages.json | 4 ++-- packages/claude/dist/zpwiki-graphrag.zip | Bin 8502 -> 8735 bytes packages/claude/dist/zpwiki-rag.zip | Bin 8744 -> 8966 bytes packages/claude/graphrag/SKILL.md | 8 +++++++- packages/claude/mcp_server.py | 6 ++++++ packages/claude/rag/SKILL.md | 8 +++++++- test/test_academic.py | 8 ++++++++ test/test_claude_packages.py | 6 ++++++ tools/claude/build_claude_packages.py | 2 +- tools/knowledge/academic.py | 11 +++++++++++ 10 files changed, 48 insertions(+), 5 deletions(-) diff --git a/packages/claude/dist/packages.json b/packages/claude/dist/packages.json index 73249ad..f8a2113 100644 --- a/packages/claude/dist/packages.json +++ b/packages/claude/dist/packages.json @@ -3,12 +3,12 @@ { "archive": "zpwiki-rag.zip", "name": "rag", - "sha256": "3eb3a59827b3eda400c7a5cd5dc3909831d5343903b159a71d843fb712970b52" + "sha256": "c710593a12c030c716ad4ba620e13182c35a86ded339e6180c235941398e2911" }, { "archive": "zpwiki-graphrag.zip", "name": "graphrag", - "sha256": "99cf35d9050b5942b1d33744c49ade436e8c4b811d536257a2d0b090700dd3e0" + "sha256": "160f58d665aa5b156589731427eeb4113a4eb0020291d338a2ec35a0c81b7696" } ], "schema_version": 1 diff --git a/packages/claude/dist/zpwiki-graphrag.zip b/packages/claude/dist/zpwiki-graphrag.zip index 165b64fcec37920f8494bbe4a545e7a1e371cc54..16846dea09f24bb0d89975d1cfdce872e9da4cd9 100644 GIT binary patch delta 3623 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 diff --git a/packages/claude/dist/zpwiki-rag.zip b/packages/claude/dist/zpwiki-rag.zip index cd84b26fac68cb023ad077aedf296832d8c2d4e3..af87f362e5605c13aa02e9c0629a10b49e5cda80 100644 GIT binary patch delta 3865 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 b!w!=H4i}TqAu0m8Ad~zdCI<2$00000K^#k5 delta 3632 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 Cs`LT? diff --git a/packages/claude/graphrag/SKILL.md b/packages/claude/graphrag/SKILL.md index 64f2756..fc7fb8c 100644 --- a/packages/claude/graphrag/SKILL.md +++ b/packages/claude/graphrag/SKILL.md @@ -39,7 +39,13 @@ that subject is unambiguous in the immediately preceding exchange. Preserve the and every remaining condition. Otherwise ask for the name. Document authorship does not establish supervision. -1. With a ZP Wiki MCP connector, call `zpwiki_graphrag` with the complete question. +1. With a ZP Wiki MCP connector, load its current tool definition before calling it. + When tools are deferred, use the host's tool search (for example `tool_search`) to find + `zpwiki_graphrag`. Use the exact loaded identifier and schema; never guess a tool name or arguments. + Pass the complete question as `query`, for example `{"query":"the complete question"}`. + The optional `limit` is an integer. Do not send an argument named `question`. + If the host reports that the tool has not been loaded, discover it first and retry the same + question with the loaded schema. This is a tool-discovery error, not evidence of a DNS failure. 2. Otherwise, with securely configured backend access in a Python execution environment, run `python scripts/query.py "the complete question"` relative to this directory. Keep every condition in the same query (maximum 500 characters): names, work type, diff --git a/packages/claude/mcp_server.py b/packages/claude/mcp_server.py index 05ae32f..740d2a5 100644 --- a/packages/claude/mcp_server.py +++ b/packages/claude/mcp_server.py @@ -20,6 +20,10 @@ from starlette.responses import JSONResponse # Host-model rules belong to MCP initialization and Skills, not tool-result data. QUESTION_POLICY = ( + 'Load each tool definition using the host tool search when required before calling it. ' + 'Use the exact loaded tool identifier and schema. For zpwiki_rag and zpwiki_graphrag, ' + 'the question belongs in the query argument, never an argument named question. ' + 'A tool-not-loaded or invalid-argument error is a host invocation error, not a DNS failure. ' 'For a follow-up omitting a person or supervisor, inherit the subject only from an unambiguous ' 'immediately preceding exchange and reconstruct one full question with the new year and all constraints. ' 'Otherwise ask for the name. Never infer supervision from document authorship. ' @@ -75,6 +79,7 @@ def tool_result(result): async def zpwiki_rag(query: str, limit: int = 5) -> CallToolResult: """Verified ZP Wiki text answer. Keep the full question, names, work type and year. + Pass the full question in query, not question. Optional limit is an integer. Present the accepted answer with its citations; add no guesses or history commentary. """ return tool_result(answer_for_presentation(await asyncio.to_thread(query_backend, query, 'rag', limit=limit))) @@ -83,6 +88,7 @@ async def zpwiki_rag(query: str, limit: int = 5) -> CallToolResult: async def zpwiki_graphrag(query: str, limit: int = 5) -> CallToolResult: """Verified graph answer: relationships, related topics, progress, dated outcomes, years and counts in ZP Wiki. + Pass the full question in query, not question. Optional limit is an integer. Present the accepted answer with its citations; no_answer means no supporting evidence. """ return tool_result(answer_for_presentation(await asyncio.to_thread(query_backend, query, 'graphrag', limit=limit))) diff --git a/packages/claude/rag/SKILL.md b/packages/claude/rag/SKILL.md index 1d05426..83b38b6 100644 --- a/packages/claude/rag/SKILL.md +++ b/packages/claude/rag/SKILL.md @@ -37,7 +37,13 @@ is unclear, ask for the name; never send a subjectless search or infer supervisi For multiple explicit commands in one message, handle each question separately in order; keep all conditions belonging to each question together. -1. If a ZP Wiki MCP connector is available, call `zpwiki_rag` with the complete question. +1. If a ZP Wiki MCP connector is available, load its current tool definition before calling it. + When tools are deferred, use the host's tool search (for example `tool_search`) to find + `zpwiki_rag`. Use the exact loaded identifier and schema; never guess a tool name or arguments. + Pass the complete question as `query`, for example `{"query":"the complete question"}`. + The optional `limit` is an integer. Do not send an argument named `question`. + If the host reports that the tool has not been loaded, discover it first and retry the same + question with the loaded schema. This is a tool-discovery error, not evidence of a DNS failure. 2. Otherwise, in a Python execution environment with securely configured backend access, run `python scripts/query.py "the complete question"` relative to this skill's directory. The question limit is 500 characters. Preserve names, work type, year and all constraints. diff --git a/test/test_academic.py b/test/test_academic.py index c8aa22d..c01b49a 100644 --- a/test/test_academic.py +++ b/test/test_academic.py @@ -164,3 +164,11 @@ def test_academic_intents_use_the_shared_backend(question,mode): def test_completed_subtasks_are_not_routed_to_degree_completion(): assert academic_intent('Aké experimenty dokončil Ján Holp?') is None assert academic_intent('Ktoré úlohy dokončil Ján Holp?') is None + + +def test_colloquial_thesis_name_keeps_the_work_type_instead_of_listing_all_works(engine): + data=index(('Ján Holp','# Diplomová práca 2021\nVedúci: Daniel Hládek\n' + '# Bakalárska práca 2019\nVedúci: Ján Staš\n')) + r=answer_academic('Kto vedie diplomovku Jána Holpa?',data,engine=engine) + assert r['status']=='ok' and 'Vedúci práce: Daniel Hládek' in r['answer'] + assert 'Bakalárska práca' not in r['answer'] and 'Ján Staš' not in r['answer'] diff --git a/test/test_claude_packages.py b/test/test_claude_packages.py index 620b810..66f0dc3 100644 --- a/test/test_claude_packages.py +++ b/test/test_claude_packages.py @@ -336,6 +336,12 @@ def test_mcp_stdio_initialization_discovery_call_and_rejection(backend): assert ANSWER_PRESENTATION_POLICY in initialized.instructions listed = await session.list_tools() assert {row.name for row in listed.tools} == {'zpwiki_rag', 'zpwiki_graphrag', 'zpwiki_health'} + for tool in listed.tools: + if tool.name in {'zpwiki_rag','zpwiki_graphrag'}: + assert tool.inputSchema['required']==['query'] + assert 'question' not in tool.inputSchema['properties'] + wrong=await session.call_tool(tool.name,{'question':'Práca Evy Novej?'}) + assert wrong.isError for engine in ['rag', 'graphrag']: result = await session.call_tool('zpwiki_' + engine, {'query': 'Práca Evy Novej?'}) assert not result.isError diff --git a/tools/claude/build_claude_packages.py b/tools/claude/build_claude_packages.py index fd675f4..0bc79a2 100644 --- a/tools/claude/build_claude_packages.py +++ b/tools/claude/build_claude_packages.py @@ -11,7 +11,7 @@ import zipfile ROOT = Path(__file__).resolve().parents[2] BASE = ROOT / 'packages/claude' ENGINES = ('rag', 'graphrag') -PACKAGE_VERSION = '1.8.0' +PACKAGE_VERSION = '1.8.1' def json_bytes(value): diff --git a/tools/knowledge/academic.py b/tools/knowledge/academic.py index a2e5217..e39bec4 100644 --- a/tools/knowledge/academic.py +++ b/tools/knowledge/academic.py @@ -144,11 +144,22 @@ def answer_academic(question, index, *, engine, limit=5, units=None, mode=None): status='ambiguous',reason='ambiguous_advisor_filter') from tools.answer_evaluation.rag_evidence import requested_types types=requested_types(resolved,[m['name'] for m in students]) + # Ordinary wording of the same work-type constraint must not silently + # broaden "diplomovku" to every bachelor thesis and project on a profile. + informal={kind for pattern,kind in [(r'\bdiplomovk\w*\b','diploma_thesis'), + (r'\bbakalark\w*\b','bachelor_thesis')] + if re.search(pattern,text)} + if len(informal)>1 or informal and types and not set(types.values())<=informal: + return respond('Upresni, či sa pýtaš na bakalársku alebo diplomovú prácu.', + status='ambiguous',reason='ambiguous_work_type') + if informal: + types={m['name']:next(iter(informal)) for m in students} global_types=set(types.values()) if not students: from tools.answer_evaluation.rag_evidence import work_type kind=work_type(resolved) if kind:global_types={kind} + elif informal:global_types=informal # Completion-year filters apply to the EVENT, not the work heading. from tools.knowledge.query import _period try:period=_period(resolved)