Spaces:
Running
Running
| import argparse | |
| import os | |
| from dataclasses import dataclass | |
| from smolagents import CodeAgent, LiteLLMModel | |
| class ProviderPreset: | |
| name: str | |
| api_key_env: str | |
| api_base_env: str | |
| model_env: str | |
| default_api_base: str | |
| default_model: str | |
| PROVIDERS: dict[str, ProviderPreset] = { | |
| # GitHub Models (OpenAI-compatible endpoint) | |
| "github": ProviderPreset( | |
| name="github", | |
| api_key_env="GITHUB_TOKEN", | |
| api_base_env="GITHUB_API_BASE", | |
| model_env="GITHUB_MODEL_ID", | |
| default_api_base="https://models.inference.ai.azure.com", | |
| default_model="openai/gpt-4.1-mini", | |
| ), | |
| # Gemini via Google OpenAI-compatible endpoint | |
| "gemini": ProviderPreset( | |
| name="gemini", | |
| api_key_env="GEMINI_API_KEY", | |
| api_base_env="GEMINI_API_BASE", | |
| model_env="GEMINI_MODEL_ID", | |
| default_api_base="https://generativelanguage.googleapis.com/v1beta/openai/", | |
| default_model="gemini-2.0-flash", | |
| ), | |
| # Z.ai / GLM (BigModel) - set ZAI_API_BASE to your account endpoint if needed | |
| "zai": ProviderPreset( | |
| name="zai", | |
| api_key_env="ZAI_API_KEY", | |
| api_base_env="ZAI_API_BASE", | |
| model_env="ZAI_MODEL_ID", | |
| default_api_base="https://open.bigmodel.cn/api/paas/v4/", | |
| default_model="zhipuai/glm-4.5", | |
| ), | |
| # Hugging Face Inference Router (OpenAI-compatible endpoint) | |
| "huggingface": ProviderPreset( | |
| name="huggingface", | |
| api_key_env="HF_TOKEN", | |
| api_base_env="HF_API_BASE", | |
| model_env="HF_MODEL_ID", | |
| default_api_base="https://router.huggingface.co/v1", | |
| default_model="moonshotai/Kimi-K2.5", | |
| ), | |
| # Fireworks (OpenAI-compatible endpoint) | |
| "fireworks": ProviderPreset( | |
| name="fireworks", | |
| api_key_env="FIREWORKS_API_KEY", | |
| api_base_env="FIREWORKS_API_BASE", | |
| model_env="FIREWORKS_MODEL_ID", | |
| default_api_base="https://api.fireworks.ai/inference/v1", | |
| default_model="accounts/fireworks/models/llama-v3p1-8b-instruct", | |
| ), | |
| # Minimax (OpenAI-compatible endpoint) | |
| "minimax": ProviderPreset( | |
| name="minimax", | |
| api_key_env="MINIMAX_API_KEY", | |
| api_base_env="MINIMAX_API_BASE", | |
| model_env="MINIMAX_MODEL_ID", | |
| default_api_base="https://api.minimax.chat/v1", | |
| default_model="MiniMax-Text-01", | |
| ), | |
| } | |
| def build_model(provider: str, model_override: str | None, temperature: float) -> LiteLLMModel: | |
| preset = PROVIDERS[provider] | |
| api_key = os.getenv(preset.api_key_env) | |
| api_base = os.getenv(preset.api_base_env, preset.default_api_base) | |
| model_id = model_override or os.getenv(preset.model_env, preset.default_model) | |
| if not api_key: | |
| raise ValueError( | |
| f"Missing API key. Set environment variable {preset.api_key_env} for provider '{provider}'." | |
| ) | |
| return LiteLLMModel( | |
| model_id=model_id, | |
| api_base=api_base, | |
| api_key=api_key, | |
| temperature=temperature, | |
| ) | |
| def parse_args() -> argparse.Namespace: | |
| parser = argparse.ArgumentParser( | |
| description="smolagents CodeAgent + LiteLLMModel template for multi-provider usage" | |
| ) | |
| parser.add_argument( | |
| "--provider", | |
| choices=sorted(PROVIDERS.keys()), | |
| default="gemini", | |
| help="Which provider preset to use", | |
| ) | |
| parser.add_argument( | |
| "--model", | |
| default=None, | |
| help="Optional model override (otherwise uses provider env/default)", | |
| ) | |
| parser.add_argument( | |
| "--prompt", | |
| default="Explain how AI agents work in 3 concise bullet points.", | |
| help="Prompt to run", | |
| ) | |
| parser.add_argument( | |
| "--temperature", | |
| type=float, | |
| default=0.2, | |
| help="Sampling temperature", | |
| ) | |
| parser.add_argument( | |
| "--max-steps", | |
| type=int, | |
| default=5, | |
| help="Maximum CodeAgent steps", | |
| ) | |
| parser.add_argument( | |
| "--dry-run", | |
| action="store_true", | |
| help="Print resolved config without calling the model", | |
| ) | |
| return parser.parse_args() | |
| def main() -> None: | |
| args = parse_args() | |
| preset = PROVIDERS[args.provider] | |
| resolved_api_base = os.getenv(preset.api_base_env, preset.default_api_base) | |
| resolved_model = args.model or os.getenv(preset.model_env, preset.default_model) | |
| if args.dry_run: | |
| print("Provider:", args.provider) | |
| print("Model:", resolved_model) | |
| print("API base:", resolved_api_base) | |
| print("Required API key env:", preset.api_key_env) | |
| return | |
| model = build_model(args.provider, args.model, args.temperature) | |
| # CodeAgent works best when models follow strict structured output behavior. | |
| # 'markdown' tags and structured outputs improve cross-provider reliability. | |
| agent = CodeAgent( | |
| tools=[], | |
| model=model, | |
| max_steps=args.max_steps, | |
| code_block_tags="markdown", | |
| use_structured_outputs_internally=True, | |
| ) | |
| answer = agent.run(args.prompt) | |
| print(answer) | |
| if __name__ == "__main__": | |
| main() | |