aragora-client 2.1.10__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.
@@ -0,0 +1,425 @@
1
+ Metadata-Version: 2.4
2
+ Name: aragora-client
3
+ Version: 2.1.10
4
+ Summary: Python SDK for Aragora multi-agent debate framework
5
+ Project-URL: Homepage, https://aragora.ai
6
+ Project-URL: Documentation, https://docs.aragora.ai/sdk/python
7
+ Project-URL: Repository, https://github.com/an0mium/aragora
8
+ Project-URL: Issues, https://github.com/an0mium/aragora/issues
9
+ Author-email: Aragora Team <team@aragora.ai>
10
+ License-Expression: MIT
11
+ Keywords: ai,anthropic,aragora,debate,llm,multi-agent,openai,sdk
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: httpx>=0.25.0
23
+ Requires-Dist: pydantic>=2.0.0
24
+ Requires-Dist: websockets>=12.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: mypy>=1.0; extra == 'dev'
27
+ Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
28
+ Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
29
+ Requires-Dist: pytest>=7.0; extra == 'dev'
30
+ Requires-Dist: ruff>=0.1; extra == 'dev'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # aragora-client
34
+
35
+ Python SDK for the Aragora multi-agent debate framework.
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ pip install aragora-client
41
+ ```
42
+
43
+ ## Quick Start
44
+
45
+ ```python
46
+ import asyncio
47
+ from aragora_client import AragoraClient
48
+
49
+ async def main():
50
+ client = AragoraClient("http://localhost:8080")
51
+
52
+ # Run a debate
53
+ debate = await client.debates.run(
54
+ task="Should we use microservices?",
55
+ agents=["anthropic-api", "openai-api"],
56
+ )
57
+
58
+ print(f"Consensus: {debate.consensus.conclusion}")
59
+
60
+ asyncio.run(main())
61
+ ```
62
+
63
+ ## API Reference
64
+
65
+ ### Client Initialization
66
+
67
+ ```python
68
+ from aragora_client import AragoraClient
69
+
70
+ client = AragoraClient(
71
+ base_url="http://localhost:8080",
72
+ api_key="your-api-key", # optional
73
+ timeout=30.0, # optional, default 30s
74
+ headers={"X-Custom": "value"} # optional
75
+ )
76
+
77
+ # Use as context manager for automatic cleanup
78
+ async with AragoraClient("http://localhost:8080") as client:
79
+ debate = await client.debates.run(task="...")
80
+ ```
81
+
82
+ ### Debates API
83
+
84
+ ```python
85
+ # Create a debate
86
+ response = await client.debates.create(
87
+ task="Design a rate limiter",
88
+ agents=["anthropic-api", "openai-api"],
89
+ max_rounds=5,
90
+ consensus_threshold=0.8,
91
+ )
92
+
93
+ # Get debate details
94
+ debate = await client.debates.get("debate-123")
95
+
96
+ # List debates
97
+ debates = await client.debates.list(limit=10, status="completed")
98
+
99
+ # Run debate and wait for completion
100
+ result = await client.debates.run(
101
+ task="Should we use TypeScript?",
102
+ timeout=300.0, # optional timeout
103
+ )
104
+ ```
105
+
106
+ ### Graph Debates API
107
+
108
+ Graph debates support automatic branching when agents identify different approaches.
109
+
110
+ ```python
111
+ # Create graph debate
112
+ response = await client.graph_debates.create(
113
+ task="Design a distributed system",
114
+ agents=["anthropic-api", "openai-api"],
115
+ max_rounds=5,
116
+ branch_threshold=0.5,
117
+ max_branches=10,
118
+ )
119
+
120
+ # Get debate with branches
121
+ debate = await client.graph_debates.get("debate-123")
122
+
123
+ # Get branches
124
+ branches = await client.graph_debates.get_branches("debate-123")
125
+ ```
126
+
127
+ ### Matrix Debates API
128
+
129
+ Matrix debates run the same question across different scenarios.
130
+
131
+ ```python
132
+ # Create matrix debate
133
+ response = await client.matrix_debates.create(
134
+ task="Should we adopt microservices?",
135
+ scenarios=[
136
+ {"name": "small_team", "parameters": {"team_size": 5}},
137
+ {"name": "large_team", "parameters": {"team_size": 50}},
138
+ {"name": "high_traffic", "parameters": {"rps": 100000}, "is_baseline": True},
139
+ ],
140
+ max_rounds=3,
141
+ )
142
+
143
+ # Get conclusions
144
+ conclusions = await client.matrix_debates.get_conclusions("matrix-123")
145
+ print(f"Universal: {conclusions.universal}")
146
+ print(f"Conditional: {conclusions.conditional}")
147
+ ```
148
+
149
+ ### Verification API
150
+
151
+ Formal verification of claims using Z3 or Lean 4.
152
+
153
+ ```python
154
+ # Verify a claim
155
+ result = await client.verification.verify(
156
+ claim="All primes > 2 are odd",
157
+ backend="z3", # "z3" | "lean"
158
+ timeout=30,
159
+ )
160
+
161
+ if result.status == "valid":
162
+ print("Claim is valid!")
163
+ print(f"Formal translation: {result.formal_translation}")
164
+
165
+ # Check backend status
166
+ status = await client.verification.status()
167
+ ```
168
+
169
+ ### Agents API
170
+
171
+ ```python
172
+ # List available agents
173
+ agents = await client.agents.list()
174
+
175
+ # Get agent profile
176
+ agent = await client.agents.get("anthropic-api")
177
+ print(f"ELO rating: {agent.elo_rating}")
178
+
179
+ # Get match history
180
+ history = await client.agents.history("anthropic-api", limit=20)
181
+
182
+ # Get rivals and allies
183
+ rivals = await client.agents.rivals("anthropic-api")
184
+ allies = await client.agents.allies("anthropic-api")
185
+ ```
186
+
187
+ ### Gauntlet API
188
+
189
+ Adversarial validation of specifications.
190
+
191
+ ```python
192
+ # Run gauntlet
193
+ response = await client.gauntlet.run(
194
+ input_content="Your spec content here...",
195
+ input_type="spec",
196
+ persona="security",
197
+ )
198
+
199
+ # Get receipt
200
+ receipt = await client.gauntlet.get_receipt(response["gauntlet_id"])
201
+ print(f"Score: {receipt.score}")
202
+ print(f"Findings: {receipt.findings}")
203
+
204
+ # Run and wait for completion
205
+ result = await client.gauntlet.run_and_wait(
206
+ input_content=spec_content,
207
+ persona="devil_advocate",
208
+ )
209
+ ```
210
+
211
+ ### Selection API
212
+
213
+ Agent selection plugins for team building.
214
+
215
+ ```python
216
+ # List available plugins
217
+ plugins = await client.selection.list_plugins()
218
+ print(f"Scorers: {[s.name for s in plugins.scorers]}")
219
+ print(f"Team Selectors: {[t.name for t in plugins.team_selectors]}")
220
+
221
+ # Score agents for a task
222
+ scores = await client.selection.score_agents(
223
+ task_description="Design a distributed cache system",
224
+ primary_domain="systems",
225
+ scorer="elo_weighted",
226
+ )
227
+
228
+ for agent in scores:
229
+ print(f"{agent.name}: {agent.score}")
230
+
231
+ # Select an optimal team
232
+ team = await client.selection.select_team(
233
+ task_description="Build a secure authentication system",
234
+ min_agents=3,
235
+ max_agents=5,
236
+ diversity_preference=0.7,
237
+ quality_priority=0.8,
238
+ )
239
+
240
+ print(f"Team: {[f'{a.name} ({a.role})' for a in team.agents]}")
241
+ print(f"Expected quality: {team.expected_quality}")
242
+ ```
243
+
244
+ ### Memory API
245
+
246
+ ```python
247
+ # Get analytics
248
+ analytics = await client.memory.analytics(days=30)
249
+ print(f"Total entries: {analytics.total_entries}")
250
+ print(f"Learning velocity: {analytics.learning_velocity}")
251
+
252
+ # Get tier-specific stats
253
+ fast_tier = await client.memory.tier_stats("fast")
254
+
255
+ # Take manual snapshot
256
+ snapshot = await client.memory.snapshot()
257
+ ```
258
+
259
+ ### Health Check
260
+
261
+ ```python
262
+ health = await client.health()
263
+ print(f"Status: {health.status}")
264
+ print(f"Version: {health.version}")
265
+ ```
266
+
267
+ ## WebSocket Streaming
268
+
269
+ Stream debate events in real-time.
270
+
271
+ ### Class-based API
272
+
273
+ ```python
274
+ from aragora_client import DebateStream
275
+
276
+ debate_id = "debate-123"
277
+ stream = DebateStream("ws://localhost:8765", debate_id)
278
+
279
+ stream.on("agent_message", lambda e: print(f"Agent: {e.data}"))
280
+ stream.on("consensus", lambda e: print("Consensus reached!"))
281
+ stream.on("debate_end", lambda e: stream.disconnect())
282
+ stream.on_error(lambda e: print(f"Error: {e}"))
283
+
284
+ await stream.connect()
285
+ ```
286
+
287
+ ### Async Iterator API
288
+
289
+ ```python
290
+ from aragora_client import stream_debate
291
+
292
+ async for event in stream_debate("ws://localhost:8765", "debate-123"):
293
+ print(event.type, event.data)
294
+
295
+ if event.type == "debate_end":
296
+ break
297
+ ```
298
+
299
+ ### WebSocket Options
300
+
301
+ ```python
302
+ stream = DebateStream(
303
+ "ws://localhost:8765",
304
+ "debate-123",
305
+ reconnect=True, # Auto-reconnect on disconnect
306
+ reconnect_interval=1.0, # Base reconnect delay (seconds)
307
+ max_reconnect_attempts=5, # Max reconnect attempts
308
+ heartbeat_interval=30.0, # Heartbeat ping interval (seconds)
309
+ )
310
+ ```
311
+
312
+ ## Error Handling
313
+
314
+ ```python
315
+ from aragora_client import (
316
+ AragoraError,
317
+ AragoraConnectionError,
318
+ AragoraAuthenticationError,
319
+ AragoraNotFoundError,
320
+ AragoraValidationError,
321
+ AragoraTimeoutError,
322
+ )
323
+
324
+ try:
325
+ await client.debates.get("nonexistent-123")
326
+ except AragoraNotFoundError as e:
327
+ print(f"Resource: {e.resource}")
328
+ print(f"ID: {e.resource_id}")
329
+ except AragoraError as e:
330
+ print(f"Code: {e.code}")
331
+ print(f"Status: {e.status}")
332
+ print(f"Message: {e.message}")
333
+ print(f"Details: {e.details}")
334
+ ```
335
+
336
+ ## Type Hints
337
+
338
+ All types are exported for use in your application:
339
+
340
+ ```python
341
+ from aragora_client import (
342
+ # Debate types
343
+ Debate,
344
+ DebateStatus,
345
+ ConsensusResult,
346
+ GraphDebate,
347
+ GraphBranch,
348
+ MatrixDebate,
349
+ MatrixConclusion,
350
+ # Verification types
351
+ VerificationResult,
352
+ VerificationStatus,
353
+ # Agent types
354
+ AgentProfile,
355
+ GauntletReceipt,
356
+ # Event types
357
+ DebateEvent,
358
+ # Selection types
359
+ SelectionPlugins,
360
+ TeamSelection,
361
+ AgentScore,
362
+ )
363
+ ```
364
+
365
+ ## Advanced Patterns
366
+
367
+ ### Retry with Exponential Backoff
368
+
369
+ ```python
370
+ from aragora_client import AragoraClient, AragoraError
371
+
372
+ async def with_retry(fn, max_retries=3, base_delay=1.0):
373
+ last_error = None
374
+
375
+ for attempt in range(max_retries):
376
+ try:
377
+ return await fn()
378
+ except AragoraError as e:
379
+ last_error = e
380
+ # Don't retry client errors (4xx)
381
+ if e.status and e.status < 500:
382
+ raise
383
+ if attempt < max_retries - 1:
384
+ delay = base_delay * (2 ** attempt)
385
+ await asyncio.sleep(delay)
386
+
387
+ raise last_error
388
+
389
+ # Usage
390
+ debate = await with_retry(
391
+ lambda: client.debates.run(task="Design a system")
392
+ )
393
+ ```
394
+
395
+ ### Concurrent Debates with Semaphore
396
+
397
+ ```python
398
+ import asyncio
399
+ from aragora_client import AragoraClient
400
+
401
+ async def run_debates_concurrent(tasks: list[str], max_concurrent: int = 3):
402
+ client = AragoraClient("http://localhost:8080")
403
+ semaphore = asyncio.Semaphore(max_concurrent)
404
+
405
+ async def run_with_semaphore(task: str):
406
+ async with semaphore:
407
+ return await client.debates.run(task=task)
408
+
409
+ return await asyncio.gather(*[run_with_semaphore(t) for t in tasks])
410
+
411
+ # Run multiple debates with controlled concurrency
412
+ tasks = ["Design auth system", "Choose database", "API architecture"]
413
+ debates = await run_debates_concurrent(tasks, max_concurrent=2)
414
+ ```
415
+
416
+ ## Requirements
417
+
418
+ - Python 3.10+
419
+ - httpx >= 0.25.0
420
+ - websockets >= 12.0
421
+ - pydantic >= 2.0.0
422
+
423
+ ## License
424
+
425
+ MIT
@@ -0,0 +1,9 @@
1
+ aragora_client/__init__.py,sha256=-cYE0IbQYSAqyLwsQ77mDHWniel-Zj0kGWHonjtY3s4,1688
2
+ aragora_client/client.py,sha256=IBlnoMjiHIc4ngIK7S4ujnbfxvS-Lkybj6G4JrLLEOo,17610
3
+ aragora_client/exceptions.py,sha256=1NBVuh-X6a4lpaxmssYlD7ctqY5ddsQsYULQ85vBFoA,2042
4
+ aragora_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ aragora_client/types.py,sha256=pidpy1iV8ETekSyeq7Q6nmXg7Gq0u_HGXH3X96O4BFM,7397
6
+ aragora_client/websocket.py,sha256=eHWjGkzqd9U7aw_IsEcrqh_BuS3f7fsuJSw-u9jG1i8,8897
7
+ aragora_client-2.1.10.dist-info/METADATA,sha256=w64inPM2H5swuMaT8opI2s4sQQZXQuGmY6D1jD4iosE,10347
8
+ aragora_client-2.1.10.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
9
+ aragora_client-2.1.10.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any