band-sdk 0.2.7__py3-none-any.whl
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.
- band_sdk-0.2.7.dist-info/METADATA +1042 -0
- band_sdk-0.2.7.dist-info/RECORD +120 -0
- band_sdk-0.2.7.dist-info/WHEEL +5 -0
- band_sdk-0.2.7.dist-info/entry_points.txt +2 -0
- band_sdk-0.2.7.dist-info/licenses/LICENSE +21 -0
- band_sdk-0.2.7.dist-info/top_level.txt +1 -0
- thenvoi/__init__.py +128 -0
- thenvoi/adapters/__init__.py +137 -0
- thenvoi/adapters/a2a.py +6 -0
- thenvoi/adapters/a2a_gateway.py +12 -0
- thenvoi/adapters/acp.py +9 -0
- thenvoi/adapters/anthropic.py +471 -0
- thenvoi/adapters/claude_sdk.py +1041 -0
- thenvoi/adapters/codex.py +1990 -0
- thenvoi/adapters/crewai.py +1314 -0
- thenvoi/adapters/gemini.py +532 -0
- thenvoi/adapters/google_adk.py +690 -0
- thenvoi/adapters/langgraph.py +277 -0
- thenvoi/adapters/letta.py +919 -0
- thenvoi/adapters/opencode.py +1168 -0
- thenvoi/adapters/parlant.py +614 -0
- thenvoi/adapters/pydantic_ai.py +561 -0
- thenvoi/agent.py +312 -0
- thenvoi/client/__init__.py +1 -0
- thenvoi/client/rest/__init__.py +50 -0
- thenvoi/client/streaming/__init__.py +39 -0
- thenvoi/client/streaming/client.py +425 -0
- thenvoi/config/__init__.py +12 -0
- thenvoi/config/loader.py +115 -0
- thenvoi/converters/__init__.py +201 -0
- thenvoi/converters/_tool_parsing.py +116 -0
- thenvoi/converters/_utils.py +23 -0
- thenvoi/converters/a2a.py +76 -0
- thenvoi/converters/a2a_gateway.py +85 -0
- thenvoi/converters/acp_client.py +61 -0
- thenvoi/converters/acp_server.py +85 -0
- thenvoi/converters/anthropic.py +249 -0
- thenvoi/converters/claude_sdk.py +100 -0
- thenvoi/converters/codex.py +49 -0
- thenvoi/converters/crewai.py +88 -0
- thenvoi/converters/gemini.py +165 -0
- thenvoi/converters/google_adk.py +247 -0
- thenvoi/converters/langchain.py +134 -0
- thenvoi/converters/letta.py +65 -0
- thenvoi/converters/opencode.py +66 -0
- thenvoi/converters/parlant.py +95 -0
- thenvoi/converters/pydantic_ai.py +167 -0
- thenvoi/core/__init__.py +21 -0
- thenvoi/core/exceptions.py +87 -0
- thenvoi/core/protocols.py +273 -0
- thenvoi/core/simple_adapter.py +155 -0
- thenvoi/core/tool_filter.py +83 -0
- thenvoi/core/types.py +132 -0
- thenvoi/integrations/__init__.py +18 -0
- thenvoi/integrations/a2a/__init__.py +33 -0
- thenvoi/integrations/a2a/adapter.py +434 -0
- thenvoi/integrations/a2a/gateway/__init__.py +12 -0
- thenvoi/integrations/a2a/gateway/adapter.py +532 -0
- thenvoi/integrations/a2a/gateway/server.py +467 -0
- thenvoi/integrations/a2a/gateway/types.py +43 -0
- thenvoi/integrations/a2a/types.py +60 -0
- thenvoi/integrations/acp/__init__.py +99 -0
- thenvoi/integrations/acp/__main__.py +7 -0
- thenvoi/integrations/acp/cli.py +123 -0
- thenvoi/integrations/acp/client_adapter.py +619 -0
- thenvoi/integrations/acp/client_types.py +281 -0
- thenvoi/integrations/acp/event_converter.py +102 -0
- thenvoi/integrations/acp/push_handler.py +64 -0
- thenvoi/integrations/acp/router.py +84 -0
- thenvoi/integrations/acp/server.py +537 -0
- thenvoi/integrations/acp/server_adapter.py +678 -0
- thenvoi/integrations/acp/types.py +66 -0
- thenvoi/integrations/anthropic/__init__.py +15 -0
- thenvoi/integrations/base.py +77 -0
- thenvoi/integrations/claude_sdk/__init__.py +23 -0
- thenvoi/integrations/claude_sdk/prompts.py +166 -0
- thenvoi/integrations/claude_sdk/session_manager.py +399 -0
- thenvoi/integrations/claude_sdk/tools.py +370 -0
- thenvoi/integrations/codex/__init__.py +21 -0
- thenvoi/integrations/codex/rpc_base.py +310 -0
- thenvoi/integrations/codex/stdio_client.py +149 -0
- thenvoi/integrations/codex/types.py +19 -0
- thenvoi/integrations/codex/websocket_client.py +105 -0
- thenvoi/integrations/langgraph/__init__.py +35 -0
- thenvoi/integrations/langgraph/graph_tools.py +199 -0
- thenvoi/integrations/langgraph/langchain_tools.py +313 -0
- thenvoi/integrations/langgraph/message_formatters.py +71 -0
- thenvoi/integrations/mcp/__init__.py +13 -0
- thenvoi/integrations/mcp/backends.py +93 -0
- thenvoi/integrations/opencode/__init__.py +15 -0
- thenvoi/integrations/opencode/client.py +266 -0
- thenvoi/integrations/opencode/types.py +16 -0
- thenvoi/integrations/parlant/__init__.py +32 -0
- thenvoi/integrations/parlant/tools.py +691 -0
- thenvoi/integrations/pydantic_ai/__init__.py +15 -0
- thenvoi/platform/__init__.py +15 -0
- thenvoi/platform/event.py +149 -0
- thenvoi/platform/link.py +552 -0
- thenvoi/preprocessing/__init__.py +5 -0
- thenvoi/preprocessing/default.py +146 -0
- thenvoi/prompts/__init__.py +7 -0
- thenvoi/prompts/roles.py +255 -0
- thenvoi/runtime/__init__.py +97 -0
- thenvoi/runtime/contact_handler.py +690 -0
- thenvoi/runtime/contact_tools.py +277 -0
- thenvoi/runtime/custom_tools.py +184 -0
- thenvoi/runtime/execution.py +1095 -0
- thenvoi/runtime/formatters.py +109 -0
- thenvoi/runtime/mcp_server.py +469 -0
- thenvoi/runtime/participant_tracker.py +99 -0
- thenvoi/runtime/platform_runtime.py +385 -0
- thenvoi/runtime/presence.py +335 -0
- thenvoi/runtime/prompts.py +140 -0
- thenvoi/runtime/retry_tracker.py +61 -0
- thenvoi/runtime/runtime.py +243 -0
- thenvoi/runtime/shutdown.py +297 -0
- thenvoi/runtime/tools.py +1388 -0
- thenvoi/runtime/types.py +205 -0
- thenvoi/testing/__init__.py +5 -0
- thenvoi/testing/fake_tools.py +281 -0
|
@@ -0,0 +1,1042 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: band-sdk
|
|
3
|
+
Version: 0.2.7
|
|
4
|
+
Summary: A Python SDK for Thenvoi API
|
|
5
|
+
Author: thenvoi
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: sdk,thenvoi,api,agents
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Requires-Python: >=3.11
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: thenvoi-client-rest==0.0.4
|
|
19
|
+
Requires-Dist: phoenix-channels-python-client>=0.1.5
|
|
20
|
+
Requires-Dist: python-dotenv>=1.1.1
|
|
21
|
+
Requires-Dist: pyyaml>=6.0
|
|
22
|
+
Requires-Dist: claude-agent-sdk>=0.1.16
|
|
23
|
+
Requires-Dist: cryptography>=46.0.5
|
|
24
|
+
Provides-Extra: codex
|
|
25
|
+
Requires-Dist: websockets>=13.0; extra == "codex"
|
|
26
|
+
Provides-Extra: opencode
|
|
27
|
+
Requires-Dist: httpx>=0.24.0; extra == "opencode"
|
|
28
|
+
Provides-Extra: letta
|
|
29
|
+
Requires-Dist: letta-client>=0.1.0; extra == "letta"
|
|
30
|
+
Provides-Extra: pydantic-ai
|
|
31
|
+
Requires-Dist: pydantic-ai-slim>=1.56.0; extra == "pydantic-ai"
|
|
32
|
+
Requires-Dist: openai>=1.0.0; extra == "pydantic-ai"
|
|
33
|
+
Provides-Extra: anthropic
|
|
34
|
+
Requires-Dist: anthropic>=0.75.0; extra == "anthropic"
|
|
35
|
+
Provides-Extra: langgraph
|
|
36
|
+
Requires-Dist: langchain>=1.0.0; extra == "langgraph"
|
|
37
|
+
Requires-Dist: langchain-core>=1.2.11; extra == "langgraph"
|
|
38
|
+
Requires-Dist: langgraph>=1.0.0; extra == "langgraph"
|
|
39
|
+
Requires-Dist: langchain-openai>=0.3.0; extra == "langgraph"
|
|
40
|
+
Requires-Dist: langchain-anthropic>=0.3.0; extra == "langgraph"
|
|
41
|
+
Requires-Dist: langchain-community>=0.4.0; extra == "langgraph"
|
|
42
|
+
Requires-Dist: langchain-text-splitters>=0.3.0; extra == "langgraph"
|
|
43
|
+
Requires-Dist: openai>=1.0.0; extra == "langgraph"
|
|
44
|
+
Requires-Dist: beautifulsoup4>=4.12.0; extra == "langgraph"
|
|
45
|
+
Provides-Extra: claude-sdk
|
|
46
|
+
Requires-Dist: claude-agent-sdk>=0.1.0; extra == "claude-sdk"
|
|
47
|
+
Provides-Extra: parlant
|
|
48
|
+
Requires-Dist: parlant>=3.0.0; extra == "parlant"
|
|
49
|
+
Requires-Dist: openai>=1.0.0; extra == "parlant"
|
|
50
|
+
Requires-Dist: werkzeug>=3.1.6; extra == "parlant"
|
|
51
|
+
Provides-Extra: crewai
|
|
52
|
+
Requires-Dist: crewai<2.0.0,>=0.80.0; extra == "crewai"
|
|
53
|
+
Requires-Dist: openai>=1.0.0; extra == "crewai"
|
|
54
|
+
Requires-Dist: nest-asyncio>=1.6.0; extra == "crewai"
|
|
55
|
+
Requires-Dist: pillow>=12.1.1; extra == "crewai"
|
|
56
|
+
Provides-Extra: gemini
|
|
57
|
+
Requires-Dist: google-genai>=1.43.0; extra == "gemini"
|
|
58
|
+
Provides-Extra: a2a
|
|
59
|
+
Requires-Dist: a2a-sdk>=0.3.22; extra == "a2a"
|
|
60
|
+
Requires-Dist: protobuf>=6.33.5; extra == "a2a"
|
|
61
|
+
Provides-Extra: a2a-gateway
|
|
62
|
+
Requires-Dist: a2a-sdk>=0.3.22; extra == "a2a-gateway"
|
|
63
|
+
Requires-Dist: starlette>=0.40.0; extra == "a2a-gateway"
|
|
64
|
+
Requires-Dist: uvicorn>=0.32.0; extra == "a2a-gateway"
|
|
65
|
+
Requires-Dist: protobuf>=6.33.5; extra == "a2a-gateway"
|
|
66
|
+
Requires-Dist: python-multipart>=0.0.22; extra == "a2a-gateway"
|
|
67
|
+
Provides-Extra: a2a-gateway-demo
|
|
68
|
+
Requires-Dist: a2a-sdk>=0.3.22; extra == "a2a-gateway-demo"
|
|
69
|
+
Requires-Dist: starlette>=0.40.0; extra == "a2a-gateway-demo"
|
|
70
|
+
Requires-Dist: uvicorn>=0.32.0; extra == "a2a-gateway-demo"
|
|
71
|
+
Requires-Dist: langgraph>=1.0.0; extra == "a2a-gateway-demo"
|
|
72
|
+
Requires-Dist: langchain-openai>=0.3.0; extra == "a2a-gateway-demo"
|
|
73
|
+
Requires-Dist: click>=8.0.0; extra == "a2a-gateway-demo"
|
|
74
|
+
Provides-Extra: acp
|
|
75
|
+
Requires-Dist: agent-client-protocol>=0.8.0; extra == "acp"
|
|
76
|
+
Requires-Dist: mcp>=1.25.0; extra == "acp"
|
|
77
|
+
Requires-Dist: starlette>=0.40.0; extra == "acp"
|
|
78
|
+
Requires-Dist: uvicorn>=0.32.0; extra == "acp"
|
|
79
|
+
Provides-Extra: bridge
|
|
80
|
+
Requires-Dist: aiohttp<4,>=3.9; extra == "bridge"
|
|
81
|
+
Requires-Dist: python-dotenv>=1.0; extra == "bridge"
|
|
82
|
+
Provides-Extra: bridge-agentcore
|
|
83
|
+
Requires-Dist: aiohttp<4,>=3.9; extra == "bridge-agentcore"
|
|
84
|
+
Requires-Dist: python-dotenv>=1.0; extra == "bridge-agentcore"
|
|
85
|
+
Requires-Dist: boto3>=1.35.0; extra == "bridge-agentcore"
|
|
86
|
+
Provides-Extra: google-adk
|
|
87
|
+
Requires-Dist: google-adk<2,>=1.0.0; extra == "google-adk"
|
|
88
|
+
Provides-Extra: bridge-langchain
|
|
89
|
+
Requires-Dist: httpx>=0.24.0; extra == "bridge-langchain"
|
|
90
|
+
Provides-Extra: dev
|
|
91
|
+
Requires-Dist: thenvoi-testing-python>=0.1.2; extra == "dev"
|
|
92
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
93
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
94
|
+
Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
|
|
95
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
96
|
+
Requires-Dist: pytest-rerunfailures>=14.0.0; extra == "dev"
|
|
97
|
+
Requires-Dist: pytest-timeout>=2.4.0; extra == "dev"
|
|
98
|
+
Requires-Dist: httpx>=0.24.0; extra == "dev"
|
|
99
|
+
Requires-Dist: pydantic-ai-slim>=1.56.0; extra == "dev"
|
|
100
|
+
Requires-Dist: anthropic>=0.75.0; extra == "dev"
|
|
101
|
+
Requires-Dist: langchain>=1.0.0; extra == "dev"
|
|
102
|
+
Requires-Dist: langchain-core>=1.2.11; extra == "dev"
|
|
103
|
+
Requires-Dist: langgraph>=1.0.0; extra == "dev"
|
|
104
|
+
Requires-Dist: langchain-openai>=0.3.0; extra == "dev"
|
|
105
|
+
Requires-Dist: langchain-anthropic>=0.3.0; extra == "dev"
|
|
106
|
+
Requires-Dist: langchain-community>=0.4.0; extra == "dev"
|
|
107
|
+
Requires-Dist: langchain-text-splitters>=0.3.0; extra == "dev"
|
|
108
|
+
Requires-Dist: openai>=1.0.0; extra == "dev"
|
|
109
|
+
Requires-Dist: beautifulsoup4>=4.12.0; extra == "dev"
|
|
110
|
+
Requires-Dist: parlant>=3.0.0; extra == "dev"
|
|
111
|
+
Requires-Dist: a2a-sdk>=0.3.22; extra == "dev"
|
|
112
|
+
Requires-Dist: starlette>=0.40.0; extra == "dev"
|
|
113
|
+
Requires-Dist: uvicorn>=0.32.0; extra == "dev"
|
|
114
|
+
Requires-Dist: click>=8.0.0; extra == "dev"
|
|
115
|
+
Requires-Dist: crewai>=0.80.0; extra == "dev"
|
|
116
|
+
Requires-Dist: nest-asyncio>=1.6.0; extra == "dev"
|
|
117
|
+
Requires-Dist: agent-client-protocol>=0.8.0; extra == "dev"
|
|
118
|
+
Requires-Dist: mcp>=1.25.0; extra == "dev"
|
|
119
|
+
Requires-Dist: google-genai>=1.43.0; extra == "dev"
|
|
120
|
+
Requires-Dist: google-adk<2,>=1.0.0; extra == "dev"
|
|
121
|
+
Requires-Dist: aiohttp<4,>=3.9; extra == "dev"
|
|
122
|
+
Requires-Dist: python-dotenv>=1.0; extra == "dev"
|
|
123
|
+
Requires-Dist: boto3>=1.35.0; extra == "dev"
|
|
124
|
+
Requires-Dist: pre-commit>=3.0.0; extra == "dev"
|
|
125
|
+
Requires-Dist: ruff>=0.8.0; extra == "dev"
|
|
126
|
+
Requires-Dist: pyrefly>=0.18.0; extra == "dev"
|
|
127
|
+
Requires-Dist: commitizen>=3.13.0; extra == "dev"
|
|
128
|
+
Dynamic: license-file
|
|
129
|
+
|
|
130
|
+
# Thenvoi Python SDK
|
|
131
|
+
|
|
132
|
+
Connect your AI agents to the Thenvoi collaborative platform.
|
|
133
|
+
|
|
134
|
+
**Supported Frameworks:**
|
|
135
|
+
- **LangGraph** - Production ready
|
|
136
|
+
- **Pydantic AI** - Production ready
|
|
137
|
+
- **Anthropic SDK** - Production ready (direct Claude integration)
|
|
138
|
+
- **Claude Agent SDK** - Production ready (streaming, extended thinking)
|
|
139
|
+
- **Codex App-Server** - Production ready (stdio/ws transport, OAuth)
|
|
140
|
+
- **CrewAI** - Production ready (role-based agents with goals)
|
|
141
|
+
- **Parlant** - Production ready (guideline-based behavior)
|
|
142
|
+
- **Gemini SDK** - Production ready (official `google-genai` adapter)
|
|
143
|
+
- **Letta** - Production ready (Cloud or self-hosted with MCP tools)
|
|
144
|
+
- **Google ADK** - Production ready (Gemini models via Agent Development Kit)
|
|
145
|
+
- **A2A Adapter** - Call external A2A-compliant agents from Thenvoi
|
|
146
|
+
- **A2A Gateway** - Expose Thenvoi peers as A2A protocol endpoints
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Quick Start
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
from thenvoi import Agent
|
|
154
|
+
from thenvoi.adapters import LangGraphAdapter
|
|
155
|
+
from langchain_openai import ChatOpenAI
|
|
156
|
+
from langgraph.checkpoint.memory import InMemorySaver
|
|
157
|
+
|
|
158
|
+
# Create adapter with your LLM
|
|
159
|
+
adapter = LangGraphAdapter(
|
|
160
|
+
llm=ChatOpenAI(model="gpt-4o"),
|
|
161
|
+
checkpointer=InMemorySaver(),
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
# Create and run agent
|
|
165
|
+
agent = Agent.create(
|
|
166
|
+
adapter=adapter,
|
|
167
|
+
agent_id="your-agent-id",
|
|
168
|
+
api_key="your-api-key",
|
|
169
|
+
)
|
|
170
|
+
await agent.run()
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Prerequisites
|
|
176
|
+
|
|
177
|
+
- **Python 3.11+**
|
|
178
|
+
- **uv** package manager
|
|
179
|
+
|
|
180
|
+
### Install uv
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Or on macOS:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
brew install uv
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Installation
|
|
195
|
+
|
|
196
|
+
### Option 1: Install as External Library (Recommended)
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
# Install base SDK
|
|
200
|
+
uv add "git+https://github.com/thenvoi/thenvoi-sdk-python.git"
|
|
201
|
+
|
|
202
|
+
# Or install with specific framework support
|
|
203
|
+
uv add "git+https://github.com/thenvoi/thenvoi-sdk-python.git[langgraph]"
|
|
204
|
+
uv add "git+https://github.com/thenvoi/thenvoi-sdk-python.git[anthropic]"
|
|
205
|
+
uv add "git+https://github.com/thenvoi/thenvoi-sdk-python.git[pydantic_ai]"
|
|
206
|
+
uv add "git+https://github.com/thenvoi/thenvoi-sdk-python.git[claude_sdk]"
|
|
207
|
+
uv add "git+https://github.com/thenvoi/thenvoi-sdk-python.git[codex]"
|
|
208
|
+
uv add "git+https://github.com/thenvoi/thenvoi-sdk-python.git[crewai]"
|
|
209
|
+
uv add "git+https://github.com/thenvoi/thenvoi-sdk-python.git[parlant]"
|
|
210
|
+
uv add "git+https://github.com/thenvoi/thenvoi-sdk-python.git[gemini]"
|
|
211
|
+
uv add "git+https://github.com/thenvoi/thenvoi-sdk-python.git[letta]"
|
|
212
|
+
uv add "git+https://github.com/thenvoi/thenvoi-sdk-python.git[google_adk]"
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
> **Note for Claude Agent SDK:** Requires Node.js 20+ and Claude Code CLI: `npm install -g @anthropic-ai/claude-code`
|
|
216
|
+
>
|
|
217
|
+
> **Note for Codex:** Install Codex CLI and authenticate once with OAuth (`codex login`).
|
|
218
|
+
|
|
219
|
+
### Option 2: Run Examples from Repository
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
git clone -b main https://github.com/thenvoi/thenvoi-sdk-python.git
|
|
223
|
+
cd thenvoi-sdk-python
|
|
224
|
+
|
|
225
|
+
# Install dependencies
|
|
226
|
+
uv sync --extra langgraph
|
|
227
|
+
|
|
228
|
+
# Configure environment
|
|
229
|
+
cp .env.example .env # Edit with your credentials
|
|
230
|
+
cp agent_config.yaml.example agent_config.yaml # Add agent credentials
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Creating External Agents on Thenvoi Platform
|
|
236
|
+
|
|
237
|
+
Before running your agent, you must create an external agent on the Thenvoi platform and obtain its credentials.
|
|
238
|
+
|
|
239
|
+
### 1. Create Agent via Platform UI
|
|
240
|
+
|
|
241
|
+
1. Log in to the [Thenvoi Platform](https://platform.thenvoi.com)
|
|
242
|
+
2. Navigate to **Agents** section
|
|
243
|
+
3. Click **"Create New Agent"**
|
|
244
|
+
4. Fill in the agent details:
|
|
245
|
+
- **Name**: Your agent's display name (e.g., "Calculator Agent")
|
|
246
|
+
- **Description**: What your agent does
|
|
247
|
+
- **Type**: Select **"External"**
|
|
248
|
+
5. Click **"Create"**
|
|
249
|
+
6. **Copy the API Key** that is displayed - you'll only see this once
|
|
250
|
+
7. Navigate to the agent details page to find the **Agent UUID** - this is your `agent_id`
|
|
251
|
+
|
|
252
|
+
### 2. Update agent_config.yaml
|
|
253
|
+
|
|
254
|
+
Add the credentials to your `agent_config.yaml` file:
|
|
255
|
+
|
|
256
|
+
```yaml
|
|
257
|
+
my_agent:
|
|
258
|
+
agent_id: "paste-your-agent-id-here"
|
|
259
|
+
api_key: "paste-your-api-key-here"
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
> **Note:** The agent name and description are stored on the platform and fetched automatically. You only need to provide `agent_id` and `api_key` in the config file.
|
|
263
|
+
|
|
264
|
+
The examples use this config file to load agent credentials:
|
|
265
|
+
|
|
266
|
+
```python
|
|
267
|
+
from thenvoi.config import load_agent_config
|
|
268
|
+
|
|
269
|
+
agent_id, api_key = load_agent_config("my_agent")
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Important Notes
|
|
273
|
+
|
|
274
|
+
- Each external agent has a **unique API key** for authentication
|
|
275
|
+
- Agent names must be **unique** within your organization
|
|
276
|
+
- Name and description are managed on the platform, not in config file
|
|
277
|
+
- `agent_config.yaml` is git-ignored - never commit credentials to version control
|
|
278
|
+
- Create the agent on the platform **first**, then update `agent_config.yaml`
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Usage by Framework
|
|
283
|
+
|
|
284
|
+
### LangGraph
|
|
285
|
+
|
|
286
|
+
```python
|
|
287
|
+
from thenvoi import Agent
|
|
288
|
+
from thenvoi.adapters import LangGraphAdapter
|
|
289
|
+
from langchain_openai import ChatOpenAI
|
|
290
|
+
from langgraph.checkpoint.memory import InMemorySaver
|
|
291
|
+
|
|
292
|
+
adapter = LangGraphAdapter(
|
|
293
|
+
llm=ChatOpenAI(model="gpt-4o"),
|
|
294
|
+
checkpointer=InMemorySaver(),
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
agent = Agent.create(
|
|
298
|
+
adapter=adapter,
|
|
299
|
+
agent_id=agent_id,
|
|
300
|
+
api_key=api_key,
|
|
301
|
+
ws_url=os.getenv("THENVOI_WS_URL"),
|
|
302
|
+
rest_url=os.getenv("THENVOI_REST_URL"),
|
|
303
|
+
)
|
|
304
|
+
await agent.run()
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Pydantic AI
|
|
308
|
+
|
|
309
|
+
```python
|
|
310
|
+
from thenvoi import Agent
|
|
311
|
+
from thenvoi.adapters import PydanticAIAdapter
|
|
312
|
+
|
|
313
|
+
adapter = PydanticAIAdapter(
|
|
314
|
+
model="openai:gpt-4o",
|
|
315
|
+
custom_section="You are a helpful assistant.",
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
agent = Agent.create(
|
|
319
|
+
adapter=adapter,
|
|
320
|
+
agent_id=agent_id,
|
|
321
|
+
api_key=api_key,
|
|
322
|
+
)
|
|
323
|
+
await agent.run()
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Anthropic SDK
|
|
327
|
+
|
|
328
|
+
```python
|
|
329
|
+
from thenvoi import Agent
|
|
330
|
+
from thenvoi.adapters import AnthropicAdapter
|
|
331
|
+
|
|
332
|
+
adapter = AnthropicAdapter(
|
|
333
|
+
model="claude-sonnet-4-5-20250929",
|
|
334
|
+
custom_section="You are a helpful assistant.",
|
|
335
|
+
enable_execution_reporting=True, # Show tool_call/tool_result events
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
agent = Agent.create(
|
|
339
|
+
adapter=adapter,
|
|
340
|
+
agent_id=agent_id,
|
|
341
|
+
api_key=api_key,
|
|
342
|
+
)
|
|
343
|
+
await agent.run()
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Claude Agent SDK
|
|
347
|
+
|
|
348
|
+
```python
|
|
349
|
+
from thenvoi import Agent
|
|
350
|
+
from thenvoi.adapters import ClaudeSDKAdapter
|
|
351
|
+
|
|
352
|
+
adapter = ClaudeSDKAdapter(
|
|
353
|
+
model="claude-sonnet-4-5-20250929",
|
|
354
|
+
max_thinking_tokens=10000, # Enable extended thinking
|
|
355
|
+
enable_execution_reporting=True,
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
agent = Agent.create(
|
|
359
|
+
adapter=adapter,
|
|
360
|
+
agent_id=agent_id,
|
|
361
|
+
api_key=api_key,
|
|
362
|
+
)
|
|
363
|
+
await agent.run()
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Codex App-Server
|
|
367
|
+
|
|
368
|
+
```python
|
|
369
|
+
from thenvoi import Agent
|
|
370
|
+
from thenvoi.adapters.codex import CodexAdapter, CodexAdapterConfig
|
|
371
|
+
|
|
372
|
+
adapter = CodexAdapter(
|
|
373
|
+
config=CodexAdapterConfig(
|
|
374
|
+
transport="stdio", # or "ws"
|
|
375
|
+
role="coding",
|
|
376
|
+
approval_policy="never",
|
|
377
|
+
approval_mode="manual",
|
|
378
|
+
emit_turn_task_markers=False, # Optional: avoid duplicate task noise
|
|
379
|
+
cwd=".",
|
|
380
|
+
)
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
agent = Agent.create(
|
|
384
|
+
adapter=adapter,
|
|
385
|
+
agent_id=agent_id,
|
|
386
|
+
api_key=api_key,
|
|
387
|
+
)
|
|
388
|
+
await agent.run()
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
Runtime chat commands (handled by adapter without starting a Codex turn):
|
|
392
|
+
- `/status` - show transport/model/thread mapping and adapter status
|
|
393
|
+
- `/model` or `/models` - show current selected/configured model
|
|
394
|
+
- `/model list` or `/models list` - list visible models from `model/list`
|
|
395
|
+
- `/model <id>` or `/models <id>` - set model override for subsequent turns
|
|
396
|
+
- `/approvals` - list pending manual approvals
|
|
397
|
+
- `/approve <id>` - accept pending approval
|
|
398
|
+
- `/decline <id>` - decline pending approval
|
|
399
|
+
- `/help` - show command help
|
|
400
|
+
|
|
401
|
+
Current support matrix:
|
|
402
|
+
- Attached folders: supported.
|
|
403
|
+
- Local runtime: set `--codex-cwd` (or `CodexAdapterConfig.cwd`) to any host path Codex should work in.
|
|
404
|
+
- Docker runtime: add extra `volumes` mounts in `examples/codex/docker-compose*.yml` and point `CODEX_CWD` (or `--codex-cwd`) to that mounted path.
|
|
405
|
+
- Custom prompts: supported.
|
|
406
|
+
- CLI-level custom prompt: `--custom-section "..."` (appended to the selected role profile prompt).
|
|
407
|
+
- Programmatic full prompt override: `CodexAdapterConfig.system_prompt` (replaces generated base+role prompt).
|
|
408
|
+
- Programmatic prompt composition control: `CodexAdapterConfig.include_base_instructions`.
|
|
409
|
+
- Other supported runtime config (CLI): `--codex-transport`, `--codex-ws-url`, `--codex-model`, `--codex-role`, `--codex-personality`, `--codex-approval-policy`, `--codex-approval-mode`, `--codex-turn-task-markers`, `--codex-cwd`, `--codex-sandbox`.
|
|
410
|
+
- Other supported runtime config (programmatic): `sandbox`, `sandbox_policy`, `codex_command`, `codex_env`, `additional_dynamic_tools`, timeout knobs (`turn_timeout_s`, approval wait/timeout settings).
|
|
411
|
+
- Not implemented yet: attach/detach folders via chat slash commands, per-room prompt profile registry in platform settings, and slash commands for sandbox/approval-policy mutation beyond `/model` and approval actions.
|
|
412
|
+
- Detailed ownership handover design + gap matrix: `docs/codex/codex-handover-design-gap-analysis.md`.
|
|
413
|
+
|
|
414
|
+
### CrewAI
|
|
415
|
+
|
|
416
|
+
```python
|
|
417
|
+
from thenvoi import Agent
|
|
418
|
+
from thenvoi.adapters import CrewAIAdapter
|
|
419
|
+
|
|
420
|
+
adapter = CrewAIAdapter(
|
|
421
|
+
model="gpt-4o",
|
|
422
|
+
role="Research Assistant",
|
|
423
|
+
goal="Help users find and analyze information",
|
|
424
|
+
backstory="Expert researcher with deep domain knowledge",
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
agent = Agent.create(
|
|
428
|
+
adapter=adapter,
|
|
429
|
+
agent_id=agent_id,
|
|
430
|
+
api_key=api_key,
|
|
431
|
+
)
|
|
432
|
+
await agent.run()
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### Parlant
|
|
436
|
+
|
|
437
|
+
```python
|
|
438
|
+
from thenvoi import Agent
|
|
439
|
+
from thenvoi.adapters import ParlantAdapter
|
|
440
|
+
|
|
441
|
+
adapter = ParlantAdapter(
|
|
442
|
+
model="gpt-4o",
|
|
443
|
+
custom_section="You are a helpful customer support agent.",
|
|
444
|
+
guidelines=[
|
|
445
|
+
{
|
|
446
|
+
"condition": "Customer asks about refunds",
|
|
447
|
+
"action": "Check order status first to see if eligible",
|
|
448
|
+
},
|
|
449
|
+
],
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
agent = Agent.create(
|
|
453
|
+
adapter=adapter,
|
|
454
|
+
agent_id=agent_id,
|
|
455
|
+
api_key=api_key,
|
|
456
|
+
)
|
|
457
|
+
await agent.run()
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Google ADK
|
|
461
|
+
|
|
462
|
+
> **Note:** Requires a Google API key for Gemini. Get one from [Google AI Studio](https://aistudio.google.com/apikey).
|
|
463
|
+
|
|
464
|
+
```python
|
|
465
|
+
from thenvoi import Agent
|
|
466
|
+
from thenvoi.adapters import GoogleADKAdapter
|
|
467
|
+
|
|
468
|
+
adapter = GoogleADKAdapter(
|
|
469
|
+
model="gemini-2.5-flash",
|
|
470
|
+
custom_section="You are a helpful assistant.",
|
|
471
|
+
enable_execution_reporting=True,
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
agent = Agent.create(
|
|
475
|
+
adapter=adapter,
|
|
476
|
+
agent_id=agent_id,
|
|
477
|
+
api_key=api_key,
|
|
478
|
+
)
|
|
479
|
+
await agent.run()
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
Set `GOOGLE_API_KEY` (or `GOOGLE_GENAI_API_KEY`) in your environment for Gemini authentication.
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
### Gemini SDK
|
|
486
|
+
|
|
487
|
+
> **Note:** Requires `GEMINI_API_KEY` for the official `google-genai` SDK.
|
|
488
|
+
|
|
489
|
+
```python
|
|
490
|
+
from thenvoi import Agent
|
|
491
|
+
from thenvoi.adapters import GeminiAdapter
|
|
492
|
+
|
|
493
|
+
adapter = GeminiAdapter(
|
|
494
|
+
model="gemini-2.5-flash",
|
|
495
|
+
custom_section="You are a helpful assistant.",
|
|
496
|
+
enable_execution_reporting=True,
|
|
497
|
+
)
|
|
498
|
+
|
|
499
|
+
agent = Agent.create(
|
|
500
|
+
adapter=adapter,
|
|
501
|
+
agent_id=agent_id,
|
|
502
|
+
api_key=api_key,
|
|
503
|
+
)
|
|
504
|
+
await agent.run()
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
Set `GEMINI_API_KEY` in your environment for Gemini SDK authentication.
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
## Examples Overview
|
|
511
|
+
|
|
512
|
+
### LangGraph (`examples/langgraph/`)
|
|
513
|
+
|
|
514
|
+
| File | Description |
|
|
515
|
+
|------|-------------|
|
|
516
|
+
| `01_simple_agent.py` | Minimal setup with `Agent.create()` and LangGraphAdapter |
|
|
517
|
+
| `02_custom_tools.py` | Custom `@tool` functions (calculator, weather) via `additional_tools` |
|
|
518
|
+
| `03_custom_personality.py` | Custom behavior via `custom_instructions` |
|
|
519
|
+
| `04_calculator_as_tool.py` | Wraps a LangGraph as a tool using `graph_as_tool()` |
|
|
520
|
+
| `05_rag_as_tool.py` | Agentic RAG graph wrapped as a tool for research questions |
|
|
521
|
+
| `06_delegate_to_sql_agent.py` | SQL agent with its own LLM and database tools as a subgraph |
|
|
522
|
+
|
|
523
|
+
### Pydantic AI (`examples/pydantic_ai/`)
|
|
524
|
+
|
|
525
|
+
| File | Description |
|
|
526
|
+
|------|-------------|
|
|
527
|
+
| `01_basic_agent.py` | Minimal setup with PydanticAIAdapter using OpenAI |
|
|
528
|
+
| `02_custom_instructions.py` | Support agent persona using Anthropic Claude |
|
|
529
|
+
|
|
530
|
+
### Anthropic SDK (`examples/anthropic/`)
|
|
531
|
+
|
|
532
|
+
| File | Description |
|
|
533
|
+
|------|-------------|
|
|
534
|
+
| `01_basic_agent.py` | Minimal setup with AnthropicAdapter using Claude Sonnet |
|
|
535
|
+
| `02_custom_instructions.py` | Support agent with execution reporting enabled |
|
|
536
|
+
|
|
537
|
+
### Claude Agent SDK (`examples/claude_sdk/`)
|
|
538
|
+
|
|
539
|
+
| File | Description |
|
|
540
|
+
|------|-------------|
|
|
541
|
+
| `01_basic_agent.py` | Minimal setup with ClaudeSDKAdapter using Claude Sonnet |
|
|
542
|
+
| `02_extended_thinking.py` | Extended thinking with 10,000 token thinking budget |
|
|
543
|
+
|
|
544
|
+
### Codex (`examples/codex/`)
|
|
545
|
+
|
|
546
|
+
| File | Description |
|
|
547
|
+
|------|-------------|
|
|
548
|
+
| `01_basic_agent.py` | CodexAdapter with room/thread mapping and dynamic Thenvoi tools |
|
|
549
|
+
|
|
550
|
+
### Gemini SDK (`examples/gemini/`)
|
|
551
|
+
|
|
552
|
+
| File | Description |
|
|
553
|
+
|------|-------------|
|
|
554
|
+
| `01_basic_agent.py` | Minimal setup with GeminiAdapter using Gemini 2.5 Flash |
|
|
555
|
+
|
|
556
|
+
### CrewAI (`examples/crewai/`)
|
|
557
|
+
|
|
558
|
+
| File | Description |
|
|
559
|
+
|------|-------------|
|
|
560
|
+
| `01_basic_agent.py` | Simple agent with CrewAIAdapter |
|
|
561
|
+
| `02_role_based_agent.py` | Agent with role, goal, and backstory |
|
|
562
|
+
| `03_coordinator_agent.py` | Multi-agent orchestration coordinator |
|
|
563
|
+
| `04_research_crew.py` | Research team with Analyst, Writer, and Editor |
|
|
564
|
+
|
|
565
|
+
### Parlant (`examples/parlant/`)
|
|
566
|
+
|
|
567
|
+
| File | Description |
|
|
568
|
+
|------|-------------|
|
|
569
|
+
| `01_basic_agent.py` | Simple agent with ParlantAdapter |
|
|
570
|
+
| `02_with_guidelines.py` | Behavioral guidelines (condition/action rules) |
|
|
571
|
+
| `03_support_agent.py` | Realistic customer support agent |
|
|
572
|
+
|
|
573
|
+
### Letta (`examples/letta/`)
|
|
574
|
+
|
|
575
|
+
| File | Description |
|
|
576
|
+
|------|-------------|
|
|
577
|
+
| `01_basic_agent.py` | Minimal setup with LettaAdapter using Cloud or self-hosted Letta |
|
|
578
|
+
|
|
579
|
+
### Google ADK (`examples/google_adk/`)
|
|
580
|
+
|
|
581
|
+
| File | Description |
|
|
582
|
+
|------|-------------|
|
|
583
|
+
| `01_basic_agent.py` | Minimal setup with GoogleADKAdapter using Gemini 2.5 Flash |
|
|
584
|
+
| `02_custom_instructions.py` | Custom system prompt with Gemini 2.5 Pro and execution reporting |
|
|
585
|
+
| `03_custom_tools.py` | Custom tools (calculator, weather) via `additional_tools` |
|
|
586
|
+
|
|
587
|
+
### A2A Adapter (`examples/a2a_bridge/`)
|
|
588
|
+
|
|
589
|
+
| File | Description |
|
|
590
|
+
|------|-------------|
|
|
591
|
+
| `01_basic_agent.py` | Basic bridge forwarding Thenvoi messages to an external A2A agent |
|
|
592
|
+
| `02_with_auth.py` | A2A bridge with API key authentication |
|
|
593
|
+
|
|
594
|
+
### A2A Gateway (`examples/a2a_gateway/`)
|
|
595
|
+
|
|
596
|
+
| File | Description |
|
|
597
|
+
|------|-------------|
|
|
598
|
+
| `01_basic_gateway.py` | Exposes Thenvoi peers as A2A protocol endpoints |
|
|
599
|
+
| `02_with_demo_agent.py` | Gateway + LangGraph demo orchestrator |
|
|
600
|
+
|
|
601
|
+
---
|
|
602
|
+
|
|
603
|
+
## Running Examples
|
|
604
|
+
|
|
605
|
+
### Quick Start with run_agent.py
|
|
606
|
+
|
|
607
|
+
```bash
|
|
608
|
+
# LangGraph (default)
|
|
609
|
+
uv run python examples/run_agent.py
|
|
610
|
+
|
|
611
|
+
# Pydantic AI
|
|
612
|
+
uv run python examples/run_agent.py --example pydantic_ai
|
|
613
|
+
|
|
614
|
+
# Anthropic SDK
|
|
615
|
+
uv run python examples/run_agent.py --example anthropic
|
|
616
|
+
|
|
617
|
+
# Claude SDK with extended thinking
|
|
618
|
+
uv run python examples/run_agent.py --example claude_sdk --thinking
|
|
619
|
+
|
|
620
|
+
# Codex App-Server adapter
|
|
621
|
+
uv run python examples/run_agent.py --example codex --agent darter --codex-transport stdio
|
|
622
|
+
|
|
623
|
+
# Codex adapter without synthetic turn task markers
|
|
624
|
+
uv run python examples/run_agent.py --example codex --agent darter --codex-transport stdio --no-codex-turn-task-markers
|
|
625
|
+
|
|
626
|
+
# Codex adapter with manual approvals (default)
|
|
627
|
+
uv run python examples/run_agent.py --example codex --agent darter --codex-approval-mode manual
|
|
628
|
+
|
|
629
|
+
# Codex adapter with explicit sandbox mode
|
|
630
|
+
uv run python examples/run_agent.py --example codex --agent darter --codex-sandbox external-sandbox
|
|
631
|
+
|
|
632
|
+
# Codex via WebSocket transport (dev/diagnostics)
|
|
633
|
+
uv run python examples/run_agent.py --example codex --agent darter --codex-transport ws --codex-ws-url ws://127.0.0.1:8765
|
|
634
|
+
|
|
635
|
+
# A2A Adapter (call external A2A agents from Thenvoi)
|
|
636
|
+
uv run python examples/run_agent.py --example a2a --a2a-url http://localhost:10000
|
|
637
|
+
|
|
638
|
+
# A2A Gateway (expose Thenvoi peers as A2A endpoints)
|
|
639
|
+
uv run python examples/run_agent.py --example a2a_gateway --debug
|
|
640
|
+
|
|
641
|
+
# Contact handling strategies
|
|
642
|
+
uv run python examples/run_agent.py --example pydantic_ai --contacts auto # Auto-approve requests
|
|
643
|
+
uv run python examples/run_agent.py --example pydantic_ai --contacts hub # LLM decides in hub room
|
|
644
|
+
uv run python examples/run_agent.py --example pydantic_ai --contacts broadcast # Broadcast-only awareness
|
|
645
|
+
|
|
646
|
+
# See all options
|
|
647
|
+
uv run python examples/run_agent.py --help
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
### Individual Examples
|
|
651
|
+
|
|
652
|
+
```bash
|
|
653
|
+
# LangGraph
|
|
654
|
+
uv run python examples/langgraph/01_simple_agent.py
|
|
655
|
+
uv run python examples/langgraph/02_custom_tools.py
|
|
656
|
+
|
|
657
|
+
# Pydantic AI
|
|
658
|
+
uv run python examples/pydantic_ai/01_basic_agent.py
|
|
659
|
+
|
|
660
|
+
# Anthropic SDK
|
|
661
|
+
uv run python examples/anthropic/01_basic_agent.py
|
|
662
|
+
|
|
663
|
+
# Claude SDK
|
|
664
|
+
uv run python examples/claude_sdk/01_basic_agent.py
|
|
665
|
+
|
|
666
|
+
# Codex
|
|
667
|
+
uv run examples/codex/01_basic_agent.py
|
|
668
|
+
|
|
669
|
+
# CrewAI
|
|
670
|
+
uv run python examples/crewai/01_basic_agent.py
|
|
671
|
+
|
|
672
|
+
# Parlant
|
|
673
|
+
uv run python examples/parlant/01_basic_agent.py
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
### A2A Adapter Setup
|
|
677
|
+
|
|
678
|
+
Connect a Thenvoi agent to an external A2A-compliant agent:
|
|
679
|
+
|
|
680
|
+
```bash
|
|
681
|
+
# Terminal 1: Start an external A2A agent (e.g., LangGraph currency agent)
|
|
682
|
+
cd /path/to/a2a-samples/samples/python/agents/langgraph
|
|
683
|
+
python -m app --host localhost --port 10000
|
|
684
|
+
|
|
685
|
+
# Terminal 2: Start the Thenvoi A2A bridge agent
|
|
686
|
+
uv run python examples/run_agent.py --example a2a --a2a-url http://localhost:10000 --debug
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
### A2A Gateway Setup
|
|
690
|
+
|
|
691
|
+
Run the gateway and orchestrator to expose Thenvoi peers as A2A endpoints:
|
|
692
|
+
|
|
693
|
+
```bash
|
|
694
|
+
# Terminal 1: Start A2A Gateway (port 10000)
|
|
695
|
+
uv run python examples/run_agent.py --example a2a_gateway --debug
|
|
696
|
+
|
|
697
|
+
# Terminal 2: Start Demo Orchestrator (port 10001)
|
|
698
|
+
uv run python examples/a2a_gateway/demo_orchestrator/__main__.py --gateway-url http://localhost:10000
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
---
|
|
702
|
+
|
|
703
|
+
## Docker Usage
|
|
704
|
+
|
|
705
|
+
You can run the examples using Docker without installing dependencies locally.
|
|
706
|
+
|
|
707
|
+
### Setup
|
|
708
|
+
|
|
709
|
+
1. Copy the example environment file and add your credentials:
|
|
710
|
+
|
|
711
|
+
```bash
|
|
712
|
+
cp .env.example .env
|
|
713
|
+
cp agent_config.yaml.example agent_config.yaml
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
Edit `.env` and `agent_config.yaml` with your actual values.
|
|
717
|
+
|
|
718
|
+
> **Note:** Both `.env` and `agent_config.yaml` are git-ignored. Never commit credentials to version control.
|
|
719
|
+
|
|
720
|
+
### Running with Docker Compose
|
|
721
|
+
|
|
722
|
+
```bash
|
|
723
|
+
# LangGraph examples
|
|
724
|
+
docker compose up langgraph-01-simple
|
|
725
|
+
docker compose up langgraph-02-custom-tools
|
|
726
|
+
|
|
727
|
+
# Rebuild after changes
|
|
728
|
+
docker compose up --build langgraph-01-simple
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
### Running with Docker (without compose)
|
|
732
|
+
|
|
733
|
+
```bash
|
|
734
|
+
# Build
|
|
735
|
+
docker build -t thenvoi-sdk .
|
|
736
|
+
|
|
737
|
+
# Run (load .env first)
|
|
738
|
+
set -a && source .env && set +a
|
|
739
|
+
docker run --rm \
|
|
740
|
+
-e THENVOI_REST_URL="${THENVOI_REST_URL}" \
|
|
741
|
+
-e THENVOI_WS_URL="${THENVOI_WS_URL}" \
|
|
742
|
+
-e OPENAI_API_KEY="${OPENAI_API_KEY}" \
|
|
743
|
+
-v ./agent_config.yaml:/app/agent_config.yaml \
|
|
744
|
+
thenvoi-sdk \
|
|
745
|
+
uv run --extra langgraph python examples/langgraph/01_simple_agent.py
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
### Codex Docker Worker (Phase 2)
|
|
749
|
+
|
|
750
|
+
Use production image assets under `docker/codex/` and run via compose examples under `examples/codex/`.
|
|
751
|
+
|
|
752
|
+
```bash
|
|
753
|
+
# Build and run a single Codex-backed Thenvoi agent
|
|
754
|
+
docker compose -f examples/codex/docker-compose.yml up --build codex-agent
|
|
755
|
+
|
|
756
|
+
# One-off smoke check inside the running container
|
|
757
|
+
docker compose -f examples/codex/docker-compose.yml exec codex-agent /app/docker/codex/smoke.sh
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
Dependency modes:
|
|
761
|
+
- Default (portable): uses publishable dependencies in-container (`uv sync`), with phoenix channels fetched over HTTPS tarball (no SSH/submodule access).
|
|
762
|
+
- Local SDK override (when `thenvoi-client-rest` on PyPI is behind): install a host wheel at container start.
|
|
763
|
+
- Runtime execution uses `/app/.venv/bin/python` (not `uv run`) to avoid re-resolving host-local `tool.uv.sources` paths from mounted repo files.
|
|
764
|
+
- Codex CLI is installed in-image via `npm i -g @openai/codex` and validated with `codex app-server --help` during build.
|
|
765
|
+
- Docker defaults `CODEX_SANDBOX=external-sandbox` so Codex defers sandboxing to Docker.
|
|
766
|
+
|
|
767
|
+
```bash
|
|
768
|
+
export THENVOI_CLIENT_REST_WHEEL_DIR=/Users/vlad/Documents/elixir/dist_rearch/fern/generated_sdk/dist
|
|
769
|
+
export THENVOI_CLIENT_REST_WHEEL=/opt/thenvoi-client-rest/thenvoi_client_rest-0.0.1.dev6-py3-none-any.whl
|
|
770
|
+
docker compose -f examples/codex/docker-compose.yml up --build codex-agent
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
If you also need a local `phoenix-channels-python-client` build:
|
|
774
|
+
|
|
775
|
+
```bash
|
|
776
|
+
export PHOENIX_CHANNELS_CLIENT_WHEEL_DIR=/path/to/phoenix-client/dist
|
|
777
|
+
export PHOENIX_CHANNELS_CLIENT_WHEEL=/opt/phoenix-client
|
|
778
|
+
# (optional: use /opt/phoenix-client/<wheel-file>.whl instead of directory)
|
|
779
|
+
docker compose -f examples/codex/docker-compose.yml up --build codex-agent
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
If you need both local wheels in one run:
|
|
783
|
+
|
|
784
|
+
```bash
|
|
785
|
+
export THENVOI_CLIENT_REST_WHEEL_DIR=/Users/vlad/Documents/elixir/dist_rearch/fern/generated_sdk/dist
|
|
786
|
+
export THENVOI_CLIENT_REST_WHEEL=/opt/thenvoi-client-rest/thenvoi_client_rest-0.0.1.dev6-py3-none-any.whl
|
|
787
|
+
export PHOENIX_CHANNELS_CLIENT_WHEEL_DIR=/Users/vlad/Documents/elixir/dist_rearch/phoenix-channels-python-client/dist
|
|
788
|
+
export PHOENIX_CHANNELS_CLIENT_WHEEL=/opt/phoenix-client
|
|
789
|
+
docker compose -f examples/codex/docker-compose.yml build --no-cache codex-agent
|
|
790
|
+
docker compose -f examples/codex/docker-compose.yml up codex-agent
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
Expected host mounts:
|
|
794
|
+
- `~/.codex` for Codex OAuth session state
|
|
795
|
+
- `~/.config/gh`, `~/.ssh`, `~/.gitconfig` for git/GitHub workflows
|
|
796
|
+
- project repo mounted at `/workspace/repo` for clone/worktree/markdown operations
|
|
797
|
+
- shared workspace state at `/workspace/state` for repo-init lock/metadata
|
|
798
|
+
- shared context docs at `/workspace/context` when repo indexing is enabled
|
|
799
|
+
|
|
800
|
+
Primary control files for identity/folders/permissions:
|
|
801
|
+
- `agent_config.yaml`: maps agent identities/credentials (use different agent keys for different containers).
|
|
802
|
+
- `docker/codex/Dockerfile`: Codex runtime image.
|
|
803
|
+
- `docker/codex/entrypoint.sh`: runtime setup and optional wheel installation.
|
|
804
|
+
- `docker/codex/smoke.sh`: in-container smoke checks.
|
|
805
|
+
- `examples/codex/docker-compose.yml`: single-agent Codex service.
|
|
806
|
+
- `examples/codex/docker-compose.multi.yml`: ready-made dual-agent setup (`codex-darter` + `codex-reviewer`).
|
|
807
|
+
- `examples/codex/docker-compose.plan-review.yml`: ready-made planner+reviewer setup (`codex-planner` + `codex-reviewer`) sharing the same repo and using plan/review-specific system instructions.
|
|
808
|
+
- `examples/codex/.env.plan-review.example`: env template for planner/reviewer overrides.
|
|
809
|
+
- `.env`: shared Thenvoi URLs and other environment defaults.
|
|
810
|
+
|
|
811
|
+
Ready-made two-agent compose (recommended):
|
|
812
|
+
```bash
|
|
813
|
+
docker compose -f examples/codex/docker-compose.multi.yml up --build
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
Ready-made planner+reviewer compose:
|
|
817
|
+
```bash
|
|
818
|
+
cp examples/codex/.env.plan-review.example .env.codex.plan-review
|
|
819
|
+
# edit .env.codex.plan-review if needed
|
|
820
|
+
docker compose --env-file .env.codex.plan-review -f examples/codex/docker-compose.plan-review.yml up --build
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
Run only one service from the multi file:
|
|
824
|
+
```bash
|
|
825
|
+
docker compose -f examples/codex/docker-compose.multi.yml up --build codex-darter
|
|
826
|
+
docker compose -f examples/codex/docker-compose.multi.yml up --build codex-reviewer
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
Override identities/folders/sandbox per service:
|
|
830
|
+
```bash
|
|
831
|
+
CODEX_DARTER_AGENT_KEY=darter CODEX_DARTER_CWD=/workspace/repo CODEX_DARTER_SANDBOX=external-sandbox \
|
|
832
|
+
CODEX_REVIEWER_AGENT_KEY=reviewer CODEX_REVIEWER_CWD=/workspace/repo CODEX_REVIEWER_SANDBOX=external-sandbox \
|
|
833
|
+
docker compose -f examples/codex/docker-compose.multi.yml up --build
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
Ad-hoc alternative (single-service compose with explicit project names):
|
|
837
|
+
```bash
|
|
838
|
+
CODEX_AGENT_KEY=darter CODEX_CWD=/workspace/repo CODEX_SANDBOX=external-sandbox \
|
|
839
|
+
docker compose -p codex-darter -f examples/codex/docker-compose.yml up --build codex-agent
|
|
840
|
+
|
|
841
|
+
CODEX_AGENT_KEY=reviewer CODEX_CWD=/workspace/repo CODEX_SANDBOX=external-sandbox \
|
|
842
|
+
docker compose -p codex-reviewer -f examples/codex/docker-compose.yml up --build codex-agent
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
Networking note:
|
|
846
|
+
- Inside Docker, `localhost` is the container, not your host.
|
|
847
|
+
- Codex compose defaults to:
|
|
848
|
+
- `THENVOI_REST_URL=http://host.docker.internal:4000`
|
|
849
|
+
- `THENVOI_WS_URL=ws://host.docker.internal:4000/api/v1/socket/websocket`
|
|
850
|
+
- Override with:
|
|
851
|
+
- `THENVOI_REST_URL_DOCKER=...`
|
|
852
|
+
- `THENVOI_WS_URL_DOCKER=...`
|
|
853
|
+
|
|
854
|
+
---
|
|
855
|
+
|
|
856
|
+
## Configuration
|
|
857
|
+
|
|
858
|
+
### 1. Copy configuration files from examples
|
|
859
|
+
|
|
860
|
+
```bash
|
|
861
|
+
cp .env.example .env
|
|
862
|
+
cp agent_config.yaml.example agent_config.yaml
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
### 2. Edit `.env` with your API keys
|
|
866
|
+
|
|
867
|
+
```bash
|
|
868
|
+
# Platform URLs
|
|
869
|
+
THENVOI_REST_URL=https://app.thenvoi.com
|
|
870
|
+
THENVOI_WS_URL=wss://app.thenvoi.com/api/v1/socket/websocket
|
|
871
|
+
|
|
872
|
+
# LLM API Keys - fill these in
|
|
873
|
+
OPENAI_API_KEY=sk-your-key-here
|
|
874
|
+
ANTHROPIC_API_KEY=sk-ant-your-key-here
|
|
875
|
+
```
|
|
876
|
+
|
|
877
|
+
### 3. Edit `agent_config.yaml` with your agent credentials
|
|
878
|
+
|
|
879
|
+
```yaml
|
|
880
|
+
my_agent:
|
|
881
|
+
agent_id: "your-agent-uuid"
|
|
882
|
+
api_key: "your-api-key"
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
> **Security:** Never commit API keys. Both `.env` and `agent_config.yaml` are git-ignored.
|
|
886
|
+
>
|
|
887
|
+
> **Important:** Always copy from example files rather than creating new files to avoid URL typos.
|
|
888
|
+
|
|
889
|
+
---
|
|
890
|
+
|
|
891
|
+
## Architecture
|
|
892
|
+
|
|
893
|
+
The SDK uses composition over inheritance:
|
|
894
|
+
|
|
895
|
+
```
|
|
896
|
+
Agent.create(adapter, ...)
|
|
897
|
+
│
|
|
898
|
+
├── Adapter (your LLM framework)
|
|
899
|
+
│ └── on_started(), on_message(), on_cleanup()
|
|
900
|
+
│
|
|
901
|
+
├── PlatformRuntime (room lifecycle)
|
|
902
|
+
│ └── RoomPresence → Execution per room
|
|
903
|
+
│
|
|
904
|
+
└── ThenvoiLink (WebSocket + REST transport)
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
### Building Custom Adapters
|
|
908
|
+
|
|
909
|
+
Implement the `SimpleAdapter` protocol:
|
|
910
|
+
|
|
911
|
+
```python
|
|
912
|
+
from thenvoi.adapters.base import SimpleAdapter
|
|
913
|
+
|
|
914
|
+
class MyAdapter(SimpleAdapter[MyHistoryType]):
|
|
915
|
+
async def on_started(self, agent_name: str, agent_description: str) -> None:
|
|
916
|
+
"""Called when agent starts."""
|
|
917
|
+
pass
|
|
918
|
+
|
|
919
|
+
async def on_message(
|
|
920
|
+
self,
|
|
921
|
+
ctx: ExecutionContext,
|
|
922
|
+
tools: AgentTools,
|
|
923
|
+
history: MyHistoryType,
|
|
924
|
+
) -> None:
|
|
925
|
+
"""Handle incoming message."""
|
|
926
|
+
# Your LLM logic here
|
|
927
|
+
await tools.send_message("Hello!")
|
|
928
|
+
|
|
929
|
+
async def on_cleanup(self) -> None:
|
|
930
|
+
"""Called when agent stops."""
|
|
931
|
+
pass
|
|
932
|
+
```
|
|
933
|
+
|
|
934
|
+
---
|
|
935
|
+
|
|
936
|
+
## Platform Tools
|
|
937
|
+
|
|
938
|
+
All adapters automatically have access to:
|
|
939
|
+
|
|
940
|
+
| Tool | Description |
|
|
941
|
+
|------|-------------|
|
|
942
|
+
| `thenvoi_send_message` | Send a message to the chat room |
|
|
943
|
+
| `thenvoi_add_participant` | Add a user or agent to the room |
|
|
944
|
+
| `thenvoi_remove_participant` | Remove a participant from the room |
|
|
945
|
+
| `thenvoi_get_participants` | List current room participants |
|
|
946
|
+
| `thenvoi_lookup_peers` | List users/agents that can be added |
|
|
947
|
+
|
|
948
|
+
---
|
|
949
|
+
|
|
950
|
+
## Custom Tools
|
|
951
|
+
|
|
952
|
+
Add domain-specific tools to your agents via the `additional_tools` parameter. Each adapter accepts tools in its framework's native format.
|
|
953
|
+
|
|
954
|
+
| Adapter | Tool Format |
|
|
955
|
+
|---------|-------------|
|
|
956
|
+
| `LangGraphAdapter` | LangChain `@tool` decorated functions |
|
|
957
|
+
| `PydanticAIAdapter` | PydanticAI-style functions with `RunContext` |
|
|
958
|
+
| `AnthropicAdapter` | `CustomToolDef` tuples (Pydantic model + callable) |
|
|
959
|
+
| `CrewAIAdapter` | `CustomToolDef` tuples |
|
|
960
|
+
| `ParlantAdapter` | `CustomToolDef` tuples |
|
|
961
|
+
| `ClaudeSDKAdapter` | `CustomToolDef` tuples (wrapped to MCP) |
|
|
962
|
+
|
|
963
|
+
### LangGraph (LangChain Tools)
|
|
964
|
+
|
|
965
|
+
```python
|
|
966
|
+
from langchain_core.tools import tool
|
|
967
|
+
|
|
968
|
+
@tool
|
|
969
|
+
def calculate(operation: str, a: float, b: float) -> str:
|
|
970
|
+
"""Perform arithmetic calculations."""
|
|
971
|
+
ops = {"add": lambda x, y: x + y, "subtract": lambda x, y: x - y}
|
|
972
|
+
return str(ops[operation](a, b))
|
|
973
|
+
|
|
974
|
+
adapter = LangGraphAdapter(
|
|
975
|
+
llm=ChatOpenAI(model="gpt-4o"),
|
|
976
|
+
checkpointer=InMemorySaver(),
|
|
977
|
+
additional_tools=[calculate],
|
|
978
|
+
)
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
### Anthropic / CrewAI / Parlant / ClaudeSDK (CustomToolDef)
|
|
982
|
+
|
|
983
|
+
```python
|
|
984
|
+
from pydantic import BaseModel, Field
|
|
985
|
+
|
|
986
|
+
class CalculatorInput(BaseModel):
|
|
987
|
+
"""Perform arithmetic calculations."""
|
|
988
|
+
operation: str = Field(description="add, subtract, multiply, divide")
|
|
989
|
+
left: float
|
|
990
|
+
right: float
|
|
991
|
+
|
|
992
|
+
def calculate(args: CalculatorInput) -> str:
|
|
993
|
+
ops = {"add": lambda a, b: a + b, "subtract": lambda a, b: a - b}
|
|
994
|
+
return str(ops[args.operation](args.left, args.right))
|
|
995
|
+
|
|
996
|
+
adapter = AnthropicAdapter(
|
|
997
|
+
additional_tools=[(CalculatorInput, calculate)],
|
|
998
|
+
)
|
|
999
|
+
```
|
|
1000
|
+
|
|
1001
|
+
---
|
|
1002
|
+
|
|
1003
|
+
## LangGraph Utilities
|
|
1004
|
+
|
|
1005
|
+
### Wrap Graph as Tool
|
|
1006
|
+
|
|
1007
|
+
```python
|
|
1008
|
+
from thenvoi.integrations.langgraph import graph_as_tool
|
|
1009
|
+
|
|
1010
|
+
calculator_tool = graph_as_tool(
|
|
1011
|
+
calculator_graph,
|
|
1012
|
+
name="calculator",
|
|
1013
|
+
description="Evaluates math expressions"
|
|
1014
|
+
)
|
|
1015
|
+
|
|
1016
|
+
adapter = LangGraphAdapter(
|
|
1017
|
+
llm=llm,
|
|
1018
|
+
checkpointer=checkpointer,
|
|
1019
|
+
additional_tools=[calculator_tool],
|
|
1020
|
+
)
|
|
1021
|
+
```
|
|
1022
|
+
|
|
1023
|
+
### Convert Platform Tools to LangChain
|
|
1024
|
+
|
|
1025
|
+
```python
|
|
1026
|
+
from thenvoi.integrations.langgraph import agent_tools_to_langchain
|
|
1027
|
+
|
|
1028
|
+
langchain_tools = agent_tools_to_langchain(agent_tools)
|
|
1029
|
+
```
|
|
1030
|
+
|
|
1031
|
+
---
|
|
1032
|
+
|
|
1033
|
+
## Development
|
|
1034
|
+
|
|
1035
|
+
See [AGENTS.md](AGENTS.md) for development setup, testing, and contributing guidelines.
|
|
1036
|
+
|
|
1037
|
+
---
|
|
1038
|
+
|
|
1039
|
+
## Help & Feedback
|
|
1040
|
+
|
|
1041
|
+
- **Documentation:** See `examples/` for complete working examples
|
|
1042
|
+
- **Issues:** https://github.com/thenvoi/thenvoi-sdk-python/issues
|