Skip to content

Commit ddc595a

Browse files
committed
copilot changes again
1 parent 5a176fc commit ddc595a

5 files changed

Lines changed: 41 additions & 14 deletions

File tree

src/ai_agent/agent/tools/repo_info_tool.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,17 @@ async def tool_repo_summary(input: RepoSummaryInput) -> RepoSummaryOutput:
121121
shared = await inflight
122122
return shared.model_copy(deep=True)
123123

124-
result = await _fetch_repo_summary(effective_url)
124+
try:
125+
result = await _fetch_repo_summary(effective_url)
126+
except BaseException as exc:
127+
await _REPO_INFO_LOCK.acquire()
128+
try:
129+
if not inflight.done():
130+
inflight.set_exception(exc)
131+
_REPO_INFO_INFLIGHT.pop(cache_key, None)
132+
finally:
133+
_REPO_INFO_LOCK.release()
134+
raise
125135

126136
await _REPO_INFO_LOCK.acquire()
127137
try:

src/ai_agent/agent/tools/search_alternative_tool.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from pydantic import BaseModel, Field
55

66
from ai_agent.generator.schema import CandidateDoc
7-
from .utils import get_catalog_docs, get_known_names, get_pipeline
7+
from .utils import get_known_names, get_pipeline
88
from .query_utils import append_format_tokens, normalize_formats, sanitize_retrieval_query
99

1010

src/ai_agent/agent/tools/search_tool.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from pydantic import BaseModel, Field
55

66
from ai_agent.generator.schema import CandidateDoc
7-
from .utils import get_catalog_docs, get_known_names, get_pipeline
7+
from .utils import get_known_names, get_pipeline
88
from .query_utils import (
99
append_format_tokens,
1010
normalize_formats,

src/ai_agent/catalog/sync.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import logging
1313

1414
from ai_agent.utils.full_processing import full_processing
15+
from ai_agent.utils.config import get_retrieval_config
1516

1617
import hashlib
1718
from ai_agent.retriever.software_doc import SoftwareDoc
@@ -21,6 +22,20 @@
2122
log = logging.getLogger("ai_agent.catalog.sync")
2223

2324

25+
def _build_embedder() -> LocalBGEEmbedder:
26+
"""Build a LocalBGEEmbedder from the current retrieval config."""
27+
retrieval_cfg = get_retrieval_config()
28+
embed_cfg = retrieval_cfg.get("embedder", {}) if isinstance(retrieval_cfg, dict) else {}
29+
return LocalBGEEmbedder(
30+
model_name=embed_cfg.get("model_name", "Qwen/Qwen3-Embedding-8B"),
31+
device=embed_cfg.get("device"),
32+
backend=embed_cfg.get("backend", "remote"),
33+
base_url=embed_cfg.get("base_url", "https://inference-rcp.epfl.ch/v1"),
34+
api_key_env=embed_cfg.get("api_key_env", "EPFL_API_KEY_EMBEDDER"),
35+
timeout_s=float(embed_cfg.get("timeout_s", 20.0)),
36+
)
37+
38+
2439
def _index_artifacts_present(index_dir: Path) -> bool:
2540
"""Return True when minimal FAISS artifacts exist."""
2641
return (index_dir / "index.faiss").exists() and (index_dir / "meta.json").exists()
@@ -398,7 +413,7 @@ def sync_once(
398413
faiss_rebuilt = False
399414
faiss_delta: Dict[str, int] = {"added": 0, "updated": 0, "removed": 0}
400415
try:
401-
embedder = LocalBGEEmbedder()
416+
embedder = _build_embedder()
402417
VectorIndex.load(index_dir, embedder)
403418
log.info(
404419
"Catalog unchanged (semantic sha1=%s); keeping FAISS index", digest[:12]
@@ -408,7 +423,7 @@ def sync_once(
408423
"Catalog unchanged but FAISS index is missing/incompatible; rebuilding index (%s)",
409424
e,
410425
)
411-
embedder = LocalBGEEmbedder()
426+
embedder = _build_embedder()
412427
idx = VectorIndex(embedder)
413428
items = [
414429
IndexItem(id=d.name, doc=d) for d in docs if getattr(d, "name", None)
@@ -461,7 +476,7 @@ def sync_once(
461476
log.info(" changed (sample): %s", chg_s)
462477
log.info("Full diff written to %s", diff_path)
463478

464-
embedder = LocalBGEEmbedder()
479+
embedder = _build_embedder()
465480
try:
466481
idx = VectorIndex.load(index_dir, embedder)
467482
except Exception as e:

src/ai_agent/utils/image_meta.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# utils/image_meta.py
22
from __future__ import annotations
3+
from collections import OrderedDict
34
from pathlib import Path
45
from typing import Optional, List
56
import threading
@@ -15,8 +16,7 @@
1516
# Avoids re-reading large files (e.g. TIFF stacks) on every retrieval call.
1617
# ---------------------------------------------------------------------------
1718
_META_CACHE_MAX = int(os.getenv("IMAGE_META_CACHE_MAX", "128"))
18-
_meta_cache: dict[tuple, str] = {} # key -> result string
19-
_meta_cache_order: list[tuple] = [] # insertion-order for simple LRU eviction
19+
_meta_cache: OrderedDict[tuple, str] = OrderedDict() # key -> result string (LRU order)
2020
_meta_cache_lock = threading.Lock()
2121

2222

@@ -31,19 +31,21 @@ def _meta_cache_key(p: Path) -> tuple:
3131

3232
def _meta_cache_get(key: tuple) -> Optional[str]:
3333
with _meta_cache_lock:
34-
return _meta_cache.get(key)
34+
value = _meta_cache.get(key)
35+
if value is not None:
36+
_meta_cache.move_to_end(key)
37+
return value
3538

3639

3740
def _meta_cache_set(key: tuple, value: str) -> None:
3841
with _meta_cache_lock:
3942
if key in _meta_cache:
43+
_meta_cache.move_to_end(key)
4044
return
4145
_meta_cache[key] = value
42-
_meta_cache_order.append(key)
43-
# Evict oldest entries when over capacity
44-
while len(_meta_cache_order) > _META_CACHE_MAX:
45-
oldest = _meta_cache_order.pop(0)
46-
_meta_cache.pop(oldest, None)
46+
# Evict least-recently-used entries when over capacity
47+
while len(_meta_cache) > _META_CACHE_MAX:
48+
_meta_cache.popitem(last=False)
4749

4850
# ---- small helpers -----------------------------------------------------------
4951

0 commit comments

Comments
 (0)