Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,6 @@ async def main():
asyncio.run(main())
```

### Pre-minted session tokens

Use a pre-minted session token when another trusted service has already
snapshotted the persona and session configuration:

```python
client = AnamClient(session_token="your-session-token")

async with client.connect() as session:
await session.talk("This text is sent directly to TTS.")
```

The token and its server-side snapshot are authoritative. Do not also pass an
API key, persona configuration, client label, routing override, or session
options that you expect to override that snapshot.

## Features

- 🎥 **Real-time Audio/Video streaming** - Receive synchronized audio/video frames from the avatar (as PyAV AudioFrame/VideoFrame objects)
Expand Down
8 changes: 2 additions & 6 deletions src/anam/_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@


class CoreApiClient:
"""Internal client for Anam REST API.

Starts sessions using either direct API-key auth or a pre-minted token.
"""
"""Internal client for Anam REST API."""

def __init__(
self,
Expand Down Expand Up @@ -49,8 +46,7 @@ async def start_session(
"""Start a new streaming session.

Args:
persona_config: The persona configuration for API-key auth. The
server-side token snapshot is used for session-token auth.
persona_config: The persona configuration for API-key auth.
session_options: Additional session options.

Returns:
Expand Down
22 changes: 2 additions & 20 deletions src/anam/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,14 @@ def __init__(
):
"""Initialize the Anam client.

Authenticate with either an API key or a pre-minted session token.

API-key authentication requires either `persona_id` for a simple setup
or `persona_config` for full configuration control. A session token
already contains the server-side persona and session snapshot, so it
must not be combined with either persona argument.
or `persona_config` for full configuration control.

Args:
api_key: Your Anam API key. Mutually exclusive with `session_token`.
api_key: Your Anam API key.
persona_id: ID of the persona to use (simple setup).
persona_config: Full persona configuration (advanced setup).
options: Additional client options.
session_token: A pre-minted Anam session token. Mutually exclusive
with `api_key` and persona configuration.

Raises:
ConfigurationError: If configuration is invalid.
Expand All @@ -116,16 +110,7 @@ def __init__(
),
)
```

Pre-minted session token:
```python
client = AnamClient(session_token="your-session-token")
```
"""
# Before direct API-key session starts were introduced, the first
# positional argument was commonly a pre-minted session token. API keys
# never contain dots, while Anam session JWTs do, so retain that legacy
# form while recommending the explicit session_token keyword.
if (
api_key
and "." in api_key
Expand Down Expand Up @@ -573,9 +558,6 @@ async def send_message(self, content: str) -> None:
Raises:
SessionError: If not connected or if LLM is not available.
"""
# A pre-minted token owns its persona/brain snapshot server-side, so
# there is intentionally no local PersonaConfig to inspect. API-key
# sessions retain the useful warning for obviously unhandled input.
persona_config = None if self._client._session_token else self._get_persona_config()
if (
persona_config
Expand Down
Loading