> ## Documentation Index
> Fetch the complete documentation index at: https://docs.maximem.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Smolagents

> Synap memory tools and a per-step turn recorder for Hugging Face Smolagents.

Give a [Smolagents](https://github.com/huggingface/smolagents) `CodeAgent` or `ToolCallingAgent` persistent memory through Synap. Smolagents keeps its own fixed step log with no pluggable memory backend, so Synap plugs into the extension points it *does* expose: `@tool` functions, a `step_callbacks` recorder, and static `instructions`.

<Note>
  Requires Python 3.11+ and `smolagents>=1.26`.
</Note>

## Overview

Three surfaces, mapped onto Smolagents' own extension points. Adopt only the ones you need.

| Surface                 | Smolagents extension point         | Purpose                                                      |
| ----------------------- | ---------------------------------- | ------------------------------------------------------------ |
| `create_synap_tools`    | `@tool`                            | Explicit `search_memory` / `store_memory` the model can call |
| `create_synap_recorder` | `step_callbacks={ActionStep: ...}` | Record each completed action into Synap for future recall    |
| `synap_st_instructions` | `CodeAgent(instructions=...)`      | Fold Synap short-term context into the agent's instructions  |

All three take an already-constructed `MaximemSynapSDK` — your app owns the SDK and its credentials.

## Setup

<CodeGroup>
  ```bash pip theme={null}
  pip install maximem-synap-smolagents smolagents
  ```

  ```bash uv theme={null}
  uv add maximem-synap-smolagents smolagents
  ```
</CodeGroup>

## Basic integration

Give the agent memory tools it can call. Because `CodeAgent` writes its actions as Python, `search_memory` / `store_memory` compose naturally into the code it generates.

```python theme={null}
from smolagents import CodeAgent, InferenceClientModel
from maximem_synap import MaximemSynapSDK
from synap_smolagents import create_synap_tools

sdk = MaximemSynapSDK(api_key="sk-...")

agent = CodeAgent(
    model=InferenceClientModel(),
    tools=create_synap_tools(sdk, user_id="alice", customer_id="acme"),
)
agent.run("What did we decide about the rollout?")
```

## Core concepts

### create\_synap\_tools

Returns `search_memory` and `store_memory` as Smolagents `@tool` functions. `search_memory` reads Synap's long-term layer and returns formatted context; `store_memory` ingests a fact for future recall. Reads degrade to a not-found message; the write raises `SynapIntegrationError` so a failed store is observable.

### create\_synap\_recorder

Records each completed step into Synap. Register it per step type on the agent:

```python theme={null}
from smolagents import CodeAgent, InferenceClientModel
from smolagents.memory import ActionStep
from synap_smolagents import create_synap_recorder

agent = CodeAgent(
    model=InferenceClientModel(),
    tools=[],
    step_callbacks={
        ActionStep: create_synap_recorder(
            sdk, user_id="alice", conversation_id="conv_abc"
        )
    },
)
```

Each `ActionStep` is written to its own Synap document, so a multi-step run is captured in full. Failed or empty steps are skipped.

### synap\_st\_instructions

Smolagents' `instructions` is a static string, so short-term context is folded into it once at construction.

```python theme={null}
from synap_smolagents import synap_st_instructions

agent = CodeAgent(
    model=InferenceClientModel(),
    tools=[],
    instructions=synap_st_instructions(
        sdk, conversation_id="conv_abc",
        instructions="You are a concise, friendly assistant.",
    ),
)
```

`conversation_id` is required. Empty context is a no-op; SDK failures are swallowed by default (`on_error="fallback"`), or set `on_error="raise"` for strict environments.

## Complete example: memory-augmented CodeAgent

```python theme={null}
from smolagents import CodeAgent, InferenceClientModel
from smolagents.memory import ActionStep
from maximem_synap import MaximemSynapSDK
from synap_smolagents import create_synap_tools, create_synap_recorder, synap_st_instructions

sdk = MaximemSynapSDK(api_key="sk-...")

agent = CodeAgent(
    model=InferenceClientModel(),
    tools=create_synap_tools(sdk, user_id="alice", customer_id="acme"),
    instructions=synap_st_instructions(
        sdk, conversation_id="conv_abc",
        instructions="You are a concise, friendly assistant.",
    ),
    step_callbacks={
        ActionStep: create_synap_recorder(
            sdk, user_id="alice", conversation_id="conv_abc", customer_id="acme"
        )
    },
)
agent.run("Remind me what plan I'm on and my open ticket.")
```

## Advanced patterns

### Synchronous framework, async SDK

Smolagents runs synchronously and its tools do not support `async`, so every surface bridges to the async Synap SDK internally (via the shared `run_async` helper). If your application is otherwise async, follow Hugging Face's guidance and run the agent on its own thread (e.g. `await anyio.to_thread.run_sync(agent.run, task)`).

### Error policy

* **The `search_memory` tool** degrades — a Synap blip returns a not-found message.
* **The `store_memory` tool** raises `SynapIntegrationError` on failure (model-driven, user-initiated).
* **The recorder logs and never raises.** It runs inside the agent loop, in a `finally` with no surrounding try/except, so a raising callback would abort the whole run — a failed ingest is logged and swallowed.

## Going further

* **Scoping.** `user_id` and `customer_id` flow straight to Synap; per-user isolation and B2C/B2B scope are derived server-side from the ids you pass.

## Next steps

<CardGroup cols={2}>
  <Card title="SDK: Ingestion" icon="upload" href="/sdk/ingestion">
    How `memories.create` extraction differs from conversation recording.
  </Card>

  <Card title="Integrations overview" icon="grid-2" href="/integrations/overview">
    Every framework Synap plugs into.
  </Card>
</CardGroup>
