Files
microdao-daarion/crews/agromatrix_crew/llm_factory.py
Apple 129e4ea1fc feat(platform): add new services, tools, tests and crews modules
New router intelligence modules (26 files): alert_ingest/store, audit_store,
architecture_pressure, backlog_generator/store, cost_analyzer, data_governance,
dependency_scanner, drift_analyzer, incident_* (5 files), llm_enrichment,
platform_priority_digest, provider_budget, release_check_runner, risk_* (6 files),
signature_state_store, sofiia_auto_router, tool_governance

New services:
- sofiia-console: Dockerfile, adapters/, monitor/nodes/ops/voice modules, launchd, react static
- memory-service: integration_endpoints, integrations, voice_endpoints, static UI
- aurora-service: full app suite (analysis, job_store, orchestrator, reporting, schemas, subagents)
- sofiia-supervisor: new supervisor service
- aistalk-bridge-lite: Telegram bridge lite
- calendar-service: CalDAV calendar service with reminders
- mlx-stt-service / mlx-tts-service: Apple Silicon speech services
- binance-bot-monitor: market monitor service
- node-worker: STT/TTS memory providers

New tools (9): agent_email, browser_tool, contract_tool, observability_tool,
oncall_tool, pr_reviewer_tool, repo_tool, safe_code_executor, secure_vault

New crews: agromatrix_crew (10 modules: depth_classifier, doc_facts, doc_focus,
farm_state, light_reply, llm_factory, memory_manager, proactivity, reflection_engine,
session_context, style_adapter, telemetry)

Tests: 85+ test files for all new modules
Made-with: Cursor
2026-03-03 07:14:14 -08:00

133 lines
5.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
LLM Factory — підтримка Anthropic Claude / DeepSeek / OpenAI / fallback.
Пріоритет:
1. ANTHROPIC_API_KEY → claude-sonnet-4-5 (через langchain-anthropic / crewai)
2. DEEPSEEK_API_KEY → deepseek-chat (через langchain-openai compatible)
3. OPENAI_API_KEY → gpt-4o-mini (через langchain-openai)
4. None → повертає None
Змінні середовища:
ANTHROPIC_API_KEY — ключ Anthropic Claude (найвищий пріоритет для Sofiia)
ANTHROPIC_MODEL — модель (default: claude-sonnet-4-5)
DEEPSEEK_API_KEY — ключ DeepSeek
DEEPSEEK_MODEL — модель (default: deepseek-chat)
OPENAI_API_KEY — ключ OpenAI (fallback)
OPENAI_MODEL — модель (default: gpt-4o-mini)
Використання:
from crews.agromatrix_crew.llm_factory import make_llm
agent = Agent(..., llm=make_llm())
"""
from __future__ import annotations
import logging
import os
logger = logging.getLogger(__name__)
def make_llm(force_provider: str | None = None):
"""
Повертає LLM-інстанс для crewAI агентів.
Fail-safe: якщо жоден ключ не знайдений — повертає None і логує warning.
Args:
force_provider: 'anthropic', 'deepseek', 'openai' — примусово обрати провайдера.
"""
anthropic_key = os.getenv("ANTHROPIC_API_KEY", "").strip()
deepseek_key = os.getenv("DEEPSEEK_API_KEY", "").strip()
openai_key = os.getenv("OPENAI_API_KEY", "").strip()
# ── Варіант 0: Anthropic Claude ──────────────────────────────────────────
if anthropic_key and force_provider in (None, "anthropic"):
# Try langchain-anthropic first
try:
from langchain_anthropic import ChatAnthropic # type: ignore[import-untyped]
model = os.getenv("ANTHROPIC_MODEL", "claude-sonnet-4-5")
llm = ChatAnthropic(
model=model,
api_key=anthropic_key,
temperature=0.2,
max_tokens=8192,
)
logger.info("LLM: Anthropic Claude via langchain-anthropic (model=%s)", model)
return llm
except ImportError:
pass
except Exception as exc:
logger.warning("langchain-anthropic init failed (%s), trying crewai.LLM", exc)
# Try crewai.LLM with anthropic provider
try:
from crewai import LLM # type: ignore[import-untyped]
model = os.getenv("ANTHROPIC_MODEL", "claude-sonnet-4-5")
llm = LLM(
model=f"anthropic/{model}",
api_key=anthropic_key,
temperature=0.2,
max_tokens=8192,
)
logger.info("LLM: Anthropic Claude via crewai.LLM (model=%s)", model)
return llm
except (ImportError, Exception) as exc:
logger.warning("crewai.LLM Anthropic init failed (%s), trying DeepSeek fallback", exc)
# ── Варіант 1: DeepSeek через OpenAI-compatible API ──────────────────────
if deepseek_key and force_provider in (None, "deepseek"):
try:
from langchain_openai import ChatOpenAI
model = os.getenv("DEEPSEEK_MODEL", "deepseek-chat")
base_url = os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com")
llm = ChatOpenAI(
model=model,
api_key=deepseek_key,
base_url=base_url,
temperature=0.3,
)
logger.info("LLM: DeepSeek via ChatOpenAI (model=%s, base_url=%s)", model, base_url)
return llm
except (ImportError, Exception) as exc:
logger.warning("DeepSeek LLM init failed (%s), trying OpenAI fallback", exc)
# ── Варіант 2: OpenAI ────────────────────────────────────────────────────
if openai_key and force_provider in (None, "openai"):
try:
from langchain_openai import ChatOpenAI
model = os.getenv("OPENAI_MODEL", "gpt-4o-mini")
llm = ChatOpenAI(
model=model,
api_key=openai_key,
temperature=0.3,
)
logger.info("LLM: OpenAI ChatOpenAI (model=%s)", model)
return llm
except ImportError:
pass
try:
from crewai import LLM
model = os.getenv("OPENAI_MODEL", "gpt-4o-mini")
llm = LLM(
model=f"openai/{model}",
api_key=openai_key,
temperature=0.3,
)
logger.info("LLM: OpenAI via crewai.LLM (model=%s)", model)
return llm
except (ImportError, Exception) as exc:
logger.warning("OpenAI LLM init failed: %s", exc)
# ── Нічого немає ────────────────────────────────────────────────────────
logger.error(
"LLM: no API key configured! "
"Set ANTHROPIC_API_KEY (preferred for Sofiia), DEEPSEEK_API_KEY, or OPENAI_API_KEY."
)
return None
def make_sofiia_llm():
"""Спеціалізований LLM для Sofiia — Claude Sonnet з розширеним контекстом."""
return make_llm(force_provider="anthropic")