You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit d4bdbfa
Browse filesBrowse the repository at this point in the historyBrowse files
The SDK README still described service discovery as a Kademlia lookup on
/mesh/kad/1.0.0 with gossip announcements beside it. It now describes
the directory request to a router the session holds, and names the files
that derive the keys and serve the requests. The service-key fixture
says the same.
Copy file name to clipboardExpand all lines: sdk/README.md
+30-34Lines changed: 30 additions & 34 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,7 +23,7 @@ An SDK member is an agent, not a service provider. It calls what the mesh
23
23
offers: MCP tools, inference and A2A services that `agentmesh-node`s publish and
24
24
the discovery table names. Inbound, it accepts one thing: A2A requests for
25
25
itself, as `a2a://<name>`, reached by peer ID through a router. It publishes
26
-
no service, writes no provider record and reports no catalog; a tool, a
26
+
no service, writes no directory record and reports no catalog; a tool, a
27
27
model or a named agent that others should find by name runs behind a
28
28
`agentmesh-node`. The reasons are in [Agents, not services](#agents-not-services).
29
29
@@ -44,7 +44,7 @@ Milestones 1 to 5 are implemented and tested in both languages:
44
44
|`/mesh/auth/1.0.0`, both sides; join = pick `k` routers (default 2) by selector, preference and load, handshake and check role | yes | yes |
45
45
| Circuit relay v2 reservation on each held router; dial and accept through them | yes | yes |
46
46
|`/mesh/goaway/1.0.0`: shun a draining or overloaded router for `retry_after` and replace it from the catalog; redial (`2s, 4s, 8s`) before failing over on a dropped connection | yes | yes |
47
-
| Service discovery in the mesh DHT (`/mesh/kad/1.0.0`) | yes | yes |
47
+
| Service discovery through a held router (`/mesh/directory/1.0.0`) | yes | yes |
48
48
|`/mesh/mcp/1.0.0` client: list and call a provider's tools, or its catalog | yes | yes |
49
49
| Caller-side label requirements on the provider's credential | yes | yes |
50
50
|`/libp2p-http` client: call inference and A2A services on the mesh; response bodies stream | yes | yes |
@@ -58,7 +58,7 @@ Milestones 1 to 5 are implemented and tested in both languages:
58
58
| Published to a registry from the release workflow | npm `@agentmesh-p2p/sdk`| PyPI `agentmesh-p2p`|
59
59
60
60
A member built this way is on the mesh and uses it in both directions: it
61
-
finds a service in the DHT and calls it through the router, verifying the
61
+
finds a service in the directory and calls it through the router, verifying the
62
62
provider on every call, and it answers A2A requests for its own agent from
63
63
a `agentmesh-node` or another SDK member that names it by peer ID, authorizing
64
64
every caller with the same Datalog the Go node evaluates. It follows the
@@ -125,14 +125,11 @@ pinned by a test:
125
125
host dials such addresses by name (libp2p/py-libp2p#1549). It also dials
126
126
`wss` with certificate verification off unless given a TLS context
127
127
(libp2p/py-libp2p#1550); the host gives it the system roots.
128
-
- py-libp2p's Kademlia client takes a protocol prefix but its provider
129
-
lookups still speak `/ipfs/kad/1.0.0`, so it cannot reach the mesh DHT.
130
-
The Python SDK does a bounded GET_PROVIDERS walk itself on
131
-
`/mesh/kad/1.0.0`, seeded by the routers (`agent_mesh/discovery.py`).
132
-
js-libp2p's `@libp2p/kad-dht` takes the protocol and works as is.
133
-
- go-libp2p-kad-dht keys provider records by the multihash, not the CID.
134
-
`sdk/testdata/service_keys.json` pins the keys both SDKs derive against
135
-
`internal/node/service.go`.
128
+
- A member keeps no DHT. Both SDKs ask a router they hold over
129
+
`/mesh/directory/1.0.0` (`discovery.ts`, `agent_mesh/discovery.py`), one
130
+
`DirectoryRequest` per stream, and the router runs the lookup in the DHT
131
+
the routers keep among themselves. `sdk/testdata/service_keys.json` pins
132
+
the keys both SDKs derive against `api/directory_keys.go`.
136
133
- go-libp2p-http is plain HTTP/1.1 on a stream, one request per stream,
137
134
with `Host` set to the peer ID. The JS SDK bridges the stream to a Node
138
135
duplex and runs Node's HTTP server and client on it; the Python SDK
@@ -144,7 +141,7 @@ pinned by a test:
144
141
`http://mesh/mesh/<peer-id>/<type>/<name>/<path>`, the shape of `agentmesh-node`'s
145
142
egress proxy and of an agent card rewritten for the mesh; the host is ignored.
146
143
- A member that publishes nothing has announced no address, so nothing in
147
-
the DHT or a router's peerstore names one. `agentmesh-node` dials
144
+
the directory names one. `agentmesh-node` dials
148
145
`/p2p/<router>/p2p-circuit` for every router it authenticated with when
149
146
it knows nothing else about a peer, as both SDKs do for a peer named by
150
147
ID (`internal/node/mcp.go`, `preparePeerAddrs`).
@@ -243,7 +240,7 @@ messages in `api/agentmesh.proto`. Bodies are capped at 1 MiB on both sides.
243
240
not.
244
241
Challenges are defined in `api/network.go`. It is the one instant on the
245
242
wire that is an `int64`: it is the number in the signed text. Every other
246
-
instant (`expire_time`, `sign_time`, `event_time`, `announce_time`) is a
243
+
instant (`expire_time`, `sign_time`, `event_time`) is a
247
244
`google.protobuf.Timestamp`, and a receiver rejects a message whose
248
245
required instant is unset.
249
246
- A bootstrap enrollment answers `PENDING` until an operator approves it,
@@ -283,7 +280,8 @@ messages in `api/agentmesh.proto`. Bodies are capped at 1 MiB on both sides.
283
280
- Muxer: yamux (libp2p default).
284
281
- Relay: circuit relay v2, with the routers as static relays; hole punching
285
282
is on. A node behind NAT is reached through a router.
286
-
- DHT: Kademlia with protocol prefix `/mesh`, mode auto.
283
+
- Directory: `/mesh/directory/1.0.0` to a router the session holds; a
284
+
member keeps no DHT and speaks no Kademlia.
287
285
288
286
### Streams
289
287
@@ -334,15 +332,15 @@ length, then the bytes), with a 64 KiB cap on the first frame.
334
332
(`2s, 4s, 8s`) and, if it does not come back or refuses auth, shuns it and
|`discovery.ts`|`discovery.py`| service keys and DHT lookups as `internal/node/service.go`; lookups only, no records |
749
+
|`discovery.ts`|`discovery.py`| service keys and directory requests to a held router, as `internal/node/directory_client.go`; lookups only, no records |
754
750
|`mcp.ts`|`mcp_client.py`| MCP over `/mesh/mcp/1.0.0`, the client side of `internal/node/gate.go`|
755
751
|`authorizer.ts`|`authorizer.py`| the provider authorizer, as `internal/node.(*AgentMeshNode).Authorize`, over the generated baseline and `datalog_rules`|
756
752
|`libp2p-http.ts`|`libp2p_http.py`|`/libp2p-http` client (streaming) and the A2A ingress for the agent, as go-libp2p-http and `StartIngressServer`; mesh URLs |
Copy file name to clipboardExpand all lines: sdk/testdata/service_keys.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,5 @@
1
1
{
2
-
"_comment": "Service discovery keys as internal/node/service.go derives them: cid = cidv1(raw, sha256(\"mesh:service:\u003ctype\u003e[:\u003cname\u003e]\")); go-libp2p-kad-dht keys the provider record by the multihash (hex).",
2
+
"_comment": "Service directory keys as api.ServiceKey derives them: multihash = sha256(\"mesh:service:<type>[:<name>]\") (hex); cid is the same key as cidv1(raw, multihash), the form the routers' DHT stores it under.",
0 commit comments