Skip to content

Commit 06b39b4

Browse files
linting
1 parent 2965d78 commit 06b39b4

1 file changed

Lines changed: 59 additions & 47 deletions

File tree

macro_agents/src/macro_agents/defs/agents/ai_models_fetcher.py

Lines changed: 59 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -25,28 +25,28 @@
2525

2626
def _get_openai_models(api_key: Optional[str] = None) -> List[str]:
2727
"""Fetch available chat/completion models from OpenAI API.
28-
28+
2929
Dynamically discovers all chat/completion models suitable for economic analysis.
3030
Excludes embeddings, fine-tuning, and other non-chat models.
3131
"""
3232
if openai is None:
3333
return []
34-
34+
3535
if api_key is None:
3636
api_key = os.getenv("OPENAI_API_KEY")
37-
37+
3838
if not api_key:
3939
return []
40-
40+
4141
try:
4242
client = openai.OpenAI(api_key=api_key)
4343
models = client.models.list()
44-
44+
4545
# Filter for chat/completion models by excluding known non-chat types
4646
chat_models = []
4747
for model in models.data:
4848
model_id = model.id.lower()
49-
49+
5050
# Exclude embeddings, fine-tuned models, and other non-chat models
5151
exclude_patterns = [
5252
"text-embedding",
@@ -58,91 +58,96 @@ def _get_openai_models(api_key: Optional[str] = None) -> List[str]:
5858
"curie-", # Old curie models
5959
"davinci-", # Old davinci models
6060
]
61-
61+
6262
# Check if model should be excluded
6363
should_exclude = any(pattern in model_id for pattern in exclude_patterns)
64-
64+
6565
# Include all models that aren't excluded (covers gpt-4, gpt-3.5, o1, gpt-5, and any future chat models)
6666
if not should_exclude:
6767
# Get the original case model ID
6868
chat_models.append(model.id)
69-
69+
7070
return sorted(chat_models)
7171
except Exception as e:
7272
raise ValueError(f"Error fetching OpenAI models: {e}")
7373

7474

7575
def _get_anthropic_models(api_key: Optional[str] = None) -> List[str]:
7676
"""Fetch available chat/completion models from Anthropic API.
77-
77+
7878
Returns all currently available Claude models (all are chat/completion models).
7979
Note: Anthropic may not provide a models list endpoint - if so, this will return an empty list.
8080
"""
8181
if anthropic is None:
8282
return []
83-
83+
8484
if api_key is None:
8585
api_key = os.getenv("ANTHROPIC_API_KEY")
86-
86+
8787
if not api_key:
8888
return []
89-
89+
9090
try:
9191
client = anthropic.Anthropic(api_key=api_key)
92-
92+
9393
# Try to use the models list endpoint if available
94-
if hasattr(client, 'models') and hasattr(client.models, 'list'):
94+
if hasattr(client, "models") and hasattr(client.models, "list"):
9595
try:
9696
models_response = client.models.list()
9797
# Extract model IDs from the response
98-
if hasattr(models_response, 'data'):
98+
if hasattr(models_response, "data"):
9999
return sorted([model.id for model in models_response.data])
100100
elif isinstance(models_response, list):
101-
return sorted([model.id if hasattr(model, 'id') else str(model) for model in models_response])
101+
return sorted(
102+
[
103+
model.id if hasattr(model, "id") else str(model)
104+
for model in models_response
105+
]
106+
)
102107
except AttributeError:
103108
# Fall through - models.list() may not be implemented
104109
pass
105110
except Exception as e:
106111
# If models.list() exists but fails, raise the error
107112
raise ValueError(f"Error calling Anthropic models.list(): {e}")
108-
113+
109114
# Anthropic doesn't provide a public models list endpoint
110115
# Return empty list since we can't dynamically discover models
111116
return []
112-
117+
113118
except Exception as e:
114119
raise ValueError(f"Error fetching Anthropic models: {e}")
115120

116121

117122
def _get_gemini_models(api_key: Optional[str] = None) -> List[str]:
118123
"""Fetch available chat/completion models from Google Gemini API.
119-
124+
120125
Filters for models that support chat/completion (generateContent).
121126
Excludes embeddings and other non-chat models.
122127
"""
123128
if genai is None:
124129
return []
125-
130+
126131
if api_key is None:
127132
api_key = os.getenv("GEMINI_API_KEY")
128-
133+
129134
if not api_key:
130135
return []
131-
136+
132137
try:
133138
genai.configure(api_key=api_key)
134-
139+
135140
# List available models
136141
models = genai.list_models()
137-
142+
138143
# Filter for chat/completion models (those that support generateContent)
139144
chat_models = []
140145
for model in models:
141146
# Only include models that support generateContent (chat/completion)
142147
if "generateContent" in model.supported_generation_methods:
143148
model_name = model.name.replace("models/", "")
144149
chat_models.append(model_name)
145-
150+
146151
return sorted(chat_models)
147152
except Exception as e:
148153
raise ValueError(f"Error fetching Gemini models: {e}")
@@ -159,7 +164,7 @@ def fetch_available_ai_models(
159164
) -> dg.MaterializeResult:
160165
"""
161166
Fetch available chat/completion models from OpenAI, Anthropic, and Gemini APIs and store results.
162-
167+
163168
This asset queries each provider's API to get the current list of available chat/completion models
164169
suitable for economic analysis. Filters out embeddings, fine-tuning models, and other non-chat models.
165170
Stores them in the database for reference and configuration.
@@ -168,15 +173,15 @@ def fetch_available_ai_models(
168173
env = os.getenv("ENVIRONMENT", "not set")
169174
context.log.info(f"Environment: {env}")
170175
context.log.info("Starting to fetch available AI models from all providers...")
171-
176+
172177
results: Dict[str, Any] = {
173178
"openai": [],
174179
"anthropic": [],
175180
"gemini": [],
176181
}
177-
182+
178183
errors: Dict[str, str] = {}
179-
184+
180185
# Fetch OpenAI models
181186
context.log.info("Fetching OpenAI models...")
182187
try:
@@ -187,7 +192,7 @@ def fetch_available_ai_models(
187192
error_msg = str(e)
188193
errors["openai"] = error_msg
189194
context.log.warning(f"Failed to fetch OpenAI models: {error_msg}")
190-
195+
191196
# Fetch Anthropic models
192197
context.log.info("Fetching Anthropic models...")
193198
try:
@@ -204,7 +209,7 @@ def fetch_available_ai_models(
204209
error_msg = str(e)
205210
errors["anthropic"] = error_msg
206211
context.log.warning(f"Failed to fetch Anthropic models: {error_msg}")
207-
212+
208213
# Fetch Gemini models
209214
context.log.info("Fetching Gemini models...")
210215
try:
@@ -215,7 +220,7 @@ def fetch_available_ai_models(
215220
error_msg = str(e)
216221
errors["gemini"] = error_msg
217222
context.log.warning(f"Failed to fetch Gemini models: {error_msg}")
218-
223+
219224
# Prepare result for database
220225
fetch_timestamp = datetime.now()
221226
result = {
@@ -232,13 +237,15 @@ def fetch_available_ai_models(
232237
"dagster_run_id": context.run_id,
233238
"dagster_asset_key": str(context.asset_key),
234239
}
235-
240+
236241
# Write to database (drop and recreate table)
237-
context.log.info("Writing model list to database (dropping and recreating table)...")
242+
context.log.info(
243+
"Writing model list to database (dropping and recreating table)..."
244+
)
238245
try:
239246
# Convert result dict to Polars DataFrame
240247
df = pl.DataFrame([result])
241-
248+
242249
# Drop and recreate table with new data
243250
md.drop_create_duck_db_table(
244251
table_name="available_ai_models",
@@ -251,37 +258,42 @@ def fetch_available_ai_models(
251258
# Add database error to errors dict
252259
errors["database"] = error_msg
253260
# Still return results in metadata even if database write fails
254-
context.log.warning("Continuing despite database write failure - results available in metadata")
255-
261+
context.log.warning(
262+
"Continuing despite database write failure - results available in metadata"
263+
)
264+
256265
# Prepare metadata
257266
metadata = {
258267
"openai_models_count": len(results["openai"]),
259268
"anthropic_models_count": len(results["anthropic"]),
260269
"gemini_models_count": len(results["gemini"]),
261270
"fetch_timestamp": fetch_timestamp.isoformat(),
262271
}
263-
272+
264273
# Add model lists to metadata (truncated if too long)
265274
if results["openai"]:
266275
metadata["openai_models"] = results["openai"][:10] # First 10 models
267276
if len(results["openai"]) > 10:
268-
metadata["openai_models_note"] = f"Showing first 10 of {len(results['openai'])} models"
269-
277+
metadata["openai_models_note"] = (
278+
f"Showing first 10 of {len(results['openai'])} models"
279+
)
280+
270281
if results["anthropic"]:
271282
metadata["anthropic_models"] = results["anthropic"]
272-
283+
273284
if results["gemini"]:
274285
metadata["gemini_models"] = results["gemini"][:10] # First 10 models
275286
if len(results["gemini"]) > 10:
276-
metadata["gemini_models_note"] = f"Showing first 10 of {len(results['gemini'])} models"
277-
287+
metadata["gemini_models_note"] = (
288+
f"Showing first 10 of {len(results['gemini'])} models"
289+
)
290+
278291
if errors:
279292
metadata["errors"] = errors
280-
293+
281294
context.log.info(
282295
f"Successfully fetched models: OpenAI={len(results['openai'])}, "
283296
f"Anthropic={len(results['anthropic'])}, Gemini={len(results['gemini'])}"
284297
)
285-
286-
return dg.MaterializeResult(metadata=metadata)
287298

299+
return dg.MaterializeResult(metadata=metadata)

0 commit comments

Comments
 (0)