Files
cobol-java-v3/agents/llm.py
hangshuo652 bc1d56d1a4 feat: Phase 2 complete — 13 Phases of COBOL type classification and test benchmark
P0.6: gcov infrastructure
P1: extract_structure output expansion (11 new feature fields)
P2: Confusion group rule engine (8 pairs + contradiction + backtrack)
P3: 4-factor confidence calculation + quality gate update
P4: 33+2 COBOL program type test samples (22 files, 7 categories)
P5: parametrized/ test data generation engine
P6: japanese_data.py lookup tables
P7-10: Type-specific test suites (~159 parametrized tests)
P11: Full classification pipeline (classify_program) + orchestrator integration
P12: Documentation (module-interfaces, test-plan v3.0, coverage-matrix)

Architecture decisions:
- classification_pipeline/ merged to hina/pipeline/
- parametrized/ as independent module
- japanese_data.py as root-level file
- hina/__all__ only exports classify_program()

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-19 23:51:55 +08:00

47 lines
1.6 KiB
Python

import json, hashlib, os
from pathlib import Path
import httpx
class LLMClient:
def __init__(self, model="gpt-4o-mini", timeout=15, cache_dir=".cache/llm"):
self.model = model
self.timeout = timeout
self.dir = Path(cache_dir)
self.dir.mkdir(parents=True, exist_ok=True)
def _key(self, msgs):
return hashlib.sha256(json.dumps(msgs, sort_keys=True).encode()).hexdigest()
def _get(self, k):
p = self.dir / f"{k}.json"
if not p.exists():
return None
try:
return json.loads(p.read_text())["response"]
except (json.JSONDecodeError, KeyError):
return None
def _set(self, k, v):
(self.dir / f"{k}.json").write_text(json.dumps({"response": v}))
def call(self, messages, retries=1):
k = self._key(messages)
c = self._get(k)
if c:
return c
key = os.environ.get("LLM_API_KEY", os.environ.get("OPENAI_API_KEY", ""))
base = os.environ.get("LLM_API_BASE", "https://api.openai.com/v1")
for a in range(retries + 1):
try:
r = httpx.post(f"{base}/chat/completions", json={"model": self.model, "messages": messages},
headers={"Authorization": f"Bearer {key}"}, timeout=self.timeout)
r.raise_for_status()
v = r.json()["choices"][0]["message"]["content"]
self._set(k, v)
return v
except Exception:
if a == retries:
raise
return ""