-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.py
More file actions
110 lines (95 loc) · 4 KB
/
Copy pathconfig.py
File metadata and controls
110 lines (95 loc) · 4 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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# config.py
# Single config for all LLM calls across the pipeline.
# Change PROVIDER and MODEL here — all agents pick it up automatically.
# Providers: "gemini" | "openai"
# Key design decision
# The design decision is: no single point of failure on the model call.
# The pipeline keeps running even when the primary model is unavailable.
import os
from dotenv import load_dotenv
load_dotenv()
from langfuse import Langfuse
from langfuse.types import TraceContext
langfuse = Langfuse(
public_key=os.environ["LANGFUSE_PUBLIC_KEY"],
secret_key=os.environ["LANGFUSE_SECRET_KEY"],
host=os.environ.get("LANGFUSE_BASE_URL", "https://cloud.langfuse.com"),
)
current_trace_id = None # set by run.py before graph.invoke(); shared across all agent calls
current_trace = None # root span object; set by run.py for post-pipeline .update()
# PROVIDER = "gemini"
PROVIDER = "openai" # PAID!
# Gemini fallback chain — tried in order until one has quota
GEMINI_MODELS_FALLBACK = [
"gemini-2.5-flash",
"gemini-2.5-pro",
"gemini-2.5-flash-lite",
"gemini-2.0-flash",
"gemini-2.0-flash-lite",
]
# OpenAI model to use
# Best price/performance for structured JSON tasks
# Handles all your agent prompts well
# Cheap enough that your entire project won't cost more than $2-3 total
OPENAI_MODEL = "gpt-4o-mini" # cheap, capable — upgrade to gpt-4o if needed
# Upgrade to if gpt-4o-mini fails on compound risk reasoning: gpt-4o
# Stronger reasoning, ~15x more expensive; Only worth it if
# the dependency agent produces weak compound risks
# OPENAI_MODEL = "gpt-4o"
def generate_with_fallback(prompt: str, agent_name: str = "unknown") -> tuple[str, int | None, int | None]:
trace_id = current_trace_id or Langfuse.create_trace_id()
span = langfuse.start_observation(
trace_context=TraceContext(trace_id=trace_id),
name=agent_name,
as_type="generation",
)
result = _gemini(prompt) if PROVIDER == "gemini" else _openai(prompt)
text, i, o, model_name = result
cost = round((i / 1000) * 0.000075 + (o / 1000) * 0.0003, 6) if i is not None and o is not None else None
span.update(
input={"agent": agent_name, "prompt_chars": len(prompt)},
output={"response_preview": text[:500], "response_chars": len(text)},
usage_details={"input": i or 0, "output": o or 0},
model=model_name,
**({"cost_details": {"total": cost}} if cost is not None else {}),
)
span.end()
return text, i, o
def _gemini(prompt: str) -> tuple[str, int | None, int | None, str]:
from google import genai
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
for model in GEMINI_MODELS_FALLBACK:
try:
response = client.models.generate_content(
model=model,
contents=prompt
)
print(f"[config] Used model: gemini/{model}")
text = response.text.strip()
try:
i = response.usage_metadata.prompt_token_count
o = response.usage_metadata.candidates_token_count
except Exception:
i, o = None, None
return text, i, o, model
except Exception as e:
if "429" in str(e) or "RESOURCE_EXHAUSTED" in str(e):
print(f"[config] gemini/{model} quota exhausted, trying next...")
continue
raise
raise RuntimeError("All Gemini models exhausted — switch PROVIDER to openai")
def _openai(prompt: str) -> tuple[str, int | None, int | None, str]:
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
response = client.chat.completions.create(
model=OPENAI_MODEL,
messages=[{"role": "user", "content": prompt}]
)
print(f"[config] Used model: openai/{OPENAI_MODEL}")
text = response.choices[0].message.content.strip()
try:
i = response.usage.prompt_tokens
o = response.usage.completion_tokens
except Exception:
i, o = None, None
return text, i, o, OPENAI_MODEL