Files
wehub-resource-sync c889a57b6b
Test Suites / Build CI Environment (push) Has been cancelled
Test Suites / Basic Tests (push) Has been cancelled
Test Suites / End-to-End Tests (push) Has been cancelled
Test Suites / CLI Tests (push) Has been cancelled
Test Suites / Slow End-to-End Tests (push) Has been cancelled
Test Suites / Graph Database Tests (push) Has been cancelled
Test Suites / Vector DB Tests (push) Has been cancelled
Test Suites / Temporal Graph Test (push) Has been cancelled
Test Suites / Search Test on Different DBs (push) Has been cancelled
Test Suites / Example Tests (push) Has been cancelled
Test Suites / Notebook Tests (push) Has been cancelled
Test Suites / OS and Python Tests Ubuntu (push) Has been cancelled
Test Suites / OS and Python Tests Extended (push) Has been cancelled
Test Suites / LLM Test Suite (push) Has been cancelled
Test Suites / S3 File Storage Test (push) Has been cancelled
Test Suites / Run Integration Tests (push) Has been cancelled
Test Suites / MCP Tests (push) Has been cancelled
Test Suites / Docker Compose Test (push) Has been cancelled
Test Suites / Docker CI test (push) Has been cancelled
Test Suites / Relational DB Migration Tests (push) Has been cancelled
Test Suites / Distributed Cognee Test (push) Has been cancelled
Test Suites / DB Examples Tests (push) Has been cancelled
Test Suites / Test Completion Status (push) Has been cancelled
Test Suites / Claude Code Review (push) Has been cancelled
Test Suites / basic checks (push) Has been cancelled
build | Build and Push Cognee MCP Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
build | Build and Push Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.11) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.12) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (kuzu, kuzu) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (neo4j, neo4j) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Examples (push) Has been cancelled
Weighted Edges Tests / Code Quality for Weighted Edges (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:02:24 +08:00

229 lines
8.5 KiB
Python

from __future__ import annotations
import json
import random
from pathlib import Path
from typing import Any, List, Optional, Tuple, Union
from cognee.eval_framework.benchmark_adapters.base_benchmark_adapter import (
BaseBenchmarkAdapter,
)
from cognee.eval_framework.benchmark_adapters.logistics_system_utils.corpus_generator.narrativize_corpus import (
PACKAGE_FOLDER,
load_narrative_corpus,
narrativize_corpus,
narrative_corpus_exists,
run_narrativize_corpus,
)
from cognee.eval_framework.benchmark_adapters.logistics_system_utils.ontology import (
add_packages_to_world,
create_world,
validate_world_packages,
write_golden_answers,
)
from cognee.eval_framework.benchmark_adapters.logistics_system_utils.utils.utils import (
_safe_filename,
load_world,
store_world,
)
DEFAULT_WORLD_ROOT = Path("data/logistics_system_worlds")
DEFAULT_WORLD_NAME = "default"
DEFAULT_WORLD_FILENAME = "stored_world.json"
DEFAULT_GOLDEN_ANSWERS_FILENAME = "golden_answers.json"
DEFAULT_QUERY_PATH = (
Path(__file__).resolve().parent / "logistics_system_utils" / "queries" / "query.txt"
)
DEFAULT_COMMON_RULES_PATH = (
Path(__file__).resolve().parent
/ "logistics_system_utils"
/ "rules"
/ "rules_common_language.txt"
)
class LogisticsSystemAdapter(BaseBenchmarkAdapter):
def __init__(
self,
world_name: str = DEFAULT_WORLD_NAME,
worlds_root: str | Path = DEFAULT_WORLD_ROOT,
user_count: int = 15,
retailer_count: int = 10,
package_count: int = 5,
query: str | None = None,
) -> None:
super().__init__()
self.world_name = world_name
self.worlds_root = Path(worlds_root)
self.user_count = user_count
self.retailer_count = retailer_count
self.package_count = package_count
self.query = query if query is not None else DEFAULT_QUERY_PATH.read_text(encoding="utf-8")
@property
def world_directory(self) -> Path:
return self.worlds_root / self.world_name
@property
def world_file(self) -> Path:
return self.world_directory / DEFAULT_WORLD_FILENAME
@property
def golden_answers_file(self) -> Path:
return self.world_directory / DEFAULT_GOLDEN_ANSWERS_FILENAME
def _create_world_with_packages(self, max_attempts: int = 10) -> dict[str, object]:
for _ in range(max_attempts):
world = create_world(
user_count=self.user_count,
retailer_count=self.retailer_count,
)
try:
return add_packages_to_world(world, package_count=self.package_count)
except ValueError:
continue
raise ValueError(
"Could not generate a logistics world with compatible user and retailer pairs."
)
def _get_or_create_world(self) -> dict[str, object]:
if self.world_file.exists():
world = load_world(self.world_file)
validate_world_packages(world)
if not self.golden_answers_file.exists():
write_golden_answers(world, self.world_directory)
return world
self.world_directory.mkdir(parents=True, exist_ok=True)
world = self._create_world_with_packages()
store_world(world, self.world_file)
write_golden_answers(world, self.world_directory)
return world
async def prepare_corpus(self) -> None:
world = self._get_or_create_world()
if not narrative_corpus_exists(self.world_directory, world):
await narrativize_corpus(self.world_directory)
def _load_golden_answers(self) -> list[dict[str, Any]]:
payload = json.loads(self.golden_answers_file.read_text(encoding="utf-8"))
return payload.get("golden_answers", [])
def _load_package_narratives(self, world: dict[str, object]) -> dict[str, str]:
if not narrative_corpus_exists(self.world_directory, world):
run_narrativize_corpus(self.world_directory)
package_narratives: dict[str, str] = {}
for package in world.get("packages", []):
narrative_path = (
self.world_directory / PACKAGE_FOLDER / f"{_safe_filename(package.package_id)}.txt"
)
if not narrative_path.exists():
raise ValueError(
f"Missing package narrative for {package.package_id} at {narrative_path}."
)
package_narratives[package.package_id] = narrative_path.read_text(
encoding="utf-8"
).strip()
return package_narratives
def _load_shared_corpus_documents(self) -> list[str]:
return [DEFAULT_COMMON_RULES_PATH.read_text(encoding="utf-8").strip()]
def _build_question_answer_pairs(
self,
world: dict[str, object],
load_golden_context: bool = False,
) -> List[dict[str, Any]]:
packages = list(world.get("packages", []))
golden_answers = self._load_golden_answers()
package_narratives = self._load_package_narratives(world)
if len(packages) != len(golden_answers):
raise ValueError(
"The number of generated packages does not match the number of golden answers."
)
qa_pairs: list[dict[str, Any]] = []
question_specs = (
(
"delivery_days",
"Estimate the total delivery days for this package.",
"estimated_delivery_days",
"estimated_delivery_days_supporting_facts",
"estimated_delivery_days_supporting_facts_data_sources",
),
(
"transport_cost",
"Estimate the transportation cost for this package.",
"estimated_transport_price",
"estimated_transport_price_supporting_facts",
"estimated_transport_price_supporting_facts_data_sources",
),
(
"carrier",
"Estimate the most suitable carrier for this package.",
"selected_carrier",
"carrier_selection_reasons",
"carrier_selection_reasons_data_sources",
),
)
for package, golden_answer in zip(packages, golden_answers, strict=False):
package_context = package_narratives[package.package_id]
for (
question_type,
question_prompt,
answer_key,
supporting_facts_key,
data_sources_key,
) in question_specs:
question_text = f"{package_context}\n\n{question_prompt}"
# if self.query.strip():
# question_text = f"{question_text}\n{self.query.strip()}"
qa_pair = {
"id": f"{self.world_name}:{package.package_id}:{question_type}",
"question": question_text,
"answer": str(golden_answer.get(answer_key)),
"golden_answer": golden_answer.get(answer_key),
"golden_context": "\n".join(golden_answer.get(supporting_facts_key, [])),
"golden_context_data_sources": golden_answer.get(data_sources_key, []),
"type": "logistics_system",
"question_type": question_type,
"world_name": self.world_name,
"package_id": package.package_id,
}
if load_golden_context:
qa_pair["package_context"] = package_context
qa_pairs.append(qa_pair)
return qa_pairs
def load_corpus(
self,
limit: Optional[int] = None,
seed: int = 42,
load_golden_context: bool = False,
instance_filter: Optional[Union[str, List[str], List[int]]] = None,
) -> Tuple[List[str], List[dict[str, Any]]]:
world = self._get_or_create_world()
if not narrative_corpus_exists(self.world_directory, world):
run_narrativize_corpus(self.world_directory)
corpus_list = self._load_shared_corpus_documents() + load_narrative_corpus(
self.world_directory
)
qa_pairs = self._build_question_answer_pairs(world, load_golden_context)
if instance_filter is not None:
qa_pairs = self._filter_instances(qa_pairs, instance_filter, id_key="id")
if limit is not None and 0 < limit < len(qa_pairs):
random.seed(seed)
qa_pairs = random.sample(qa_pairs, limit)
return corpus_list, qa_pairs