agenthub-python 0.3.0__tar.gz → 0.3.2__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.
Files changed (31) hide show
  1. agenthub_python-0.3.2/PKG-INFO +351 -0
  2. agenthub_python-0.3.2/README.md +330 -0
  3. agenthub_python-0.3.2/agenthub/abort_signal.py +135 -0
  4. {agenthub_python-0.3.0 → agenthub_python-0.3.2}/agenthub/auto_client.py +34 -15
  5. {agenthub_python-0.3.0 → agenthub_python-0.3.2}/agenthub/base_client.py +96 -13
  6. {agenthub_python-0.3.0 → agenthub_python-0.3.2}/agenthub/claude4_6/client.py +28 -14
  7. agenthub_python-0.3.2/agenthub/claude4_8/__init__.py +18 -0
  8. agenthub_python-0.3.2/agenthub/claude4_8/client.py +429 -0
  9. agenthub_python-0.3.2/agenthub/deepseek_v4/__init__.py +18 -0
  10. agenthub_python-0.3.2/agenthub/deepseek_v4/client.py +337 -0
  11. {agenthub_python-0.3.0 → agenthub_python-0.3.2}/agenthub/gemini3/client.py +117 -2
  12. {agenthub_python-0.3.0/agenthub/qwen3 → agenthub_python-0.3.2/agenthub/glm5_1}/__init__.py +2 -2
  13. {agenthub_python-0.3.0/agenthub/glm5 → agenthub_python-0.3.2/agenthub/glm5_1}/client.py +13 -12
  14. {agenthub_python-0.3.0/agenthub/gpt5_4 → agenthub_python-0.3.2/agenthub/gpt5_5}/__init__.py +2 -2
  15. {agenthub_python-0.3.0/agenthub/gpt5_4 → agenthub_python-0.3.2/agenthub/gpt5_5}/client.py +18 -18
  16. agenthub_python-0.3.2/agenthub/integration/playground.py +1192 -0
  17. agenthub_python-0.3.2/agenthub/integration/tracer.py +786 -0
  18. {agenthub_python-0.3.0/agenthub/kimi_k2_5 → agenthub_python-0.3.2/agenthub/kimi_k2_6}/__init__.py +2 -2
  19. {agenthub_python-0.3.0/agenthub/kimi_k2_5 → agenthub_python-0.3.2/agenthub/kimi_k2_6}/client.py +14 -13
  20. {agenthub_python-0.3.0/agenthub/glm5 → agenthub_python-0.3.2/agenthub/openai}/__init__.py +2 -2
  21. {agenthub_python-0.3.0/agenthub/qwen3 → agenthub_python-0.3.2/agenthub/openai}/client.py +92 -95
  22. {agenthub_python-0.3.0 → agenthub_python-0.3.2}/agenthub/types.py +57 -1
  23. {agenthub_python-0.3.0 → agenthub_python-0.3.2}/pyproject.toml +10 -4
  24. agenthub_python-0.3.0/PKG-INFO +0 -10
  25. agenthub_python-0.3.0/agenthub/integration/playground.py +0 -646
  26. agenthub_python-0.3.0/agenthub/integration/tracer.py +0 -528
  27. {agenthub_python-0.3.0 → agenthub_python-0.3.2}/agenthub/__init__.py +0 -0
  28. {agenthub_python-0.3.0 → agenthub_python-0.3.2}/agenthub/claude4_6/__init__.py +0 -0
  29. {agenthub_python-0.3.0 → agenthub_python-0.3.2}/agenthub/gemini3/__init__.py +0 -0
  30. {agenthub_python-0.3.0 → agenthub_python-0.3.2}/agenthub/integration/__init__.py +0 -0
  31. {agenthub_python-0.3.0 → agenthub_python-0.3.2}/agenthub/utils.py +0 -0
@@ -0,0 +1,351 @@
1
+ Metadata-Version: 2.4
2
+ Name: agenthub-python
3
+ Version: 0.3.2
4
+ Summary: AgentHub is the LLM API Hub for the Agent era, built for high-precision autonomous agents.
5
+ Keywords: agent,llm,gemini,claude,gpt
6
+ Author: PrismShadow
7
+ License-Expression: Apache-2.0
8
+ Requires-Dist: google-genai>=1.70.0
9
+ Requires-Dist: anthropic[bedrock]>=0.87.0
10
+ Requires-Dist: flask>=3.0.0
11
+ Requires-Dist: openai>=2.30.0
12
+ Requires-Dist: httpx>=0.27.0
13
+ Requires-Dist: httpx[socks] ; extra == 'dev'
14
+ Requires-Dist: pytest>=8.4.2 ; extra == 'dev'
15
+ Requires-Dist: pytest-asyncio>=0.23.0 ; extra == 'dev'
16
+ Requires-Dist: ruff>=0.14.3 ; extra == 'dev'
17
+ Requires-Dist: pillow>=10.0.0 ; extra == 'dev'
18
+ Requires-Python: >=3.11
19
+ Provides-Extra: dev
20
+ Description-Content-Type: text/markdown
21
+
22
+ # AgentHub Python Implementation
23
+
24
+ This document demonstrates how to use `AutoLLMClient` for unified LLM interactions in AgentHub.
25
+
26
+ ## Building
27
+
28
+ ```bash
29
+ make install # Install dependencies
30
+ make build # Build Python package
31
+ make lint # Run ruff linter
32
+ make test # Run tests
33
+ ```
34
+
35
+ ## AutoLLMClient Overview
36
+
37
+ `AutoLLMClient` is a stateful client that automatically routes requests to the appropriate model-specific implementation. It maintains conversation history and provides a unified interface for different LLM providers.
38
+
39
+ ### Initialization
40
+
41
+ Create a client by specifying the model name:
42
+
43
+ ```python
44
+ from agenthub import AutoLLMClient
45
+
46
+ # Initialize with model name
47
+ client = AutoLLMClient(model="gpt-5.5")
48
+
49
+ # Optionally specify API key (if not using environment variables)
50
+ client = AutoLLMClient(model="gpt-5.5", api_key="your-openai-api-key")
51
+
52
+ # Use OpenAI Chat Completions-compatible routing explicitly
53
+ client = AutoLLMClient(model="custom-model", client_type="openai")
54
+ ```
55
+
56
+ The client automatically selects the appropriate client based on the model name.
57
+
58
+ ## Core Methods
59
+
60
+ ### streaming_response
61
+
62
+ Stateless method that requires passing the full message history on each call:
63
+
64
+ ```python
65
+ import asyncio
66
+ from agenthub import AutoLLMClient
67
+
68
+ async def main():
69
+ client = AutoLLMClient(model="gpt-5.5")
70
+
71
+ async for event in client.streaming_response(
72
+ messages=[
73
+ {
74
+ "role": "user",
75
+ "content_items": [{"type": "text", "text": "Hello!"}]
76
+ }
77
+ ],
78
+ config={}
79
+ ):
80
+ print(event)
81
+
82
+ asyncio.run(main())
83
+ ```
84
+
85
+ ### streaming_response_stateful
86
+
87
+ Stateful method that maintains conversation history internally:
88
+
89
+ ```python
90
+ import asyncio
91
+ from agenthub import AutoLLMClient
92
+
93
+ async def main():
94
+ client = AutoLLMClient(model="gpt-5.5")
95
+
96
+ # First message
97
+ async for event in client.streaming_response_stateful(
98
+ message={
99
+ "role": "user",
100
+ "content_items": [{"type": "text", "text": "My name is Alice"}]
101
+ },
102
+ config={}
103
+ ):
104
+ print(event)
105
+
106
+ # Second message - history is maintained automatically
107
+ async for event in client.streaming_response_stateful(
108
+ message={
109
+ "role": "user",
110
+ "content_items": [{"type": "text", "text": "What's my name?"}]
111
+ },
112
+ config={}
113
+ ):
114
+ print(event)
115
+
116
+ asyncio.run(main())
117
+ ```
118
+
119
+ ### get_history
120
+
121
+ Retrieve the conversation history:
122
+
123
+ ```python
124
+ # Get all messages in the conversation
125
+ history = client.get_history()
126
+ print(f"Total messages: {len(history)}")
127
+
128
+ for msg in history:
129
+ print(f"Role: {msg['role']}")
130
+ print(f"Content: {msg['content_items']}")
131
+ ```
132
+
133
+ ### clear_history
134
+
135
+ Clear the conversation history:
136
+
137
+ ```python
138
+ # Clear all conversation history
139
+ client.clear_history()
140
+
141
+ # Verify history is empty
142
+ assert len(client.get_history()) == 0
143
+ ```
144
+
145
+ ### set_history
146
+
147
+ Replace the conversation history with a copy of the provided list:
148
+
149
+ ```python
150
+ # Save current history
151
+ saved_history = client.get_history()
152
+
153
+ # ... do other things, then restore
154
+ client.set_history(saved_history)
155
+
156
+ # Verify history was replaced
157
+ assert len(client.get_history()) == len(saved_history)
158
+ ```
159
+
160
+ ## Tool Calling
161
+
162
+ When using tools, you must handle `tool_call_id` correctly:
163
+
164
+ ```python
165
+ import asyncio
166
+ import json
167
+ from agenthub import AutoLLMClient
168
+
169
+ def get_weather(location: str) -> str:
170
+ """Mock function to get weather."""
171
+ return f"Temperature in {location}: 22°C"
172
+
173
+ async def main():
174
+ # Define tool
175
+ weather_function = {
176
+ "name": "get_weather",
177
+ "description": "Gets the current weather for a given location.",
178
+ "parameters": {
179
+ "type": "object",
180
+ "properties": {
181
+ "location": {
182
+ "type": "string",
183
+ "description": "The city name"
184
+ }
185
+ },
186
+ "required": ["location"]
187
+ }
188
+ }
189
+
190
+ client = AutoLLMClient(model="gpt-5.5")
191
+ config = {"tools": [weather_function]}
192
+
193
+ # User asks about weather
194
+ events = []
195
+ async for event in client.streaming_response_stateful(
196
+ message={
197
+ "role": "user",
198
+ "content_items": [{"type": "text", "text": "What's the weather in London?"}]
199
+ },
200
+ config=config
201
+ ):
202
+ events.append(event)
203
+
204
+ # Extract function call and tool_call_id
205
+ tool_call = None
206
+ for event in events:
207
+ for item in event["content_items"]:
208
+ if item["type"] == "tool_call":
209
+ tool_call = item
210
+ break
211
+
212
+ if tool_call:
213
+ break
214
+
215
+ # Execute function and send result back with tool_call_id
216
+ if tool_call:
217
+ result = get_weather(**tool_call["arguments"])
218
+
219
+ # IMPORTANT: Include tool_call_id in the tool response
220
+ async for event in client.streaming_response_stateful(
221
+ message={
222
+ "role": "user",
223
+ "content_items": [
224
+ {
225
+ "type": "tool_result",
226
+ "text": result,
227
+ "tool_call_id": tool_call["tool_call_id"] # Required for tool responses
228
+ }
229
+ ]
230
+ },
231
+ config=config
232
+ ):
233
+ print(event)
234
+
235
+ asyncio.run(main())
236
+ ```
237
+
238
+ ## Message Format
239
+
240
+ ### UniMessage Structure
241
+
242
+ ```python
243
+ {
244
+ "role": "user" | "assistant",
245
+ "content_items": [
246
+ {"type": "text", "text": "Hello"},
247
+ {"type": "image_url", "image_url": "https://..."},
248
+ {"type": "tool_call", "name": "get_weather", "arguments": {"location": "London"}, "tool_call_id": "call_abc123"}
249
+ ]
250
+ }
251
+ ```
252
+
253
+ ### Tool Response with tool_call_id
254
+
255
+ When responding to a tool call, include the `tool_call_id` in the result content item:
256
+
257
+ ```python
258
+ {
259
+ "role": "user",
260
+ "content_items": [
261
+ {
262
+ "type": "tool_result",
263
+ "text": "London is 22°C today.",
264
+ "tool_call_id": "call_abc123" # From tool_call event
265
+ }
266
+ ]
267
+ }
268
+ ```
269
+
270
+ ## Configuration Options
271
+
272
+ ```python
273
+ from agenthub import PromptCaching, ThinkingLevel
274
+
275
+ config = {
276
+ "max_tokens": 500,
277
+ "temperature": 1.0,
278
+ "tools": [tool_definition],
279
+ "thinking_summary": True,
280
+ "thinking_level": ThinkingLevel.HIGH,
281
+ "tool_choice": "auto", # "auto", "required", "none", or ["tool_name"]
282
+ "system_prompt": "You are a helpful assistant",
283
+ "prompt_caching": PromptCaching.ENABLE,
284
+ "trace_id": "agent1/conversation_001" # Optional: save conversation trace
285
+ }
286
+ ```
287
+
288
+ ## Conversation Tracing
289
+
290
+ AgentHub provides a built-in `Tracer` to save and browse conversation history. When you specify a `trace_id` in the config, conversations are automatically saved to both JSON and TXT formats.
291
+
292
+ ### Basic Usage
293
+
294
+ ```python
295
+ from agenthub import AutoLLMClient
296
+
297
+ client = AutoLLMClient(model="gpt-5.5")
298
+
299
+ # Add trace_id to config
300
+ config = {"trace_id": "agent1/conversation_001"}
301
+
302
+ async for event in client.streaming_response_stateful(
303
+ message={"role": "user", "content_items": [{"type": "text", "text": "Hello"}]},
304
+ config=config
305
+ ):
306
+ pass # Conversation is automatically saved
307
+ ```
308
+
309
+ The default cache directory is `cache`, you can change it by setting `AGENTHUB_CACHE_DIR` environment variable.
310
+
311
+ This creates two files in the `cache` directory:
312
+ - `cache/agent1/conversation_001.json` - Structured data with full history and config
313
+ - `cache/agent1/conversation_001.txt` - Human-readable conversation format
314
+
315
+ ### Browsing Traces with Web Interface
316
+
317
+ Start a web server to browse and view saved conversations:
318
+
319
+ ```python
320
+ from agenthub.integration.tracer import Tracer
321
+
322
+ # Start web server
323
+ Tracer("path/to/cache").start_web_server(host="127.0.0.1", port=25750)
324
+ ```
325
+
326
+ Or use the CLI:
327
+
328
+ ```bash
329
+ python -m agenthub.integration.tracer --cache_dir ./cache --host 127.0.0.1 --port 25750
330
+ ```
331
+
332
+ Then visit `http://127.0.0.1:25750` in your browser to browse saved conversations.
333
+
334
+ ### Test with Playground
335
+
336
+ Start a web server to test with the playground:
337
+
338
+ ```python
339
+ from agenthub.integration.playground import start_playground_server
340
+
341
+ start_playground_server()
342
+ ```
343
+
344
+ Or use the CLI:
345
+
346
+ ```bash
347
+ python -m agenthub.integration.playground --host 127.0.0.1 --port 25751
348
+ ```
349
+
350
+ Then visit `http://127.0.0.1:25751` in your browser to test with the playground.
351
+ The integrated tracer is available at `http://127.0.0.1:25751/tracer/`.
@@ -0,0 +1,330 @@
1
+ # AgentHub Python Implementation
2
+
3
+ This document demonstrates how to use `AutoLLMClient` for unified LLM interactions in AgentHub.
4
+
5
+ ## Building
6
+
7
+ ```bash
8
+ make install # Install dependencies
9
+ make build # Build Python package
10
+ make lint # Run ruff linter
11
+ make test # Run tests
12
+ ```
13
+
14
+ ## AutoLLMClient Overview
15
+
16
+ `AutoLLMClient` is a stateful client that automatically routes requests to the appropriate model-specific implementation. It maintains conversation history and provides a unified interface for different LLM providers.
17
+
18
+ ### Initialization
19
+
20
+ Create a client by specifying the model name:
21
+
22
+ ```python
23
+ from agenthub import AutoLLMClient
24
+
25
+ # Initialize with model name
26
+ client = AutoLLMClient(model="gpt-5.5")
27
+
28
+ # Optionally specify API key (if not using environment variables)
29
+ client = AutoLLMClient(model="gpt-5.5", api_key="your-openai-api-key")
30
+
31
+ # Use OpenAI Chat Completions-compatible routing explicitly
32
+ client = AutoLLMClient(model="custom-model", client_type="openai")
33
+ ```
34
+
35
+ The client automatically selects the appropriate client based on the model name.
36
+
37
+ ## Core Methods
38
+
39
+ ### streaming_response
40
+
41
+ Stateless method that requires passing the full message history on each call:
42
+
43
+ ```python
44
+ import asyncio
45
+ from agenthub import AutoLLMClient
46
+
47
+ async def main():
48
+ client = AutoLLMClient(model="gpt-5.5")
49
+
50
+ async for event in client.streaming_response(
51
+ messages=[
52
+ {
53
+ "role": "user",
54
+ "content_items": [{"type": "text", "text": "Hello!"}]
55
+ }
56
+ ],
57
+ config={}
58
+ ):
59
+ print(event)
60
+
61
+ asyncio.run(main())
62
+ ```
63
+
64
+ ### streaming_response_stateful
65
+
66
+ Stateful method that maintains conversation history internally:
67
+
68
+ ```python
69
+ import asyncio
70
+ from agenthub import AutoLLMClient
71
+
72
+ async def main():
73
+ client = AutoLLMClient(model="gpt-5.5")
74
+
75
+ # First message
76
+ async for event in client.streaming_response_stateful(
77
+ message={
78
+ "role": "user",
79
+ "content_items": [{"type": "text", "text": "My name is Alice"}]
80
+ },
81
+ config={}
82
+ ):
83
+ print(event)
84
+
85
+ # Second message - history is maintained automatically
86
+ async for event in client.streaming_response_stateful(
87
+ message={
88
+ "role": "user",
89
+ "content_items": [{"type": "text", "text": "What's my name?"}]
90
+ },
91
+ config={}
92
+ ):
93
+ print(event)
94
+
95
+ asyncio.run(main())
96
+ ```
97
+
98
+ ### get_history
99
+
100
+ Retrieve the conversation history:
101
+
102
+ ```python
103
+ # Get all messages in the conversation
104
+ history = client.get_history()
105
+ print(f"Total messages: {len(history)}")
106
+
107
+ for msg in history:
108
+ print(f"Role: {msg['role']}")
109
+ print(f"Content: {msg['content_items']}")
110
+ ```
111
+
112
+ ### clear_history
113
+
114
+ Clear the conversation history:
115
+
116
+ ```python
117
+ # Clear all conversation history
118
+ client.clear_history()
119
+
120
+ # Verify history is empty
121
+ assert len(client.get_history()) == 0
122
+ ```
123
+
124
+ ### set_history
125
+
126
+ Replace the conversation history with a copy of the provided list:
127
+
128
+ ```python
129
+ # Save current history
130
+ saved_history = client.get_history()
131
+
132
+ # ... do other things, then restore
133
+ client.set_history(saved_history)
134
+
135
+ # Verify history was replaced
136
+ assert len(client.get_history()) == len(saved_history)
137
+ ```
138
+
139
+ ## Tool Calling
140
+
141
+ When using tools, you must handle `tool_call_id` correctly:
142
+
143
+ ```python
144
+ import asyncio
145
+ import json
146
+ from agenthub import AutoLLMClient
147
+
148
+ def get_weather(location: str) -> str:
149
+ """Mock function to get weather."""
150
+ return f"Temperature in {location}: 22°C"
151
+
152
+ async def main():
153
+ # Define tool
154
+ weather_function = {
155
+ "name": "get_weather",
156
+ "description": "Gets the current weather for a given location.",
157
+ "parameters": {
158
+ "type": "object",
159
+ "properties": {
160
+ "location": {
161
+ "type": "string",
162
+ "description": "The city name"
163
+ }
164
+ },
165
+ "required": ["location"]
166
+ }
167
+ }
168
+
169
+ client = AutoLLMClient(model="gpt-5.5")
170
+ config = {"tools": [weather_function]}
171
+
172
+ # User asks about weather
173
+ events = []
174
+ async for event in client.streaming_response_stateful(
175
+ message={
176
+ "role": "user",
177
+ "content_items": [{"type": "text", "text": "What's the weather in London?"}]
178
+ },
179
+ config=config
180
+ ):
181
+ events.append(event)
182
+
183
+ # Extract function call and tool_call_id
184
+ tool_call = None
185
+ for event in events:
186
+ for item in event["content_items"]:
187
+ if item["type"] == "tool_call":
188
+ tool_call = item
189
+ break
190
+
191
+ if tool_call:
192
+ break
193
+
194
+ # Execute function and send result back with tool_call_id
195
+ if tool_call:
196
+ result = get_weather(**tool_call["arguments"])
197
+
198
+ # IMPORTANT: Include tool_call_id in the tool response
199
+ async for event in client.streaming_response_stateful(
200
+ message={
201
+ "role": "user",
202
+ "content_items": [
203
+ {
204
+ "type": "tool_result",
205
+ "text": result,
206
+ "tool_call_id": tool_call["tool_call_id"] # Required for tool responses
207
+ }
208
+ ]
209
+ },
210
+ config=config
211
+ ):
212
+ print(event)
213
+
214
+ asyncio.run(main())
215
+ ```
216
+
217
+ ## Message Format
218
+
219
+ ### UniMessage Structure
220
+
221
+ ```python
222
+ {
223
+ "role": "user" | "assistant",
224
+ "content_items": [
225
+ {"type": "text", "text": "Hello"},
226
+ {"type": "image_url", "image_url": "https://..."},
227
+ {"type": "tool_call", "name": "get_weather", "arguments": {"location": "London"}, "tool_call_id": "call_abc123"}
228
+ ]
229
+ }
230
+ ```
231
+
232
+ ### Tool Response with tool_call_id
233
+
234
+ When responding to a tool call, include the `tool_call_id` in the result content item:
235
+
236
+ ```python
237
+ {
238
+ "role": "user",
239
+ "content_items": [
240
+ {
241
+ "type": "tool_result",
242
+ "text": "London is 22°C today.",
243
+ "tool_call_id": "call_abc123" # From tool_call event
244
+ }
245
+ ]
246
+ }
247
+ ```
248
+
249
+ ## Configuration Options
250
+
251
+ ```python
252
+ from agenthub import PromptCaching, ThinkingLevel
253
+
254
+ config = {
255
+ "max_tokens": 500,
256
+ "temperature": 1.0,
257
+ "tools": [tool_definition],
258
+ "thinking_summary": True,
259
+ "thinking_level": ThinkingLevel.HIGH,
260
+ "tool_choice": "auto", # "auto", "required", "none", or ["tool_name"]
261
+ "system_prompt": "You are a helpful assistant",
262
+ "prompt_caching": PromptCaching.ENABLE,
263
+ "trace_id": "agent1/conversation_001" # Optional: save conversation trace
264
+ }
265
+ ```
266
+
267
+ ## Conversation Tracing
268
+
269
+ AgentHub provides a built-in `Tracer` to save and browse conversation history. When you specify a `trace_id` in the config, conversations are automatically saved to both JSON and TXT formats.
270
+
271
+ ### Basic Usage
272
+
273
+ ```python
274
+ from agenthub import AutoLLMClient
275
+
276
+ client = AutoLLMClient(model="gpt-5.5")
277
+
278
+ # Add trace_id to config
279
+ config = {"trace_id": "agent1/conversation_001"}
280
+
281
+ async for event in client.streaming_response_stateful(
282
+ message={"role": "user", "content_items": [{"type": "text", "text": "Hello"}]},
283
+ config=config
284
+ ):
285
+ pass # Conversation is automatically saved
286
+ ```
287
+
288
+ The default cache directory is `cache`, you can change it by setting `AGENTHUB_CACHE_DIR` environment variable.
289
+
290
+ This creates two files in the `cache` directory:
291
+ - `cache/agent1/conversation_001.json` - Structured data with full history and config
292
+ - `cache/agent1/conversation_001.txt` - Human-readable conversation format
293
+
294
+ ### Browsing Traces with Web Interface
295
+
296
+ Start a web server to browse and view saved conversations:
297
+
298
+ ```python
299
+ from agenthub.integration.tracer import Tracer
300
+
301
+ # Start web server
302
+ Tracer("path/to/cache").start_web_server(host="127.0.0.1", port=25750)
303
+ ```
304
+
305
+ Or use the CLI:
306
+
307
+ ```bash
308
+ python -m agenthub.integration.tracer --cache_dir ./cache --host 127.0.0.1 --port 25750
309
+ ```
310
+
311
+ Then visit `http://127.0.0.1:25750` in your browser to browse saved conversations.
312
+
313
+ ### Test with Playground
314
+
315
+ Start a web server to test with the playground:
316
+
317
+ ```python
318
+ from agenthub.integration.playground import start_playground_server
319
+
320
+ start_playground_server()
321
+ ```
322
+
323
+ Or use the CLI:
324
+
325
+ ```bash
326
+ python -m agenthub.integration.playground --host 127.0.0.1 --port 25751
327
+ ```
328
+
329
+ Then visit `http://127.0.0.1:25751` in your browser to test with the playground.
330
+ The integrated tracer is available at `http://127.0.0.1:25751/tracer/`.