Search for a command to run...
Compiled from 18 nodes · est. 8 min read
Updated
(no content yet for this node)
Updated
Model credentials and API keys are never serialised when calling model.to_dict(). The to_dict() method in src/smolagents/models.py explicitly prints a warning and skips token and api_key attributes. All other model parameters (endpoint, provider, temperature, etc.) are included.
For secrets management in practice, the library loads a .env file automatically via python-dotenv if it is installed (the import is guarded with a try/except in src/smolagents/remote_executors.py). SECURITY.md at the repo root contains the vulnerability reporting policy. The .github/workflows/trufflehog.yml GitHub Actions workflow runs TruffleHog on every push to prevent secret leaks into the repository.
Loading tools or agents from the Hub requires explicitly passing trust_remote_code=True; without it, Tool.from_hub() and MultiStepAgent.from_hub() raise a ValueError with a clear explanation.
src/smolagents/models.pysrc/smolagents/remote_executors.pySECURITY.md.github/workflows/trufflehog.ymlUpdated
(no content yet for this node)
Updated
Documentation source lives in docs/source/ and is available in five languages: English (en/), Spanish (es/), Hindi (hi/), Korean (ko/), and Chinese (zh/). Each locale has its own _toctree.yml and _config.py.
The English docs under docs/source/en/ are structured into:
conceptual_guides/ — explanations of how agents and tools worktutorials/ — step-by-step usage guidesexamples/ — extended worked examplesreference/ — API reference pagesguided_tour.md, installation.md, index.mdDocs are built and deployed via three GitHub Actions workflows: build_documentation.yml, build_pr_documentation.yml, and upload_pr_documentation.yml. The published docs are hosted at https://huggingface.co/docs/smolagents.
docs/.github/workflows/build_documentation.ymlUpdated
The TransformersModel in src/smolagents/models.py auto-detects whether the target checkpoint is a vision-language model (VLM) by first attempting to load it with AutoModelForImageTextToText; if that raises ValueError: Unrecognized configuration class, it falls back to AutoModelForCausalLM. This means the same class handles both pure-text and multimodal local models without any user configuration.
For streaming, TransformersModel.generate_stream() spawns the model.generate() call in a background Thread and yields ChatMessageStreamDelta objects via TextIteratorStreamer. Token usage (input prompt token count + generated token count) is tracked per-delta.
VLLMModel also supports structured outputs via vLLM's StructuredOutputsParams with JSON Schema, enabling reliable structured-output generation locally. MLXModel explicitly does not support structured outputs and raises ValueError if response_format is passed.
src/smolagents/models.pyUpdated
Agent memory is modelled in src/smolagents/memory.py as a typed step list on AgentMemory. Step types form a hierarchy:
SystemPromptStep — the initial system promptTaskStep — the user task, with optional attached imagesPlanningStep — an optional planning message produced at planning_intervalActionStep — one ReAct cycle: model input messages, code/tool call, observations, error, token usage, and step timingFinalAnswerStep — the terminal step holding the agent's answerEach step implements to_messages(summary_mode: bool) which renders it as a list of ChatMessage dicts suitable for the next LLM call. summary_mode=True is used during planning updates to strip previous plan messages and shrink context.
Step callbacks are registered via CallbackRegistry and are dispatched per step type; this is the integration point for custom logging, evaluation harnesses, or live UI updates.
src/smolagents/memory.pysrc/smolagents/agents.pyUpdated
The ChatMessage dataclass (in src/smolagents/models.py) is the universal message format across all model backends. It carries role (a MessageRole enum: user/assistant/system/tool-call/tool-response), content (str or multi-modal list of dicts), tool_calls (list of ChatMessageToolCall), raw (original provider response), and token_usage.
get_clean_message_list() normalises a heterogeneous list of ChatMessage objects and dicts into a clean provider-compatible format: it merges consecutive same-role messages, handles image encoding (inline base64 or image_url), applies role conversions (e.g. tool-response → user for providers that don't support tool roles), and optionally flattens multimodal content to plain text for providers like Ollama and Groq.
Streaming is modelled via ChatMessageStreamDelta / ChatMessageToolCallStreamDelta; agglomerate_stream_deltas() assembles a complete ChatMessage from a stream.
src/smolagents/models.pyUpdated
Agent and tool serialisation is handled by src/smolagents/serialization.py. The SafeSerializer class provides a prefix-based wire format for passing Python objects in and out of remote execution sandboxes:
safe:<json> — JSON-safe encoding that handles common Python types (dicts, lists, tuples, sets, bytes, complex numbers, PIL Images, numpy arrays, dataclasses, datetime types, Path, Decimal).pickle:<base64> — pickle fallback, only used when allow_pickle=True is explicitly set.When allow_pickle=False (the default in all remote executors), any object that cannot be safely JSON-encoded raises a SerializationError rather than silently falling back to pickle. The SafeSerializer deserialiser code is injected verbatim into the remote kernel via get_deserializer_code() so it runs without needing smolagents installed in the sandbox.
src/smolagents/serialization.pysrc/smolagents/remote_executors.pyUpdated
Prompt templates for all agent types are stored as YAML files under src/smolagents/prompts/:
code_agent.yaml — for CodeAgentstructured_code_agent.yaml — for CodeAgent using structured JSON output (used with providers like Cerebras and Fireworks-AI)toolcalling_agent.yaml — for ToolCallingAgentTemplates are rendered at runtime via Jinja2 (jinja2.StrictUndefined mode) and injected into a PromptTemplates TypedDict containing keys: system_prompt, planning.initial_plan, planning.update_plan_pre_messages, planning.update_plan_post_messages, managed_agent.task, managed_agent.report, final_answer.pre_messages, final_answer.post_messages.
Custom prompt templates can be passed at agent construction time; any missing keys relative to EMPTY_PROMPT_TEMPLATES raise an assertion error immediately. The code_agent.yaml prompt is also included in the package data via pyproject.toml's [tool.setuptools.package-data] entry.
src/smolagents/prompts/src/smolagents/agents.pypyproject.tomlUpdated
smolagents is a Python library for building LLM-powered agents that reason and act using Python code. The core pitch: agent logic fits in roughly 1,000 lines of code (src/smolagents/agents.py), with minimal abstractions on top of raw LLM calls. The two primary agent classes are CodeAgent — which writes its actions as Python code snippets — and ToolCallingAgent, which uses the conventional JSON/text tool-call format. Both follow the ReAct (Reason + Act) loop pattern.
The library is intentionally small: pyproject.toml lists only five hard runtime dependencies (huggingface-hub, requests, rich, jinja2, pillow). Everything else (LiteLLM, transformers, Gradio, E2B, Docker, MCP, OpenAI, Bedrock, vLLM, etc.) is opt-in via extras. The package requires Python ≥ 3.10 and is currently at version 1.25.0.dev0.
README.mdpyproject.tomlsrc/smolagents/agents.pyUpdated
The examples/ directory contains 34 files that demonstrate real usage patterns:
examples/open_deep_research/ — a full multi-agent deep-research application with a Gradio UI (app.py), GAIA benchmark runner (run_gaia.py), and supporting scripts for web browsing, visual QA, text inspection, and Markdown conversion.examples/async_agent/ — shows how to wrap agent runs in an async server.examples/server/ — minimal HTTP server exposing an agent as an endpoint.examples/plan_customization/ — demonstrates overriding the default planning prompts.examples/smolagents_benchmark/ — benchmark harness with a scoring notebook.rag.py, rag_using_chromadb.py, text_to_sql.py, multi_llm_agent.py, sandboxed_execution.py, structured_output_tool.py, gradio_ui.py.These examples are excluded from ruff's E402 (module-import-not-at-top-of-file) rule. The dev extra in pyproject.toml adds sqlalchemy specifically to support the text_to_sql.py example.
examples/pyproject.tomlUpdated
MCP (Model Context Protocol) integration is provided through ToolCollection.from_mcp() in src/smolagents/tools.py and the dedicated src/smolagents/mcp_client.py. The from_mcp method is a context manager that spawns a background thread running an asyncio event loop to handle the MCP server connection.
Three MCP transport types are supported:
mcp.StdioServerParameters — launches a subprocess and communicates over stdin/stdout{"url": "...", "transport": "streamable-http"} — Streamable HTTP (default for dict input){"url": "...", "transport": "sse"} — legacy HTTP+SSE (deprecated)The structured_output parameter controls whether MCP tool outputSchema and structuredContent responses are forwarded to the agent. It currently defaults to False for backwards compatibility, but a FutureWarning is emitted indicating the default will change to True in version 1.25.
Depends on mcpadapt>=0.1.13 and mcp; available via smolagents[mcp].
src/smolagents/tools.pysrc/smolagents/mcp_client.pypyproject.tomlUpdated
The agent loop is implemented in src/smolagents/agents.py as a class hierarchy rooted at MultiStepAgent. Concrete subclasses are CodeAgent and ToolCallingAgent. The loop (_run_stream) cycles through ReAct steps: generate → parse action → execute → store observation → repeat until final_answer() is called or max_steps is reached.
Key design points for engineers:
Steps are yielded as a generator (_run_stream), enabling both blocking (run()) and streaming (run(stream=True)) modes.
A planning_interval parameter triggers an optional planning step that injects an explicit plan into the agent's context every N steps.
final_answer_checks accepts a list of validator callables that gate whether a proposed final answer is accepted.
MultiStepAgent is abstract; subclasses must implement initialize_system_prompt() and _step_stream().
RunResult is the return type when return_full_result=True; it carries output, state, step list, token usage, and timing.
src/smolagents/agents.py
Updated
(no content yet for this node)
Updated
The MultiStepAgent base class supports multi-agent hierarchies through its managed_agents parameter. Any agent can act as an orchestrator by receiving a list of sub-agents; each sub-agent is exposed to the parent as a callable tool with a standardised signature (task: str, additional_args: object).
Agents can be serialised to disk (agent.save(output_dir)) or pushed to a Hugging Face Hub Space repo (agent.push_to_hub(repo_id)). The save format produces:
agent.json — model + tool + metadata dictprompts.yaml — all prompt templatestools/<name>.py — one file per toolmanaged_agents/<name>/ — recursively saved sub-agentsapp.py — auto-generated Gradio UI entry pointrequirements.txt — inferred from tool importsLoading is via MultiStepAgent.from_hub(repo_id, trust_remote_code=True) or MultiStepAgent.from_folder(path).
src/smolagents/agents.pyUpdated
Token usage, step timing, and log output are tracked in src/smolagents/monitoring.py. The Monitor class attaches to every MultiStepAgent instance and records input/output token counts per step via the TokenUsage dataclass. AgentLogger wraps rich.console.Console for coloured terminal output at configurable LogLevel (DEBUG, INFO, WARNING, ERROR).
OpenTelemetry-based observability is available via the telemetry optional extra (pyproject.toml), which installs arize-phoenix, opentelemetry-sdk, opentelemetry-exporter-otlp, and openinference-instrumentation-smolagents>=0.1.15. When this extra is installed and a Phoenix server is running, agent traces are exported automatically using OpenInference conventions.
The RunResult object (returned by agent.run(return_full_result=True)) carries aggregated TokenUsage and a Timing record with wall-clock start/end times for the full run.
src/smolagents/monitoring.pysrc/smolagents/agents.pypyproject.tomlUpdated
Cost awareness in smolagents is handled through token usage tracking rather than direct dollar amounts. TokenUsage (defined in src/smolagents/monitoring.py) accumulates input_tokens and output_tokens for each ActionStep and PlanningStep. When return_full_result=True, the run-level RunResult.token_usage sums all step-level counts.
The benchmark (examples/smolagents_benchmark/) demonstrates that CodeAgent uses ~30% fewer steps than ToolCallingAgent for the same tasks, which directly translates to fewer LLM calls and lower cost. The planning_interval knob trades token cost (planning calls add tokens) against solution quality (plans help on long-horizon tasks). The max_steps hard limit on MultiStepAgent prevents runaway cost from infinite loops.
For providers with strict rate limits, ApiModel accepts a requests_per_minute float that activates RateLimiter throttling across all calls.
src/smolagents/monitoring.pysrc/smolagents/agents.pysrc/smolagents/models.pyUpdated
The codebase deliberately chose CodeAgent (code-as-actions) over the more common JSON tool-call format as its primary agent paradigm. The README cites two papers to justify this: code actions require 30% fewer steps than JSON tool dictionaries, and outperform JSON agents on difficult benchmarks. The benchmark code lives in examples/smolagents_benchmark/run.py.
A consequence of this choice is that the entire execution pipeline must maintain a consistent code format across: the system prompt (which explains the format to the LLM), the parser (parse_code_blobs() in src/smolagents/utils.py), and the executor (LocalPythonExecutor or a remote executor). A fix-up pass (fix_final_answer_code() in src/smolagents/local_python_executor.py) handles the common LLM mistake of assigning to final_answer instead of calling it as a function.
README.mdsrc/smolagents/local_python_executor.pysrc/smolagents/utils.py