AI Agent commited on
Commit Β·
3f6235f
1
Parent(s): e1c98c1
Fix nvidia_llm httpx connection leaks and improve crew.py retrieval logging
Browse files- agents/crew.py +9 -9
- agents/nvidia_llm.py +18 -14
agents/crew.py
CHANGED
|
@@ -185,7 +185,7 @@ def run_query_crew(query: str, top_k: int = None, max_tokens: int = None, use_ve
|
|
| 185 |
if status_callback:
|
| 186 |
status_callback("inference")
|
| 187 |
|
| 188 |
-
|
| 189 |
t0 = time.time()
|
| 190 |
|
| 191 |
# Import pipeline modules directly for fast retrieval (bypasses CrewAI overhead)
|
|
@@ -211,7 +211,7 @@ def run_query_crew(query: str, top_k: int = None, max_tokens: int = None, use_ve
|
|
| 211 |
r_chunks = vector_store.query_bm25(clean_name, top_k=top_k if top_k is not None else cfg.TOP_K_VECTOR, session_token=session_token)
|
| 212 |
graph_results.extend(r_chunks)
|
| 213 |
except Exception as e:
|
| 214 |
-
|
| 215 |
if status_callback:
|
| 216 |
status_callback({"status": "graph", "chunks": len(graph_results)})
|
| 217 |
|
|
@@ -228,7 +228,7 @@ def run_query_crew(query: str, top_k: int = None, max_tokens: int = None, use_ve
|
|
| 228 |
session_token=session_token,
|
| 229 |
)
|
| 230 |
except Exception as e:
|
| 231 |
-
|
| 232 |
if status_callback:
|
| 233 |
status_callback({"status": "vector", "chunks": len(vec_results)})
|
| 234 |
|
|
@@ -244,7 +244,7 @@ def run_query_crew(query: str, top_k: int = None, max_tokens: int = None, use_ve
|
|
| 244 |
session_token=session_token,
|
| 245 |
)
|
| 246 |
except Exception as e:
|
| 247 |
-
|
| 248 |
if status_callback:
|
| 249 |
status_callback({"status": "bm25", "chunks": len(bm25_results)})
|
| 250 |
|
|
@@ -258,8 +258,8 @@ def run_query_crew(query: str, top_k: int = None, max_tokens: int = None, use_ve
|
|
| 258 |
unique_chunks = list(all_chunks.values())
|
| 259 |
|
| 260 |
t_retrieval = time.time() - t0
|
| 261 |
-
|
| 262 |
-
|
| 263 |
f"{len(unique_chunks)} unique chunks retrieved from Vector DB, Graph DB, and BM25.")
|
| 264 |
|
| 265 |
# ββ Phase 2: Reranking Agent βββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -268,7 +268,7 @@ def run_query_crew(query: str, top_k: int = None, max_tokens: int = None, use_ve
|
|
| 268 |
|
| 269 |
retrieval_is_empty = len(unique_chunks) == 0
|
| 270 |
|
| 271 |
-
|
| 272 |
|
| 273 |
if retrieval_is_empty:
|
| 274 |
end_time = time.time()
|
|
@@ -300,9 +300,9 @@ def run_query_crew(query: str, top_k: int = None, max_tokens: int = None, use_ve
|
|
| 300 |
|
| 301 |
# Sort by score descending
|
| 302 |
unique_chunks.sort(key=lambda x: x.get("agent_score", -9999.0), reverse=True)
|
| 303 |
-
|
| 304 |
except Exception as e:
|
| 305 |
-
|
| 306 |
|
| 307 |
# Take Final Top 10
|
| 308 |
final_top_k = top_k if top_k is not None else cfg.TOP_K_VECTOR
|
|
|
|
| 185 |
if status_callback:
|
| 186 |
status_callback("inference")
|
| 187 |
|
| 188 |
+
log.info(f"[Retrieval Phase] Performing vector+graph search for: '{query}'")
|
| 189 |
t0 = time.time()
|
| 190 |
|
| 191 |
# Import pipeline modules directly for fast retrieval (bypasses CrewAI overhead)
|
|
|
|
| 211 |
r_chunks = vector_store.query_bm25(clean_name, top_k=top_k if top_k is not None else cfg.TOP_K_VECTOR, session_token=session_token)
|
| 212 |
graph_results.extend(r_chunks)
|
| 213 |
except Exception as e:
|
| 214 |
+
log.warning(f"[Retrieval] Graph search failed (non-fatal): {e}")
|
| 215 |
if status_callback:
|
| 216 |
status_callback({"status": "graph", "chunks": len(graph_results)})
|
| 217 |
|
|
|
|
| 228 |
session_token=session_token,
|
| 229 |
)
|
| 230 |
except Exception as e:
|
| 231 |
+
log.warning(f"[Retrieval] Vector dense search failed: {e}")
|
| 232 |
if status_callback:
|
| 233 |
status_callback({"status": "vector", "chunks": len(vec_results)})
|
| 234 |
|
|
|
|
| 244 |
session_token=session_token,
|
| 245 |
)
|
| 246 |
except Exception as e:
|
| 247 |
+
log.warning(f"[Retrieval] Vector BM25 search failed: {e}")
|
| 248 |
if status_callback:
|
| 249 |
status_callback({"status": "bm25", "chunks": len(bm25_results)})
|
| 250 |
|
|
|
|
| 258 |
unique_chunks = list(all_chunks.values())
|
| 259 |
|
| 260 |
t_retrieval = time.time() - t0
|
| 261 |
+
log.info(f"[Retrieval] Vector chunks: {len(vec_results)}, Graph chunks: {len(graph_results)}, BM25 chunks: {len(bm25_results)}")
|
| 262 |
+
log.info(f"[Retrieval Phase] Done in {t_retrieval:.2f}s β "
|
| 263 |
f"{len(unique_chunks)} unique chunks retrieved from Vector DB, Graph DB, and BM25.")
|
| 264 |
|
| 265 |
# ββ Phase 2: Reranking Agent βββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
| 268 |
|
| 269 |
retrieval_is_empty = len(unique_chunks) == 0
|
| 270 |
|
| 271 |
+
log.info(f"[Gatekeeper] empty={retrieval_is_empty}")
|
| 272 |
|
| 273 |
if retrieval_is_empty:
|
| 274 |
end_time = time.time()
|
|
|
|
| 300 |
|
| 301 |
# Sort by score descending
|
| 302 |
unique_chunks.sort(key=lambda x: x.get("agent_score", -9999.0), reverse=True)
|
| 303 |
+
log.info("[Reranking] Successfully reranked chunks using CrossEncoder.")
|
| 304 |
except Exception as e:
|
| 305 |
+
log.warning(f"[Reranking] CrossEncoder Failed: {e}. Proceeding without reranking.")
|
| 306 |
|
| 307 |
# Take Final Top 10
|
| 308 |
final_top_k = top_k if top_k is not None else cfg.TOP_K_VECTOR
|
agents/nvidia_llm.py
CHANGED
|
@@ -39,6 +39,14 @@ def after_request(response):
|
|
| 39 |
# ββ Inference Queue (multi-user serialization) βββββββββββββββββββββββββββββββββ
|
| 40 |
_inference_queue: _queue_module.Queue = _queue_module.Queue(maxsize=_QUEUE_MAX_SIZE)
|
| 41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
def _run_inference(data: dict) -> dict:
|
| 43 |
raw_prompt = data.get("prompt", "")
|
| 44 |
if not raw_prompt:
|
|
@@ -51,14 +59,6 @@ def _run_inference(data: dict) -> dict:
|
|
| 51 |
top_p = float(data.get("top_p", 1.0))
|
| 52 |
model_name = data.get("model", DEFAULT_MODEL)
|
| 53 |
|
| 54 |
-
if not NVIDIA_API_KEY:
|
| 55 |
-
log.warning("NVIDIA_API_KEY is not set. API calls might fail if the token is required.")
|
| 56 |
-
|
| 57 |
-
client = OpenAI(
|
| 58 |
-
base_url="https://nim.api.nvidia.com/v1",
|
| 59 |
-
api_key=NVIDIA_API_KEY or "dummy-key-if-not-required-locally"
|
| 60 |
-
)
|
| 61 |
-
|
| 62 |
choices = []
|
| 63 |
|
| 64 |
for i, prompt in enumerate(prompts):
|
|
@@ -70,7 +70,7 @@ def _run_inference(data: dict) -> dict:
|
|
| 70 |
]
|
| 71 |
|
| 72 |
try:
|
| 73 |
-
completion =
|
| 74 |
model=model_name,
|
| 75 |
messages=messages,
|
| 76 |
temperature=temperature,
|
|
@@ -83,11 +83,15 @@ def _run_inference(data: dict) -> dict:
|
|
| 83 |
print(f"\n[CONSOLE STREAM] Generating via NVIDIA for: {model_name}")
|
| 84 |
print("-" * 30)
|
| 85 |
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
|
| 92 |
print("\n" + "-" * 30)
|
| 93 |
|
|
|
|
| 39 |
# ββ Inference Queue (multi-user serialization) βββββββββββββββββββββββββββββββββ
|
| 40 |
_inference_queue: _queue_module.Queue = _queue_module.Queue(maxsize=_QUEUE_MAX_SIZE)
|
| 41 |
|
| 42 |
+
if not NVIDIA_API_KEY:
|
| 43 |
+
log.warning("NVIDIA_API_KEY is not set. API calls might fail if the token is required.")
|
| 44 |
+
|
| 45 |
+
_nvidia_client = OpenAI(
|
| 46 |
+
base_url="https://nim.api.nvidia.com/v1",
|
| 47 |
+
api_key=NVIDIA_API_KEY or "dummy-key-if-not-required-locally"
|
| 48 |
+
)
|
| 49 |
+
|
| 50 |
def _run_inference(data: dict) -> dict:
|
| 51 |
raw_prompt = data.get("prompt", "")
|
| 52 |
if not raw_prompt:
|
|
|
|
| 59 |
top_p = float(data.get("top_p", 1.0))
|
| 60 |
model_name = data.get("model", DEFAULT_MODEL)
|
| 61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
choices = []
|
| 63 |
|
| 64 |
for i, prompt in enumerate(prompts):
|
|
|
|
| 70 |
]
|
| 71 |
|
| 72 |
try:
|
| 73 |
+
completion = _nvidia_client.chat.completions.create(
|
| 74 |
model=model_name,
|
| 75 |
messages=messages,
|
| 76 |
temperature=temperature,
|
|
|
|
| 83 |
print(f"\n[CONSOLE STREAM] Generating via NVIDIA for: {model_name}")
|
| 84 |
print("-" * 30)
|
| 85 |
|
| 86 |
+
try:
|
| 87 |
+
for chunk in completion:
|
| 88 |
+
if chunk.choices and chunk.choices[0].delta.content is not None:
|
| 89 |
+
content = chunk.choices[0].delta.content
|
| 90 |
+
print(content, end="", flush=True)
|
| 91 |
+
full_output += content
|
| 92 |
+
finally:
|
| 93 |
+
if hasattr(completion, "close"):
|
| 94 |
+
completion.close()
|
| 95 |
|
| 96 |
print("\n" + "-" * 30)
|
| 97 |
|