From 23b97401c9d95c7ea6cee154c5b105fb448aa822 Mon Sep 17 00:00:00 2001 From: jp170na Date: Wed, 4 Nov 2026 03:53:14 +0100 Subject: [PATCH] =?UTF-8?q?Stru=C4=8Dnej=C5=A1ie=20v=C3=BDstupy=20n=C3=A1s?= =?UTF-8?q?trojov?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +++++- packages/claude/client.py | 14 +++++++ packages/claude/dist/packages.json | 4 +- packages/claude/dist/zpwiki-graphrag.zip | Bin 7424 -> 7672 bytes packages/claude/dist/zpwiki-rag.zip | Bin 7553 -> 7748 bytes packages/claude/graphrag/SKILL.md | 11 +++--- packages/claude/mcp_server.py | 15 ++++---- packages/claude/rag/SKILL.md | 13 +++---- scripts/build_claude_packages.py | 2 +- test/test_claude_packages.py | 45 +++++++++++++++++++++++ 10 files changed, 91 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 3c628c3..a1c776d 100644 --- a/README.md +++ b/README.md @@ -1160,7 +1160,16 @@ upozornenie na neúplnosť, nezamieňať autora dokumentu s autorom práce a pri sa nevysvetľujú odhadom; verzia dát neoznačuje verziu programu. Tieto pokyny ovplyvňujú správanie Claude, jeho finálny text však náš backend nemôže programovo vynútiť. Po aktualizácii už nahratých Skills nahraď ich -novými ZIPmi z `packages/claude/dist/` (verzia 1.5.0) a over správanie v novom chate. +novými ZIPmi z `packages/claude/dist/` (verzia 1.5.1) a over správanie v novom chate. + +Predvolený výstup Claude nástrojov obsahuje overenú odpoveď, citácie, identitu +otázky/nástroja, stav doručenia a verziu dát. Technické údaje o výbere kandidátov, +orezaní retrievalu, `answer_coverage`, jednotlivé claims a pomocné počty sa do +prezentačného výsledku nekopírujú. Plný validovaný kontrakt zostáva v `/answer` +a internom klientovi; diagnostika je dostupná cez `--mode retrieve` a `--health`. +Samotný text odpovede sa nemení: konkrétne chýbajúce údaje aj upozornenia pri +skutočne skrátenom výpise zostávajú zachované. Neprítomnosť technických polí +neznamená úplnosť vyhľadania. ### Nahratie Skills do webového Claude diff --git a/packages/claude/client.py b/packages/claude/client.py index 748af74..1f6984a 100644 --- a/packages/claude/client.py +++ b/packages/claude/client.py @@ -231,6 +231,18 @@ def backend_health(config=None): return {**error_result(str(exc)), 'ready': False} +def answer_for_presentation(result: dict) -> dict: + """Keep approved prose/caveats intact; retrieval telemetry is not answer prose. + + Called after query_backend validates the complete backend contract. Full + metadata remains available there, in /answer and in diagnostic retrieval. + Never change an incomplete result into a claim of completeness. + """ + fields = {'status', 'reason', 'query', 'engine', 'output_kind', + 'accepted_for_delivery', 'answer', 'source_urls', 'index_version'} + return {key: value for key, value in result.items() if key in fields} + + def main(engine=None): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('query', nargs='?') @@ -242,6 +254,8 @@ def main(engine=None): args = parser.parse_args() result = backend_health() if args.health else query_backend(args.query, engine or args.engine, mode=args.mode, limit=args.limit) + if not args.health and args.mode == 'answer': + result = answer_for_presentation(result) print(json.dumps(result, ensure_ascii=False, separators=(',', ':'))) return 1 if result.get('status') == 'error' else 0 diff --git a/packages/claude/dist/packages.json b/packages/claude/dist/packages.json index e5fdc26..bcca32c 100644 --- a/packages/claude/dist/packages.json +++ b/packages/claude/dist/packages.json @@ -3,12 +3,12 @@ { "archive": "zpwiki-rag.zip", "name": "rag", - "sha256": "8e5ab92284ee6f53d10e468cb4edee6cfd354ae869583673cbb6aea8ea9ca437" + "sha256": "f439237795a770473bf5efd0760667f9ef75fa4882086133996d4a928a9d0252" }, { "archive": "zpwiki-graphrag.zip", "name": "graphrag", - "sha256": "99a9ea36b439d6b14edc35c2d4d0c1c2cf97139f78e8fd73b8ce2347d82b1092" + "sha256": "cd748dc0035bf932a72f6d178f986b18609728a3478fdf9a49ab6247a37a431d" } ], "schema_version": 1 diff --git a/packages/claude/dist/zpwiki-graphrag.zip b/packages/claude/dist/zpwiki-graphrag.zip index 63dd60f35a1063ccc34f9373827884114efdbffc..609eafb093a1acc476fddffed50cb5576b4a4649 100644 GIT binary patch delta 7123 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 Gg8u^t(yjae delta 6886 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 X1+k_I3iv-H^1qG$@2N$K|7`yQ4ps_j diff --git a/packages/claude/dist/zpwiki-rag.zip b/packages/claude/dist/zpwiki-rag.zip index 7f1361d64101df7eefd2a2646eb1a9c2706510fb..3c5d3afa81ba1502303ceb72bb84609acc50d2c2 100644 GIT binary patch delta 7203 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 delta 7022 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 CallToolResult: Present the accepted answer with its citations; add no guesses or history commentary. """ - return tool_result(await asyncio.to_thread(query_backend, query, 'rag', limit=limit)) + return tool_result(answer_for_presentation(await asyncio.to_thread(query_backend, query, 'rag', limit=limit))) async def zpwiki_graphrag(query: str, limit: int = 5) -> CallToolResult: @@ -74,7 +73,7 @@ async def zpwiki_graphrag(query: str, limit: int = 5) -> CallToolResult: Present the accepted answer with its citations; no_answer means no supporting evidence. """ - return tool_result(await asyncio.to_thread(query_backend, query, 'graphrag', limit=limit)) + return tool_result(answer_for_presentation(await asyncio.to_thread(query_backend, query, 'graphrag', limit=limit))) async def zpwiki_health() -> CallToolResult: diff --git a/packages/claude/rag/SKILL.md b/packages/claude/rag/SKILL.md index 650c9bf..5f46e1a 100644 --- a/packages/claude/rag/SKILL.md +++ b/packages/claude/rag/SKILL.md @@ -36,13 +36,12 @@ keep all conditions belonging to each question together. 4. For `status=error` or rejected delivery, explain that verified output is unavailable; never reproduce rejected text or invent a replacement. For `ambiguous`, ask the user to clarify. For `no_answer`, report the absence of evidence without claiming the fact is false. -5. Respect `complete`, `truncated`, `truncation_reasons` and `index_version`. - These describe retrieval, not whether the selected answer is supported. `answer_coverage` - separately describes the answer scope: `supported` means evidence-backed, never exhaustive. - Present the backend's specific notices unchanged. Do not append a generic incompleteness - warning to a supported fact or short description just because retrieval selected top results. - Never describe an incomplete or unknown-completeness result as an exhaustive list. - Do not combine different index versions as if they represented one snapshot. +5. The default verified-answer result contains presentation fields, not retrieval telemetry. + Missing aspects and actual limitations are already stated specifically in `answer`. + Preserve those notices unchanged. Do not append commentary about backend checks, + `partial`, candidate/result limits, excerpt limits or general incompleteness. + Absence of technical metadata never establishes an exhaustive list or uniqueness. + Do not combine different `index_version` values as if they represented one snapshot. Presentation boundaries: - Use the current tool response for the current question. Do not append factual material diff --git a/scripts/build_claude_packages.py b/scripts/build_claude_packages.py index 9a0042a..1ce0a96 100644 --- a/scripts/build_claude_packages.py +++ b/scripts/build_claude_packages.py @@ -11,7 +11,7 @@ import zipfile ROOT = Path(__file__).resolve().parents[1] BASE = ROOT / 'packages/claude' ENGINES = ('rag', 'graphrag') -PACKAGE_VERSION = '1.5.0' +PACKAGE_VERSION = '1.5.1' def json_bytes(value): diff --git a/test/test_claude_packages.py b/test/test_claude_packages.py index 2114a87..c5ab605 100644 --- a/test/test_claude_packages.py +++ b/test/test_claude_packages.py @@ -141,6 +141,37 @@ def test_answer_coverage_is_forwarded_without_overwriting_retrieval_limits(backe assert 'presentation_instructions' not in result +@pytest.mark.parametrize('engine', ['rag', 'graphrag']) +@pytest.mark.parametrize('text', [ + 'V podkladoch chýbajú údaje o riešených problémoch.', + 'Doložené ciele práce. Časť podkladov k zadaniu bola skrátená; uvedené body nemusia tvoriť celé zadanie.', + 'Doložené práce. Výpis je neúplný. Výpis môžeš zúžiť uvedením osoby alebo roku.', +]) +def test_presentation_preserves_specific_caveats_without_retrieval_telemetry(backend, engine, text): + backend['checked'].update(answer=text, answer_coverage={ + 'scope':'fact', 'status':'partial', 'warnings':['partial_requested_aspects'], + 'limitations':['candidate_limit','result_limit','per_document_limit']}) + raw=client.query_backend('Práca?',engine) + original=copy.deepcopy(raw) + shown=client.answer_for_presentation(raw) + assert shown['answer']==text and shown['source_urls']==raw['source_urls'] + assert shown['query']==raw['query'] and shown['engine']==engine + assert shown['index_version']==raw['index_version'] and shown['accepted_for_delivery'] is True + hidden={'complete','truncated','truncation_reasons','answer_coverage','claims','count'} + assert not hidden.intersection(shown) + assert not any(token in json.dumps(shown) for token in ['candidate_limit','per_document_limit','partial_requested_aspects']) + # The full API/client contract still reports the actual incomplete retrieval. + assert raw==original and raw['complete'] is False and raw['truncated'] is True + assert raw['answer_coverage']['status']=='partial' + + +def test_presentation_cannot_turn_a_rejected_response_into_an_approved_answer(backend): + backend['checked'].update(status='error', answer='PRIVATE REJECTED ANSWER') + shown=client.answer_for_presentation(client.query_backend('Práca?','rag')) + assert shown['status']=='error' and shown['accepted_for_delivery'] is False + assert 'PRIVATE' not in json.dumps(shown) + + @pytest.mark.parametrize('coverage', [None, [], {'status': 'complete'}, {'scope': 'fact', 'status': 'supported', 'warnings': 'none', 'limitations': []}, {'scope': [], 'status': 'supported', 'warnings': [], 'limitations': []}, @@ -244,6 +275,13 @@ def test_zip_is_reproducible_and_runs_without_repository(tmp_path, backend, engi assert result.returncode == 0, result.stderr assert json.loads(result.stdout)['answer'] == backend['checked']['answer'] assert 'presentation_instructions' not in json.loads(result.stdout) + assert not {'complete','truncated','truncation_reasons','answer_coverage','claims'}.intersection(json.loads(result.stdout)) + diagnostic=subprocess.run([*command,'--mode','retrieve'],cwd=folder,env=environment, + capture_output=True,text=True,timeout=15) + assert diagnostic.returncode==0,diagnostic.stderr + raw=json.loads(diagnostic.stdout) + assert raw['output_kind']=='retrieval_context' and raw['requires_final_answer_verification'] is True + assert raw['complete'] is False and raw['truncated'] is True def test_committed_archives_match_current_sources(tmp_path): @@ -259,6 +297,8 @@ def test_mcp_stdio_initialization_discovery_call_and_rejection(backend): from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client from packages.claude.mcp_server import ANSWER_PRESENTATION_POLICY + backend['checked']['answer_coverage']={'scope':'fact','status':'partial', + 'warnings':['partial_requested_aspects'],'limitations':['candidate_limit','per_document_limit']} async def run(): params = StdioServerParameters(command=sys.executable, @@ -275,7 +315,12 @@ def test_mcp_stdio_initialization_discovery_call_and_rejection(backend): result = await session.call_tool('zpwiki_' + engine, {'query': 'Práca Evy Novej?'}) assert not result.isError assert result.structuredContent['answer'] == backend['checked']['answer'] + assert not {'complete','truncated','truncation_reasons','answer_coverage','claims'}.intersection(result.structuredContent) assert 'presentation_instructions' not in result.structuredContent + assert all(json.loads(block.text)==result.structuredContent + for block in result.content if block.type=='text') + assert 'candidate_limit' not in json.dumps(result.model_dump()) + assert 'partial_requested_aspects' not in json.dumps(result.model_dump()) assert all('presentation_instructions' not in json.loads(block.text) for block in result.content if block.type == 'text') rejected = await session.call_tool('zpwiki_rag', {'query': ''})