generated from coulomb/repo-seed
additive candidate confidence scoring
This commit is contained in:
@@ -68,7 +68,14 @@ class CandidateGraphGenerator:
|
|||||||
ability = CandidateAbilityDraft(
|
ability = CandidateAbilityDraft(
|
||||||
name=f"Review {repository.name} Repository Usefulness",
|
name=f"Review {repository.name} Repository Usefulness",
|
||||||
description=self._ability_description(chunks),
|
description=self._ability_description(chunks),
|
||||||
confidence=0.55 if docs else 0.35,
|
confidence=self._ability_confidence(
|
||||||
|
docs=docs,
|
||||||
|
interfaces=interfaces,
|
||||||
|
tests=tests,
|
||||||
|
examples=examples,
|
||||||
|
frameworks=frameworks,
|
||||||
|
languages=languages,
|
||||||
|
),
|
||||||
source_refs=self._source_refs(ability_sources),
|
source_refs=self._source_refs(ability_sources),
|
||||||
capabilities=[],
|
capabilities=[],
|
||||||
)
|
)
|
||||||
@@ -88,7 +95,12 @@ class CandidateGraphGenerator:
|
|||||||
),
|
),
|
||||||
inputs=[],
|
inputs=[],
|
||||||
outputs=["repository structure summary"],
|
outputs=["repository structure summary"],
|
||||||
confidence=0.6,
|
confidence=self._structure_confidence(
|
||||||
|
manifests=manifests,
|
||||||
|
frameworks=frameworks,
|
||||||
|
languages=languages,
|
||||||
|
docs=docs,
|
||||||
|
),
|
||||||
source_refs=self._source_refs(manifests + frameworks + languages),
|
source_refs=self._source_refs(manifests + frameworks + languages),
|
||||||
evidence=self._evidence(tests, examples, docs),
|
evidence=self._evidence(tests, examples, docs),
|
||||||
)
|
)
|
||||||
@@ -127,7 +139,12 @@ class CandidateGraphGenerator:
|
|||||||
description=self._interface_description(chunks),
|
description=self._interface_description(chunks),
|
||||||
inputs=[],
|
inputs=[],
|
||||||
outputs=["callable interface"],
|
outputs=["callable interface"],
|
||||||
confidence=0.65,
|
confidence=self._interface_confidence(
|
||||||
|
interfaces=interfaces,
|
||||||
|
tests=tests,
|
||||||
|
examples=examples,
|
||||||
|
docs=docs,
|
||||||
|
),
|
||||||
source_refs=self._source_refs(interfaces),
|
source_refs=self._source_refs(interfaces),
|
||||||
features=features,
|
features=features,
|
||||||
evidence=self._evidence(tests, examples, docs),
|
evidence=self._evidence(tests, examples, docs),
|
||||||
@@ -177,6 +194,73 @@ class CandidateGraphGenerator:
|
|||||||
return "API"
|
return "API"
|
||||||
return "interface"
|
return "interface"
|
||||||
|
|
||||||
|
def _ability_confidence(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
docs: list[ObservedFact],
|
||||||
|
interfaces: list[ObservedFact],
|
||||||
|
tests: list[ObservedFact],
|
||||||
|
examples: list[ObservedFact],
|
||||||
|
frameworks: list[ObservedFact],
|
||||||
|
languages: list[ObservedFact],
|
||||||
|
) -> float:
|
||||||
|
return self._confidence(
|
||||||
|
0.25,
|
||||||
|
[
|
||||||
|
(0.20, bool(docs)),
|
||||||
|
(0.15, bool(interfaces)),
|
||||||
|
(0.15, bool(tests)),
|
||||||
|
(0.10, bool(examples)),
|
||||||
|
(0.10, bool(frameworks)),
|
||||||
|
(0.05, bool(languages)),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
def _interface_confidence(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
interfaces: list[ObservedFact],
|
||||||
|
tests: list[ObservedFact],
|
||||||
|
examples: list[ObservedFact],
|
||||||
|
docs: list[ObservedFact],
|
||||||
|
) -> float:
|
||||||
|
return self._confidence(
|
||||||
|
0.30,
|
||||||
|
[
|
||||||
|
(0.20, bool(interfaces)),
|
||||||
|
(0.15, bool(tests)),
|
||||||
|
(0.10, bool(examples)),
|
||||||
|
(0.10, bool(docs)),
|
||||||
|
(0.05, len(interfaces) > 1),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
def _structure_confidence(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
manifests: list[ObservedFact],
|
||||||
|
frameworks: list[ObservedFact],
|
||||||
|
languages: list[ObservedFact],
|
||||||
|
docs: list[ObservedFact],
|
||||||
|
) -> float:
|
||||||
|
return self._confidence(
|
||||||
|
0.25,
|
||||||
|
[
|
||||||
|
(0.20, bool(manifests)),
|
||||||
|
(0.15, bool(frameworks)),
|
||||||
|
(0.10, bool(languages)),
|
||||||
|
(0.05, bool(docs)),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
def _confidence(
|
||||||
|
self,
|
||||||
|
base: float,
|
||||||
|
factors: list[tuple[float, bool]],
|
||||||
|
) -> float:
|
||||||
|
score = base + sum(weight for weight, applies in factors if applies)
|
||||||
|
return min(1.0, round(score, 2))
|
||||||
|
|
||||||
def _ability_description(self, chunks: list[ContentChunk]) -> str:
|
def _ability_description(self, chunks: list[ContentChunk]) -> str:
|
||||||
doc_summary = self._document_summary(chunks)
|
doc_summary = self._document_summary(chunks)
|
||||||
if doc_summary:
|
if doc_summary:
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ def test_candidate_generator_builds_review_seed_from_observed_facts():
|
|||||||
assert ability.source_refs[0].path == "README.md"
|
assert ability.source_refs[0].path == "README.md"
|
||||||
interface_capability = ability.capabilities[0]
|
interface_capability = ability.capabilities[0]
|
||||||
assert interface_capability.name == "Expose Repository Interface"
|
assert interface_capability.name == "Expose Repository Interface"
|
||||||
|
assert interface_capability.confidence == 0.75
|
||||||
assert interface_capability.features[0].type == "API"
|
assert interface_capability.features[0].type == "API"
|
||||||
assert interface_capability.features[0].location == "app.py"
|
assert interface_capability.features[0].location == "app.py"
|
||||||
assert interface_capability.evidence[0].strength == "strong"
|
assert interface_capability.evidence[0].strength == "strong"
|
||||||
@@ -94,3 +95,48 @@ def test_candidate_generator_enriches_descriptions_from_content_chunks():
|
|||||||
|
|
||||||
assert "MailRouter. Routes incoming customer email" in graph[0].description
|
assert "MailRouter. Routes incoming customer email" in graph[0].description
|
||||||
assert '@app.post("/classify")' in graph[0].capabilities[0].description
|
assert '@app.post("/classify")' in graph[0].capabilities[0].description
|
||||||
|
|
||||||
|
|
||||||
|
def test_candidate_confidence_scoring_stays_conservative_for_weak_facts():
|
||||||
|
repository = Repository(
|
||||||
|
id=1,
|
||||||
|
name="WeakDocs",
|
||||||
|
url="/tmp/weak-docs",
|
||||||
|
description=None,
|
||||||
|
branch="main",
|
||||||
|
status="analyzed",
|
||||||
|
)
|
||||||
|
|
||||||
|
graph = CandidateGraphGenerator().generate(
|
||||||
|
repository,
|
||||||
|
[fact(1, "documentation", "README", "README.md")],
|
||||||
|
)
|
||||||
|
|
||||||
|
assert graph[0].confidence == 0.45
|
||||||
|
assert graph[0].capabilities == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_candidate_confidence_scoring_increases_with_supporting_facts():
|
||||||
|
repository = Repository(
|
||||||
|
id=1,
|
||||||
|
name="Supported",
|
||||||
|
url="/tmp/supported",
|
||||||
|
description=None,
|
||||||
|
branch="main",
|
||||||
|
status="analyzed",
|
||||||
|
)
|
||||||
|
facts = [
|
||||||
|
fact(1, "documentation", "README", "README.md"),
|
||||||
|
fact(2, "interface", "python route decorator", "app.py", '@app.get("/health")'),
|
||||||
|
fact(3, "test", "test_app.py", "tests/test_app.py"),
|
||||||
|
fact(4, "example", "client.py", "examples/client.py"),
|
||||||
|
fact(5, "framework", "FastAPI", "requirements.txt"),
|
||||||
|
fact(6, "language", "Python"),
|
||||||
|
fact(7, "manifest", "requirements.txt", "requirements.txt"),
|
||||||
|
]
|
||||||
|
|
||||||
|
graph = CandidateGraphGenerator().generate(repository, facts)
|
||||||
|
|
||||||
|
assert graph[0].confidence == 1.0
|
||||||
|
assert graph[0].capabilities[0].confidence == 0.85
|
||||||
|
assert graph[0].capabilities[1].confidence == 0.75
|
||||||
|
|||||||
Reference in New Issue
Block a user