intermesh 0.3.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.
- intermesh-0.3.0/PKG-INFO +198 -0
- intermesh-0.3.0/README.md +169 -0
- intermesh-0.3.0/intermesh/__init__.py +56 -0
- intermesh-0.3.0/intermesh/adapters.py +90 -0
- intermesh-0.3.0/intermesh/admin.py +733 -0
- intermesh-0.3.0/intermesh/agent.py +520 -0
- intermesh-0.3.0/intermesh/apikeys.py +273 -0
- intermesh-0.3.0/intermesh/audit.py +153 -0
- intermesh-0.3.0/intermesh/bridge.py +181 -0
- intermesh-0.3.0/intermesh/cli.py +453 -0
- intermesh-0.3.0/intermesh/config.py +145 -0
- intermesh-0.3.0/intermesh/crypto.py +150 -0
- intermesh-0.3.0/intermesh/egress.py +180 -0
- intermesh-0.3.0/intermesh/escrow.py +208 -0
- intermesh-0.3.0/intermesh/guardrails.py +235 -0
- intermesh-0.3.0/intermesh/hardware.py +32 -0
- intermesh-0.3.0/intermesh/health.py +56 -0
- intermesh-0.3.0/intermesh/hub.py +996 -0
- intermesh-0.3.0/intermesh/identity.py +94 -0
- intermesh-0.3.0/intermesh/logger.py +90 -0
- intermesh-0.3.0/intermesh/message.py +152 -0
- intermesh-0.3.0/intermesh/metrics.py +49 -0
- intermesh-0.3.0/intermesh/peering.py +103 -0
- intermesh-0.3.0/intermesh/pipeline.py +218 -0
- intermesh-0.3.0/intermesh/policy.py +35 -0
- intermesh-0.3.0/intermesh/ratelimit.py +42 -0
- intermesh-0.3.0/intermesh/schema.py +125 -0
- intermesh-0.3.0/intermesh/secret.py +115 -0
- intermesh-0.3.0/intermesh/signing.py +64 -0
- intermesh-0.3.0/intermesh/snapshot.py +342 -0
- intermesh-0.3.0/intermesh/store.py +177 -0
- intermesh-0.3.0/intermesh/task.py +122 -0
- intermesh-0.3.0/intermesh.egg-info/PKG-INFO +198 -0
- intermesh-0.3.0/intermesh.egg-info/SOURCES.txt +38 -0
- intermesh-0.3.0/intermesh.egg-info/dependency_links.txt +1 -0
- intermesh-0.3.0/intermesh.egg-info/entry_points.txt +2 -0
- intermesh-0.3.0/intermesh.egg-info/requires.txt +3 -0
- intermesh-0.3.0/intermesh.egg-info/top_level.txt +1 -0
- intermesh-0.3.0/pyproject.toml +56 -0
- intermesh-0.3.0/setup.cfg +4 -0
intermesh-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: intermesh
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Universal coordination protocol for AI agents — E2E encrypted, cross-language, federated
|
|
5
|
+
Author: InterMesh Protocol Authors
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/intermeshteam/intermesh
|
|
8
|
+
Project-URL: Repository, https://github.com/intermeshteam/intermesh
|
|
9
|
+
Project-URL: Documentation, https://github.com/intermeshteam/intermesh/tree/main/docs
|
|
10
|
+
Project-URL: Issues, https://github.com/intermeshteam/intermesh/issues
|
|
11
|
+
Keywords: ai,agents,multi-agent-systems,protocol,coordination,e2e-encryption,distributed-systems,llm
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
|
+
Classifier: Topic :: System :: Distributed Computing
|
|
23
|
+
Classifier: Topic :: Security :: Cryptography
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
Requires-Dist: websockets>=12.0
|
|
27
|
+
Requires-Dist: PyJWT>=2.8.0
|
|
28
|
+
Requires-Dist: cryptography>=42.0.0
|
|
29
|
+
|
|
30
|
+
# InterMesh — Python SDK
|
|
31
|
+
|
|
32
|
+
The official Python SDK for **InterMesh Protocol**, the universal open-source coordination
|
|
33
|
+
protocol for AI agents.
|
|
34
|
+
|
|
35
|
+
InterMesh lets agents — regardless of language, framework, or vendor — discover each other,
|
|
36
|
+
communicate with end-to-end encryption, and collaborate on distributed tasks.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install intermesh
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
> The distribution is named `intermesh`; the import module is `intermesh`.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Quick start
|
|
47
|
+
|
|
48
|
+
**Start the coordination hub:**
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
intermesh hub
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Write a worker agent:**
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
import asyncio
|
|
58
|
+
from intermesh import InterMeshAgent
|
|
59
|
+
|
|
60
|
+
async def compute(input_data, task):
|
|
61
|
+
return {"result": input_data["a"] + input_data["b"]}
|
|
62
|
+
|
|
63
|
+
async def main():
|
|
64
|
+
agent = InterMeshAgent(
|
|
65
|
+
name="calc_bot",
|
|
66
|
+
capabilities=["calculate"],
|
|
67
|
+
roles=["worker"],
|
|
68
|
+
)
|
|
69
|
+
agent.on_task(compute)
|
|
70
|
+
await agent.connect()
|
|
71
|
+
await asyncio.Future() # stay online
|
|
72
|
+
|
|
73
|
+
asyncio.run(main())
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Delegate work from an orchestrator:**
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from intermesh import InterMeshAgent
|
|
80
|
+
|
|
81
|
+
orchestrator = InterMeshAgent(name="lead", roles=["admin"])
|
|
82
|
+
await orchestrator.connect()
|
|
83
|
+
|
|
84
|
+
# Find an agent by capability, then hand it a task
|
|
85
|
+
found = await orchestrator.discover(capabilities=["calculate"])
|
|
86
|
+
result = await orchestrator.submit_task(
|
|
87
|
+
title="Add two numbers",
|
|
88
|
+
assignee=found["agents"][0]["name"],
|
|
89
|
+
input_data={"a": 20, "b": 22},
|
|
90
|
+
)
|
|
91
|
+
# {"result": 42} — encrypted end-to-end in transit
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Bridge an existing framework agent
|
|
97
|
+
|
|
98
|
+
Wrap an existing agent without changing a line of it — it becomes discoverable
|
|
99
|
+
and receives delegated tasks like a native InterMesh agent.
|
|
100
|
+
|
|
101
|
+
A LangChain runnable:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from intermesh import from_langchain
|
|
105
|
+
|
|
106
|
+
agent = from_langchain(my_chain, name="analyst", capabilities=["market_analysis"])
|
|
107
|
+
await agent.connect()
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Anything else — a CrewAI crew, an AutoGen agent, a LlamaIndex engine, or a
|
|
111
|
+
plain function — goes through `from_callable`:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
import asyncio
|
|
115
|
+
from intermesh import from_callable
|
|
116
|
+
|
|
117
|
+
async def run(data):
|
|
118
|
+
# to_thread keeps a blocking LLM call off the event loop, so the agent
|
|
119
|
+
# stays responsive instead of freezing for the whole inference.
|
|
120
|
+
return await asyncio.to_thread(lambda: my_crew.kickoff(inputs=data))
|
|
121
|
+
|
|
122
|
+
agent = from_callable(run, name="research", capabilities=["research"])
|
|
123
|
+
await agent.connect()
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Or as a decorator:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from intermesh import intermesh_service
|
|
130
|
+
|
|
131
|
+
@intermesh_service(name="summarizer", capabilities=["summarize"])
|
|
132
|
+
def summarize(data):
|
|
133
|
+
return {"summary": my_model(data["text"])}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Runnable examples for all four frameworks are in
|
|
137
|
+
[`examples/frameworks/`](https://github.com/intermeshteam/intermesh/tree/main/examples/frameworks).
|
|
138
|
+
|
|
139
|
+
## Orchestrate multiple agents
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from intermesh import InterMeshPipeline
|
|
143
|
+
|
|
144
|
+
pipeline = (
|
|
145
|
+
InterMeshPipeline(orchestrator)
|
|
146
|
+
.step("Translate", capabilities=["translate"])
|
|
147
|
+
.step("Calculate", capabilities=["calculate"],
|
|
148
|
+
input_fn=lambda prev: {"expression": prev["translated_text"]})
|
|
149
|
+
)
|
|
150
|
+
result = await pipeline.run({"text": "compute forty two doubled"})
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
`fan_out(orchestrator, branches, capabilities=...)` runs independent branches in
|
|
154
|
+
parallel instead. Full guide: [`docs/AGENT-INTEGRATION.md`](https://github.com/intermeshteam/intermesh/blob/main/docs/AGENT-INTEGRATION.md).
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Features
|
|
159
|
+
|
|
160
|
+
- **End-to-end encryption** — RSA-2048-OAEP + AES-256-GCM. The hub routes ciphertext it cannot read.
|
|
161
|
+
- **Verifiable identity** — SHA-256 fingerprints over roles, permissions, and capabilities.
|
|
162
|
+
- **JWT authentication** — every message after registration carries a hub-signed token.
|
|
163
|
+
- **Role-based access control** — per-agent policies enforced at the hub.
|
|
164
|
+
- **Discovery** — locate agents by capability, role, metadata, or name.
|
|
165
|
+
- **Distributed tasks** — async lifecycle: `pending → running → completed / failed`.
|
|
166
|
+
- **Federation** — hub-to-hub peering across organizations, encryption preserved end to end.
|
|
167
|
+
- **Immutable audit log** — Merkle-chained events; retroactive edits break the chain.
|
|
168
|
+
- **Rate limiting** — token-bucket throttling per agent.
|
|
169
|
+
- **Developer CLI** — `intermesh hub | discover | ping | ask | task | keygen | dashboard | docs`.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## API summary
|
|
174
|
+
|
|
175
|
+
| Method | Purpose |
|
|
176
|
+
|---|---|
|
|
177
|
+
| `connect()` | Open the connection and obtain a JWT |
|
|
178
|
+
| `send(to, content)` | Fire-and-forget encrypted message |
|
|
179
|
+
| `ask(to, content)` | Encrypted request, awaits the reply |
|
|
180
|
+
| `discover(...)` | Find agents by capability, role, or metadata |
|
|
181
|
+
| `submit_task(title, assignee, input_data)` | Delegate a task and await its result |
|
|
182
|
+
| `who_is(name)` | Fetch an agent's certified identity and public key |
|
|
183
|
+
| `on_message / on_request / on_task` | Register inbound handlers |
|
|
184
|
+
|
|
185
|
+
Full reference: [`docs/API-REFERENCE.md`](https://github.com/intermeshteam/intermesh/blob/main/docs/API-REFERENCE.md)
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Documentation
|
|
190
|
+
|
|
191
|
+
- [Agent integration — adapters and orchestration](https://github.com/intermeshteam/intermesh/blob/main/docs/AGENT-INTEGRATION.md)
|
|
192
|
+
- [RFC-001 — Core protocol specification](https://github.com/intermeshteam/intermesh/blob/main/docs/RFC-001-CORE-PROTOCOL.md)
|
|
193
|
+
- [Security and encryption model](https://github.com/intermeshteam/intermesh/blob/main/docs/SECURITY-AND-ENCRYPTION.md)
|
|
194
|
+
- [API reference](https://github.com/intermeshteam/intermesh/blob/main/docs/API-REFERENCE.md)
|
|
195
|
+
|
|
196
|
+
## License
|
|
197
|
+
|
|
198
|
+
[Apache 2.0](https://github.com/intermeshteam/intermesh/blob/main/LICENSE)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# InterMesh — Python SDK
|
|
2
|
+
|
|
3
|
+
The official Python SDK for **InterMesh Protocol**, the universal open-source coordination
|
|
4
|
+
protocol for AI agents.
|
|
5
|
+
|
|
6
|
+
InterMesh lets agents — regardless of language, framework, or vendor — discover each other,
|
|
7
|
+
communicate with end-to-end encryption, and collaborate on distributed tasks.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install intermesh
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
> The distribution is named `intermesh`; the import module is `intermesh`.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
**Start the coordination hub:**
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
intermesh hub
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Write a worker agent:**
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
import asyncio
|
|
29
|
+
from intermesh import InterMeshAgent
|
|
30
|
+
|
|
31
|
+
async def compute(input_data, task):
|
|
32
|
+
return {"result": input_data["a"] + input_data["b"]}
|
|
33
|
+
|
|
34
|
+
async def main():
|
|
35
|
+
agent = InterMeshAgent(
|
|
36
|
+
name="calc_bot",
|
|
37
|
+
capabilities=["calculate"],
|
|
38
|
+
roles=["worker"],
|
|
39
|
+
)
|
|
40
|
+
agent.on_task(compute)
|
|
41
|
+
await agent.connect()
|
|
42
|
+
await asyncio.Future() # stay online
|
|
43
|
+
|
|
44
|
+
asyncio.run(main())
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Delegate work from an orchestrator:**
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from intermesh import InterMeshAgent
|
|
51
|
+
|
|
52
|
+
orchestrator = InterMeshAgent(name="lead", roles=["admin"])
|
|
53
|
+
await orchestrator.connect()
|
|
54
|
+
|
|
55
|
+
# Find an agent by capability, then hand it a task
|
|
56
|
+
found = await orchestrator.discover(capabilities=["calculate"])
|
|
57
|
+
result = await orchestrator.submit_task(
|
|
58
|
+
title="Add two numbers",
|
|
59
|
+
assignee=found["agents"][0]["name"],
|
|
60
|
+
input_data={"a": 20, "b": 22},
|
|
61
|
+
)
|
|
62
|
+
# {"result": 42} — encrypted end-to-end in transit
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Bridge an existing framework agent
|
|
68
|
+
|
|
69
|
+
Wrap an existing agent without changing a line of it — it becomes discoverable
|
|
70
|
+
and receives delegated tasks like a native InterMesh agent.
|
|
71
|
+
|
|
72
|
+
A LangChain runnable:
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
from intermesh import from_langchain
|
|
76
|
+
|
|
77
|
+
agent = from_langchain(my_chain, name="analyst", capabilities=["market_analysis"])
|
|
78
|
+
await agent.connect()
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Anything else — a CrewAI crew, an AutoGen agent, a LlamaIndex engine, or a
|
|
82
|
+
plain function — goes through `from_callable`:
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
import asyncio
|
|
86
|
+
from intermesh import from_callable
|
|
87
|
+
|
|
88
|
+
async def run(data):
|
|
89
|
+
# to_thread keeps a blocking LLM call off the event loop, so the agent
|
|
90
|
+
# stays responsive instead of freezing for the whole inference.
|
|
91
|
+
return await asyncio.to_thread(lambda: my_crew.kickoff(inputs=data))
|
|
92
|
+
|
|
93
|
+
agent = from_callable(run, name="research", capabilities=["research"])
|
|
94
|
+
await agent.connect()
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Or as a decorator:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from intermesh import intermesh_service
|
|
101
|
+
|
|
102
|
+
@intermesh_service(name="summarizer", capabilities=["summarize"])
|
|
103
|
+
def summarize(data):
|
|
104
|
+
return {"summary": my_model(data["text"])}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Runnable examples for all four frameworks are in
|
|
108
|
+
[`examples/frameworks/`](https://github.com/intermeshteam/intermesh/tree/main/examples/frameworks).
|
|
109
|
+
|
|
110
|
+
## Orchestrate multiple agents
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from intermesh import InterMeshPipeline
|
|
114
|
+
|
|
115
|
+
pipeline = (
|
|
116
|
+
InterMeshPipeline(orchestrator)
|
|
117
|
+
.step("Translate", capabilities=["translate"])
|
|
118
|
+
.step("Calculate", capabilities=["calculate"],
|
|
119
|
+
input_fn=lambda prev: {"expression": prev["translated_text"]})
|
|
120
|
+
)
|
|
121
|
+
result = await pipeline.run({"text": "compute forty two doubled"})
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`fan_out(orchestrator, branches, capabilities=...)` runs independent branches in
|
|
125
|
+
parallel instead. Full guide: [`docs/AGENT-INTEGRATION.md`](https://github.com/intermeshteam/intermesh/blob/main/docs/AGENT-INTEGRATION.md).
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Features
|
|
130
|
+
|
|
131
|
+
- **End-to-end encryption** — RSA-2048-OAEP + AES-256-GCM. The hub routes ciphertext it cannot read.
|
|
132
|
+
- **Verifiable identity** — SHA-256 fingerprints over roles, permissions, and capabilities.
|
|
133
|
+
- **JWT authentication** — every message after registration carries a hub-signed token.
|
|
134
|
+
- **Role-based access control** — per-agent policies enforced at the hub.
|
|
135
|
+
- **Discovery** — locate agents by capability, role, metadata, or name.
|
|
136
|
+
- **Distributed tasks** — async lifecycle: `pending → running → completed / failed`.
|
|
137
|
+
- **Federation** — hub-to-hub peering across organizations, encryption preserved end to end.
|
|
138
|
+
- **Immutable audit log** — Merkle-chained events; retroactive edits break the chain.
|
|
139
|
+
- **Rate limiting** — token-bucket throttling per agent.
|
|
140
|
+
- **Developer CLI** — `intermesh hub | discover | ping | ask | task | keygen | dashboard | docs`.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## API summary
|
|
145
|
+
|
|
146
|
+
| Method | Purpose |
|
|
147
|
+
|---|---|
|
|
148
|
+
| `connect()` | Open the connection and obtain a JWT |
|
|
149
|
+
| `send(to, content)` | Fire-and-forget encrypted message |
|
|
150
|
+
| `ask(to, content)` | Encrypted request, awaits the reply |
|
|
151
|
+
| `discover(...)` | Find agents by capability, role, or metadata |
|
|
152
|
+
| `submit_task(title, assignee, input_data)` | Delegate a task and await its result |
|
|
153
|
+
| `who_is(name)` | Fetch an agent's certified identity and public key |
|
|
154
|
+
| `on_message / on_request / on_task` | Register inbound handlers |
|
|
155
|
+
|
|
156
|
+
Full reference: [`docs/API-REFERENCE.md`](https://github.com/intermeshteam/intermesh/blob/main/docs/API-REFERENCE.md)
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Documentation
|
|
161
|
+
|
|
162
|
+
- [Agent integration — adapters and orchestration](https://github.com/intermeshteam/intermesh/blob/main/docs/AGENT-INTEGRATION.md)
|
|
163
|
+
- [RFC-001 — Core protocol specification](https://github.com/intermeshteam/intermesh/blob/main/docs/RFC-001-CORE-PROTOCOL.md)
|
|
164
|
+
- [Security and encryption model](https://github.com/intermeshteam/intermesh/blob/main/docs/SECURITY-AND-ENCRYPTION.md)
|
|
165
|
+
- [API reference](https://github.com/intermeshteam/intermesh/blob/main/docs/API-REFERENCE.md)
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
[Apache 2.0](https://github.com/intermeshteam/intermesh/blob/main/LICENSE)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from intermesh.agent import InterMeshAgent
|
|
2
|
+
from intermesh.message import MessageType, InterMeshMessage
|
|
3
|
+
from intermesh.identity import AgentIdentity
|
|
4
|
+
from intermesh.task import InterMeshTask, TaskStatus
|
|
5
|
+
from intermesh.audit import ImmutableAuditLog, AuditEntry
|
|
6
|
+
from intermesh.ratelimit import RateLimiter, TokenBucket
|
|
7
|
+
from intermesh.adapters import from_callable, from_langchain, intermesh_service
|
|
8
|
+
from intermesh.bridge import (
|
|
9
|
+
BridgeError, exec_handler, from_command, from_http, http_handler,
|
|
10
|
+
post_task, run_command,
|
|
11
|
+
)
|
|
12
|
+
from intermesh.egress import EgressBlocked, EgressPolicy, EgressRule, apply_egress
|
|
13
|
+
from intermesh.guardrails import AsimovGuardrailEngine, GuardrailPolicy, PolicyViolationError, CircuitBreaker
|
|
14
|
+
|
|
15
|
+
# Imports optionnels pour la rétro-compatibilité complète
|
|
16
|
+
try:
|
|
17
|
+
from intermesh.store import InterMeshStore
|
|
18
|
+
except ImportError:
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
from intermesh.pipeline import InterMeshPipeline, PipelineError, fan_out
|
|
23
|
+
except ImportError:
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
from intermesh.logger import get_logger, JSONFormatter, StandardFormatter
|
|
28
|
+
except ImportError:
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
from intermesh.metrics import InterMeshMetricsCollector
|
|
33
|
+
except ImportError:
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
from intermesh.policy import InterMeshPolicy
|
|
38
|
+
except ImportError:
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
from intermesh.health import InterMeshHealthChecker
|
|
43
|
+
except ImportError:
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
from intermesh.config import Settings
|
|
48
|
+
except ImportError:
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
from intermesh.snapshot import SnapshotError
|
|
53
|
+
except ImportError:
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
__version__ = "0.3.0"
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import inspect
|
|
3
|
+
from typing import Callable, Any, Optional, List
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def from_callable(
|
|
7
|
+
fn: Callable[[Any], Any],
|
|
8
|
+
name: str,
|
|
9
|
+
capabilities: Optional[List[str]] = None,
|
|
10
|
+
roles: Optional[List[str]] = None,
|
|
11
|
+
permissions: Optional[List[str]] = None,
|
|
12
|
+
org_id: str = "default",
|
|
13
|
+
hub_url: str = "ws://localhost:8765",
|
|
14
|
+
encrypt: bool = True
|
|
15
|
+
):
|
|
16
|
+
from intermesh.agent import InterMeshAgent
|
|
17
|
+
|
|
18
|
+
agent = InterMeshAgent(
|
|
19
|
+
name=name,
|
|
20
|
+
org_id=org_id,
|
|
21
|
+
capabilities=capabilities or ["compute"],
|
|
22
|
+
roles=roles or ["worker"],
|
|
23
|
+
permissions=permissions or [],
|
|
24
|
+
hub_url=hub_url,
|
|
25
|
+
encrypt=encrypt
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
async def adapter_task_handler(input_data: Any, task: Any):
|
|
29
|
+
if inspect.iscoroutinefunction(fn):
|
|
30
|
+
return await fn(input_data)
|
|
31
|
+
else:
|
|
32
|
+
return fn(input_data)
|
|
33
|
+
|
|
34
|
+
agent.on_task(adapter_task_handler)
|
|
35
|
+
return agent
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def from_langchain(
|
|
39
|
+
chain_or_runnable: Any,
|
|
40
|
+
name: str,
|
|
41
|
+
capabilities: Optional[List[str]] = None,
|
|
42
|
+
roles: Optional[List[str]] = None,
|
|
43
|
+
hub_url: str = "ws://localhost:8765",
|
|
44
|
+
encrypt: bool = True
|
|
45
|
+
):
|
|
46
|
+
from intermesh.agent import InterMeshAgent
|
|
47
|
+
|
|
48
|
+
agent = InterMeshAgent(
|
|
49
|
+
name=name,
|
|
50
|
+
capabilities=capabilities or ["langchain_chain"],
|
|
51
|
+
roles=roles or ["worker"],
|
|
52
|
+
hub_url=hub_url,
|
|
53
|
+
encrypt=encrypt
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
async def langchain_handler(input_data: Any, task: Any):
|
|
57
|
+
if hasattr(chain_or_runnable, "ainvoke"):
|
|
58
|
+
res = await chain_or_runnable.ainvoke(input_data)
|
|
59
|
+
elif hasattr(chain_or_runnable, "invoke"):
|
|
60
|
+
res = chain_or_runnable.invoke(input_data)
|
|
61
|
+
elif hasattr(chain_or_runnable, "run"):
|
|
62
|
+
res = chain_or_runnable.run(input_data)
|
|
63
|
+
elif callable(chain_or_runnable):
|
|
64
|
+
res = chain_or_runnable(input_data)
|
|
65
|
+
else:
|
|
66
|
+
raise TypeError("L'objet fourni n'est pas un Runnable/Chain LangChain valide.")
|
|
67
|
+
|
|
68
|
+
return {"output": res, "adapter": "langchain_intermesh_v1"}
|
|
69
|
+
|
|
70
|
+
agent.on_task(langchain_handler)
|
|
71
|
+
return agent
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def intermesh_service(
|
|
75
|
+
name: str,
|
|
76
|
+
capabilities: Optional[List[str]] = None,
|
|
77
|
+
roles: Optional[List[str]] = None,
|
|
78
|
+
hub_url: str = "ws://localhost:8765",
|
|
79
|
+
encrypt: bool = True
|
|
80
|
+
):
|
|
81
|
+
def decorator(fn: Callable[[Any], Any]):
|
|
82
|
+
return from_callable(
|
|
83
|
+
fn=fn,
|
|
84
|
+
name=name,
|
|
85
|
+
capabilities=capabilities,
|
|
86
|
+
roles=roles,
|
|
87
|
+
hub_url=hub_url,
|
|
88
|
+
encrypt=encrypt
|
|
89
|
+
)
|
|
90
|
+
return decorator
|