-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.py
More file actions
95 lines (71 loc) · 3.29 KB
/
Copy pathconfig.py
File metadata and controls
95 lines (71 loc) · 3.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""Project configuration: model names, endpoints, and LLM factory.
All "magic strings" live here. Change a model name in one place and the
rest of the app picks it up.
"""
import os
from typing import Optional
import truststore
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
# Use the OS trust store for SSL verification (handles corporate proxies
# that inject self-signed certs). Must run before any HTTPS connections.
truststore.inject_into_ssl()
load_dotenv()
# ---------------------------------------------------------------------------
# Models — see README for the rationale of the two-model strategy.
# ---------------------------------------------------------------------------
# Small, fast model for the router node.
# Classification (structured / unstructured / out-of-scope) is a simple task,
# so we use Qwen3-30B-A3B — a Mixture-of-Experts model with only 3B active
# parameters, giving very low latency while staying smart enough for routing.
ROUTER_MODEL = "Qwen/Qwen3-30B-A3B-Instruct-2507"
# Larger model for the ReAct agent itself.
# Multi-step reasoning, tool selection, and summarization benefit from a
# strong instruction-following model. We use Qwen3-32B because in practice it
# follows the STOPPING RULES in the system prompt more reliably than Llama
# 3.3 70B, which tended to loop on get_examples when filtered by category.
AGENT_MODEL = "Qwen/Qwen3-32B"
# ---------------------------------------------------------------------------
# Agent loop limits
# ---------------------------------------------------------------------------
# Maximum number of ReAct iterations. Each iteration is one Think + Act cycle.
# Beyond this the agent returns a graceful fallback message.
MAX_ITERATIONS = 12
# ---------------------------------------------------------------------------
# Nebius Token Factory endpoint (OpenAI-compatible)
# ---------------------------------------------------------------------------
NEBIUS_BASE_URL = "https://api.studio.nebius.com/v1/"
# ---------------------------------------------------------------------------
# LLM factory
# ---------------------------------------------------------------------------
def get_llm(
model: str,
temperature: float = 0.0,
api_key: Optional[str] = None,
) -> ChatOpenAI:
"""Create a ChatOpenAI client pointed at the Nebius Token Factory.
Nebius exposes an OpenAI-compatible API, so we can reuse the standard
langchain_openai.ChatOpenAI class — only the base_url and api_key change.
Args:
model: One of the Nebius model IDs (ROUTER_MODEL or AGENT_MODEL).
temperature: Sampling temperature. Default 0.0 for deterministic
tool-using behavior; raise for more creative summaries.
api_key: Optional explicit API key. If not provided, reads
NEBIUS_API_KEY from the environment (loaded from .env).
Returns:
A configured ChatOpenAI instance.
Raises:
ValueError: If no API key is available.
"""
key = api_key or os.getenv("NEBIUS_API_KEY")
if not key:
raise ValueError(
"NEBIUS_API_KEY is not set. Add it to your .env file: "
"NEBIUS_API_KEY=your_key_here"
)
return ChatOpenAI(
model=model,
base_url=NEBIUS_BASE_URL,
api_key=key,
temperature=temperature,
)