eil-card 0.1.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.
- eil_card-0.1.1/.gitignore +25 -0
- eil_card-0.1.1/PKG-INFO +162 -0
- eil_card-0.1.1/README.md +123 -0
- eil_card-0.1.1/eil_card/__init__.py +64 -0
- eil_card-0.1.1/eil_card/act.py +98 -0
- eil_card-0.1.1/eil_card/agent_tool.py +60 -0
- eil_card-0.1.1/eil_card/capabilities.py +42 -0
- eil_card-0.1.1/eil_card/client.py +193 -0
- eil_card-0.1.1/eil_card/errors.py +39 -0
- eil_card-0.1.1/eil_card/integrations/__init__.py +1 -0
- eil_card-0.1.1/eil_card/integrations/crewai.py +69 -0
- eil_card-0.1.1/eil_card/integrations/langchain.py +58 -0
- eil_card-0.1.1/eil_card/integrations/llamaindex.py +250 -0
- eil_card-0.1.1/eil_card/jws.py +153 -0
- eil_card-0.1.1/eil_card/tool_schema.py +72 -0
- eil_card-0.1.1/eil_card/types.py +53 -0
- eil_card-0.1.1/pyproject.toml +48 -0
- eil_card-0.1.1/tests/test_client.py +131 -0
- eil_card-0.1.1/tests/test_jws.py +34 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
node_modules/
|
|
2
|
+
dist/
|
|
3
|
+
__pycache__/
|
|
4
|
+
*.py[cod]
|
|
5
|
+
.next/
|
|
6
|
+
.env
|
|
7
|
+
.env.local
|
|
8
|
+
.env.production
|
|
9
|
+
.env.prod
|
|
10
|
+
*.tsbuildinfo
|
|
11
|
+
drizzle/meta/
|
|
12
|
+
.DS_Store
|
|
13
|
+
Thumbs.db
|
|
14
|
+
|
|
15
|
+
# Internal planning — keep local, do not publish
|
|
16
|
+
digital.md
|
|
17
|
+
saha-analizi.md
|
|
18
|
+
is-plani.md
|
|
19
|
+
faz.md
|
|
20
|
+
pilot-sektor.md
|
|
21
|
+
teknik-stack.md
|
|
22
|
+
.cursor/*
|
|
23
|
+
!.cursor/rules/
|
|
24
|
+
!.cursor/rules/**
|
|
25
|
+
schema/examples/organization.sinyalle.json
|
eil_card-0.1.1/PKG-INFO
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: eil-card
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: EIL Card Python SDK — resolve verified entity identity for AI agents
|
|
5
|
+
Project-URL: Homepage, https://eilcard.com
|
|
6
|
+
Project-URL: Documentation, https://eilcard.com/docs/agents
|
|
7
|
+
Project-URL: Repository, https://github.com/Mendocan/eilcard
|
|
8
|
+
Project-URL: Issues, https://github.com/Mendocan/eilcard/issues
|
|
9
|
+
Author: EIL Card
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
Keywords: agents,crewai,digital-card,eil,entity-identity,langchain
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: requests>=2.31
|
|
23
|
+
Provides-Extra: all
|
|
24
|
+
Requires-Dist: crewai>=0.80; extra == 'all'
|
|
25
|
+
Requires-Dist: langchain-core>=0.3; extra == 'all'
|
|
26
|
+
Requires-Dist: llama-index-core>=0.11; extra == 'all'
|
|
27
|
+
Provides-Extra: crewai
|
|
28
|
+
Requires-Dist: crewai>=0.80; extra == 'crewai'
|
|
29
|
+
Provides-Extra: crypto
|
|
30
|
+
Requires-Dist: cryptography>=42; extra == 'crypto'
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
33
|
+
Requires-Dist: responses>=0.25; extra == 'dev'
|
|
34
|
+
Provides-Extra: langchain
|
|
35
|
+
Requires-Dist: langchain-core>=0.3; extra == 'langchain'
|
|
36
|
+
Provides-Extra: llamaindex
|
|
37
|
+
Requires-Dist: llama-index-core>=0.11; extra == 'llamaindex'
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# EIL Card Python SDK (`eil-card`)
|
|
41
|
+
|
|
42
|
+
Resolve verified organization and person identity from the EIL Card registry — with LangChain, CrewAI, and LlamaIndex integrations.
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install eil-card
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Optional framework extras:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install eil-card[langchain]
|
|
54
|
+
pip install eil-card[llamaindex]
|
|
55
|
+
pip install eil-card[crewai]
|
|
56
|
+
pip install eil-card[all]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Quick start
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from eil_card import DigitalCard, discover_capabilities, discover_act_capabilities
|
|
63
|
+
|
|
64
|
+
result = DigitalCard.resolve(domain="sinyalle.com")
|
|
65
|
+
card = result["card"]
|
|
66
|
+
print(card["name"]["official"], card.get("verified"))
|
|
67
|
+
|
|
68
|
+
caps = discover_capabilities(card)
|
|
69
|
+
if caps["available"]:
|
|
70
|
+
print("Gateway:", caps["agent_gateway"])
|
|
71
|
+
|
|
72
|
+
act = discover_act_capabilities(card)
|
|
73
|
+
print("Write/act scopes:", act["scopes_parsed"]["write"], act["scopes_parsed"]["act"])
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## LangChain
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from eil_card.integrations.langchain import create_eil_resolve_tool
|
|
80
|
+
|
|
81
|
+
tool = create_eil_resolve_tool()
|
|
82
|
+
# tools = [tool]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Tool name matches the TypeScript SDK: `resolve_entity_identity`.
|
|
86
|
+
|
|
87
|
+
## CrewAI
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from crewai import Agent
|
|
91
|
+
from eil_card.integrations.crewai import create_eil_resolve_crewai_tool
|
|
92
|
+
|
|
93
|
+
resolve_tool = create_eil_resolve_crewai_tool()
|
|
94
|
+
agent = Agent(role="Researcher", goal="Verify entities", tools=[resolve_tool])
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## LlamaIndex
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from eil_card.integrations.llamaindex import EILReader
|
|
101
|
+
|
|
102
|
+
docs = EILReader().load_data(domain="sinyalle.com")
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## JWS trust (Registry+)
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from eil_card import DigitalCard
|
|
109
|
+
|
|
110
|
+
result = DigitalCard.resolve(domain="sinyalle.com", verify_jws=True)
|
|
111
|
+
print(result.get("trust", {}).get("jws"))
|
|
112
|
+
|
|
113
|
+
# Crypto verify: pip install eil-card[crypto]
|
|
114
|
+
result = DigitalCard.resolve(
|
|
115
|
+
domain="sinyalle.com",
|
|
116
|
+
verify_jws={"public_key_pem": open("registry-public.pem").read(), "require_valid": True},
|
|
117
|
+
)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Agent act headers (pilot gateway)
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from eil_card import build_idempotency_key, build_agent_act_headers, agent_act_headers_to_fetch
|
|
124
|
+
|
|
125
|
+
key = build_idempotency_key(
|
|
126
|
+
agent_client_id="my-agent",
|
|
127
|
+
action_id="create_post",
|
|
128
|
+
entity_id="sinyalle.com",
|
|
129
|
+
nonce="run-1",
|
|
130
|
+
)
|
|
131
|
+
headers = agent_act_headers_to_fetch(
|
|
132
|
+
build_agent_act_headers(
|
|
133
|
+
access_token="...",
|
|
134
|
+
idempotency_key=key,
|
|
135
|
+
action_id="create_post",
|
|
136
|
+
card_id="sinyalle.com",
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Development
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
cd packages/python
|
|
145
|
+
pip install -e ".[dev]"
|
|
146
|
+
pytest
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Publish (maintainers)
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
pip install build twine
|
|
153
|
+
python -m build
|
|
154
|
+
twine upload dist/*
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Set `PYPI_API_TOKEN` in the environment or `~/.pypirc`.
|
|
158
|
+
|
|
159
|
+
## Docs
|
|
160
|
+
|
|
161
|
+
- https://eilcard.com/docs/agents
|
|
162
|
+
- TypeScript SDK parity: `packages/sdk/SDK.md`
|
eil_card-0.1.1/README.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# EIL Card Python SDK (`eil-card`)
|
|
2
|
+
|
|
3
|
+
Resolve verified organization and person identity from the EIL Card registry — with LangChain, CrewAI, and LlamaIndex integrations.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install eil-card
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Optional framework extras:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install eil-card[langchain]
|
|
15
|
+
pip install eil-card[llamaindex]
|
|
16
|
+
pip install eil-card[crewai]
|
|
17
|
+
pip install eil-card[all]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from eil_card import DigitalCard, discover_capabilities, discover_act_capabilities
|
|
24
|
+
|
|
25
|
+
result = DigitalCard.resolve(domain="sinyalle.com")
|
|
26
|
+
card = result["card"]
|
|
27
|
+
print(card["name"]["official"], card.get("verified"))
|
|
28
|
+
|
|
29
|
+
caps = discover_capabilities(card)
|
|
30
|
+
if caps["available"]:
|
|
31
|
+
print("Gateway:", caps["agent_gateway"])
|
|
32
|
+
|
|
33
|
+
act = discover_act_capabilities(card)
|
|
34
|
+
print("Write/act scopes:", act["scopes_parsed"]["write"], act["scopes_parsed"]["act"])
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## LangChain
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from eil_card.integrations.langchain import create_eil_resolve_tool
|
|
41
|
+
|
|
42
|
+
tool = create_eil_resolve_tool()
|
|
43
|
+
# tools = [tool]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Tool name matches the TypeScript SDK: `resolve_entity_identity`.
|
|
47
|
+
|
|
48
|
+
## CrewAI
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from crewai import Agent
|
|
52
|
+
from eil_card.integrations.crewai import create_eil_resolve_crewai_tool
|
|
53
|
+
|
|
54
|
+
resolve_tool = create_eil_resolve_crewai_tool()
|
|
55
|
+
agent = Agent(role="Researcher", goal="Verify entities", tools=[resolve_tool])
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## LlamaIndex
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from eil_card.integrations.llamaindex import EILReader
|
|
62
|
+
|
|
63
|
+
docs = EILReader().load_data(domain="sinyalle.com")
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## JWS trust (Registry+)
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from eil_card import DigitalCard
|
|
70
|
+
|
|
71
|
+
result = DigitalCard.resolve(domain="sinyalle.com", verify_jws=True)
|
|
72
|
+
print(result.get("trust", {}).get("jws"))
|
|
73
|
+
|
|
74
|
+
# Crypto verify: pip install eil-card[crypto]
|
|
75
|
+
result = DigitalCard.resolve(
|
|
76
|
+
domain="sinyalle.com",
|
|
77
|
+
verify_jws={"public_key_pem": open("registry-public.pem").read(), "require_valid": True},
|
|
78
|
+
)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Agent act headers (pilot gateway)
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from eil_card import build_idempotency_key, build_agent_act_headers, agent_act_headers_to_fetch
|
|
85
|
+
|
|
86
|
+
key = build_idempotency_key(
|
|
87
|
+
agent_client_id="my-agent",
|
|
88
|
+
action_id="create_post",
|
|
89
|
+
entity_id="sinyalle.com",
|
|
90
|
+
nonce="run-1",
|
|
91
|
+
)
|
|
92
|
+
headers = agent_act_headers_to_fetch(
|
|
93
|
+
build_agent_act_headers(
|
|
94
|
+
access_token="...",
|
|
95
|
+
idempotency_key=key,
|
|
96
|
+
action_id="create_post",
|
|
97
|
+
card_id="sinyalle.com",
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Development
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
cd packages/python
|
|
106
|
+
pip install -e ".[dev]"
|
|
107
|
+
pytest
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Publish (maintainers)
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
pip install build twine
|
|
114
|
+
python -m build
|
|
115
|
+
twine upload dist/*
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Set `PYPI_API_TOKEN` in the environment or `~/.pypirc`.
|
|
119
|
+
|
|
120
|
+
## Docs
|
|
121
|
+
|
|
122
|
+
- https://eilcard.com/docs/agents
|
|
123
|
+
- TypeScript SDK parity: `packages/sdk/SDK.md`
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""EIL Card Python SDK — resolve verified entity identity for AI agents."""
|
|
2
|
+
|
|
3
|
+
from eil_card.act import (
|
|
4
|
+
agent_act_headers_to_fetch,
|
|
5
|
+
build_agent_act_headers,
|
|
6
|
+
build_idempotency_key,
|
|
7
|
+
discover_act_capabilities,
|
|
8
|
+
parse_capability_scopes,
|
|
9
|
+
)
|
|
10
|
+
from eil_card.agent_tool import (
|
|
11
|
+
format_resolve_tool_error,
|
|
12
|
+
format_resolve_tool_result,
|
|
13
|
+
invoke_eil_resolve,
|
|
14
|
+
invoke_eil_resolve_async,
|
|
15
|
+
)
|
|
16
|
+
from eil_card.capabilities import discover_capabilities
|
|
17
|
+
from eil_card.client import DigitalCard, DigitalCardClient, normalize_domain
|
|
18
|
+
from eil_card.errors import (
|
|
19
|
+
CardNotFoundError,
|
|
20
|
+
DigitalCardError,
|
|
21
|
+
InvalidResolveInputError,
|
|
22
|
+
JwsVerificationError,
|
|
23
|
+
RegistryError,
|
|
24
|
+
SchemaValidationError,
|
|
25
|
+
)
|
|
26
|
+
from eil_card.jws import canonical_card_without_signatures, verify_registry_jws
|
|
27
|
+
from eil_card.tool_schema import (
|
|
28
|
+
EIL_RESOLVE_TOOL_DESCRIPTION,
|
|
29
|
+
EIL_RESOLVE_TOOL_NAME,
|
|
30
|
+
build_eil_resolve_tool_definitions,
|
|
31
|
+
build_resolve_input_json_schema,
|
|
32
|
+
)
|
|
33
|
+
from eil_card.types import SCHEMA_VERSION
|
|
34
|
+
|
|
35
|
+
__all__ = [
|
|
36
|
+
"SCHEMA_VERSION",
|
|
37
|
+
"DigitalCard",
|
|
38
|
+
"DigitalCardClient",
|
|
39
|
+
"normalize_domain",
|
|
40
|
+
"discover_capabilities",
|
|
41
|
+
"discover_act_capabilities",
|
|
42
|
+
"parse_capability_scopes",
|
|
43
|
+
"build_idempotency_key",
|
|
44
|
+
"build_agent_act_headers",
|
|
45
|
+
"agent_act_headers_to_fetch",
|
|
46
|
+
"invoke_eil_resolve",
|
|
47
|
+
"invoke_eil_resolve_async",
|
|
48
|
+
"format_resolve_tool_result",
|
|
49
|
+
"format_resolve_tool_error",
|
|
50
|
+
"EIL_RESOLVE_TOOL_NAME",
|
|
51
|
+
"EIL_RESOLVE_TOOL_DESCRIPTION",
|
|
52
|
+
"build_resolve_input_json_schema",
|
|
53
|
+
"build_eil_resolve_tool_definitions",
|
|
54
|
+
"DigitalCardError",
|
|
55
|
+
"CardNotFoundError",
|
|
56
|
+
"InvalidResolveInputError",
|
|
57
|
+
"JwsVerificationError",
|
|
58
|
+
"RegistryError",
|
|
59
|
+
"SchemaValidationError",
|
|
60
|
+
"canonical_card_without_signatures",
|
|
61
|
+
"verify_registry_jws",
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
__version__ = "0.1.1"
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from eil_card.capabilities import discover_capabilities
|
|
7
|
+
from eil_card.types import DiscoveredActCapabilities, ParsedCapabilityScopes
|
|
8
|
+
|
|
9
|
+
_SCOPE_KIND_PATTERN = re.compile(r"^(read|write|act):")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def parse_capability_scopes(scopes: list[str] | None = None) -> ParsedCapabilityScopes:
|
|
13
|
+
result: ParsedCapabilityScopes = {
|
|
14
|
+
"read": [],
|
|
15
|
+
"write": [],
|
|
16
|
+
"act": [],
|
|
17
|
+
"unknown": [],
|
|
18
|
+
"all": list(scopes) if scopes else [],
|
|
19
|
+
}
|
|
20
|
+
if not scopes:
|
|
21
|
+
return result
|
|
22
|
+
|
|
23
|
+
for scope in scopes:
|
|
24
|
+
if scope.startswith("read:"):
|
|
25
|
+
result["read"].append(scope)
|
|
26
|
+
elif scope.startswith("write:"):
|
|
27
|
+
result["write"].append(scope)
|
|
28
|
+
elif scope.startswith("act:"):
|
|
29
|
+
result["act"].append(scope)
|
|
30
|
+
elif _SCOPE_KIND_PATTERN.match(scope):
|
|
31
|
+
result["unknown"].append(scope)
|
|
32
|
+
else:
|
|
33
|
+
result["unknown"].append(scope)
|
|
34
|
+
|
|
35
|
+
return result
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def discover_act_capabilities(card: dict[str, Any]) -> DiscoveredActCapabilities:
|
|
39
|
+
base = discover_capabilities(card)
|
|
40
|
+
scopes_parsed = parse_capability_scopes(base.get("scopes"))
|
|
41
|
+
actions = (card.get("capabilities") or {}).get("actions")
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
**base,
|
|
45
|
+
"scopes_parsed": scopes_parsed,
|
|
46
|
+
"actions": actions,
|
|
47
|
+
"has_write_or_act": bool(
|
|
48
|
+
scopes_parsed["write"] or scopes_parsed["act"] or (actions or [])
|
|
49
|
+
),
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def build_idempotency_key(
|
|
54
|
+
*,
|
|
55
|
+
agent_client_id: str,
|
|
56
|
+
action_id: str,
|
|
57
|
+
entity_id: str,
|
|
58
|
+
nonce: str,
|
|
59
|
+
) -> str:
|
|
60
|
+
def slug(value: str) -> str:
|
|
61
|
+
out = value.strip().lower()
|
|
62
|
+
out = re.sub(r"[^a-z0-9._-]+", "-", out)
|
|
63
|
+
out = re.sub(r"-+", "-", out)
|
|
64
|
+
return out.strip("-")
|
|
65
|
+
|
|
66
|
+
return "/".join(
|
|
67
|
+
[
|
|
68
|
+
"eil-act",
|
|
69
|
+
slug(agent_client_id),
|
|
70
|
+
slug(action_id),
|
|
71
|
+
slug(entity_id),
|
|
72
|
+
slug(nonce),
|
|
73
|
+
]
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def build_agent_act_headers(
|
|
78
|
+
*,
|
|
79
|
+
access_token: str,
|
|
80
|
+
idempotency_key: str,
|
|
81
|
+
action_id: str,
|
|
82
|
+
card_id: str,
|
|
83
|
+
) -> dict[str, str]:
|
|
84
|
+
return {
|
|
85
|
+
"authorization": f"Bearer {access_token}",
|
|
86
|
+
"idempotency_key": idempotency_key,
|
|
87
|
+
"action_id": action_id,
|
|
88
|
+
"card_id": card_id,
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def agent_act_headers_to_fetch(headers: dict[str, str]) -> dict[str, str]:
|
|
93
|
+
return {
|
|
94
|
+
"Authorization": headers["authorization"],
|
|
95
|
+
"Idempotency-Key": headers["idempotency_key"],
|
|
96
|
+
"X-EIL-Action-Id": headers["action_id"],
|
|
97
|
+
"X-EIL-Card-Id": headers["card_id"],
|
|
98
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from eil_card.client import DigitalCard, DigitalCardClient
|
|
7
|
+
from eil_card.errors import InvalidResolveInputError
|
|
8
|
+
from eil_card.tool_schema import EIL_RESOLVE_TOOL_DESCRIPTION, EIL_RESOLVE_TOOL_NAME
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
async def invoke_eil_resolve_async(
|
|
12
|
+
*,
|
|
13
|
+
domain: str | None = None,
|
|
14
|
+
handle: str | None = None,
|
|
15
|
+
registry_base_url: str = "https://eilcard.com",
|
|
16
|
+
api_key: str | None = None,
|
|
17
|
+
timeout: float = 10.0,
|
|
18
|
+
skip_well_known_fallback: bool = False,
|
|
19
|
+
) -> dict[str, Any]:
|
|
20
|
+
"""Async wrapper — runs sync resolve in thread pool if needed by frameworks."""
|
|
21
|
+
return invoke_eil_resolve(
|
|
22
|
+
domain=domain,
|
|
23
|
+
handle=handle,
|
|
24
|
+
registry_base_url=registry_base_url,
|
|
25
|
+
api_key=api_key,
|
|
26
|
+
timeout=timeout,
|
|
27
|
+
skip_well_known_fallback=skip_well_known_fallback,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def invoke_eil_resolve(
|
|
32
|
+
*,
|
|
33
|
+
domain: str | None = None,
|
|
34
|
+
handle: str | None = None,
|
|
35
|
+
registry_base_url: str = "https://eilcard.com",
|
|
36
|
+
api_key: str | None = None,
|
|
37
|
+
timeout: float = 10.0,
|
|
38
|
+
skip_well_known_fallback: bool = False,
|
|
39
|
+
) -> dict[str, Any]:
|
|
40
|
+
"""Framework-agnostic handler for tool-calling agents."""
|
|
41
|
+
client = DigitalCardClient(
|
|
42
|
+
registry_base_url=registry_base_url,
|
|
43
|
+
api_key=api_key,
|
|
44
|
+
timeout=timeout,
|
|
45
|
+
skip_well_known_fallback=skip_well_known_fallback,
|
|
46
|
+
)
|
|
47
|
+
if domain:
|
|
48
|
+
return client.resolve(domain=domain)
|
|
49
|
+
if handle:
|
|
50
|
+
return client.resolve(handle=handle)
|
|
51
|
+
raise InvalidResolveInputError()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def format_resolve_tool_result(result: dict[str, Any]) -> str:
|
|
55
|
+
return json.dumps(result, indent=2, ensure_ascii=False)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def format_resolve_tool_error(entity: str, error: Exception | str) -> str:
|
|
59
|
+
message = str(error)
|
|
60
|
+
return f"Could not resolve EIL identity for {entity}: {message}"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from eil_card.types import DiscoveredCapabilities
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def discover_capabilities(card: dict[str, Any]) -> DiscoveredCapabilities:
|
|
9
|
+
"""Read capability manifest from a resolved card (Registry+ only)."""
|
|
10
|
+
edition = card.get("edition") or "core"
|
|
11
|
+
|
|
12
|
+
if edition != "registry_plus":
|
|
13
|
+
return {
|
|
14
|
+
"available": False,
|
|
15
|
+
"edition": edition,
|
|
16
|
+
"reason": "Capabilities require Registry+ edition (schema 1.2)",
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
caps = card.get("capabilities")
|
|
20
|
+
if not caps:
|
|
21
|
+
return {
|
|
22
|
+
"available": False,
|
|
23
|
+
"edition": edition,
|
|
24
|
+
"reason": "No capabilities object on card",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if not caps.get("agent_gateway"):
|
|
28
|
+
return {
|
|
29
|
+
"available": False,
|
|
30
|
+
"edition": edition,
|
|
31
|
+
"auth": caps.get("auth"),
|
|
32
|
+
"scopes": caps.get("scopes"),
|
|
33
|
+
"reason": "capabilities.agent_gateway is not set",
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
"available": True,
|
|
38
|
+
"edition": edition,
|
|
39
|
+
"agent_gateway": caps["agent_gateway"],
|
|
40
|
+
"auth": caps.get("auth"),
|
|
41
|
+
"scopes": caps.get("scopes"),
|
|
42
|
+
}
|