generated from coulomb/repo-seed
configuration support for optional LLM extraction
This commit is contained in:
@@ -127,6 +127,9 @@ When an extractor is present and returns candidates, analysis stores those
|
|||||||
reviewable candidates; when it returns no candidates, the deterministic
|
reviewable candidates; when it returns no candidates, the deterministic
|
||||||
heuristic generator remains the fallback.
|
heuristic generator remains the fallback.
|
||||||
|
|
||||||
|
The FastAPI settings object also accepts `llm_provider` and `llm_model`. By
|
||||||
|
default `llm_provider` is unset, so analysis is fully offline and deterministic.
|
||||||
|
|
||||||
## Agent-Facing Endpoints
|
## Agent-Facing Endpoints
|
||||||
|
|
||||||
The v0.1 API covers the main registration, analysis, review, search, and inspection loop:
|
The v0.1 API covers the main registration, analysis, review, search, and inspection loop:
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from fastapi import Depends, FastAPI, HTTPException
|
|||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from repo_registry.core.service import RegistryService
|
from repo_registry.core.service import RegistryService
|
||||||
|
from repo_registry.llm_extraction import LLMCandidateExtractor, create_llm_connect_adapter
|
||||||
from repo_registry.repo_ingestion.git import GitIngestionService
|
from repo_registry.repo_ingestion.git import GitIngestionService
|
||||||
from repo_registry.storage.sqlite import NotFoundError, RegistryStore
|
from repo_registry.storage.sqlite import NotFoundError, RegistryStore
|
||||||
|
|
||||||
@@ -14,6 +15,8 @@ from repo_registry.storage.sqlite import NotFoundError, RegistryStore
|
|||||||
class Settings(BaseModel):
|
class Settings(BaseModel):
|
||||||
database_path: str = Field(default="var/repo-registry.sqlite3")
|
database_path: str = Field(default="var/repo-registry.sqlite3")
|
||||||
checkout_root: str = Field(default="var/checkouts")
|
checkout_root: str = Field(default="var/checkouts")
|
||||||
|
llm_provider: str | None = Field(default=None)
|
||||||
|
llm_model: str | None = Field(default=None)
|
||||||
|
|
||||||
|
|
||||||
def get_settings() -> Settings:
|
def get_settings() -> Settings:
|
||||||
@@ -25,7 +28,18 @@ def get_service(settings: Settings = Depends(get_settings)) -> RegistryService:
|
|||||||
database_path.parent.mkdir(parents=True, exist_ok=True)
|
database_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
store = RegistryStore(database_path)
|
store = RegistryStore(database_path)
|
||||||
store.initialize()
|
store.initialize()
|
||||||
return RegistryService(store, ingestion=GitIngestionService(settings.checkout_root))
|
llm_extractor = None
|
||||||
|
if settings.llm_provider:
|
||||||
|
adapter = create_llm_connect_adapter(
|
||||||
|
settings.llm_provider,
|
||||||
|
model=settings.llm_model,
|
||||||
|
)
|
||||||
|
llm_extractor = LLMCandidateExtractor(adapter)
|
||||||
|
return RegistryService(
|
||||||
|
store,
|
||||||
|
ingestion=GitIngestionService(settings.checkout_root),
|
||||||
|
llm_extractor=llm_extractor,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class RepositoryCreate(BaseModel):
|
class RepositoryCreate(BaseModel):
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
from repo_registry.web_api.app import Settings, app, get_settings
|
from repo_registry.web_api import app as app_module
|
||||||
|
from repo_registry.web_api.app import Settings, app, get_service, get_settings
|
||||||
|
|
||||||
|
|
||||||
def test_api_manual_registry_loop(tmp_path):
|
def test_api_manual_registry_loop(tmp_path):
|
||||||
@@ -164,6 +165,34 @@ def test_api_registers_repository_from_url_metadata(tmp_path):
|
|||||||
app.dependency_overrides.clear()
|
app.dependency_overrides.clear()
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_service_settings_can_enable_llm_extractor(monkeypatch, tmp_path):
|
||||||
|
class Response:
|
||||||
|
content = '{"abilities": [{"name": "Configured LLM Ability"}]}'
|
||||||
|
|
||||||
|
class Adapter:
|
||||||
|
def execute_prompt(self, prompt, config):
|
||||||
|
return Response()
|
||||||
|
|
||||||
|
calls = []
|
||||||
|
|
||||||
|
def fake_create_adapter(provider, model=None):
|
||||||
|
calls.append((provider, model))
|
||||||
|
return Adapter()
|
||||||
|
|
||||||
|
monkeypatch.setattr(app_module, "create_llm_connect_adapter", fake_create_adapter)
|
||||||
|
service = get_service(
|
||||||
|
Settings(
|
||||||
|
database_path=str(tmp_path / "llm-settings.sqlite3"),
|
||||||
|
checkout_root=str(tmp_path / "checkouts"),
|
||||||
|
llm_provider="mock",
|
||||||
|
llm_model="demo-model",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assert calls == [("mock", "demo-model")]
|
||||||
|
assert service.llm_extractor is not None
|
||||||
|
|
||||||
|
|
||||||
def test_api_analysis_run_loop(tmp_path):
|
def test_api_analysis_run_loop(tmp_path):
|
||||||
source = tmp_path / "repo"
|
source = tmp_path / "repo"
|
||||||
source.mkdir()
|
source.mkdir()
|
||||||
|
|||||||
Reference in New Issue
Block a user