stella-ai-agent-sdk 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stella_ai_agent_sdk-0.5.0/LICENSE +21 -0
- stella_ai_agent_sdk-0.5.0/PKG-INFO +272 -0
- stella_ai_agent_sdk-0.5.0/README.md +237 -0
- stella_ai_agent_sdk-0.5.0/pyproject.toml +60 -0
- stella_ai_agent_sdk-0.5.0/setup.cfg +4 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/__init__.py +155 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/_grpc/__init__.py +13 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/_grpc/agent_pb2.py +96 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/_grpc/agent_pb2.pyi +277 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/_grpc/agent_pb2_grpc.py +283 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/_grpc/state_machine_pb2.py +96 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/_grpc/state_machine_pb2.pyi +306 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/_grpc/state_machine_pb2_grpc.py +546 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/_grpc/stt_pb2.py +48 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/_grpc/stt_pb2_grpc.py +192 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/_grpc/tts_pb2.py +50 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/_grpc/tts_pb2_grpc.py +232 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/agent/__init__.py +6 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/agent/barge_in_evaluator.py +191 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/agent/base.py +1071 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/audio/__init__.py +5 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/audio/pipeline.py +2284 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/env.py +48 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/language.py +239 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/livekit/__init__.py +5 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/livekit/room.py +564 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/llm/__init__.py +32 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/llm/service.py +850 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/messages/__init__.py +21 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/messages/input.py +88 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/messages/output.py +537 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/messages/types.py +172 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/plan/__init__.py +53 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/plan/migration.py +223 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/plan/types.py +240 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/progress/__init__.py +94 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/progress/builder.py +343 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/progress/types.py +477 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/prompts/__init__.py +66 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/prompts/base.py +41 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/prompts/placeholder_compiler.py +552 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/prompts/registry.py +113 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/prompts/template.py +121 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/py.typed +0 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/run.py +698 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/services/__init__.py +15 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/services/agent_server_client.py +106 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/services/history_client.py +244 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/services/state_machine_client.py +532 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/services/stt_client.py +321 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/services/tts_client.py +244 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/__init__.py +20 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/base.py +163 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/executor.py +297 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/registry.py +140 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/state_machine/__init__.py +61 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/state_machine/batch_update.py +303 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/state_machine/complete_task.py +105 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/state_machine/get_deliverables.py +61 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/state_machine/get_state.py +64 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/state_machine/get_tasks.py +61 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/state_machine/guidance.py +32 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/state_machine/result.py +44 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/state_machine/set_deliverable.py +91 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/state_machine/skip_state.py +67 -0
- stella_ai_agent_sdk-0.5.0/src/stella_agent_sdk/tools/state_machine/skip_task.py +88 -0
- stella_ai_agent_sdk-0.5.0/src/stella_ai_agent_sdk.egg-info/PKG-INFO +272 -0
- stella_ai_agent_sdk-0.5.0/src/stella_ai_agent_sdk.egg-info/SOURCES.txt +84 -0
- stella_ai_agent_sdk-0.5.0/src/stella_ai_agent_sdk.egg-info/dependency_links.txt +1 -0
- stella_ai_agent_sdk-0.5.0/src/stella_ai_agent_sdk.egg-info/requires.txt +15 -0
- stella_ai_agent_sdk-0.5.0/src/stella_ai_agent_sdk.egg-info/top_level.txt +1 -0
- stella_ai_agent_sdk-0.5.0/tests/test_barge_in.py +540 -0
- stella_ai_agent_sdk-0.5.0/tests/test_base_agent.py +227 -0
- stella_ai_agent_sdk-0.5.0/tests/test_floor_hold_236.py +139 -0
- stella_ai_agent_sdk-0.5.0/tests/test_latency_budget.py +34 -0
- stella_ai_agent_sdk-0.5.0/tests/test_llm_stream.py +77 -0
- stella_ai_agent_sdk-0.5.0/tests/test_messages.py +171 -0
- stella_ai_agent_sdk-0.5.0/tests/test_pending_tools.py +96 -0
- stella_ai_agent_sdk-0.5.0/tests/test_progress_builder.py +521 -0
- stella_ai_agent_sdk-0.5.0/tests/test_prompt_compiler.py +289 -0
- stella_ai_agent_sdk-0.5.0/tests/test_sentence_chunking.py +118 -0
- stella_ai_agent_sdk-0.5.0/tests/test_session_end.py +241 -0
- stella_ai_agent_sdk-0.5.0/tests/test_state_machine_tools.py +117 -0
- stella_ai_agent_sdk-0.5.0/tests/test_teleprompter.py +237 -0
- stella_ai_agent_sdk-0.5.0/tests/test_text_barge_in.py +385 -0
- stella_ai_agent_sdk-0.5.0/tests/test_version.py +10 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Universität St. Gallen (HSG) & University of Zurich (UZH)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stella-ai-agent-sdk
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: SDK for building agents that integrate with the STELLA platform
|
|
5
|
+
Author: STELLA Team
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/c4dhi/STELLA/tree/main/agents/stella-ai-agent-sdk
|
|
8
|
+
Project-URL: Documentation, https://github.com/c4dhi/STELLA/tree/main/agents/stella-ai-agent-sdk#readme
|
|
9
|
+
Project-URL: Source, https://github.com/c4dhi/STELLA
|
|
10
|
+
Project-URL: Issues, https://github.com/c4dhi/STELLA/issues
|
|
11
|
+
Keywords: stella,agent,conversational-ai,livekit,grpc
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: grpcio>=1.60.0
|
|
22
|
+
Requires-Dist: grpcio-tools>=1.60.0
|
|
23
|
+
Requires-Dist: pydantic>=2.0.0
|
|
24
|
+
Requires-Dist: livekit<1.0.0,>=0.11.0
|
|
25
|
+
Requires-Dist: PyJWT>=2.0.0
|
|
26
|
+
Requires-Dist: numpy>=1.24.0
|
|
27
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
32
|
+
Provides-Extra: examples
|
|
33
|
+
Requires-Dist: openai>=1.0.0; extra == "examples"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# STELLA Agent SDK
|
|
37
|
+
|
|
38
|
+
A communication SDK for building agents that integrate with the STELLA platform.
|
|
39
|
+
|
|
40
|
+
## Overview
|
|
41
|
+
|
|
42
|
+
The SDK defines the communication protocol - agents implement whatever logic they want internally. It provides:
|
|
43
|
+
|
|
44
|
+
- **Message types** (`AgentInput`, `AgentOutput`) - Standardized formats for agent communication
|
|
45
|
+
- **`BaseAgent`** - Abstract class that agents implement
|
|
46
|
+
- **gRPC client** - Handles connection to session-management server
|
|
47
|
+
|
|
48
|
+
**What the SDK does NOT include:** LLM services, RAG, expert pools, or any processing logic. Those are your agent's implementation details.
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
Requires Python 3.10 or newer.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install stella-ai-agent-sdk
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
To work against unreleased changes, install from source:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git clone https://github.com/c4dhi/STELLA.git
|
|
62
|
+
pip install -e STELLA/agents/stella-ai-agent-sdk
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Or pin directly to a tag without cloning:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install "stella-ai-agent-sdk @ git+https://github.com/c4dhi/STELLA.git@sdk-v0.5.0#subdirectory=agents/stella-ai-agent-sdk"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Quick Start
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
import asyncio
|
|
75
|
+
from typing import AsyncIterator
|
|
76
|
+
from stella_agent_sdk import BaseAgent, AgentInput, AgentOutput, run_agent_from_env
|
|
77
|
+
|
|
78
|
+
class MyAgent(BaseAgent):
|
|
79
|
+
async def on_session_start(self, session_id: str, config: dict) -> None:
|
|
80
|
+
# Initialize your agent with configuration
|
|
81
|
+
self.model = config.get("model", "gpt-4")
|
|
82
|
+
|
|
83
|
+
async def process(self, input: AgentInput) -> AsyncIterator[AgentOutput]:
|
|
84
|
+
# Process user input and yield responses
|
|
85
|
+
yield AgentOutput.thinking(input.session_id)
|
|
86
|
+
|
|
87
|
+
# Your LLM/processing logic here
|
|
88
|
+
response = await my_llm_call(input.text)
|
|
89
|
+
|
|
90
|
+
yield AgentOutput.text_final(input.session_id, response)
|
|
91
|
+
|
|
92
|
+
async def on_interrupt(self, session_id: str) -> None:
|
|
93
|
+
# Handle user interrupt (barge-in)
|
|
94
|
+
self.cancel_current_task()
|
|
95
|
+
|
|
96
|
+
async def on_session_end(self, session_id: str) -> dict:
|
|
97
|
+
# Cleanup and return final data
|
|
98
|
+
return {"messages": self.message_count}
|
|
99
|
+
|
|
100
|
+
# run_agent_from_env() is the ONLY entry point. It reads all connection config
|
|
101
|
+
# (LiveKit room, STT/TTS addresses, AGENT_CONFIG, ...) from environment variables
|
|
102
|
+
# set by the session-management-server, connects everything, and runs the agent.
|
|
103
|
+
if __name__ == "__main__":
|
|
104
|
+
asyncio.run(run_agent_from_env(MyAgent()))
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Architecture
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
LiveKit Server (WebRTC audio/video)
|
|
111
|
+
│
|
|
112
|
+
│ Audio tracks
|
|
113
|
+
│
|
|
114
|
+
▼
|
|
115
|
+
Your Agent (uses SDK)
|
|
116
|
+
│
|
|
117
|
+
├─ STT Service ← Transcribes user speech
|
|
118
|
+
├─ TTS Service ← Synthesizes agent responses
|
|
119
|
+
├─ Receives: AgentInput (text from user)
|
|
120
|
+
└─ Sends: AgentOutput (text responses)
|
|
121
|
+
│
|
|
122
|
+
│ gRPC (SDK protocol)
|
|
123
|
+
│
|
|
124
|
+
▼
|
|
125
|
+
Session-Management-Server (session state, plans, deliverables)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The agent is a **black box** from session-management's perspective:
|
|
129
|
+
1. Agent joins a LiveKit room and subscribes to user audio
|
|
130
|
+
2. STT service transcribes user speech into text
|
|
131
|
+
3. Agent processes input (using whatever LLM/logic you want)
|
|
132
|
+
4. Agent streams text responses back
|
|
133
|
+
5. TTS service synthesizes agent text into audio (unless disabled)
|
|
134
|
+
|
|
135
|
+
## Message Types
|
|
136
|
+
|
|
137
|
+
### Input (from server to agent)
|
|
138
|
+
|
|
139
|
+
| Type | Description |
|
|
140
|
+
|------|-------------|
|
|
141
|
+
| `TEXT` | Transcribed user speech or typed text |
|
|
142
|
+
| `INTERRUPT` | User interrupted (barge-in) |
|
|
143
|
+
| `SESSION_START` | Session starting with configuration |
|
|
144
|
+
| `SESSION_END` | Session ending |
|
|
145
|
+
| `CONFIG` | Runtime configuration update |
|
|
146
|
+
|
|
147
|
+
### Output (from agent to server)
|
|
148
|
+
|
|
149
|
+
| Type | Description | TTS? |
|
|
150
|
+
|------|-------------|------|
|
|
151
|
+
| `TEXT_CHUNK` | Streaming text chunk | Buffered |
|
|
152
|
+
| `TEXT_FINAL` | Complete text response | Yes |
|
|
153
|
+
| `STATUS` | Processing status update | No |
|
|
154
|
+
| `METADATA` | Plan/deliverable update | No |
|
|
155
|
+
| `ERROR` | Error message | No |
|
|
156
|
+
|
|
157
|
+
## Prompt Compiler
|
|
158
|
+
|
|
159
|
+
The SDK ships a shared, **versioned** prompt compiler that resolves
|
|
160
|
+
`{{placeholder}}` tokens in an authored prompt (from the Configurator or a plan)
|
|
161
|
+
against live runtime state. Agents call one entry point:
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from stella_agent_sdk import prompts
|
|
165
|
+
|
|
166
|
+
final = prompts.compile(
|
|
167
|
+
"Helping with: {{current_focus}}\n\n{{history_8}}\n\n{{user_message}}",
|
|
168
|
+
version="1.0.0", # required — no implicit "latest"
|
|
169
|
+
sm_context=sm_context,
|
|
170
|
+
conversation_history=history,
|
|
171
|
+
user_input=text,
|
|
172
|
+
)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
The `version` is **mandatory** so an SDK upgrade can never silently change how an
|
|
176
|
+
agent's prompts compile. Pin the version your agent was tested against
|
|
177
|
+
(`PROMPT_COMPILER_VERSION`), and let a deployment override it via
|
|
178
|
+
`config["compiler_version"]`.
|
|
179
|
+
|
|
180
|
+
Add a new version by subclassing `PlaceholderPromptCompiler` (or `PromptCompiler`),
|
|
181
|
+
bumping `VERSION`, and calling `register_compiler` — older versions stay registered
|
|
182
|
+
so existing prompts keep compiling.
|
|
183
|
+
|
|
184
|
+
See the full guide — placeholders, versioning, manifest declaration, and adding a
|
|
185
|
+
compiler — in **[SDK Reference → Prompt Compiler](../../docs-site/docs/sdk/prompt-compiler.md)**.
|
|
186
|
+
|
|
187
|
+
## Environment Variables
|
|
188
|
+
|
|
189
|
+
### Required
|
|
190
|
+
|
|
191
|
+
| Variable | Description |
|
|
192
|
+
|----------|-------------|
|
|
193
|
+
| `LIVEKIT_URL` | LiveKit server WebSocket URL |
|
|
194
|
+
| `ROOM_NAME` | LiveKit room to join |
|
|
195
|
+
| `AGENT_IDENTITY` | Agent participant identity |
|
|
196
|
+
| `LIVEKIT_API_KEY` | LiveKit API key |
|
|
197
|
+
| `LIVEKIT_API_SECRET` | LiveKit API secret |
|
|
198
|
+
|
|
199
|
+
### Optional
|
|
200
|
+
|
|
201
|
+
| Variable | Default | Description |
|
|
202
|
+
|----------|---------|-------------|
|
|
203
|
+
| `STT_SERVICE_ADDRESS` | `stt-service:50051` | STT gRPC service address |
|
|
204
|
+
| `TTS_SERVICE_ADDRESS` | `tts-service:50052` | TTS gRPC service address |
|
|
205
|
+
| `TTS_ENABLED` | `true` | Set to `false` to disable TTS entirely. The agent will still receive speech input and send text responses, but no audio will be synthesized — effectively turning it into a text chatbot. |
|
|
206
|
+
| `STT_WARMUP_ENABLED` | `true` | Warm up STT model before first utterance |
|
|
207
|
+
| `SESSION_SERVER_URL` | `http://session-management-server:3000` | Session management HTTP URL |
|
|
208
|
+
| `GRPC_SERVER` | `session-management-server:50051` | Session management gRPC address |
|
|
209
|
+
| `SESSION_ID` | *(falls back to ROOM_NAME)* | Database session UUID |
|
|
210
|
+
| `AGENT_NAME` | `Agent` | Display name for the agent |
|
|
211
|
+
| `AGENT_ID` | *(falls back to AGENT_IDENTITY)* | Unique agent identifier |
|
|
212
|
+
| `AGENT_ICON` | `🤖` | Display icon for the agent |
|
|
213
|
+
| `AGENT_CONFIG` | | JSON string with agent-specific configuration |
|
|
214
|
+
| `TRANSCRIPT_DEBOUNCE_MS` | `0` | Aggregate rapid successive finals within this window (ms). Off by default: STT endpointing already guarantees a >1s gap between finals, so any window this size is unreachable. Set it only for an STT provider that can fragment faster than that. |
|
|
215
|
+
| `INTERRUPT_MODE` | `none` | Barge-in behavior: `none` (strict gating) or `smart` |
|
|
216
|
+
|
|
217
|
+
## Examples
|
|
218
|
+
|
|
219
|
+
Both examples are runnable as-is once the environment variables below are set.
|
|
220
|
+
They are not shipped inside the installed package, so read them on GitHub:
|
|
221
|
+
|
|
222
|
+
- [`echo_agent.py`](https://github.com/c4dhi/STELLA/blob/main/agents/stella-ai-agent-sdk/examples/echo_agent.py)
|
|
223
|
+
— the smallest possible agent (echoes input back)
|
|
224
|
+
- [`openai_agent.py`](https://github.com/c4dhi/STELLA/blob/main/agents/stella-ai-agent-sdk/examples/openai_agent.py)
|
|
225
|
+
— an LLM-backed agent that streams its reply token by token, and stops
|
|
226
|
+
generating when the user barges in
|
|
227
|
+
|
|
228
|
+
## Development
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
# Install dev dependencies
|
|
232
|
+
pip install -e ".[dev]"
|
|
233
|
+
|
|
234
|
+
# Run tests
|
|
235
|
+
pytest
|
|
236
|
+
|
|
237
|
+
# Generate gRPC stubs
|
|
238
|
+
python -m grpc_tools.protoc \
|
|
239
|
+
-I proto \
|
|
240
|
+
--python_out=src/stella_agent_sdk/_grpc/generated \
|
|
241
|
+
--grpc_python_out=src/stella_agent_sdk/_grpc/generated \
|
|
242
|
+
proto/agent.proto
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Changelog
|
|
246
|
+
|
|
247
|
+
See [CHANGELOG.md](https://github.com/c4dhi/STELLA/blob/main/agents/stella-ai-agent-sdk/CHANGELOG.md).
|
|
248
|
+
The SDK versions independently of the STELLA platform.
|
|
249
|
+
|
|
250
|
+
## Releasing
|
|
251
|
+
|
|
252
|
+
Releases are published to [PyPI](https://pypi.org/project/stella-ai-agent-sdk/) by
|
|
253
|
+
[`.github/workflows/publish-sdk.yml`](../../.github/workflows/publish-sdk.yml), which is
|
|
254
|
+
triggered by pushing a `sdk-v<version>` tag:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# 1. Bump `version` in agents/stella-ai-agent-sdk/pyproject.toml, then commit it to main.
|
|
258
|
+
# 2. Tag the commit. The tag version must match pyproject.toml or the workflow fails.
|
|
259
|
+
git tag sdk-v0.6.0
|
|
260
|
+
git push origin sdk-v0.6.0
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
The workflow builds the sdist and wheel, installs the wheel into a clean environment and runs
|
|
264
|
+
the test suite against it, publishes to PyPI via trusted publishing (OIDC — no API token is
|
|
265
|
+
stored in the repo), and creates a GitHub release with the distributions attached.
|
|
266
|
+
|
|
267
|
+
Run the workflow manually (`workflow_dispatch`) to build and verify without publishing.
|
|
268
|
+
Note that a version number can never be reused on PyPI, even after a release is deleted.
|
|
269
|
+
|
|
270
|
+
## License
|
|
271
|
+
|
|
272
|
+
MIT
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# STELLA Agent SDK
|
|
2
|
+
|
|
3
|
+
A communication SDK for building agents that integrate with the STELLA platform.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The SDK defines the communication protocol - agents implement whatever logic they want internally. It provides:
|
|
8
|
+
|
|
9
|
+
- **Message types** (`AgentInput`, `AgentOutput`) - Standardized formats for agent communication
|
|
10
|
+
- **`BaseAgent`** - Abstract class that agents implement
|
|
11
|
+
- **gRPC client** - Handles connection to session-management server
|
|
12
|
+
|
|
13
|
+
**What the SDK does NOT include:** LLM services, RAG, expert pools, or any processing logic. Those are your agent's implementation details.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
Requires Python 3.10 or newer.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install stella-ai-agent-sdk
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
To work against unreleased changes, install from source:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
git clone https://github.com/c4dhi/STELLA.git
|
|
27
|
+
pip install -e STELLA/agents/stella-ai-agent-sdk
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or pin directly to a tag without cloning:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install "stella-ai-agent-sdk @ git+https://github.com/c4dhi/STELLA.git@sdk-v0.5.0#subdirectory=agents/stella-ai-agent-sdk"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
import asyncio
|
|
40
|
+
from typing import AsyncIterator
|
|
41
|
+
from stella_agent_sdk import BaseAgent, AgentInput, AgentOutput, run_agent_from_env
|
|
42
|
+
|
|
43
|
+
class MyAgent(BaseAgent):
|
|
44
|
+
async def on_session_start(self, session_id: str, config: dict) -> None:
|
|
45
|
+
# Initialize your agent with configuration
|
|
46
|
+
self.model = config.get("model", "gpt-4")
|
|
47
|
+
|
|
48
|
+
async def process(self, input: AgentInput) -> AsyncIterator[AgentOutput]:
|
|
49
|
+
# Process user input and yield responses
|
|
50
|
+
yield AgentOutput.thinking(input.session_id)
|
|
51
|
+
|
|
52
|
+
# Your LLM/processing logic here
|
|
53
|
+
response = await my_llm_call(input.text)
|
|
54
|
+
|
|
55
|
+
yield AgentOutput.text_final(input.session_id, response)
|
|
56
|
+
|
|
57
|
+
async def on_interrupt(self, session_id: str) -> None:
|
|
58
|
+
# Handle user interrupt (barge-in)
|
|
59
|
+
self.cancel_current_task()
|
|
60
|
+
|
|
61
|
+
async def on_session_end(self, session_id: str) -> dict:
|
|
62
|
+
# Cleanup and return final data
|
|
63
|
+
return {"messages": self.message_count}
|
|
64
|
+
|
|
65
|
+
# run_agent_from_env() is the ONLY entry point. It reads all connection config
|
|
66
|
+
# (LiveKit room, STT/TTS addresses, AGENT_CONFIG, ...) from environment variables
|
|
67
|
+
# set by the session-management-server, connects everything, and runs the agent.
|
|
68
|
+
if __name__ == "__main__":
|
|
69
|
+
asyncio.run(run_agent_from_env(MyAgent()))
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Architecture
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
LiveKit Server (WebRTC audio/video)
|
|
76
|
+
│
|
|
77
|
+
│ Audio tracks
|
|
78
|
+
│
|
|
79
|
+
▼
|
|
80
|
+
Your Agent (uses SDK)
|
|
81
|
+
│
|
|
82
|
+
├─ STT Service ← Transcribes user speech
|
|
83
|
+
├─ TTS Service ← Synthesizes agent responses
|
|
84
|
+
├─ Receives: AgentInput (text from user)
|
|
85
|
+
└─ Sends: AgentOutput (text responses)
|
|
86
|
+
│
|
|
87
|
+
│ gRPC (SDK protocol)
|
|
88
|
+
│
|
|
89
|
+
▼
|
|
90
|
+
Session-Management-Server (session state, plans, deliverables)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The agent is a **black box** from session-management's perspective:
|
|
94
|
+
1. Agent joins a LiveKit room and subscribes to user audio
|
|
95
|
+
2. STT service transcribes user speech into text
|
|
96
|
+
3. Agent processes input (using whatever LLM/logic you want)
|
|
97
|
+
4. Agent streams text responses back
|
|
98
|
+
5. TTS service synthesizes agent text into audio (unless disabled)
|
|
99
|
+
|
|
100
|
+
## Message Types
|
|
101
|
+
|
|
102
|
+
### Input (from server to agent)
|
|
103
|
+
|
|
104
|
+
| Type | Description |
|
|
105
|
+
|------|-------------|
|
|
106
|
+
| `TEXT` | Transcribed user speech or typed text |
|
|
107
|
+
| `INTERRUPT` | User interrupted (barge-in) |
|
|
108
|
+
| `SESSION_START` | Session starting with configuration |
|
|
109
|
+
| `SESSION_END` | Session ending |
|
|
110
|
+
| `CONFIG` | Runtime configuration update |
|
|
111
|
+
|
|
112
|
+
### Output (from agent to server)
|
|
113
|
+
|
|
114
|
+
| Type | Description | TTS? |
|
|
115
|
+
|------|-------------|------|
|
|
116
|
+
| `TEXT_CHUNK` | Streaming text chunk | Buffered |
|
|
117
|
+
| `TEXT_FINAL` | Complete text response | Yes |
|
|
118
|
+
| `STATUS` | Processing status update | No |
|
|
119
|
+
| `METADATA` | Plan/deliverable update | No |
|
|
120
|
+
| `ERROR` | Error message | No |
|
|
121
|
+
|
|
122
|
+
## Prompt Compiler
|
|
123
|
+
|
|
124
|
+
The SDK ships a shared, **versioned** prompt compiler that resolves
|
|
125
|
+
`{{placeholder}}` tokens in an authored prompt (from the Configurator or a plan)
|
|
126
|
+
against live runtime state. Agents call one entry point:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from stella_agent_sdk import prompts
|
|
130
|
+
|
|
131
|
+
final = prompts.compile(
|
|
132
|
+
"Helping with: {{current_focus}}\n\n{{history_8}}\n\n{{user_message}}",
|
|
133
|
+
version="1.0.0", # required — no implicit "latest"
|
|
134
|
+
sm_context=sm_context,
|
|
135
|
+
conversation_history=history,
|
|
136
|
+
user_input=text,
|
|
137
|
+
)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The `version` is **mandatory** so an SDK upgrade can never silently change how an
|
|
141
|
+
agent's prompts compile. Pin the version your agent was tested against
|
|
142
|
+
(`PROMPT_COMPILER_VERSION`), and let a deployment override it via
|
|
143
|
+
`config["compiler_version"]`.
|
|
144
|
+
|
|
145
|
+
Add a new version by subclassing `PlaceholderPromptCompiler` (or `PromptCompiler`),
|
|
146
|
+
bumping `VERSION`, and calling `register_compiler` — older versions stay registered
|
|
147
|
+
so existing prompts keep compiling.
|
|
148
|
+
|
|
149
|
+
See the full guide — placeholders, versioning, manifest declaration, and adding a
|
|
150
|
+
compiler — in **[SDK Reference → Prompt Compiler](../../docs-site/docs/sdk/prompt-compiler.md)**.
|
|
151
|
+
|
|
152
|
+
## Environment Variables
|
|
153
|
+
|
|
154
|
+
### Required
|
|
155
|
+
|
|
156
|
+
| Variable | Description |
|
|
157
|
+
|----------|-------------|
|
|
158
|
+
| `LIVEKIT_URL` | LiveKit server WebSocket URL |
|
|
159
|
+
| `ROOM_NAME` | LiveKit room to join |
|
|
160
|
+
| `AGENT_IDENTITY` | Agent participant identity |
|
|
161
|
+
| `LIVEKIT_API_KEY` | LiveKit API key |
|
|
162
|
+
| `LIVEKIT_API_SECRET` | LiveKit API secret |
|
|
163
|
+
|
|
164
|
+
### Optional
|
|
165
|
+
|
|
166
|
+
| Variable | Default | Description |
|
|
167
|
+
|----------|---------|-------------|
|
|
168
|
+
| `STT_SERVICE_ADDRESS` | `stt-service:50051` | STT gRPC service address |
|
|
169
|
+
| `TTS_SERVICE_ADDRESS` | `tts-service:50052` | TTS gRPC service address |
|
|
170
|
+
| `TTS_ENABLED` | `true` | Set to `false` to disable TTS entirely. The agent will still receive speech input and send text responses, but no audio will be synthesized — effectively turning it into a text chatbot. |
|
|
171
|
+
| `STT_WARMUP_ENABLED` | `true` | Warm up STT model before first utterance |
|
|
172
|
+
| `SESSION_SERVER_URL` | `http://session-management-server:3000` | Session management HTTP URL |
|
|
173
|
+
| `GRPC_SERVER` | `session-management-server:50051` | Session management gRPC address |
|
|
174
|
+
| `SESSION_ID` | *(falls back to ROOM_NAME)* | Database session UUID |
|
|
175
|
+
| `AGENT_NAME` | `Agent` | Display name for the agent |
|
|
176
|
+
| `AGENT_ID` | *(falls back to AGENT_IDENTITY)* | Unique agent identifier |
|
|
177
|
+
| `AGENT_ICON` | `🤖` | Display icon for the agent |
|
|
178
|
+
| `AGENT_CONFIG` | | JSON string with agent-specific configuration |
|
|
179
|
+
| `TRANSCRIPT_DEBOUNCE_MS` | `0` | Aggregate rapid successive finals within this window (ms). Off by default: STT endpointing already guarantees a >1s gap between finals, so any window this size is unreachable. Set it only for an STT provider that can fragment faster than that. |
|
|
180
|
+
| `INTERRUPT_MODE` | `none` | Barge-in behavior: `none` (strict gating) or `smart` |
|
|
181
|
+
|
|
182
|
+
## Examples
|
|
183
|
+
|
|
184
|
+
Both examples are runnable as-is once the environment variables below are set.
|
|
185
|
+
They are not shipped inside the installed package, so read them on GitHub:
|
|
186
|
+
|
|
187
|
+
- [`echo_agent.py`](https://github.com/c4dhi/STELLA/blob/main/agents/stella-ai-agent-sdk/examples/echo_agent.py)
|
|
188
|
+
— the smallest possible agent (echoes input back)
|
|
189
|
+
- [`openai_agent.py`](https://github.com/c4dhi/STELLA/blob/main/agents/stella-ai-agent-sdk/examples/openai_agent.py)
|
|
190
|
+
— an LLM-backed agent that streams its reply token by token, and stops
|
|
191
|
+
generating when the user barges in
|
|
192
|
+
|
|
193
|
+
## Development
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# Install dev dependencies
|
|
197
|
+
pip install -e ".[dev]"
|
|
198
|
+
|
|
199
|
+
# Run tests
|
|
200
|
+
pytest
|
|
201
|
+
|
|
202
|
+
# Generate gRPC stubs
|
|
203
|
+
python -m grpc_tools.protoc \
|
|
204
|
+
-I proto \
|
|
205
|
+
--python_out=src/stella_agent_sdk/_grpc/generated \
|
|
206
|
+
--grpc_python_out=src/stella_agent_sdk/_grpc/generated \
|
|
207
|
+
proto/agent.proto
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Changelog
|
|
211
|
+
|
|
212
|
+
See [CHANGELOG.md](https://github.com/c4dhi/STELLA/blob/main/agents/stella-ai-agent-sdk/CHANGELOG.md).
|
|
213
|
+
The SDK versions independently of the STELLA platform.
|
|
214
|
+
|
|
215
|
+
## Releasing
|
|
216
|
+
|
|
217
|
+
Releases are published to [PyPI](https://pypi.org/project/stella-ai-agent-sdk/) by
|
|
218
|
+
[`.github/workflows/publish-sdk.yml`](../../.github/workflows/publish-sdk.yml), which is
|
|
219
|
+
triggered by pushing a `sdk-v<version>` tag:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
# 1. Bump `version` in agents/stella-ai-agent-sdk/pyproject.toml, then commit it to main.
|
|
223
|
+
# 2. Tag the commit. The tag version must match pyproject.toml or the workflow fails.
|
|
224
|
+
git tag sdk-v0.6.0
|
|
225
|
+
git push origin sdk-v0.6.0
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
The workflow builds the sdist and wheel, installs the wheel into a clean environment and runs
|
|
229
|
+
the test suite against it, publishes to PyPI via trusted publishing (OIDC — no API token is
|
|
230
|
+
stored in the repo), and creates a GitHub release with the distributions attached.
|
|
231
|
+
|
|
232
|
+
Run the workflow manually (`workflow_dispatch`) to build and verify without publishing.
|
|
233
|
+
Note that a version number can never be reused on PyPI, even after a release is deleted.
|
|
234
|
+
|
|
235
|
+
## License
|
|
236
|
+
|
|
237
|
+
MIT
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "stella-ai-agent-sdk"
|
|
7
|
+
version = "0.5.0"
|
|
8
|
+
description = "SDK for building agents that integrate with the STELLA platform"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
keywords = ["stella", "agent", "conversational-ai", "livekit", "grpc"]
|
|
14
|
+
authors = [
|
|
15
|
+
{name = "STELLA Team"}
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"grpcio>=1.60.0",
|
|
27
|
+
"grpcio-tools>=1.60.0",
|
|
28
|
+
"pydantic>=2.0.0",
|
|
29
|
+
"livekit>=0.11.0,<1.0.0",
|
|
30
|
+
"PyJWT>=2.0.0",
|
|
31
|
+
"numpy>=1.24.0",
|
|
32
|
+
"aiohttp>=3.9.0",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
dev = [
|
|
37
|
+
"pytest>=7.0.0",
|
|
38
|
+
"pytest-asyncio>=0.21.0",
|
|
39
|
+
"pytest-cov>=4.0.0",
|
|
40
|
+
]
|
|
41
|
+
examples = [
|
|
42
|
+
"openai>=1.0.0",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[project.urls]
|
|
46
|
+
Homepage = "https://github.com/c4dhi/STELLA/tree/main/agents/stella-ai-agent-sdk"
|
|
47
|
+
Documentation = "https://github.com/c4dhi/STELLA/tree/main/agents/stella-ai-agent-sdk#readme"
|
|
48
|
+
Source = "https://github.com/c4dhi/STELLA"
|
|
49
|
+
Issues = "https://github.com/c4dhi/STELLA/issues"
|
|
50
|
+
|
|
51
|
+
[tool.setuptools.packages.find]
|
|
52
|
+
where = ["src"]
|
|
53
|
+
|
|
54
|
+
[tool.setuptools.package-data]
|
|
55
|
+
"stella_agent_sdk" = ["py.typed"]
|
|
56
|
+
"stella_agent_sdk._grpc" = ["*.py"]
|
|
57
|
+
|
|
58
|
+
[tool.pytest.ini_options]
|
|
59
|
+
asyncio_mode = "auto"
|
|
60
|
+
testpaths = ["tests"]
|