Agent Versioning

View as Markdown

Every agent’s config — prompt, tools, voice, language, post-call metrics, and more — is managed as versions. You edit in isolated drafts, publish drafts as new versions, and activate the version you want live. Previous versions are kept so you can compare and restore at any time.


Core Concepts

ConceptDescription
VersionAn immutable snapshot of agent config. Only metadata (label, description, pin) can change after publish.
Active versionThe single version currently serving calls. Every agent has exactly one.
DraftA mutable workspace forked from a version or from another draft. Edits are auto-saved and do not affect live calls.
RevisionEach edit inside a draft increments a revision counter, giving you a save history per draft.

When you open an older or non-active version, the editor is read-only — the only way to change it is to create a draft from it.

Create a draft to edit

Read-only view. Editing requires a draft.

Creating a Draft

Drafts can be forked from either a published version or another draft:

  • From the active version — click Create Draft on a read-only version.
  • From any older version — open the Version history panel, then New draft next to the version.
  • From an existing draft — hover a draft in the Drafts panel and click New draft to fork it.

New draft from draft

Fork a new draft from an existing draft.

Once the draft is created, the agent header switches from V1 (Read-only) to Draft #N and every field in the editor becomes editable.

Draft editable

Draft #2-ce62 is now editable. Edits auto-save with a revision counter.

Drafts are private scratch space. Multiple drafts can exist in parallel — for example, one experimenting with a new voice and another tuning the prompt.


Browsing Versions and Drafts

The version switcher at the top of the editor has two tabs:

Every published version, newest first. The currently-active one is tagged Active. Older versions show a Restore action; the active one shows a New draft link.

Version history

Version history. V1 is active.

Comparing Versions

Use Compare versions to see exactly what changed between any two snapshots — published versions or drafts.

1

Pick a base and a comparison

Both dropdowns list all published versions and all open drafts.

Select versions to compare

2

Review the diff

Sections are shown only if they changed. Red is removed content, green is added. The Workflow Prompt section shows a line-by-line diff:

Prompt diff

3

Inspect config sections

LLM model, voice config, and language settings each render as their own grouped diff:

Config diff


Publishing a Draft

When a draft is ready, click Publish in the top right. The Review Changes dialog shows the diff against the current active version and asks for a label + description.

Review Changes

Review diff, label the version, and choose whether to activate on publish.
FieldRequiredDescription
Version labelYesShort human-readable name (e.g., “Version 2 with Hindi”).
DescriptionNoLonger note about what changed and why.
Activate after publishingDefault onWhen enabled, the new version immediately takes over live calls.

After publishing, the draft is removed and the new version appears in the Version history. If you chose to activate, it also becomes the new Active entry. The previous active version gets a Restore action.

After publish

V2 is now active. V1 can still be restored.

Restoring an Older Version

Click Restore next to an older version to set it active again. The currently-active version is not deleted — you can swap back any time. Restoring never modifies config; it just changes which version serves live calls.


Managing Versions via API

Every action in the UI is available through the public API.

All examples assume BASE="https://api.smallest.ai/atoms/v1" and API_KEY is set in your environment.

Full flow — edit, publish, activate

1import os
2import requests
3
4API_KEY = os.environ["SMALLEST_API_KEY"]
5AGENT_ID = "YOUR_AGENT_ID"
6BASE = "https://api.smallest.ai/atoms/v1"
7HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
8
9# 1. Read the active version
10agent = requests.get(f"{BASE}/agent/{AGENT_ID}", headers=HEADERS).json()
11active_version_id = agent["data"]["activeVersionId"]
12
13# 2. Fork a draft from the active version
14draft = requests.post(
15 f"{BASE}/agent/{AGENT_ID}/drafts",
16 headers=HEADERS,
17 json={"sourceVersionId": active_version_id, "draftName": "tune-prompt"},
18).json()
19draft_id = draft["data"]["draftId"]
20
21# 3. Update fields on the draft (any subset is allowed)
22requests.patch(
23 f"{BASE}/agent/{AGENT_ID}/drafts/{draft_id}/config",
24 headers=HEADERS,
25 json={
26 "singlePromptConfig": {
27 "prompt": "You are a helpful assistant..."
28 },
29 "synthesizer": {
30 "voiceConfig": {"model": "waves_lightning_large", "voiceId": "nyah"},
31 "speed": 1.2,
32 },
33 },
34).raise_for_status()
35
36# 4. Publish as a new version and activate it
37published = requests.post(
38 f"{BASE}/agent/{AGENT_ID}/drafts/{draft_id}/publish",
39 headers=HEADERS,
40 json={"label": "v2 - friendlier prompt", "description": "Softened tone", "activate": True},
41).json()
42print("New active version:", published["data"]["version"]["_id"])

Common operations

OperationMethod + Path
List draftsGET /agent/{id}/drafts
Fork a draftPOST /agent/{id}/drafts with sourceVersionId or sourceDraftId
Rename a draftPATCH /agent/{id}/drafts/{draftId}
Discard a draftDELETE /agent/{id}/drafts/{draftId}
Update draft configPATCH /agent/{id}/drafts/{draftId}/config
Diff draft vs versionGET /agent/{id}/drafts/{draftId}/diff?versionId=...
Publish a draftPOST /agent/{id}/drafts/{draftId}/publish
List published versionsGET /agent/{id}/versions
Get one versionGET /agent/{id}/versions/{versionId}
Diff two versionsGET /agent/{id}/versions/diff?baseId=...&compareId=...
Activate a versionPATCH /agent/{id}/versions/{versionId}/activate
Update version metadataPATCH /agent/{id}/versions/{versionId} (label, description, isPinned)

See the full schema in the API Reference.

Reading active config

GET /agent/{id} returns the agent document with the active version’s resolved config merged under _resolvedConfig:

$curl -H "Authorization: Bearer $SMALLEST_API_KEY" \
> "$BASE/agent/$AGENT_ID" \
> | jq '.data | {activeVersionId, prompt: ._resolvedConfig.prompt, tools: ._resolvedConfig.tools, analytics: ._resolvedConfig.postCallAnalyticsConfig}'

GET /agent/{id}/workflow returns {prompt, tools} for the active version only. The versionId query parameter on this endpoint is currently ignored — to inspect a non-active version’s config, call GET /agent/{id}/versions/{versionId} instead.

PATCH /workflow/{id} still works but bypasses versioning. It writes directly to the legacy workflow document: the change is not captured as a version, and any field missing from the PATCH payload can be silently wiped. On a versioned agent, always go through PATCH /agent/{id}/drafts/{draftId}/config and publish.