Skip to content

Commit 3d1293c

Browse files
committed
refactor: codex_integration routes through AiGateway, removes direct API calls
call_ai_optimization_decision() now uses AiServiceClient.review() instead of calling quant_strategy_plugins.ai_audit directly with ANTHROPIC_API_KEY. No remaining direct API calls in strategy_lifecycle module. All AI traffic → CODEX_AUDIT_SERVICE_URL → AiGateway (VPS).
1 parent b4dbea0 commit 3d1293c

1 file changed

Lines changed: 25 additions & 26 deletions

File tree

src/quant_platform_kit/strategy_lifecycle/codex_integration.py

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -332,21 +332,21 @@ def build_optimization_prompt(context: AiOptimizationContext) -> str:
332332
def call_ai_optimization_decision(
333333
context: AiOptimizationContext,
334334
*,
335-
provider: str = "anthropic",
336335
dry_run: bool = False,
337336
) -> dict[str, Any]:
338-
"""Call an AI model (via ai_audit.py) to decide on optimization.
337+
"""Call AiGateway to decide whether optimization is needed.
338+
339+
Routes through AiGateway (Claude/GPT via LlmAdapter).
340+
No API keys needed — CODEX_AUDIT_SERVICE_URL only.
339341
340342
Args:
341343
context: The optimization context with drift and snapshot data.
342-
provider: "anthropic", "openai", or "codex".
343-
dry_run: If True, return a simulated decision.
344+
dry_run: If True, return a simulated decision without AI call.
344345
345346
Returns:
346347
AI decision dict with optimization_needed, reason, etc.
347348
"""
348349
if dry_run:
349-
# Simulate a decision based on drift status
350350
if context.drift and context.drift.status in (DriftStatus.REVIEW, DriftStatus.CRITICAL):
351351
return {
352352
"optimization_needed": True,
@@ -364,33 +364,32 @@ def call_ai_optimization_decision(
364364
"confidence": 0.95,
365365
}
366366

367-
# Try using ai_audit.py from QuantStrategyPlugins
368367
try:
369-
from quant_strategy_plugins.ai_audit import AiAuditEndpoint, call_ai_audit
370-
371-
endpoint = AiAuditEndpoint(
372-
name="strategy_optimizer",
373-
api_key=os.environ.get("AI_AUDIT_API_KEY", os.environ.get("ANTHROPIC_API_KEY", "")),
374-
provider=provider,
375-
model="claude-sonnet-4-6" if provider == "anthropic" else "gpt-5.4-mini",
368+
from quant_platform_kit.strategy_lifecycle.ai_provider import (
369+
AiServiceConfig, AiServiceClient, AiProviderConfig,
376370
)
377371

372+
config = AiServiceConfig.from_env()
373+
if not config.reviewers:
374+
return {"optimization_needed": False, "reason": "No AI backend configured (set CODEX_AUDIT_SERVICE_URL)"}
375+
376+
client = AiServiceClient(config)
378377
prompt = build_optimization_prompt(context)
379-
messages = [{"role": "user", "content": prompt}]
380-
381-
raw = call_ai_audit(endpoint, messages, timeout=30.0)
382-
if isinstance(raw, str):
383-
# Try to extract JSON from the response
384-
import re
385-
match = re.search(r"\{[\s\S]*\}", raw)
386-
if match:
387-
return json.loads(match.group(0))
388-
return {"optimization_needed": False, "reason": "Could not parse AI response", "raw": raw[:500]}
389-
return raw if isinstance(raw, Mapping) else {"optimization_needed": False, "reason": "Unexpected response type"}
378+
results = client.review(prompt, timeout=30.0)
379+
380+
# Use the first successful reviewer result
381+
for r in results:
382+
if r.success and r.output:
383+
import re
384+
match = re.search(r"\{[\s\S]*\}", r.output)
385+
if match:
386+
return json.loads(match.group(0))
387+
return {"optimization_needed": False, "reason": "Could not parse AI response", "raw": r.output[:500]}
388+
389+
return {"optimization_needed": False, "reason": "All AI backends unavailable"}
390390

391391
except ImportError:
392-
# Fallback: use the dry_run heuristic
393-
return call_ai_optimization_decision(context, provider=provider, dry_run=True)
392+
return call_ai_optimization_decision(context, dry_run=True)
394393
except Exception as exc:
395394
return {"optimization_needed": False, "reason": f"AI call failed: {exc}", "error": str(exc)}
396395

0 commit comments

Comments
 (0)