What is Atoms Agent Crews SDK?

View as Markdown

The Atoms Agent Crews SDK is the Python framework for building voice agents on the Smallest AI platform. Your code owns the LLM turn and any application logic. The platform owns speech-to-text, text-to-speech, telephony, and turn-taking. The SDK handles streaming audio, conversation state, and tool coordination in between.

This page walks the whole picture. What each piece is called, how the lifecycle runs from create to live call, the two independent versioning axes, and a working sample you can drop in.

What agent-crew is

Agent-crew lets you run the agent’s brain (the LLM turn plus your logic) as your own code, in real time over a WebSocket. Smallest handles speech-to-text, text-to-speech, telephony, and turn-taking around it. Your code owns the words. The platform owns everything around them.

Runtime boundary. Smallest handles STT and TTS. Your crew node handles the LLM turn.

Crew, node, and crew code

  • Crew. The framework that runs a set of nodes collaborating in one real-time WebSocket session. Even a single agent is a crew of one node. In code, AtomsCrewApp is the WebSocket server that hosts crews. CrewSession is the crew instance for one live call, which the platform connects to when a call comes in.

  • Node. A unit of logic inside a session. There are two kinds.

    • OutputCrewNode produces user-facing output. Its generate_response() yields text that the platform speaks. This is the “agent” most people mean.
    • BackgroundCrewNode observes events silently, no audio. Use it for live sentiment, compliance, or logging. Output nodes can read its state mid-call.

    Multiple nodes can run in parallel in one session.

  • Crew code. Your Python project (server.py + node files + requirements.txt) that defines the crew and wires its nodes in the setup_handler. It’s the deployable artifact. agent-crew deploy zips it into a build.

One agent runs one live crew build. A CrewSession hosts your nodes per call.

One agent = one platform agent (config, versioned) + one live crew build (your code, one or more nodes).

The two versioning axes

AxisWhat it isManaged byVersioned as
Configprompt, voice, language, STT/TTS, model settings, tools, timeoutsdashboard or the versioning APIbranches + revisions
Crew codeyour Python that produces the LLM responseagent-crew CLIbuilds

They’re independent. Deploying crew code never creates a config revision. Publishing a config revision never changes which crew build is live. Two axes, two rollback controls.

What the crew node owns

A crew node produces text. generate_response() yields text, and speak(text) emits a text event. It has no voice, language, STT, or TTS setting. Those live on the agent config. At call time the platform voices your node’s text using the agent’s active config revision, so the node always uses the latest activated voice and language. You change them by editing the config, not the node.

Full lifecycle

1

Create the agent (platform)

Dashboard, CLI, or SDK.

agent-crew does not create the agent. It links your local code to an existing agent. Create the agent first.

1from smallestai import SmallestAI
2agent_id = SmallestAI().atoms.agents.create_agent(name="my-agent").data

Or from the terminal:

$smallestai agents create "my-agent"

A new agent starts with a main branch at revision 1, live.

2

Set the config

Voice, language, STT model, TTS voice, first message, prompt. Dashboard, or the versioning API. Each publish is a tracked revision.

3

Write the crew code

A project with server.py (an AtomsCrewApp) and one or more nodes. Include a requirements.txt or a pyproject.toml. See the working sample below.

5

Test locally

$python server.py # ws://localhost:8080/ws
$smallestai agent-crew chat # in another terminal

Uses your shell env for keys.

6

Deploy (upload)

$smallestai agent-crew deploy

The CLI zips the directory, base64-encodes it, and sends it to the backend. The backend stores it in S3. An orchestrator builds a container image (BUILDING), deploys it (DEPLOYING), assigns a websocketUrl, and marks the build SUCCEEDED (or BUILD_FAILED / DEPLOY_FAILED).

Secrets aren’t injected yet, so ship a .env next to server.py. It rides in the zip, and load_dotenv() reads it in the cloud.

7

Go live

A SUCCEEDED build isn’t live by default. Promote it:

$smallestai agent-crew builds # then choose Make Live

One build is live at a time. Making a new one live takes the old one down. This refreshes the agent config cache so calls route to your build.

8

A call runs

Smallest STT transcribes the caller. Your live crew build (the LLM) produces text. Smallest TTS speaks it using the active config revision’s voice and language. Telephony carries it to the caller.

Updating config or crew code

  • Update config (voice, language, prompt, and so on). Edit and publish. This creates a new revision. The next call uses it. Roll back by restoring an earlier revision.
  • Update crew code. Edit and agent-crew deploy. This creates a new build. Make it live. Roll back by making an older build live.

Config versioning

Everything on the config side works normally. Create, edit, publish, view history, diff, restore.

1from smallestai import SmallestAI
2from smallestai.atoms.helpers import Versioning
3
4client = SmallestAI() # reads SMALLEST_API_KEY
5v = Versioning(client)
6agent_id = "..."
7
8# find the live Main branch
9main = next(b for b in v.branches.list(id=agent_id).data.branches if b.branch.is_default).branch.id
10
11# change the voice + language (a tracked revision), publish, wait for the scan
12rev = v.edit_and_publish(
13 agent_id, main,
14 synthesizer={"voiceConfig": {"model": "waves_lightning_v3_1", "voiceId": "emily"}},
15 language={"default": "en", "supported": ["en"]},
16 label="switch voice to emily",
17)
18print(rev.id, rev.status) # -> published
19
20# history, diff, restore
21revs = client.atoms.agent_versioning_revisions.list(id=agent_id, branch_id=main).data
22client.atoms.agent_versioning_revisions.diff(id=agent_id, a="<revA>", b="<revB>")
23client.atoms.agent_versioning_revisions.restore(id=agent_id, branch_id=main, revision_id="<older>")

Eventual consistency. After a publish, get_agent and the branch head read-back lag ~1-3s. A call started right after publishing may still use the previous revision. Poll or re-fetch.

Crew-code versioning

  • agent-crew deploy produces a new build (deploy history).
  • agent-crew builds lists builds. You can Make Live, Take Down, or roll back to an older build.

Deploying doesn’t touch config revisions. The two axes roll back independently.

Working sample

assistant.py is the node. Bring your own LLM by pointing base_url at your runtime, drop it for OpenAI, or use Smallest’s Electron.

1import os
2from smallestai.atoms.crew.nodes import OutputCrewNode
3from smallestai.atoms.crew.clients.openai import OpenAIClient
4
5
6class Assistant(OutputCrewNode):
7 def __init__(self):
8 super().__init__(name="assistant")
9 self.llm = OpenAIClient(
10 model="gpt-4o-mini",
11 api_key=os.getenv("OPENAI_API_KEY"),
12 # base_url="https://your-runtime.example.com/v1", # bring your own LLM
13 )
14 self.context.messages.append(
15 {"role": "system", "content": "You are a friendly, concise voice assistant."}
16 )
17
18 async def generate_response(self):
19 response = await self.llm.chat(messages=self.context.messages, stream=True)
20 full = ""
21 async for chunk in response:
22 if chunk.content:
23 full += chunk.content
24 yield chunk.content
25 self.context.messages.append({"role": "assistant", "content": full})

server.py is the WebSocket app. It greets on join.

1from smallestai.atoms.crew import AtomsCrewApp
2from smallestai.atoms.crew.events import SDKSystemUserJoinedEvent
3from assistant import Assistant
4
5
6async def setup_session(session):
7 agent = Assistant()
8 session.add_node(agent)
9 await session.start()
10
11 @session.on_event("on_event_received")
12 async def on_event(event):
13 if isinstance(event, SDKSystemUserJoinedEvent):
14 await agent.speak("Hi! How can I help you today?")
15
16 await session.wait_until_complete()
17
18
19AtomsCrewApp(setup_handler=setup_session).run()

requirements.txt:

smallestai>=5.3.0

Run and test.

$export SMALLEST_API_KEY=sk_...
$export OPENAI_API_KEY=sk-... # or your runtime's key
>pip install -r requirements.txt
>python server.py # ws://localhost:8080/ws
># second terminal:
>smallestai agent-crew chat

FAQ

No. Create the agent on the platform first (dashboard, smallestai agents create, or client.atoms.agents.create_agent). Then agent-crew init links your code to it.

The agent config, which is versioned. Not the crew code. The node emits text. The platform voices it with the active revision.

No. Crew code and config are independent axes.

Yes on both axes.

  • Config. Branches and revisions. Restore an earlier revision.
  • Crew code. Builds. Make Live an older build.

Roll them back separately.

Edit the agent config (dashboard or edit_and_publish on the synthesizer field). Publish. It becomes a tracked revision and applies on the next call.

Yes. Multiple OutputCrewNodes and BackgroundCrewNodes in one CrewSession.


Get Started


Build