feat(ingest): resolve project labels with Jev
CI / quality (push) Canceled after 0s

This commit is contained in:
vasily committed 2026-10-15 10:53:30 +08:00
1 parent 0e1a2ad008
commit 34f4923566
28 files changed
+3932 -81

No files matched your search

+88 -3
View File
@@ -16,6 +16,7 @@ from mcp.types import TextContent
from gewu.adapters.git_repository import GitCanonicalRepository
from gewu.adapters.source_extractor import LocalSourceExtractor
from gewu.adapters.sqlite_identity import SQLiteIdentityStore
from gewu.adapters.sqlite_ingest_reviews import SQLiteIngestReviewStore
from gewu.adapters.url_fetch import PublicUrlFetcher
from gewu.application.acceptance import AcceptanceService
from gewu.application.context import ValidationContext
@@ -176,6 +177,7 @@ def test_mcp_source_to_citation_vertical_slice(tmp_path: Path) -> None:
acceptance_service=acceptance,
context_provider=lambda: context,
url_fetcher=_fixture_fetcher(),
ingest_review_store=SQLiteIngestReviewStore(tmp_path / "ingest-reviews.sqlite3"),
)
async with app.router.lifespan_context(app):
async with httpx2.AsyncClient(
@@ -193,6 +195,7 @@ def test_mcp_source_to_citation_vertical_slice(tmp_path: Path) -> None:
"node_history",
"get_project_context",
"get_source",
"ingest_review_create",
"source_upload_begin",
"source_capture_text",
"source_capture_url",
@@ -201,6 +204,7 @@ def test_mcp_source_to_citation_vertical_slice(tmp_path: Path) -> None:
"source_upload_finalize",
"source_extract",
"source_extraction_block",
"proposal_prepare",
"proposal_evaluate",
"proposal_submit",
"proposal_status",
@@ -221,6 +225,62 @@ def test_mcp_source_to_citation_vertical_slice(tmp_path: Path) -> None:
PROJECTS["dome-performance"].key_questions
)
assert "autonomy_policy_id" not in lens_result["lens"]
draft = proposal().model_dump(mode="json")
draft.pop("payload_digest")
for operation in draft["operations"]:
node = operation.get("node")
if node is None:
continue
for group in ("claims", "assumptions", "limitations"):
for claim in node.get(group, []):
claim["assessment"].pop("assertion_digest")
claim["assessment"].pop("evidence_digests")
for evidence in claim["evidence"]:
evidence.pop("assertion_path")
evidence.pop("assertion_digest")
prepared_result = await mcp.call_tool(
"proposal_prepare",
{"proposal_json": json.dumps(draft, ensure_ascii=False)},
)
assert not prepared_result.is_error, prepared_result.content
prepared_payload = json.loads(_text_payload(prepared_result))
assert prepared_payload["status"] == "prepared"
prepared_proposal = ProposalRevision.model_validate_json(
prepared_payload["proposal_json"], strict=True
)
assert prepared_payload["payload_digest"] == prepared_proposal.payload_digest
assert prepared_proposal.payload_digest == proposal_payload_digest(
prepared_proposal
)
invalid_draft = json.loads(json.dumps(draft))
invalid_evidence = invalid_draft["operations"][1]["node"]["claims"][0][
"evidence"
][0]
invalid_evidence["locator"]["kind"] = "text_span"
invalid_evidence["locator"]["page"] = 1
invalid_result = await mcp.call_tool(
"proposal_prepare",
{"proposal_json": json.dumps(invalid_draft, ensure_ascii=False)},
)
assert not invalid_result.is_error, invalid_result.content
invalid_payload = json.loads(_text_payload(invalid_result))
assert invalid_payload["status"] == "invalid"
assert any(
issue["path"].endswith("locator")
and "PDF locators" in issue["message"]
for issue in invalid_payload["issues"]
)
invalid_review = await mcp.call_tool(
"ingest_review_create", {"review_json": "{}"}
)
assert not invalid_review.is_error, invalid_review.content
review_payload = json.loads(_text_payload(invalid_review))
assert review_payload["status"] == "invalid"
assert {issue["path"] for issue in review_payload["issues"]} >= {
"review_id",
"extraction_id",
"relevance_rationale",
}
denied_lens = await mcp.call_tool(
"get_project_context", {"project_id": "interactive-video"}
)
@@ -238,6 +298,11 @@ def test_mcp_source_to_citation_vertical_slice(tmp_path: Path) -> None:
{"proposal_json": proposal().model_dump_json()},
)
assert viewer_proposal.is_error
viewer_prepare = await viewer_mcp.call_tool(
"proposal_prepare",
{"proposal_json": json.dumps(draft, ensure_ascii=False)},
)
assert viewer_prepare.is_error
viewer_upload = await viewer_mcp.call_tool(
"source_upload_begin",
{
@@ -549,9 +614,28 @@ def test_mcp_source_to_citation_vertical_slice(tmp_path: Path) -> None:
},
)
assert not html_block_result.is_error
html_block = _text_payload(html_block_result)
assert "Exact HTML statement." in html_block
assert "ignoreInjection" not in html_block
html_block = json.loads(_text_payload(html_block_result))
assert "Exact HTML statement." in html_block["normalized_text"]
assert "original_text" not in html_block
assert "normalization_map" not in html_block
mapped_html_result = await mcp.call_tool(
"source_extraction_block",
{
"project_id": "dome-performance",
"extraction_id": html_extraction["extraction_id"],
"block_id": html_extraction["blocks"][0]["block_id"],
"offset": 0,
"length": 500,
"include_original_mapping": True,
},
)
assert not mapped_html_result.is_error
mapped_html = json.loads(_text_payload(mapped_html_result))
assert mapped_html["original_text"]
assert len(mapped_html["normalization_map"]) == len(
mapped_html["normalized_text"]
)
assert "ignoreInjection" not in html_block["normalized_text"]
captured_pdf = await mcp.call_tool(
"source_capture_url",
{
@@ -591,6 +675,7 @@ def test_mcp_source_to_citation_vertical_slice(tmp_path: Path) -> None:
pdf_block = json.loads(_text_payload(pdf_block_result))
assert pdf_block["page"] == 1
assert "Archived PDF evidence." in pdf_block["normalized_text"]
assert "normalization_map" not in pdf_block
malformed_pdf = await mcp.call_tool(
"source_capture_url",
{