wire-ai 0.1.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.
- wire_ai-0.1.0/.gitignore +12 -0
- wire_ai-0.1.0/PKG-INFO +251 -0
- wire_ai-0.1.0/README.md +172 -0
- wire_ai-0.1.0/examples/sprint1_langgraph.py +99 -0
- wire_ai-0.1.0/pyproject.toml +94 -0
- wire_ai-0.1.0/src/wire/__init__.py +28 -0
- wire_ai-0.1.0/src/wire/adapters/__init__.py +1 -0
- wire_ai-0.1.0/src/wire/adapters/langgraph.py +234 -0
- wire_ai-0.1.0/src/wire/cli.py +117 -0
- wire_ai-0.1.0/src/wire/core/__init__.py +1 -0
- wire_ai-0.1.0/src/wire/core/audit.py +152 -0
- wire_ai-0.1.0/src/wire/core/budget.py +110 -0
- wire_ai-0.1.0/src/wire/core/errors.py +57 -0
- wire_ai-0.1.0/src/wire/core/events.py +80 -0
- wire_ai-0.1.0/src/wire/core/guard.py +112 -0
- wire_ai-0.1.0/src/wire/core/models.py +62 -0
- wire_ai-0.1.0/src/wire/deploy.py +99 -0
- wire_ai-0.1.0/tests/__init__.py +0 -0
- wire_ai-0.1.0/tests/conftest.py +10 -0
- wire_ai-0.1.0/tests/test_audit_chain.py +145 -0
- wire_ai-0.1.0/tests/test_budget.py +79 -0
- wire_ai-0.1.0/tests/test_loop_guard.py +97 -0
wire_ai-0.1.0/.gitignore
ADDED
wire_ai-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wire-ai
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Workforce Intelligence & Reasoning Engine — framework-agnostic governance layer for autonomous enterprise AI agents
|
|
5
|
+
Project-URL: Homepage, https://github.com/naveenkumarbaskaran/wire-ai
|
|
6
|
+
Project-URL: Repository, https://github.com/naveenkumarbaskaran/wire-ai
|
|
7
|
+
Project-URL: Issues, https://github.com/naveenkumarbaskaran/wire-ai/issues
|
|
8
|
+
Author-email: Naveen Kumar Baskaran <naveen.kumar.baskaran@sap.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: a2a,agents,ai,autogen,crewai,enterprise,governance,langgraph,llm,mcp
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Requires-Dist: aiosqlite>=0.20
|
|
20
|
+
Requires-Dist: anthropic>=0.30
|
|
21
|
+
Requires-Dist: anyio>=4.4
|
|
22
|
+
Requires-Dist: httpx>=0.27
|
|
23
|
+
Requires-Dist: opentelemetry-api>=1.25
|
|
24
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.25
|
|
25
|
+
Requires-Dist: opentelemetry-sdk>=1.25
|
|
26
|
+
Requires-Dist: orjson>=3.10
|
|
27
|
+
Requires-Dist: prometheus-client>=0.20
|
|
28
|
+
Requires-Dist: pydantic>=2.7
|
|
29
|
+
Requires-Dist: rich>=13.7
|
|
30
|
+
Requires-Dist: sqlmodel>=0.0.19
|
|
31
|
+
Requires-Dist: structlog>=24.2
|
|
32
|
+
Requires-Dist: tenacity>=8.3
|
|
33
|
+
Requires-Dist: tiktoken>=0.7
|
|
34
|
+
Requires-Dist: typer>=0.12
|
|
35
|
+
Requires-Dist: xxhash>=3.4
|
|
36
|
+
Provides-Extra: all
|
|
37
|
+
Requires-Dist: asyncpg>=0.29; extra == 'all'
|
|
38
|
+
Requires-Dist: crewai>=0.80; extra == 'all'
|
|
39
|
+
Requires-Dist: hiredis>=2.3; extra == 'all'
|
|
40
|
+
Requires-Dist: langchain-core>=0.2; extra == 'all'
|
|
41
|
+
Requires-Dist: langgraph>=0.2; extra == 'all'
|
|
42
|
+
Requires-Dist: openai-agents>=0.1; extra == 'all'
|
|
43
|
+
Requires-Dist: openai>=1.35; extra == 'all'
|
|
44
|
+
Requires-Dist: psycopg[binary]>=3.1; extra == 'all'
|
|
45
|
+
Requires-Dist: pyautogen>=0.4; extra == 'all'
|
|
46
|
+
Requires-Dist: redis>=5.0; extra == 'all'
|
|
47
|
+
Requires-Dist: slack-sdk>=3.30; extra == 'all'
|
|
48
|
+
Requires-Dist: textual>=0.75; extra == 'all'
|
|
49
|
+
Provides-Extra: autogen
|
|
50
|
+
Requires-Dist: pyautogen>=0.4; extra == 'autogen'
|
|
51
|
+
Provides-Extra: crewai
|
|
52
|
+
Requires-Dist: crewai>=0.80; extra == 'crewai'
|
|
53
|
+
Provides-Extra: dashboard
|
|
54
|
+
Requires-Dist: textual>=0.75; extra == 'dashboard'
|
|
55
|
+
Provides-Extra: dev
|
|
56
|
+
Requires-Dist: hypothesis>=6.100; extra == 'dev'
|
|
57
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
58
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
|
|
59
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
60
|
+
Requires-Dist: pytest>=8.2; extra == 'dev'
|
|
61
|
+
Requires-Dist: respx>=0.21; extra == 'dev'
|
|
62
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
63
|
+
Requires-Dist: time-machine>=2.14; extra == 'dev'
|
|
64
|
+
Provides-Extra: langgraph
|
|
65
|
+
Requires-Dist: langchain-core>=0.2; extra == 'langgraph'
|
|
66
|
+
Requires-Dist: langgraph>=0.2; extra == 'langgraph'
|
|
67
|
+
Provides-Extra: openai
|
|
68
|
+
Requires-Dist: openai-agents>=0.1; extra == 'openai'
|
|
69
|
+
Requires-Dist: openai>=1.35; extra == 'openai'
|
|
70
|
+
Provides-Extra: postgres
|
|
71
|
+
Requires-Dist: asyncpg>=0.29; extra == 'postgres'
|
|
72
|
+
Requires-Dist: psycopg[binary]>=3.1; extra == 'postgres'
|
|
73
|
+
Provides-Extra: redis
|
|
74
|
+
Requires-Dist: hiredis>=2.3; extra == 'redis'
|
|
75
|
+
Requires-Dist: redis>=5.0; extra == 'redis'
|
|
76
|
+
Provides-Extra: slack
|
|
77
|
+
Requires-Dist: slack-sdk>=3.30; extra == 'slack'
|
|
78
|
+
Description-Content-Type: text/markdown
|
|
79
|
+
|
|
80
|
+
# WIRE — Workforce Intelligence & Reasoning Engine
|
|
81
|
+
|
|
82
|
+
**Framework-agnostic governance layer for autonomous enterprise AI agents.**
|
|
83
|
+
|
|
84
|
+
> *"Describe the work. WIRE hires the workforce."*
|
|
85
|
+
|
|
86
|
+
[](https://pypi.org/project/wire-ai)
|
|
87
|
+
[](https://www.python.org)
|
|
88
|
+
[](LICENSE)
|
|
89
|
+
[](https://github.com/naveenkumarbaskaran/wire-ai/actions)
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## The Problem
|
|
94
|
+
|
|
95
|
+
Every major agent framework ships without the five things enterprises actually need:
|
|
96
|
+
|
|
97
|
+
| Gap | LangGraph | CrewAI | AutoGen |
|
|
98
|
+
|-----|-----------|--------|---------|
|
|
99
|
+
| Loop protection | ❌ | ❌ | ❌ |
|
|
100
|
+
| Tamper-proof audit | ❌ | ❌ | ❌ |
|
|
101
|
+
| Hard cost ceilings | ❌ | ❌ | ❌ |
|
|
102
|
+
| HITL as first-class primitive | Partial | ❌ | Unstable |
|
|
103
|
+
| Live workforce visibility | ❌ | ❌ | ❌ |
|
|
104
|
+
|
|
105
|
+
WIRE adds all of them — without replacing your existing framework.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Install
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
pip install wire-ai # core
|
|
113
|
+
pip install wire-ai[langgraph] # + LangGraph adapter
|
|
114
|
+
pip install wire-ai[crewai] # + CrewAI adapter (Sprint 5)
|
|
115
|
+
pip install wire-ai[autogen] # + AutoGen adapter (Sprint 5)
|
|
116
|
+
pip install wire-ai[all] # everything
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Sprint 1 — 5 lines, full governance
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
import wire
|
|
125
|
+
|
|
126
|
+
# Your existing LangGraph graph — unchanged
|
|
127
|
+
from langgraph.graph import StateGraph
|
|
128
|
+
graph = StateGraph(...).compile()
|
|
129
|
+
|
|
130
|
+
# Wrap with WIRE
|
|
131
|
+
workforce = wire.deploy(
|
|
132
|
+
graph,
|
|
133
|
+
backend="langgraph",
|
|
134
|
+
max_iterations=30, # LoopGuard: halt before runaway
|
|
135
|
+
max_cost_usd=0.50, # Budget: hard $0.50 ceiling
|
|
136
|
+
hourly_budget_usd=0.10, # Budget: $0.10/hour rolling
|
|
137
|
+
audit_path="audit.jsonl" # AuditChain: tamper-proof log
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
# Run — same API as graph.ainvoke()
|
|
141
|
+
result = await workforce.ainvoke({"messages": [...]})
|
|
142
|
+
|
|
143
|
+
# Verify audit integrity
|
|
144
|
+
wire.AuditChain.verify("audit.jsonl")
|
|
145
|
+
# ✓ 12 entries · chain intact
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## What You Get
|
|
151
|
+
|
|
152
|
+
### LoopGuard
|
|
153
|
+
Halts runaway agent loops before they exhaust your API quota. Configurable iteration and cost limits. Raises `LoopBreachError` with full context.
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
# Fires when iterations > 30 OR cost > $0.50
|
|
157
|
+
workforce = wire.deploy(graph, max_iterations=30, max_cost_usd=0.50)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### AuditChain
|
|
161
|
+
Every agent action, node execution, and tool call is recorded in a tamper-proof SHA-256 hash-linked log. Verify integrity at any time.
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
wire.AuditChain.verify("audit.jsonl")
|
|
165
|
+
# Raises AuditChainError with entry index if tampered
|
|
166
|
+
|
|
167
|
+
# Replay any past run
|
|
168
|
+
wire replay --run-id run_20260612_abc123
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Budget
|
|
172
|
+
Hard cost ceilings with rolling hourly and daily windows. Never get a surprise bill.
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
budget = wire.Budget(hourly=0.50, daily=5.00)
|
|
176
|
+
# BudgetBreachError fires before the ceiling is exceeded
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### EventBus
|
|
180
|
+
Typed events for every runtime moment. Subscribe handlers for alerting, logging, or custom business logic.
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
@workforce.on(wire.EventKind.LOOP_BREACH)
|
|
184
|
+
async def alert(event):
|
|
185
|
+
await slack.send(f"Loop breach in {event.run_id}!")
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## CLI
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
wire version # v0.1.0
|
|
194
|
+
wire status # installed adapters
|
|
195
|
+
wire audit audit.jsonl # verify chain integrity
|
|
196
|
+
wire replay --run-id abc123 # replay a past run
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Sprint Roadmap
|
|
202
|
+
|
|
203
|
+
| Sprint | Ships | Status |
|
|
204
|
+
|--------|-------|--------|
|
|
205
|
+
| **S1 — MVP** | `deploy()` + `LoopGuard` + `AuditChain` + `Budget` | ✅ **v0.1.0** |
|
|
206
|
+
| **S2 — Governance** | `HITLGate` + `IdempotencyGuard` + `SLATracker` | 🔜 v0.2.0 |
|
|
207
|
+
| **S3 — HIRE** | `wire.hire("...")` + 20 role templates | 🔜 v0.3.0 |
|
|
208
|
+
| **S4 — Visibility** | Live dashboard + Slack HITL + time-travel replay | 🔜 v0.4.0 |
|
|
209
|
+
| **S5 — Multi-Framework** | CrewAI + AutoGen + OpenAI adapters | 🔜 v0.5.0 |
|
|
210
|
+
| **S6 — Enterprise** | SOC-2 presets + SSO + RBAC + web dashboard | 🔜 v1.0.0 |
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Architecture
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
┌──────────────────────────────────────────────────────┐
|
|
218
|
+
│ HIRE LAYER intent → role matching → workforce │
|
|
219
|
+
├──────────────────────────────────────────────────────┤
|
|
220
|
+
│ RUNTIME LAYER LoopGuard · HITLGate · SLATracker │
|
|
221
|
+
│ IdempotencyGuard · Budget · State │
|
|
222
|
+
├──────────────────────────────────────────────────────┤
|
|
223
|
+
│ VISIBILITY Dashboard · AuditChain · CostLedger │
|
|
224
|
+
│ TimeTravel · DriftDetector │
|
|
225
|
+
├──────────────────────────────────────────────────────┤
|
|
226
|
+
│ ADAPTERS LangGraph · CrewAI · AutoGen · OpenAI│
|
|
227
|
+
└──────────────────────────────────────────────────────┘
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Why WIRE?
|
|
233
|
+
|
|
234
|
+
Built from 95 adversarially-verified research claims across 24 sources:
|
|
235
|
+
|
|
236
|
+
- **LangGraph** self-describes as "very low-level" — no governance primitives
|
|
237
|
+
- **AutoGen** Studio is "not meant for production" — their own README
|
|
238
|
+
- **CrewAI** has no idempotency guard — payments and emails can fire twice on retry
|
|
239
|
+
- **No framework** ships a tamper-proof audit chain, built-in workforce visibility, or HITL routing
|
|
240
|
+
|
|
241
|
+
WIRE fills every gap. Framework-agnostic. Enterprise-ready from day 1.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Contributing
|
|
246
|
+
|
|
247
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). MIT licensed.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
*Built by [Naveen Kumar Baskaran](https://github.com/naveenkumarbaskaran)*
|
wire_ai-0.1.0/README.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# WIRE — Workforce Intelligence & Reasoning Engine
|
|
2
|
+
|
|
3
|
+
**Framework-agnostic governance layer for autonomous enterprise AI agents.**
|
|
4
|
+
|
|
5
|
+
> *"Describe the work. WIRE hires the workforce."*
|
|
6
|
+
|
|
7
|
+
[](https://pypi.org/project/wire-ai)
|
|
8
|
+
[](https://www.python.org)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](https://github.com/naveenkumarbaskaran/wire-ai/actions)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## The Problem
|
|
15
|
+
|
|
16
|
+
Every major agent framework ships without the five things enterprises actually need:
|
|
17
|
+
|
|
18
|
+
| Gap | LangGraph | CrewAI | AutoGen |
|
|
19
|
+
|-----|-----------|--------|---------|
|
|
20
|
+
| Loop protection | ❌ | ❌ | ❌ |
|
|
21
|
+
| Tamper-proof audit | ❌ | ❌ | ❌ |
|
|
22
|
+
| Hard cost ceilings | ❌ | ❌ | ❌ |
|
|
23
|
+
| HITL as first-class primitive | Partial | ❌ | Unstable |
|
|
24
|
+
| Live workforce visibility | ❌ | ❌ | ❌ |
|
|
25
|
+
|
|
26
|
+
WIRE adds all of them — without replacing your existing framework.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install wire-ai # core
|
|
34
|
+
pip install wire-ai[langgraph] # + LangGraph adapter
|
|
35
|
+
pip install wire-ai[crewai] # + CrewAI adapter (Sprint 5)
|
|
36
|
+
pip install wire-ai[autogen] # + AutoGen adapter (Sprint 5)
|
|
37
|
+
pip install wire-ai[all] # everything
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Sprint 1 — 5 lines, full governance
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
import wire
|
|
46
|
+
|
|
47
|
+
# Your existing LangGraph graph — unchanged
|
|
48
|
+
from langgraph.graph import StateGraph
|
|
49
|
+
graph = StateGraph(...).compile()
|
|
50
|
+
|
|
51
|
+
# Wrap with WIRE
|
|
52
|
+
workforce = wire.deploy(
|
|
53
|
+
graph,
|
|
54
|
+
backend="langgraph",
|
|
55
|
+
max_iterations=30, # LoopGuard: halt before runaway
|
|
56
|
+
max_cost_usd=0.50, # Budget: hard $0.50 ceiling
|
|
57
|
+
hourly_budget_usd=0.10, # Budget: $0.10/hour rolling
|
|
58
|
+
audit_path="audit.jsonl" # AuditChain: tamper-proof log
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# Run — same API as graph.ainvoke()
|
|
62
|
+
result = await workforce.ainvoke({"messages": [...]})
|
|
63
|
+
|
|
64
|
+
# Verify audit integrity
|
|
65
|
+
wire.AuditChain.verify("audit.jsonl")
|
|
66
|
+
# ✓ 12 entries · chain intact
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## What You Get
|
|
72
|
+
|
|
73
|
+
### LoopGuard
|
|
74
|
+
Halts runaway agent loops before they exhaust your API quota. Configurable iteration and cost limits. Raises `LoopBreachError` with full context.
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
# Fires when iterations > 30 OR cost > $0.50
|
|
78
|
+
workforce = wire.deploy(graph, max_iterations=30, max_cost_usd=0.50)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### AuditChain
|
|
82
|
+
Every agent action, node execution, and tool call is recorded in a tamper-proof SHA-256 hash-linked log. Verify integrity at any time.
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
wire.AuditChain.verify("audit.jsonl")
|
|
86
|
+
# Raises AuditChainError with entry index if tampered
|
|
87
|
+
|
|
88
|
+
# Replay any past run
|
|
89
|
+
wire replay --run-id run_20260612_abc123
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Budget
|
|
93
|
+
Hard cost ceilings with rolling hourly and daily windows. Never get a surprise bill.
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
budget = wire.Budget(hourly=0.50, daily=5.00)
|
|
97
|
+
# BudgetBreachError fires before the ceiling is exceeded
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### EventBus
|
|
101
|
+
Typed events for every runtime moment. Subscribe handlers for alerting, logging, or custom business logic.
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
@workforce.on(wire.EventKind.LOOP_BREACH)
|
|
105
|
+
async def alert(event):
|
|
106
|
+
await slack.send(f"Loop breach in {event.run_id}!")
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## CLI
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
wire version # v0.1.0
|
|
115
|
+
wire status # installed adapters
|
|
116
|
+
wire audit audit.jsonl # verify chain integrity
|
|
117
|
+
wire replay --run-id abc123 # replay a past run
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Sprint Roadmap
|
|
123
|
+
|
|
124
|
+
| Sprint | Ships | Status |
|
|
125
|
+
|--------|-------|--------|
|
|
126
|
+
| **S1 — MVP** | `deploy()` + `LoopGuard` + `AuditChain` + `Budget` | ✅ **v0.1.0** |
|
|
127
|
+
| **S2 — Governance** | `HITLGate` + `IdempotencyGuard` + `SLATracker` | 🔜 v0.2.0 |
|
|
128
|
+
| **S3 — HIRE** | `wire.hire("...")` + 20 role templates | 🔜 v0.3.0 |
|
|
129
|
+
| **S4 — Visibility** | Live dashboard + Slack HITL + time-travel replay | 🔜 v0.4.0 |
|
|
130
|
+
| **S5 — Multi-Framework** | CrewAI + AutoGen + OpenAI adapters | 🔜 v0.5.0 |
|
|
131
|
+
| **S6 — Enterprise** | SOC-2 presets + SSO + RBAC + web dashboard | 🔜 v1.0.0 |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Architecture
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
┌──────────────────────────────────────────────────────┐
|
|
139
|
+
│ HIRE LAYER intent → role matching → workforce │
|
|
140
|
+
├──────────────────────────────────────────────────────┤
|
|
141
|
+
│ RUNTIME LAYER LoopGuard · HITLGate · SLATracker │
|
|
142
|
+
│ IdempotencyGuard · Budget · State │
|
|
143
|
+
├──────────────────────────────────────────────────────┤
|
|
144
|
+
│ VISIBILITY Dashboard · AuditChain · CostLedger │
|
|
145
|
+
│ TimeTravel · DriftDetector │
|
|
146
|
+
├──────────────────────────────────────────────────────┤
|
|
147
|
+
│ ADAPTERS LangGraph · CrewAI · AutoGen · OpenAI│
|
|
148
|
+
└──────────────────────────────────────────────────────┘
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Why WIRE?
|
|
154
|
+
|
|
155
|
+
Built from 95 adversarially-verified research claims across 24 sources:
|
|
156
|
+
|
|
157
|
+
- **LangGraph** self-describes as "very low-level" — no governance primitives
|
|
158
|
+
- **AutoGen** Studio is "not meant for production" — their own README
|
|
159
|
+
- **CrewAI** has no idempotency guard — payments and emails can fire twice on retry
|
|
160
|
+
- **No framework** ships a tamper-proof audit chain, built-in workforce visibility, or HITL routing
|
|
161
|
+
|
|
162
|
+
WIRE fills every gap. Framework-agnostic. Enterprise-ready from day 1.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Contributing
|
|
167
|
+
|
|
168
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). MIT licensed.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
*Built by [Naveen Kumar Baskaran](https://github.com/naveenkumarbaskaran)*
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sprint 1 example — wrap an existing LangGraph graph with WIRE governance.
|
|
3
|
+
|
|
4
|
+
What this adds in 5 lines:
|
|
5
|
+
- LoopGuard: halts at 30 iterations (no more runaway loops)
|
|
6
|
+
- Budget: hard $0.50 ceiling per run, $0.10/hour
|
|
7
|
+
- AuditChain: tamper-proof JSONL log of every node execution
|
|
8
|
+
- EventBus: typed events for downstream handlers (alerting, logging)
|
|
9
|
+
|
|
10
|
+
Run:
|
|
11
|
+
pip install wire-ai[langgraph] langchain-anthropic
|
|
12
|
+
python examples/sprint1_langgraph.py
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import asyncio
|
|
18
|
+
|
|
19
|
+
import wire
|
|
20
|
+
from wire.core.events import EventKind
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# ── 1. Build any LangGraph graph as you normally would ──────────────────────
|
|
24
|
+
|
|
25
|
+
def build_example_graph():
|
|
26
|
+
"""Minimal LangGraph graph for demonstration."""
|
|
27
|
+
try:
|
|
28
|
+
from langchain_anthropic import ChatAnthropic
|
|
29
|
+
from langchain_core.messages import HumanMessage
|
|
30
|
+
from langgraph.graph import END, START, StateGraph, MessagesState
|
|
31
|
+
|
|
32
|
+
model = ChatAnthropic(model="claude-haiku-4-5-20251001")
|
|
33
|
+
|
|
34
|
+
def call_model(state: MessagesState):
|
|
35
|
+
return {"messages": [model.invoke(state["messages"])]}
|
|
36
|
+
|
|
37
|
+
graph = StateGraph(MessagesState)
|
|
38
|
+
graph.add_node("agent", call_model)
|
|
39
|
+
graph.add_edge(START, "agent")
|
|
40
|
+
graph.add_edge("agent", END)
|
|
41
|
+
return graph.compile()
|
|
42
|
+
|
|
43
|
+
except ImportError:
|
|
44
|
+
print("Install langchain-anthropic to run the full example.")
|
|
45
|
+
print("Showing WIRE setup only.\n")
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
async def main() -> None:
|
|
50
|
+
graph = build_example_graph()
|
|
51
|
+
|
|
52
|
+
# ── 2. Wrap with WIRE — this is the only change ─────────────────────────
|
|
53
|
+
workforce = wire.deploy(
|
|
54
|
+
graph,
|
|
55
|
+
backend="langgraph",
|
|
56
|
+
max_iterations=30, # LoopGuard: halt at 30 steps
|
|
57
|
+
max_cost_usd=0.50, # Budget: lifetime $0.50 ceiling
|
|
58
|
+
hourly_budget_usd=0.10, # Budget: $0.10/hour rolling window
|
|
59
|
+
audit_path="wire-audit.jsonl", # AuditChain: tamper-proof log
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# ── 3. Subscribe to WIRE events ──────────────────────────────────────────
|
|
63
|
+
@workforce.on(EventKind.LOOP_BREACH)
|
|
64
|
+
async def on_loop_breach(event):
|
|
65
|
+
print(f"\n🚨 Loop breach! {event.data['iterations']} iterations, "
|
|
66
|
+
f"${event.data['cost_usd']:.4f} spent")
|
|
67
|
+
|
|
68
|
+
@workforce.on(EventKind.BUDGET_BREACH)
|
|
69
|
+
async def on_budget_breach(event):
|
|
70
|
+
print(f"\n💸 Budget breach [{event.data['window']}]! "
|
|
71
|
+
f"${event.data['spent']:.4f} / ${event.data['limit']:.4f}")
|
|
72
|
+
|
|
73
|
+
@workforce.on(EventKind.STEP_END)
|
|
74
|
+
async def on_step(event):
|
|
75
|
+
print(f" ✓ {event.data['node']} (iter {event.data['iteration']}, "
|
|
76
|
+
f"${event.data.get('cost_usd', 0):.6f})")
|
|
77
|
+
|
|
78
|
+
# ── 4. Run ───────────────────────────────────────────────────────────────
|
|
79
|
+
print(workforce.describe())
|
|
80
|
+
print()
|
|
81
|
+
|
|
82
|
+
if graph is not None:
|
|
83
|
+
from langchain_core.messages import HumanMessage
|
|
84
|
+
result = await workforce.ainvoke(
|
|
85
|
+
{"messages": [HumanMessage(content="What is WIRE?")]}
|
|
86
|
+
)
|
|
87
|
+
print("\nResult:", result)
|
|
88
|
+
|
|
89
|
+
# ── 5. Verify the audit chain ────────────────────────────────────────────
|
|
90
|
+
from pathlib import Path
|
|
91
|
+
if Path("wire-audit.jsonl").exists():
|
|
92
|
+
count = wire.AuditChain.verify("wire-audit.jsonl")
|
|
93
|
+
print(f"\n✓ Audit chain intact — {count} entries")
|
|
94
|
+
print(" Run: wire audit wire-audit.jsonl")
|
|
95
|
+
print(" Run: wire replay --run-id <run_id>")
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
if __name__ == "__main__":
|
|
99
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "wire-ai"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Workforce Intelligence & Reasoning Engine — framework-agnostic governance layer for autonomous enterprise AI agents"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
authors = [{ name = "Naveen Kumar Baskaran", email = "naveen.kumar.baskaran@sap.com" }]
|
|
13
|
+
keywords = ["ai", "agents", "llm", "governance", "enterprise", "langgraph", "crewai", "autogen", "a2a", "mcp"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Topic :: Software Development :: Libraries",
|
|
21
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
# Core
|
|
25
|
+
"pydantic>=2.7", # typed models, validation, serialisation
|
|
26
|
+
"anyio>=4.4", # async primitives (trio + asyncio)
|
|
27
|
+
"structlog>=24.2", # structured JSON logging
|
|
28
|
+
"rich>=13.7", # terminal UI, dashboard, progress
|
|
29
|
+
"typer>=0.12", # CLI (wire status, wire replay, wire audit)
|
|
30
|
+
"httpx>=0.27", # async HTTP (HITL webhooks, Slack, email)
|
|
31
|
+
# Audit + state
|
|
32
|
+
"sqlmodel>=0.0.19", # SQLite/Postgres durable state (SQLAlchemy + Pydantic)
|
|
33
|
+
"aiosqlite>=0.20", # async SQLite backend
|
|
34
|
+
"orjson>=3.10", # fast JSON for audit chain serialisation
|
|
35
|
+
"xxhash>=3.4", # fast hashing for idempotency keys
|
|
36
|
+
# Observability
|
|
37
|
+
"opentelemetry-api>=1.25", # OTel traces + spans
|
|
38
|
+
"opentelemetry-sdk>=1.25", # OTel SDK
|
|
39
|
+
"opentelemetry-exporter-otlp-proto-grpc>=1.25", # OTLP export
|
|
40
|
+
"prometheus-client>=0.20", # metrics endpoint (/metrics)
|
|
41
|
+
# AI / LLM
|
|
42
|
+
"anthropic>=0.30", # Claude (HIRE engine LLM fallback)
|
|
43
|
+
"tiktoken>=0.7", # token counting across models
|
|
44
|
+
"tenacity>=8.3", # retry with exponential backoff
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[project.optional-dependencies]
|
|
48
|
+
langgraph = ["langgraph>=0.2", "langchain-core>=0.2"]
|
|
49
|
+
crewai = ["crewai>=0.80"]
|
|
50
|
+
autogen = ["pyautogen>=0.4"]
|
|
51
|
+
openai = ["openai>=1.35", "openai-agents>=0.1"]
|
|
52
|
+
redis = ["redis>=5.0", "hiredis>=2.3"] # enterprise durable state backend
|
|
53
|
+
postgres = ["asyncpg>=0.29", "psycopg[binary]>=3.1"] # enterprise audit + state backend
|
|
54
|
+
slack = ["slack-sdk>=3.30"] # Slack HITL routing
|
|
55
|
+
dashboard = ["textual>=0.75"] # full TUI dashboard (beyond Rich)
|
|
56
|
+
all = [
|
|
57
|
+
"wire-ai[langgraph,crewai,autogen,openai,redis,postgres,slack,dashboard]"
|
|
58
|
+
]
|
|
59
|
+
dev = [
|
|
60
|
+
"pytest>=8.2",
|
|
61
|
+
"pytest-asyncio>=0.24",
|
|
62
|
+
"pytest-cov>=5.0",
|
|
63
|
+
"ruff>=0.5",
|
|
64
|
+
"mypy>=1.10",
|
|
65
|
+
"hypothesis>=6.100", # property-based testing for audit chain
|
|
66
|
+
"respx>=0.21", # mock httpx for HITL webhook tests
|
|
67
|
+
"time-machine>=2.14", # deterministic time in tests
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[project.scripts]
|
|
71
|
+
wire = "wire.cli:app"
|
|
72
|
+
|
|
73
|
+
[project.urls]
|
|
74
|
+
Homepage = "https://github.com/naveenkumarbaskaran/wire-ai"
|
|
75
|
+
Repository = "https://github.com/naveenkumarbaskaran/wire-ai"
|
|
76
|
+
Issues = "https://github.com/naveenkumarbaskaran/wire-ai/issues"
|
|
77
|
+
|
|
78
|
+
[tool.hatch.build.targets.wheel]
|
|
79
|
+
packages = ["src/wire"]
|
|
80
|
+
|
|
81
|
+
[tool.pytest.ini_options]
|
|
82
|
+
asyncio_mode = "auto"
|
|
83
|
+
testpaths = ["tests"]
|
|
84
|
+
|
|
85
|
+
[tool.ruff]
|
|
86
|
+
line-length = 100
|
|
87
|
+
src = ["src"]
|
|
88
|
+
select = ["E", "F", "I", "UP", "ANN", "ASYNC"]
|
|
89
|
+
ignore = ["ANN101"]
|
|
90
|
+
|
|
91
|
+
[tool.mypy]
|
|
92
|
+
python_version = "3.11"
|
|
93
|
+
strict = true
|
|
94
|
+
ignore_missing_imports = true
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
WIRE — Workforce Intelligence & Reasoning Engine
|
|
3
|
+
Framework-agnostic governance layer for autonomous enterprise AI agents.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from wire.core.audit import AuditChain, AuditEntry
|
|
7
|
+
from wire.core.budget import Budget, BudgetBreachError
|
|
8
|
+
from wire.core.errors import WIREError, LoopBreachError
|
|
9
|
+
from wire.core.events import WIREEvent, EventBus
|
|
10
|
+
from wire.core.guard import LoopGuard
|
|
11
|
+
from wire.core.models import Risk, DeployConfig
|
|
12
|
+
from wire.deploy import deploy
|
|
13
|
+
|
|
14
|
+
__version__ = "0.1.0"
|
|
15
|
+
__all__ = [
|
|
16
|
+
"deploy",
|
|
17
|
+
"AuditChain",
|
|
18
|
+
"AuditEntry",
|
|
19
|
+
"Budget",
|
|
20
|
+
"BudgetBreachError",
|
|
21
|
+
"LoopGuard",
|
|
22
|
+
"LoopBreachError",
|
|
23
|
+
"WIREError",
|
|
24
|
+
"WIREEvent",
|
|
25
|
+
"EventBus",
|
|
26
|
+
"Risk",
|
|
27
|
+
"DeployConfig",
|
|
28
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Adapters package — one module per backend framework."""
|