Coevolution extension

This commit is contained in:
2026-04-29 01:19:59 +02:00
parent 88afdc09fd
commit 991c34ce52
17 changed files with 764 additions and 4 deletions

View File

@@ -69,6 +69,23 @@ MANIFEST_FRAMEWORK_HINTS = {
},
}
LLM_PROVIDER_HINTS = {
"openrouter": "OpenRouter",
"anthropic": "Anthropic",
"claude": "Claude",
"openai": "OpenAI",
"gemini": "Gemini",
"google-generativeai": "Gemini",
}
LLM_CREDENTIAL_HINTS = {
"OPENROUTER_API_KEY": "OpenRouter API key",
"ANTHROPIC_API_KEY": "Anthropic API key",
"OPENAI_API_KEY": "OpenAI API key",
"GEMINI_API_KEY": "Gemini API key",
"GOOGLE_API_KEY": "Google API key",
}
@dataclass(frozen=True)
class FactCandidate:
@@ -102,6 +119,7 @@ class DeterministicScanner:
facts.extend(self._classified_file_facts(files, root))
facts.extend(self._framework_facts(files, root))
facts.extend(self._interface_facts(files, root))
facts.extend(self._llm_provider_facts(files, root))
return ScanResult(
source_path=str(root),
@@ -223,6 +241,96 @@ class DeterministicScanner:
facts.append(FactCandidate("interface", "possible API surface", relative))
return facts
def _llm_provider_facts(self, files: list[Path], root: Path) -> list[FactCandidate]:
facts: list[FactCandidate] = []
seen: set[tuple[str, str, str]] = set()
for path in files:
if path.suffix.lower() not in {
".py",
".ts",
".js",
".json",
".toml",
".yaml",
".yml",
".md",
".txt",
".env",
} and not path.name.lower().startswith(".env"):
continue
try:
text = path.read_text(encoding="utf-8", errors="ignore")
except OSError:
continue
lower_text = text.lower()
relative = path.relative_to(root).as_posix()
for needle, provider in LLM_PROVIDER_HINTS.items():
if needle not in lower_text:
continue
self._append_once(
facts,
seen,
FactCandidate(
kind="llm_provider",
name=provider,
path=relative,
value=needle,
metadata={"source": "provider_hint"},
),
)
for env_name, label in LLM_CREDENTIAL_HINTS.items():
if env_name.lower() not in lower_text:
continue
self._append_once(
facts,
seen,
FactCandidate(
kind="credential_config",
name=label,
path=relative,
value=env_name,
metadata={"source": "environment_variable"},
),
)
if any(term in lower_text for term in ("provider_registry", "providers =", "adapter")):
if any(needle in lower_text for needle in LLM_PROVIDER_HINTS):
self._append_once(
facts,
seen,
FactCandidate(
kind="provider_registry",
name="LLM provider registry",
path=relative,
metadata={"source": "provider_registry_hint"},
),
)
if "fallback" in lower_text and any(
needle in lower_text for needle in LLM_PROVIDER_HINTS
):
self._append_once(
facts,
seen,
FactCandidate(
kind="fallback_policy",
name="LLM provider fallback policy",
path=relative,
metadata={"source": "fallback_hint"},
),
)
return facts
def _append_once(
self,
facts: list[FactCandidate],
seen: set[tuple[str, str, str]],
fact: FactCandidate,
) -> None:
key = (fact.kind, fact.name, fact.path)
if key in seen:
return
seen.add(key)
facts.append(fact)
def _python_interface_facts(self, path: Path, relative: str) -> list[FactCandidate]:
facts: list[FactCandidate] = []
try: