npm package: @smallest-ai/agent-sdk
Description: SDK for connecting to Smallest AI voice agents — no WebRTC required
Latest version: 0.1.0

# Atoms Agent SDK

Connect to your Atoms voice agent with a few lines of code. The SDK handles microphone capture, audio playback, and WebSocket communication — you just listen for events.

## Installation

```bash
npm install @smallest-ai/agent-sdk
```

Or use the CDN in a browser:

```html
<script src="https://cdn.jsdelivr.net/npm/@smallest-ai/agent-sdk/dist/agent-sdk.browser.js"></script>
```

## Quick Start

### npm / Bundler

```javascript
import { AtomsAgent } from "@smallest-ai/agent-sdk";

const agent = new AtomsAgent({
  apiKey: "sk_...",
  agentId: "your_agent_id",
});

agent.on("agent_start_talking", () => console.log("Agent speaking..."));
agent.on("agent_stop_talking", () => console.log("Agent stopped"));

await agent.connect();
// Microphone is automatically captured.
// Speak and the agent will respond through your speakers.

// When done:
agent.disconnect();
```

### Browser (CDN)

```html
<script src="https://cdn.jsdelivr.net/npm/@smallest-ai/agent-sdk/dist/agent-sdk.browser.js"></script>
<script>
  const agent = new AtomsSdk.AtomsAgent({
    apiKey: "sk_...",
    agentId: "your_agent_id",
  });

  agent.on("agent_start_talking", () => console.log("Agent speaking..."));
  agent.on("agent_stop_talking", () => console.log("Agent stopped"));

  agent.connect();
</script>
```

## Configuration

```javascript
const agent = new AtomsAgent({
  apiKey: "sk_...",       // Required — your API key
  agentId: "...",         // Required — agent to connect to
});
```

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `apiKey` | string | — | Your Atoms API key |
| `agentId` | string | — | The agent ID to connect to |

## Methods

### `connect()`

Connect to the agent and start a session. If `autoCaptureMic` is `true`, the microphone starts immediately.

```javascript
await agent.connect();
```

### `disconnect()`

End the session and clean up all resources (microphone, audio playback, WebSocket).

```javascript
agent.disconnect();
```

### `mute()`

Stop sending microphone audio to the agent. The connection stays open.

```javascript
agent.mute();
```

### `unmute()`

Resume sending microphone audio.

```javascript
agent.unmute();
```

### `isConnected`

Returns `true` if connected to the agent.

```javascript
if (agent.isConnected) { ... }
```

### `isMuted`

Returns `true` if the microphone is muted.

```javascript
if (agent.isMuted) { ... }
```

## Events

Listen for events using `agent.on(eventName, callback)`.

### `session_started`

Fired when the session is created and ready.

```javascript
agent.on("session_started", (event) => {
  console.log("Session ID:", event.session_id);
  console.log("Call ID:", event.call_id);
});
```

### `session_ended`

Fired when the session ends. After this event, the agent is disconnected.

```javascript
agent.on("session_ended", (event) => {
  console.log("Ended:", event.reason);
  // reason: "client_requested", "agent_disconnected", "websocket_closed", etc.
});
```

### `agent_start_talking`

Fired when the agent begins speaking.

```javascript
agent.on("agent_start_talking", () => {
  console.log("Agent is speaking...");
});
```

### `agent_stop_talking`

Fired when the agent finishes speaking.

```javascript
agent.on("agent_stop_talking", () => {
  console.log("Agent stopped speaking.");
});
```

### `error`

Fired when an error occurs.

```javascript
agent.on("error", (event) => {
  console.error(`Error [${event.code}]: ${event.message}`);
});
```

## Examples

### Voice Agent

The user speaks into the microphone, the agent responds with audio.

```javascript
const agent = new AtomsAgent({
  apiKey: "sk_...",
  agentId: "...",
});

agent.on("session_started", () => console.log("Ready — speak now"));
agent.on("agent_start_talking", () => console.log("Agent speaking..."));
agent.on("agent_stop_talking", () => console.log("Agent stopped"));
agent.on("session_ended", (e) => console.log("Ended:", e.reason));
agent.on("error", (e) => console.error(e.message));

await agent.connect();
```

### Mute / Unmute

```javascript
await agent.connect();

agent.mute();   // Stop sending mic audio
agent.unmute(); // Resume
```

### UI Integration

```javascript
const agent = new AtomsAgent({
  apiKey: "sk_...",
  agentId: "...",
});

agent.on("session_started", () => showStatus("Connected"));
agent.on("agent_start_talking", () => showStatus("Agent speaking..."));
agent.on("agent_stop_talking", () => showStatus("Listening..."));
agent.on("error", (e) => showStatus(`Error: ${e.message}`));
agent.on("session_ended", () => showStatus("Disconnected"));

connectButton.onclick = () => agent.connect();
disconnectButton.onclick = () => agent.disconnect();
muteButton.onclick = () => {
  agent.isMuted ? agent.unmute() : agent.mute();
};
```

## Audio Format

All audio is handled internally by the SDK. If you're building a custom integration without the SDK, the raw WebSocket protocol uses:

| Property | Value |
|----------|-------|
| Encoding | PCM 16-bit signed, little-endian |
| Sample rate | 24,000 Hz |
| Channels | 1 (mono) |
| Transport | Base64-encoded inside JSON |

## Error Handling

If the session fails to create (invalid API key, no credits, agent not found), the WebSocket closes with code `4000` and the error as the close reason:

```javascript
agent.on("error", (e) => {
  if (e.code === "400") {
    // Credits exhausted, agent not found, etc.
  }
});

agent.on("session_ended", (e) => {
  // e.reason contains the close reason
});
```

## Browser Support

The SDK uses standard Web APIs:
- `WebSocket` — for server communication
- `getUserMedia` — for microphone access
- `AudioContext` — for audio playback
- `ScriptProcessorNode` — for audio capture

Supported in all modern browsers (Chrome, Firefox, Safari, Edge).

## Limits

| Limit | Value |
|-------|-------|
| Max session duration | 15 minutes |
| Audio format | PCM 16-bit, 24kHz, mono |