Skip to content

Commit 7dfa19e

Browse files
committed
feat(adapters): PR_BODY.md
1 parent 4807bc6 commit 7dfa19e

1 file changed

Lines changed: 90 additions & 0 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Add AgentCard v1.0 integration for agent identity declaration
2+
3+
## Summary
4+
5+
This PR adds a `langchain_community/utilities/agentcard.py` integration that allows
6+
LangChain tools and agents to declare their identity using the **AgentCard v1.0**
7+
open standard (https://github.com/kwailapt/AgentCard).
8+
9+
AgentCard is to A2A (agent-to-agent) communication what HTTP headers are to the web:
10+
a standardised, machine-parseable capability declaration that works with any framework.
11+
12+
## Why this matters
13+
14+
As LangChain agents begin communicating with agents from other frameworks (CrewAI,
15+
AutoGen, custom agents), they need a **framework-neutral identity format**.
16+
AgentCard fills this gap:
17+
18+
- **Zero dependencies** in core — pure Python dataclasses
19+
- **Framework-agnostic** — same JSON schema works for LangChain, CrewAI, AutoGen, MCP
20+
- **Physics-grounded pricing**`base_cost_joules` uses Landauer's thermodynamic floor
21+
as a machine-verifiable minimum cost, preventing fake "zero-cost" claims
22+
- **Open standard** — Apache 2.0 + CC-BY 4.0, patent non-reservation
23+
24+
## What's included
25+
26+
### `langchain_community/utilities/agentcard.py`
27+
28+
- `tool_to_agentcard(tool, agent_id, endpoint_url)` — convert a `BaseTool` to AgentCard
29+
- `tools_to_agentcard(tools, agent_id, agent_name, endpoint_url)` — bundle multiple tools
30+
- `agentcard_to_tool(card)` — reconstruct a `StructuredTool` from an AgentCard
31+
- `AgentCardMixin` — wrap any `AgentExecutor` with AgentCard identity
32+
33+
### `tests/unit_tests/utilities/test_agentcard.py`
34+
35+
Full test coverage using mock tools (no network calls, no external dependencies).
36+
37+
## Usage example
38+
39+
```python
40+
from langchain.tools import BaseTool
41+
from langchain_community.utilities.agentcard import tool_to_agentcard
42+
43+
class WebSearchTool(BaseTool):
44+
name = "web_search"
45+
description = "Search the web for current information."
46+
def _run(self, query: str) -> str: ...
47+
48+
card = tool_to_agentcard(
49+
tool=WebSearchTool(),
50+
agent_id="01HZQK3P8EMXR9V7T5N2W4J6C0", # ULID
51+
endpoint_url="https://my-agent.example.com/api",
52+
)
53+
print(card.to_json(indent=2))
54+
# {
55+
# "agent_id": "01HZQK3P8EMXR9V7T5N2W4J6C0",
56+
# "name": "web_search",
57+
# "version": "1.0.0",
58+
# "capabilities": [{"id": "web_search", "description": "Search the web..."}],
59+
# "endpoint": {"protocol": "http", "url": "https://my-agent.example.com/api"}
60+
# }
61+
```
62+
63+
## AgentCard JSON Schema
64+
65+
Full schema: https://github.com/kwailapt/AgentCard/blob/main/schema.json
66+
67+
Key fields:
68+
| Field | Type | Description |
69+
|-------|------|-------------|
70+
| `agent_id` | string | 26-char Crockford Base32 ULID |
71+
| `name` | string | Display name 1–128 chars |
72+
| `version` | string | Semantic version (semver 2.0) |
73+
| `capabilities[]` | array | Dot-namespaced capability ids |
74+
| `endpoint` | object | Protocol + URL + optional auth |
75+
| `pricing.base_cost_joules` | float | Landauer thermodynamic floor |
76+
77+
## Checklist
78+
79+
- [x] Zero new mandatory dependencies (optional: `agentcard-adapters`)
80+
- [x] Tests pass with mock objects (no real framework calls)
81+
- [x] `BaseTool.args_schema``input_schema` (Pydantic v1 + v2 both supported)
82+
- [x] Round-trip serialisation verified (Python dict ↔ JSON ↔ AgentCard)
83+
- [x] Landauer floor validation (physically implausible prices rejected)
84+
- [x] Apache 2.0 license compatible with LangChain MIT license
85+
86+
## References
87+
88+
- AgentCard spec: https://github.com/kwailapt/AgentCard
89+
- JSON Schema: https://github.com/kwailapt/AgentCard/blob/main/schema.json
90+
- License: Apache 2.0 + CC-BY 4.0, no patent reservation

0 commit comments

Comments
 (0)