Skip to content

Commit 35aef89

Browse files
authored
Merge pull request #212 from pfahlr/codex/resolve-merge-and-cli-issues
Fix multi-agent harness invocation and docs
2 parents f1801f9 + a90375f commit 35aef89

4 files changed

Lines changed: 45 additions & 48 deletions

File tree

docs/verification.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
the existing CLI scripts (`lc_build_index.py`, `lc_ask.py`, optional
55
`multi_agent.py`) against a gold corpus and a set of reference questions. The
66
script never imports those tools directly; instead it shells out to the CLIs so
7-
that the exact same entry points used in production are exercised.
7+
that the exact same entry points used in production are exercised. Multi-agent
8+
runs are dispatched via `python -m src.cli.multi_agent ...` so package-relative
9+
imports resolve consistently for Typer-based entry points.
810

911
## Questions file schema
1012

run_rag_verification.py

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -589,9 +589,11 @@ def script_base_command(script: Path) -> list[str]:
589589

590590
return [sys.executable, str(script)]
591591

592+
592593
def _advertised_flags(help_text: str) -> set[str]:
593594
return {match.group(1) for match in _FLAG_PATTERN.finditer(help_text)}
594595

596+
595597
@lru_cache(maxsize=None)
596598
def script_help_text(script: Path) -> str:
597599
try:
@@ -613,10 +615,15 @@ def determine_flag(script: Path, candidates: Sequence[str]) -> str | None:
613615
try:
614616
source = script.read_text(encoding="utf-8")
615617
except (OSError, UnicodeDecodeError):
616-
return None
618+
source = ""
619+
620+
for flag in candidates:
621+
if flag and flag in advertised:
622+
return flag
623+
617624
for flag in candidates:
618625
if flag and flag in source:
619-
return flag
626+
return flag
620627
return None
621628

622629

@@ -633,6 +640,20 @@ def _script_supports_flag(
633640
return None
634641

635642

643+
def script_supports_subcommand(script: Path, name: str) -> bool:
644+
"""Return True if the script advertises a Typer-style subcommand."""
645+
646+
help_text = script_help_text(script)
647+
if "Commands:" not in help_text:
648+
return False
649+
_, commands_section = help_text.split("Commands:", 1)
650+
for line in commands_section.splitlines():
651+
command_name = line.strip().split(" ", 1)[0] if line.strip() else ""
652+
if command_name == name:
653+
return True
654+
return False
655+
656+
636657
def build_question_command(
637658
script: Path, prompt: str, base_args: List[str]
638659
) -> List[str]:
@@ -641,7 +662,6 @@ def build_question_command(
641662
If the script advertises a question flag, use it; otherwise pass the prompt positionally.
642663
"""
643664

644-
645665
argv: List[str] = [*script_base_command(script), *base_args]
646666
flag = _script_supports_flag(script, ["--question", "-q"])
647667

@@ -651,28 +671,6 @@ def build_question_command(
651671
argv.append(prompt)
652672
return argv
653673

654-
655-
def build_builder_command(
656-
*,
657-
builder: Path,
658-
index_key: str,
659-
pdf_dir: Path,
660-
chunks_dir: Path,
661-
index_dir: Path,
662-
) -> list[str]:
663-
"""Construct the lc_build_index command for the verification run."""
664-
665-
return [
666-
*script_base_command(builder),
667-
index_key,
668-
"--input-dir",
669-
str(pdf_dir),
670-
"--chunks-dir",
671-
str(chunks_dir),
672-
"--index-dir",
673-
str(index_dir),
674-
]
675-
676674

677675
def build_builder_command(
678676
*,
@@ -883,14 +881,13 @@ def build_question_invocation(
883881
if script is None:
884882
raise RuntimeError("No asker script available")
885883
route = "multi" if use_multi else "asker"
886-
def _append_flag(script_path: Path, args: list[str], candidates: list[str], value: str) -> None:
884+
885+
def _append_flag(
886+
script_path: Path, args: list[str], candidates: list[str], value: str
887+
) -> None:
887888
flag = determine_flag(script_path, candidates)
888889
if not flag:
889-
# Typer-based CLIs such as multi_agent.py require running via ``-m`` to
890-
# expose subcommand help. When invoked as a script from the harness the
891-
# ``--help`` probe used by ``determine_flag`` fails, so fall back to the
892-
# primary candidate.
893-
flag = candidates[0]
890+
return
894891
args.extend([flag, value])
895892

896893
if not use_multi:
@@ -912,6 +909,9 @@ def _append_flag(script_path: Path, args: list[str], candidates: list[str], valu
912909
else:
913910
base_args: list[str] = []
914911

912+
if script_supports_subcommand(multi, "ask"):
913+
base_args.append("ask")
914+
915915
_append_flag(multi, base_args, ["--key", "-k"], index_key)
916916
_append_flag(multi, base_args, ["--index-dir", "--index"], str(index_dir))
917917

src/research/clients/docs/arxiv_api.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
<<<<<<< ours
21
# arXiv API Documentation
32

43
[See the entire API documentation site here](https://info.arxiv.org/help/api/user-manual.html)
@@ -219,14 +218,12 @@ print_r($response);
219218
* Use `id_list=cond-mat/0207270` for latest version
220219
* Use `id_list=cond-mat/0207270v1` for specific version
221220

222-
=======
223-
# ArXiv API
221+
## 🧩 Integration Notes
224222

225-
The metadata scanner uses the [ArXiv API](https://arxiv.org/help/api/user-manual) as a fallback
226-
when a DOI cannot be resolved via Crossref. The API is queried at
227-
`https://export.arxiv.org/api/query` with the `id_list` parameter set to the
228-
arXiv identifier extracted from a DOI like `10.48550/arXiv.XXXX`.
223+
The metadata scanner uses the [arXiv API](https://arxiv.org/help/api/user-manual) as a
224+
fallback when a DOI cannot be resolved via Crossref. The API is queried at
225+
`https://export.arxiv.org/api/query` with the `id_list` parameter set to the arXiv
226+
identifier extracted from a DOI such as `10.48550/arXiv.XXXX`.
229227

230-
The response is an Atom feed. The scanner parses the first entry to obtain
231-
fields such as title, authors, publication date, and DOI.
232-
>>>>>>> theirs
228+
Because the response is an Atom feed, the scanner parses the first `<entry>` element to
229+
obtain fields including title, authors, publication date, and DOI.

tests/unit/test_run_rag_verification.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
def test_prepare_pdf_corpus_creates_pdfs(tmp_path: Path) -> None:
2020
markdown_dir = tmp_path / "md"
2121
markdown_dir.mkdir()
22-
(markdown_dir / "sample.md").write_text("hello world\nsecond line", encoding="utf-8")
22+
(markdown_dir / "sample.md").write_text(
23+
"hello world\nsecond line", encoding="utf-8"
24+
)
2325

2426
output_dir = tmp_path / "pdf"
2527
pdf_paths = prepare_pdf_corpus(markdown_dir, output_dir)
@@ -50,9 +52,6 @@ def test_build_builder_command_targets_pdf_and_chunks(tmp_path: Path) -> None:
5052
index_dir=index_dir,
5153
)
5254

53-
54-
assert command[:2] == [sys.executable, str(builder)]
55-
5655
assert command[0] == sys.executable
5756
assert command[1:3] == ["-m", "src.langchain.lc_build_index"]
5857
assert "--input-dir" in command
@@ -171,7 +170,7 @@ def main() -> None:
171170
for forbidden in ("--key", "--index-dir", "--chunks-dir", "--embed-model"):
172171
assert forbidden not in command
173172

174-
173+
175174
def test_determine_flag_matches_full_option(tmp_path: Path) -> None:
176175
script = tmp_path / "cli.py"
177176
script.write_text(
@@ -196,4 +195,3 @@ def main() -> None:
196195
flag = determine_flag(script, ["--index", "--index-dir"])
197196

198197
assert flag == "--index-dir"
199-

0 commit comments

Comments
 (0)