Commit b055a154 authored by Kantz's avatar Kantz
Browse files

chapter weitere geupdatet

parent bb0dd6ee
...@@ -16,6 +16,7 @@ def retrieve( ...@@ -16,6 +16,7 @@ def retrieve(
embedder: EmbeddingLike, embedder: EmbeddingLike,
query: str, query: str,
k: int = 4, k: int = 4,
chapter_index: int | None = None,
section_index: int | None = None, section_index: int | None = None,
subsection_index: int | None = None, subsection_index: int | None = None,
source_type_filter: list[str] | None = None, source_type_filter: list[str] | None = None,
...@@ -28,6 +29,7 @@ def retrieve( ...@@ -28,6 +29,7 @@ def retrieve(
embedder=embedder, embedder=embedder,
query=query, query=query,
k=k, k=k,
chapter_index=chapter_index,
section_index=section_index, section_index=section_index,
subsection_index=subsection_index, subsection_index=subsection_index,
source_type_filter=source_type_filter, source_type_filter=source_type_filter,
...@@ -40,6 +42,7 @@ def retrieve( ...@@ -40,6 +42,7 @@ def retrieve(
embedder=embedder, embedder=embedder,
query=query, query=query,
k=k, k=k,
chapter_index=chapter_index,
section_index=section_index, section_index=section_index,
subsection_index=subsection_index, subsection_index=subsection_index,
source_type_filter=source_type_filter, source_type_filter=source_type_filter,
...@@ -54,6 +57,7 @@ def retrieve_with_subsections( ...@@ -54,6 +57,7 @@ def retrieve_with_subsections(
query: str, query: str,
subsection_refs: list[vector_store.SubsectionRef] | None = None, subsection_refs: list[vector_store.SubsectionRef] | None = None,
k: int = 4, k: int = 4,
chapter_index: int | None = None,
section_index: int | None = None, section_index: int | None = None,
subsection_index: int | None = None, subsection_index: int | None = None,
source_type_filter: list[str] | None = None, source_type_filter: list[str] | None = None,
...@@ -67,6 +71,7 @@ def retrieve_with_subsections( ...@@ -67,6 +71,7 @@ def retrieve_with_subsections(
query=query, query=query,
subsection_refs=subsection_refs, subsection_refs=subsection_refs,
k=k, k=k,
chapter_index=chapter_index,
section_index=section_index, section_index=section_index,
subsection_index=subsection_index, subsection_index=subsection_index,
source_type_filter=source_type_filter, source_type_filter=source_type_filter,
...@@ -80,6 +85,7 @@ def retrieve_with_subsections( ...@@ -80,6 +85,7 @@ def retrieve_with_subsections(
query=query, query=query,
subsection_refs=subsection_refs, subsection_refs=subsection_refs,
k=k, k=k,
chapter_index=chapter_index,
section_index=section_index, section_index=section_index,
subsection_index=subsection_index, subsection_index=subsection_index,
source_type_filter=source_type_filter, source_type_filter=source_type_filter,
......
...@@ -24,14 +24,14 @@ def _normalize_subsection_key(value: str) -> str: ...@@ -24,14 +24,14 @@ def _normalize_subsection_key(value: str) -> str:
return re.sub(r"\s+", " ", collapsed) return re.sub(r"\s+", " ", collapsed)
def _parse_subsection_ref(value: str) -> tuple[int, int] | None: def _parse_subsection_ref(value: str) -> tuple[int, int, int] | None:
match = re.match(r"^\s*(\d+)\s*[:.]\s*(\d+)\s*$", str(value)) match = re.match(r"^\s*(\d+)\s*[:.]\s*(\d+)\s*[:.]\s*(\d+)\s*$", str(value))
if not match: if not match:
return None return None
return int(match.group(1)), int(match.group(2)) return int(match.group(1)), int(match.group(2)), int(match.group(3))
def load_subsection_map(path: Path = SUBSECTION_MAP_PATH) -> dict[str, tuple[int, int]]: def load_subsection_map(path: Path = SUBSECTION_MAP_PATH) -> dict[str, tuple[int, int, int]]:
if not path.exists(): if not path.exists():
return {} return {}
try: try:
...@@ -41,7 +41,7 @@ def load_subsection_map(path: Path = SUBSECTION_MAP_PATH) -> dict[str, tuple[int ...@@ -41,7 +41,7 @@ def load_subsection_map(path: Path = SUBSECTION_MAP_PATH) -> dict[str, tuple[int
if not isinstance(content, dict): if not isinstance(content, dict):
return {} return {}
mapped: dict[str, tuple[int, int]] = {} mapped: dict[str, tuple[int, int, int]] = {}
for raw_key, raw_ref in content.items(): for raw_key, raw_ref in content.items():
key = _normalize_subsection_key(str(raw_key)) key = _normalize_subsection_key(str(raw_key))
parsed = _parse_subsection_ref(str(raw_ref)) parsed = _parse_subsection_ref(str(raw_ref))
...@@ -53,21 +53,21 @@ def load_subsection_map(path: Path = SUBSECTION_MAP_PATH) -> dict[str, tuple[int ...@@ -53,21 +53,21 @@ def load_subsection_map(path: Path = SUBSECTION_MAP_PATH) -> dict[str, tuple[int
def _resolve_task_subsection_refs( def _resolve_task_subsection_refs(
task_file: dict[str, Any], task_file: dict[str, Any],
subsection_map: dict[str, tuple[int, int]] | None = None, subsection_map: dict[str, tuple[int, int, int]] | None = None,
) -> list[tuple[int, int]]: ) -> list[tuple[int, int, int]]:
mapping = subsection_map if subsection_map is not None else load_subsection_map() mapping = subsection_map if subsection_map is not None else load_subsection_map()
subsections = task_file.get("subsections", []) subsections = task_file.get("subsections", [])
if not isinstance(subsections, list): if not isinstance(subsections, list):
return [] return []
refs: set[tuple[int, int]] = set() refs: set[tuple[int, int, int]] = set()
for subsection in subsections: for subsection in subsections:
key = _normalize_subsection_key(str(subsection)) key = _normalize_subsection_key(str(subsection))
if not key: if not key:
continue continue
ref = mapping.get(key) ref = mapping.get(key)
if ref is not None: if ref is not None:
refs.add((int(ref[0]), int(ref[1]))) refs.add((int(ref[0]), int(ref[1]), int(ref[2])))
return sorted(refs) return sorted(refs)
...@@ -141,7 +141,7 @@ def set_selected_task( ...@@ -141,7 +141,7 @@ def set_selected_task(
sheet["task_file_id"] = str(task_file.get("_file_id", "")) sheet["task_file_id"] = str(task_file.get("_file_id", ""))
sheet["task_id"] = str(task_entry.get("id", "")).zfill(2) sheet["task_id"] = str(task_entry.get("id", "")).zfill(2)
refs = _resolve_task_subsection_refs(task_file) refs = _resolve_task_subsection_refs(task_file)
sheet["task_subsection_refs"] = [[sec, sub] for sec, sub in refs] sheet["task_subsection_refs"] = [[chap, sec, sub] for chap, sec, sub in refs]
def select_task_by_ids( def select_task_by_ids(
...@@ -167,16 +167,16 @@ def get_selected_task_ids(sheet: dict[str, Any]) -> tuple[str | None, str | None ...@@ -167,16 +167,16 @@ def get_selected_task_ids(sheet: dict[str, Any]) -> tuple[str | None, str | None
return (file_id or None, task_id or None) return (file_id or None, task_id or None)
def get_selected_task_subsection_refs(sheet: dict[str, Any]) -> list[tuple[int, int]]: def get_selected_task_subsection_refs(sheet: dict[str, Any]) -> list[tuple[int, int, int]]:
refs_raw = sheet.get("task_subsection_refs", []) refs_raw = sheet.get("task_subsection_refs", [])
if not isinstance(refs_raw, list): if not isinstance(refs_raw, list):
return [] return []
refs: set[tuple[int, int]] = set() refs: set[tuple[int, int, int]] = set()
for item in refs_raw: for item in refs_raw:
if isinstance(item, (list, tuple)) and len(item) >= 2: if isinstance(item, (list, tuple)) and len(item) >= 3:
try: try:
refs.add((int(item[0]), int(item[1]))) refs.add((int(item[0]), int(item[1]), int(item[2])))
except Exception: except Exception:
continue continue
return sorted(refs) return sorted(refs)
......
...@@ -546,7 +546,7 @@ def retrieve( ...@@ -546,7 +546,7 @@ def retrieve(
# -------------------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------------------
SubsectionRef = Tuple[int, int] SubsectionRef = Tuple[int, int, int]
def _normalize_subsection_refs( def _normalize_subsection_refs(
...@@ -554,7 +554,9 @@ def _normalize_subsection_refs( ...@@ -554,7 +554,9 @@ def _normalize_subsection_refs(
) -> List[SubsectionRef]: ) -> List[SubsectionRef]:
if not subsection_refs: if not subsection_refs:
return [] return []
normalized = {(int(sec), int(sub)) for sec, sub in subsection_refs} normalized = {
(int(chap), int(sec), int(sub)) for chap, sec, sub in subsection_refs
}
return sorted(normalized) return sorted(normalized)
...@@ -566,8 +568,9 @@ def load_children_for_subsections( ...@@ -566,8 +568,9 @@ def load_children_for_subsections(
if not refs: if not refs:
return [] return []
sec_arr = [sec for sec, _ in refs] chap_arr = [chap for chap, _, _ in refs]
sub_arr = [sub for _, sub in refs] sec_arr = [sec for _, sec, _ in refs]
sub_arr = [sub for _, _, sub in refs]
sql = """ sql = """
SELECT SELECT
d.uid, d.doc_type, d.uid, d.doc_type,
...@@ -576,14 +579,21 @@ def load_children_for_subsections( ...@@ -576,14 +579,21 @@ def load_children_for_subsections(
d.path, d.markdown, d.path, d.markdown,
1.0 AS score 1.0 AS score
FROM docs d FROM docs d
JOIN unnest(%(sec_arr)s::int[], %(sub_arr)s::int[]) AS u(sec, sub) JOIN unnest(%(chap_arr)s::int[], %(sec_arr)s::int[], %(sub_arr)s::int[]) AS u(chap, sec, sub)
ON d.section_index = u.sec AND d.subsection_index = u.sub ON d.chapter_index = u.chap AND d.section_index = u.sec AND d.subsection_index = u.sub
WHERE d.doc_type = 'child' WHERE d.doc_type = 'child'
ORDER BY d.section_index, d.subsection_index, d.child_index ORDER BY d.chapter_index, d.section_index, d.subsection_index, d.child_index
""" """
with psycopg.connect(pg_url, row_factory=dict_row) as conn: with psycopg.connect(pg_url, row_factory=dict_row) as conn:
with conn.cursor() as cur: with conn.cursor() as cur:
cur.execute(sql, {"sec_arr": sec_arr, "sub_arr": sub_arr}) cur.execute(
sql,
{
"chap_arr": chap_arr,
"sec_arr": sec_arr,
"sub_arr": sub_arr,
},
)
rows = cur.fetchall() rows = cur.fetchall()
children = [_row_to_retrieved(row) for row in rows] children = [_row_to_retrieved(row) for row in rows]
...@@ -619,6 +629,7 @@ def retrieve_with_subsections( ...@@ -619,6 +629,7 @@ def retrieve_with_subsections(
query: str, query: str,
subsection_refs: Optional[List[SubsectionRef]] = None, subsection_refs: Optional[List[SubsectionRef]] = None,
k: int = 4, k: int = 4,
chapter_index: Optional[int] = None,
section_index: Optional[int] = None, section_index: Optional[int] = None,
subsection_index: Optional[int] = None, subsection_index: Optional[int] = None,
source_type_filter: Optional[List[str]] = None, source_type_filter: Optional[List[str]] = None,
...@@ -633,6 +644,7 @@ def retrieve_with_subsections( ...@@ -633,6 +644,7 @@ def retrieve_with_subsections(
embedder=embedder, embedder=embedder,
query=query, query=query,
k=vector_k, k=vector_k,
chapter_index=chapter_index,
section_index=section_index, section_index=section_index,
subsection_index=subsection_index, subsection_index=subsection_index,
source_type_filter=source_type_filter, source_type_filter=source_type_filter,
......
...@@ -24,6 +24,7 @@ def retrieve( ...@@ -24,6 +24,7 @@ def retrieve(
embedder: EmbeddingLike, embedder: EmbeddingLike,
query: str, query: str,
k: int = 4, k: int = 4,
chapter_index: Optional[int] = None,
section_index: Optional[int] = None, section_index: Optional[int] = None,
subsection_index: Optional[int] = None, subsection_index: Optional[int] = None,
source_type_filter: Optional[List[str]] = None, source_type_filter: Optional[List[str]] = None,
...@@ -43,6 +44,10 @@ def retrieve( ...@@ -43,6 +44,10 @@ def retrieve(
"sub_doc_types": ["subsection", "chapter"], "sub_doc_types": ["subsection", "chapter"],
} }
if chapter_index is not None:
where.append("chapter_index = %(chapter_index)s")
params["chapter_index"] = chapter_index
if section_index is not None: if section_index is not None:
where.append("section_index = %(section_index)s") where.append("section_index = %(section_index)s")
params["section_index"] = section_index params["section_index"] = section_index
...@@ -86,6 +91,7 @@ def retrieve_with_subsections( ...@@ -86,6 +91,7 @@ def retrieve_with_subsections(
query: str, query: str,
subsection_refs: Optional[List[SubsectionRef]] = None, subsection_refs: Optional[List[SubsectionRef]] = None,
k: int = 4, k: int = 4,
chapter_index: Optional[int] = None,
section_index: Optional[int] = None, section_index: Optional[int] = None,
subsection_index: Optional[int] = None, subsection_index: Optional[int] = None,
source_type_filter: Optional[List[str]] = None, source_type_filter: Optional[List[str]] = None,
...@@ -98,6 +104,7 @@ def retrieve_with_subsections( ...@@ -98,6 +104,7 @@ def retrieve_with_subsections(
embedder=embedder, embedder=embedder,
query=query, query=query,
k=vector_k, k=vector_k,
chapter_index=chapter_index,
section_index=section_index, section_index=section_index,
subsection_index=subsection_index, subsection_index=subsection_index,
source_type_filter=source_type_filter, source_type_filter=source_type_filter,
......
...@@ -7,27 +7,38 @@ from app.deterministic_services import retrieval_store ...@@ -7,27 +7,38 @@ from app.deterministic_services import retrieval_store
def _parse_subsections( def _parse_subsections(
raw_values: list[str] | None, raw_values: list[str] | None,
chapter_index: int | None,
section_index: int | None, section_index: int | None,
) -> list[tuple[int, int]]: ) -> list[tuple[int, int, int]]:
if not raw_values: if not raw_values:
return [] return []
refs: set[tuple[int, int]] = set() refs: set[tuple[int, int, int]] = set()
for raw in raw_values: for raw in raw_values:
token = str(raw).strip() token = str(raw).strip()
if not token: if not token:
continue continue
if ":" in token: parts = token.split(":")
sec_raw, sub_raw = token.split(":", 1) if len(parts) == 3:
refs.add((int(sec_raw), int(sub_raw))) chap_raw, sec_raw, sub_raw = parts
refs.add((int(chap_raw), int(sec_raw), int(sub_raw)))
continue continue
if section_index is None: if len(parts) == 2:
if chapter_index is None:
raise ValueError( raise ValueError(
"Subsection ohne Section ist ungueltig. Nutze '<sec>:<sub>' oder --section-index." "Subsection ohne Chapter ist ungueltig. Nutze '<chap>:<sec>:<sub>' oder --chapter-index."
) )
refs.add((int(section_index), int(token))) sec_raw, sub_raw = parts
refs.add((int(chapter_index), int(sec_raw), int(sub_raw)))
continue
if section_index is None or chapter_index is None:
raise ValueError(
"Subsection ohne Chapter/Section ist ungueltig. Nutze '<chap>:<sec>:<sub>' oder --chapter-index und --section-index."
)
refs.add((int(chapter_index), int(section_index), int(token)))
return sorted(refs) return sorted(refs)
...@@ -40,13 +51,14 @@ def main() -> None: ...@@ -40,13 +51,14 @@ def main() -> None:
help="Postgres URL (oder set POSTGRES_URL)") help="Postgres URL (oder set POSTGRES_URL)")
parser.add_argument("--k", type=int, default=8) parser.add_argument("--k", type=int, default=8)
parser.add_argument("--expand", action="store_true") parser.add_argument("--expand", action="store_true")
parser.add_argument("--chapter-index", type=int, default=None)
parser.add_argument("--section-index", type=int, default=None) parser.add_argument("--section-index", type=int, default=None)
parser.add_argument("--subsection-index", type=int, default=None) parser.add_argument("--subsection-index", type=int, default=None)
parser.add_argument( parser.add_argument(
"--subsections", "--subsections",
nargs="*", nargs="*",
default=None, default=None,
help="Liste von Subsections: '<sec>:<sub>' oder '<sub>' zusammen mit --section-index", help="Liste von Subsections: '<chap>:<sec>:<sub>'; alternativ '<sec>:<sub>' mit --chapter-index oder '<sub>' mit --chapter-index und --section-index",
) )
parser.add_argument("--source-type-filter", nargs="*", default=None) parser.add_argument("--source-type-filter", nargs="*", default=None)
parser.add_argument("--neighbor-expand", type=int, default=0) parser.add_argument("--neighbor-expand", type=int, default=0)
...@@ -56,7 +68,9 @@ def main() -> None: ...@@ -56,7 +68,9 @@ def main() -> None:
pg_url = args.pg or config.get_postgres_url() pg_url = args.pg or config.get_postgres_url()
embedder = EmbeddingFactory.create(config.get_embedding_settings()) embedder = EmbeddingFactory.create(config.get_embedding_settings())
subsection_refs = _parse_subsections(args.subsections, args.section_index) subsection_refs = _parse_subsections(
args.subsections, args.chapter_index, args.section_index
)
if subsection_refs: if subsection_refs:
sources = retrieval_store.retrieve_with_subsections( sources = retrieval_store.retrieve_with_subsections(
pg_url=pg_url, pg_url=pg_url,
...@@ -65,6 +79,7 @@ def main() -> None: ...@@ -65,6 +79,7 @@ def main() -> None:
subsection_refs=subsection_refs, subsection_refs=subsection_refs,
k=args.k, k=args.k,
expand_links=args.expand, expand_links=args.expand,
chapter_index=args.chapter_index,
section_index=args.section_index, section_index=args.section_index,
subsection_index=args.subsection_index, subsection_index=args.subsection_index,
source_type_filter=args.source_type_filter, source_type_filter=args.source_type_filter,
...@@ -77,6 +92,7 @@ def main() -> None: ...@@ -77,6 +92,7 @@ def main() -> None:
query=args.query, query=args.query,
k=args.k, k=args.k,
expand_links=args.expand, expand_links=args.expand,
chapter_index=args.chapter_index,
section_index=args.section_index, section_index=args.section_index,
subsection_index=args.subsection_index, subsection_index=args.subsection_index,
source_type_filter=args.source_type_filter, source_type_filter=args.source_type_filter,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment