sm-bridge 0.3.1__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.
@@ -0,0 +1,87 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # PyInstaller
28
+ *.manifest
29
+ *.spec
30
+
31
+ # Installer logs
32
+ pip-log.txt
33
+ pip-delete-this-directory.txt
34
+
35
+ # Unit test / coverage reports
36
+ htmlcov/
37
+ .tox/
38
+ .nox/
39
+ .coverage
40
+ .coverage.*
41
+ .cache
42
+ nosetests.xml
43
+ coverage.xml
44
+ *.cover
45
+ *.py,cover
46
+ .hypothesis/
47
+ .pytest_cache/
48
+
49
+ # Translations
50
+ *.mo
51
+ *.pot
52
+
53
+ # Environments
54
+ .env
55
+ .venv
56
+ env/
57
+ venv/
58
+ ENV/
59
+ env.bak/
60
+ venv.bak/
61
+
62
+ # IDEs
63
+ .idea/
64
+ .vscode/
65
+ *.swp
66
+ *.swo
67
+ *~
68
+
69
+ # Jupyter Notebook
70
+ .ipynb_checkpoints
71
+
72
+ # mypy
73
+ .mypy_cache/
74
+ .dmypy.json
75
+ dmypy.json
76
+
77
+ # Ruff
78
+ .ruff_cache/
79
+
80
+ # macOS
81
+ .DS_Store
82
+
83
+ # Windows Zone.Identifier alternate data streams
84
+ *:Zone.Identifier
85
+
86
+ # Benchmarks
87
+ .benchmarks/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Project NANDA Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,390 @@
1
+ Metadata-Version: 2.4
2
+ Name: sm-bridge
3
+ Version: 0.3.1
4
+ Summary: A Python library for building NANDA-compatible AI agent registries
5
+ Project-URL: Homepage, https://github.com/Sharathvc23/sm-bridge
6
+ Project-URL: Documentation, https://github.com/Sharathvc23/sm-bridge#readme
7
+ Project-URL: Repository, https://github.com/Sharathvc23/sm-bridge.git
8
+ Project-URL: Issues, https://github.com/Sharathvc23/sm-bridge/issues
9
+ Author-email: StellarMinds <hello@stellarminds.ai>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: a2a,agent-registry,ai-agents,decentralized-identity,did,fastapi,mcp,nanda
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Framework :: FastAPI
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
23
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: fastapi>=0.100.0
26
+ Requires-Dist: pydantic>=2.0.0
27
+ Provides-Extra: all
28
+ Requires-Dist: httpx>=0.24.0; extra == 'all'
29
+ Requires-Dist: sm-model-card>=0.1.0; extra == 'all'
30
+ Requires-Dist: sm-model-governance>=0.1.0; extra == 'all'
31
+ Requires-Dist: sm-model-integrity-layer>=0.1.0; extra == 'all'
32
+ Requires-Dist: sm-model-provenance>=0.1.0; extra == 'all'
33
+ Provides-Extra: card
34
+ Requires-Dist: sm-model-card>=0.1.0; extra == 'card'
35
+ Provides-Extra: dev
36
+ Requires-Dist: httpx>=0.24.0; extra == 'dev'
37
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
38
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
39
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
40
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
41
+ Provides-Extra: federation
42
+ Requires-Dist: httpx>=0.24.0; extra == 'federation'
43
+ Provides-Extra: governance
44
+ Requires-Dist: sm-model-governance>=0.1.0; extra == 'governance'
45
+ Provides-Extra: integrity
46
+ Requires-Dist: sm-model-integrity-layer>=0.1.0; extra == 'integrity'
47
+ Provides-Extra: provenance
48
+ Requires-Dist: sm-model-provenance>=0.1.0; extra == 'provenance'
49
+ Description-Content-Type: text/markdown
50
+
51
+ # SM Bridge
52
+
53
+ A Python library for building NANDA-compatible AI agent registries.
54
+
55
+ **[NANDA](https://projectnanda.org)** (Network of AI Agents in Decentralized Architecture) is the protocol for federated AI agent discovery and communication. This library provides the primitives needed to make your agent registry interoperable with the NANDA ecosystem.
56
+
57
+ ## Features
58
+
59
+ - **NANDA AgentFacts Models** - Pydantic models implementing the [projnanda/agentfacts-format](https://github.com/projnanda) specification
60
+ - **FastAPI Router** - Drop-in endpoints for `/nanda/index`, `/nanda/resolve`, `/nanda/deltas`
61
+ - **Delta Store** - Change tracking for registry synchronization
62
+ - **Converter Interface** - Abstract pattern for integrating with your existing registry
63
+
64
+ ## Installation
65
+
66
+ ```bash
67
+ pip install git+https://github.com/Sharathvc23/sm-bridge.git
68
+ ```
69
+
70
+ Or install from source:
71
+
72
+ ```bash
73
+ git clone https://github.com/Sharathvc23/sm-bridge
74
+ cd sm-bridge
75
+ pip install -e .
76
+ ```
77
+
78
+ ## Quick Start
79
+
80
+ ### Basic Usage
81
+
82
+ ```python
83
+ from fastapi import FastAPI
84
+ from sm_bridge import SmBridge, SimpleAgent
85
+
86
+ # Create the bridge
87
+ bridge = SmBridge(
88
+ registry_id="my-registry",
89
+ provider_name="My Company",
90
+ provider_url="https://example.com",
91
+ base_url="https://registry.example.com"
92
+ )
93
+
94
+ # Register agents
95
+ bridge.register_agent(SimpleAgent(
96
+ id="my-agent",
97
+ name="My Agent",
98
+ description="An agent that does things",
99
+ namespace="production",
100
+ labels=["chat", "tool-use"],
101
+ skills=[
102
+ {"id": "summarize", "description": "Summarizes text"},
103
+ {"id": "translate", "description": "Translates between languages"}
104
+ ]
105
+ ))
106
+
107
+ # Mount routers
108
+ app = FastAPI()
109
+ app.include_router(bridge.router) # /nanda/* endpoints
110
+ app.include_router(bridge.wellknown_router) # /.well-known/nanda.json (RFC 8615)
111
+ ```
112
+
113
+ This gives you:
114
+
115
+ - `GET /nanda/index` - List all public agents (with correct `total_count` for pagination)
116
+ - `GET /nanda/resolve?agent=my-agent` - Resolve a single agent
117
+ - `GET /nanda/deltas?since=0` - Get changes for sync
118
+ - `GET /.well-known/nanda.json` - Registry discovery (RFC 8615 compliant)
119
+
120
+ ### Custom Registry Integration
121
+
122
+ For existing registries with their own data models:
123
+
124
+ ```python
125
+ from sm_bridge import (
126
+ AbstractAgentConverter,
127
+ SmAgentFacts,
128
+ SmProvider,
129
+ SmEndpoints,
130
+ SmCapabilities,
131
+ SmSkill,
132
+ DeltaStore,
133
+ create_sm_router,
134
+ )
135
+ from typing import Iterator
136
+
137
+ class MyRegistryConverter(AbstractAgentConverter):
138
+ def __init__(self, db_connection):
139
+ super().__init__(
140
+ registry_id="my-registry",
141
+ provider_name="My Company",
142
+ provider_url="https://example.com"
143
+ )
144
+ self.db = db_connection
145
+
146
+ def to_sm(self, agent) -> SmAgentFacts:
147
+ return SmAgentFacts(
148
+ id=f"did:web:example.com:agents:{agent.id}",
149
+ handle=self.build_handle(agent.namespace, agent.id),
150
+ agent_name=agent.display_name,
151
+ label=agent.category,
152
+ description=agent.description,
153
+ version=agent.version,
154
+ provider=self.build_provider(),
155
+ endpoints=SmEndpoints(static=[agent.endpoint_url]),
156
+ capabilities=SmCapabilities(modalities=agent.capabilities),
157
+ skills=[SmSkill(id=s.id, description=s.desc) for s in agent.skills],
158
+ metadata={
159
+ "x_my_registry": {
160
+ "internal_id": agent.internal_id,
161
+ "created_at": agent.created_at.isoformat(),
162
+ }
163
+ }
164
+ )
165
+
166
+ def list_agents(self, limit: int, offset: int) -> Iterator:
167
+ return self.db.query_agents(limit=limit, offset=offset)
168
+
169
+ def get_agent(self, agent_id: str):
170
+ return self.db.get_agent(agent_id)
171
+
172
+ def is_public(self, agent) -> bool:
173
+ return agent.visibility == "public"
174
+
175
+ # Create router with custom converter
176
+ converter = MyRegistryConverter(db_connection)
177
+ delta_store = DeltaStore()
178
+
179
+ nanda_router, wellknown_router = create_sm_router(
180
+ converter=converter,
181
+ delta_store=delta_store,
182
+ registry_id="my-registry",
183
+ base_url="https://registry.example.com",
184
+ provider_name="My Company",
185
+ provider_url="https://example.com"
186
+ )
187
+
188
+ app = FastAPI()
189
+ app.include_router(nanda_router)
190
+ app.include_router(wellknown_router)
191
+ ```
192
+
193
+ ## Models
194
+
195
+ ### SmAgentFacts
196
+
197
+ The core data structure for agent metadata:
198
+
199
+ ```python
200
+ from sm_bridge import SmAgentFacts
201
+
202
+ facts = SmAgentFacts(
203
+ id="did:web:example.com:agents:my-agent",
204
+ handle="@my-registry:production/my-agent",
205
+ agent_name="My Agent",
206
+ label="assistant",
207
+ description="An AI assistant",
208
+ version="1.0.0",
209
+ provider=SmProvider(
210
+ name="My Company",
211
+ url="https://example.com"
212
+ ),
213
+ endpoints=SmEndpoints(
214
+ static=["https://api.example.com/agents/my-agent"]
215
+ ),
216
+ capabilities=SmCapabilities(
217
+ modalities=["text", "tool-use"],
218
+ authentication=SmAuthentication(methods=["did-auth"])
219
+ ),
220
+ skills=[
221
+ SmSkill(
222
+ id="urn:my-registry:cap:summarize:v1",
223
+ description="Summarizes long documents",
224
+ inputModes=["text"],
225
+ outputModes=["text"]
226
+ )
227
+ ],
228
+ metadata={
229
+ "x_my_registry": {
230
+ "custom_field": "custom_value"
231
+ }
232
+ }
233
+ )
234
+ ```
235
+
236
+ ### Handle Format
237
+
238
+ NANDA handles follow the format `@registry:namespace/agent-id`:
239
+
240
+ ```python
241
+ handle = SmAgentFacts.create_handle(
242
+ registry="my-registry",
243
+ namespace="production",
244
+ agent_id="my-agent"
245
+ )
246
+ # Returns: "@my-registry:production/my-agent"
247
+ ```
248
+
249
+ ## Delta Store
250
+
251
+ Track changes for registry synchronization:
252
+
253
+ ```python
254
+ from sm_bridge import DeltaStore, SmAgentFacts
255
+
256
+ store = DeltaStore()
257
+
258
+ # Record an agent creation/update
259
+ delta = store.add("upsert", agent_facts)
260
+ print(f"Recorded delta with seq={delta.seq}")
261
+
262
+ # Get all changes since seq 0
263
+ deltas = store.since(0)
264
+
265
+ # Get next sequence number for polling
266
+ next_seq = store.next_seq
267
+ ```
268
+
269
+ For production, extend `PersistentDeltaStore` to persist to a database:
270
+
271
+ ```python
272
+ from sm_bridge import PersistentDeltaStore
273
+
274
+ class PostgresDeltaStore(PersistentDeltaStore):
275
+ def __init__(self, dsn: str):
276
+ super().__init__()
277
+ self.conn = psycopg2.connect(dsn)
278
+
279
+ def _persist(self, delta):
280
+ # INSERT INTO nanda_deltas ...
281
+ pass
282
+
283
+ def _load_since(self, seq):
284
+ # SELECT * FROM nanda_deltas WHERE seq > ...
285
+ pass
286
+ ```
287
+
288
+ ## MCP Tools
289
+
290
+ Advertise MCP tools that agents can use:
291
+
292
+ ```python
293
+ from sm_bridge import SmBridge, SmTool
294
+
295
+ bridge = SmBridge(
296
+ registry_id="my-registry",
297
+ provider_name="My Company",
298
+ provider_url="https://example.com",
299
+ tools=[
300
+ SmTool(
301
+ tool_id="search",
302
+ description="Search the web",
303
+ endpoint="https://api.example.com/mcp/search",
304
+ params=["query", "limit"]
305
+ ),
306
+ SmTool(
307
+ tool_id="calculate",
308
+ description="Perform calculations",
309
+ endpoint="https://api.example.com/mcp/calculate",
310
+ params=["expression"]
311
+ )
312
+ ]
313
+ )
314
+ ```
315
+
316
+ ## Registry Discovery
317
+
318
+ The library serves `/.well-known/nanda.json` at the domain root (RFC 8615) via the separate `wellknown_router`:
319
+
320
+ ```json
321
+ {
322
+ "registry_id": "my-registry",
323
+ "registry_did": "did:web:registry.example.com",
324
+ "namespaces": ["did:web:example.com:*"],
325
+ "index_url": "https://registry.example.com/nanda/index",
326
+ "resolve_url": "https://registry.example.com/nanda/resolve",
327
+ "deltas_url": "https://registry.example.com/nanda/deltas",
328
+ "tools_url": "https://registry.example.com/nanda/tools",
329
+ "provider": {
330
+ "name": "My Company",
331
+ "url": "https://example.com"
332
+ },
333
+ "capabilities": ["agentfacts", "deltas", "mcp-tools"]
334
+ }
335
+ ```
336
+
337
+ ## Federating with NANDA
338
+
339
+ To join the NANDA network:
340
+
341
+ 1. Deploy your registry with the NANDA bridge endpoints
342
+ 2. Ensure `/.well-known/nanda.json` is accessible
343
+ 3. Contact the MIT NANDA team to register as a federated peer
344
+ 4. (Optional) Implement incremental sync or gossip mechanisms for real-time or near-real-time federation
345
+
346
+ ## AI Catalog gateway
347
+
348
+ `create_gateway_router` serves the AI Catalog discovery endpoints for the agents in a
349
+ `DeltaStore`, alongside the `/nanda/*` router (the two surfaces are independent):
350
+
351
+ ```python
352
+ from fastapi import FastAPI
353
+ from sm_bridge import DeltaStore, create_gateway_router
354
+
355
+ delta_store = DeltaStore()
356
+
357
+ app = FastAPI()
358
+ app.include_router(
359
+ create_gateway_router(delta_store, base_url="https://reg.example.com", domain="example.com")
360
+ )
361
+ ```
362
+
363
+ | Endpoint | Returns |
364
+ |----------|---------|
365
+ | `GET /.well-known/ai-catalog.json` | `CatalogDocument` — all agents |
366
+ | `GET /agents/{slug}` | `CatalogEntry` — a pointer to the agent's card |
367
+ | `GET /cards/{slug}.json` | A2A `AgentCard` (full `SmAgentFacts` included under `_meta`) |
368
+
369
+ Each `SmAgentFacts` is translated into a `CatalogEntry` and an A2A `AgentCard` whose `url`
370
+ is the agent's runtime. Point a NANDA index at `base_url` (as a `hosting_path=registry`
371
+ entry) to make the agents discoverable through the AI Catalog flow.
372
+
373
+ ## Related Packages
374
+
375
+ | Package | Question it answers |
376
+ |---------|-------------------|
377
+ | [`sm-model-provenance`](https://github.com/Sharathvc23/sm-model-provenance) | "Where did this model come from?" (identity, versioning, provider, NANDA serialization) |
378
+ | [`sm-model-card`](https://github.com/Sharathvc23/sm-model-card) | "What is this model?" (unified metadata schema — type, status, risk level, metrics, weights hash) |
379
+ | [`sm-model-integrity-layer`](https://github.com/Sharathvc23/sm-model-integrity-layer) | "Does this model's metadata meet policy?" (rule-based checks) |
380
+ | [`sm-model-governance`](https://github.com/Sharathvc23/sm-model-governance) | "Has this model been cryptographically approved for deployment?" (approval flow with signatures, quorum, scoping, revocation) |
381
+ | `sm-bridge` (this package) | "How do I expose this to the NANDA network?" (FastAPI router, AgentFacts models, delta sync) |
382
+
383
+
384
+ ## License
385
+
386
+ MIT
387
+
388
+ ---
389
+
390
+ *Personal research contributions aligned with [Project NANDA](https://projectnanda.org) standards. [Stellarminds.ai](https://stellarminds.ai)*