├── anp
├── utils
│ ├── __init__.py
│ ├── llm
│ │ └── __init__.py
│ ├── llm_output_processer.py
│ ├── log_base.py
│ ├── did_verify.py
│ └── did_generate.py
├── anp_crawler
│ ├── test
│ │ ├── __init__.py
│ │ ├── run_tests.py
│ │ ├── test_data_agent_description.json
│ │ └── README.md
│ ├── __init__.py
│ ├── README.cn.md
│ ├── README.md
│ ├── Interface.md
│ ├── API_IMPROVEMENTS.md
│ └── API_PROPOSAL.md
├── node
│ └── __init__.py
├── meta_protocol
│ ├── code_generator
│ │ └── __init__.py
│ └── __init__.py
├── e2e_encryption
│ └── __init__.py
├── __init__.py
├── fastanp
│ ├── __init__.py
│ ├── ad_generator.py
│ ├── TEST_REPORT.md
│ ├── test_agent_domain_normalization.py
│ └── middleware.py
├── authentication
│ └── __init__.py
└── ap2
│ ├── __init__.py
│ ├── cart_mandate.py
│ └── payment_mandate.py
├── golang
├── go.mod
├── README.cn.md
└── README.md
├── examples
└── python
│ ├── ap2_examples
│ ├── __init__.py
│ ├── README.cn.md
│ └── README.md
│ ├── minimal_example
│ ├── __init__.py
│ ├── README.md
│ ├── minimal_anp_client.py
│ ├── minimal_two_nodes.py
│ └── minimal_anp_node.py
│ ├── did_wba_examples
│ ├── generated
│ │ ├── key-1_public.pem
│ │ ├── key-1_private.pem
│ │ └── did.json
│ ├── create_did_document.py
│ ├── README.md
│ ├── authenticate_and_verify.py
│ ├── validate_did_document.py
│ └── README.cn.md
│ ├── fastanp_examples
│ ├── test_simple.sh
│ ├── test_examples.sh
│ ├── simple_agent.py
│ ├── config_example.py
│ └── simple_agent_with_context.py
│ ├── negotiation_mode
│ └── config.py
│ └── anp_crawler_examples
│ ├── simple_amap_example.py
│ ├── README.cn.md
│ └── README.md
├── images
├── agentic-web.png
├── protocol-layer-design.png
├── agent-connect-architecture.png
└── agentic-web-new.svg
├── .claude
└── settings.local.json
├── tools
└── did_generater
│ ├── user_public
│ ├── private_keys.json
│ ├── key-1_private.pem
│ └── did.json
│ ├── user_yanlq
│ ├── key-1_private.pem
│ ├── private_keys.json
│ └── did.json
│ ├── README_did_generater_cn.md
│ └── README_did_generater.md
├── docs
├── did_public
│ ├── public-private-key.pem
│ └── public-did-doc.json
└── jwt_rs256
│ ├── RS256-public.pem
│ ├── public_key.pem
│ ├── RS256-private.pem
│ └── private_key.pem
├── .env.example
├── java
├── src
│ ├── main
│ │ ├── resources
│ │ │ └── logback.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── agentconnect
│ │ │ ├── utils
│ │ │ ├── package-info.java
│ │ │ ├── LLMOutputProcessor.java
│ │ │ ├── LogBase.java
│ │ │ └── DIDVerifier.java
│ │ │ └── authentication
│ │ │ ├── package-info.java
│ │ │ ├── VerificationMethod.java
│ │ │ └── Ed25519VerificationKey2018.java
│ └── test
│ │ └── java
│ │ └── com
│ │ └── agentconnect
│ │ └── test
│ │ ├── example
│ │ ├── DidWbaDocumentCreator.java
│ │ ├── FileUtils.java
│ │ └── JsonUtils.java
│ │ ├── DidAllTest.java
│ │ ├── DidWbaTest.java
│ │ └── DIDWBAUnitTest.java
├── README.cn.md
├── README.md
└── pom.xml
├── .gitignore
├── CONTRIBUTING.cn.md
├── pyproject.toml
├── CONTRIBUTING.md
├── AGENTS.md
└── README.cn.md
/anp/utils/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/anp/utils/llm/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/anp/anp_crawler/test/__init__.py:
--------------------------------------------------------------------------------
1 | # Test package
--------------------------------------------------------------------------------
/golang/go.mod:
--------------------------------------------------------------------------------
1 | module anp/agentconnect
2 |
3 | go 1.23.8
--------------------------------------------------------------------------------
/examples/python/ap2_examples/__init__.py:
--------------------------------------------------------------------------------
1 | """AP2 Protocol Examples."""
2 |
--------------------------------------------------------------------------------
/examples/python/minimal_example/__init__.py:
--------------------------------------------------------------------------------
1 | # Minimal ANP Example
2 |
3 |
--------------------------------------------------------------------------------
/images/agentic-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agent-network-protocol/anp/HEAD/images/agentic-web.png
--------------------------------------------------------------------------------
/anp/node/__init__.py:
--------------------------------------------------------------------------------
1 | """ANP node package."""
2 |
3 | from .node import ANPNode
4 |
5 | __all__ = ["ANPNode"]
6 |
7 |
--------------------------------------------------------------------------------
/images/protocol-layer-design.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agent-network-protocol/anp/HEAD/images/protocol-layer-design.png
--------------------------------------------------------------------------------
/images/agent-connect-architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agent-network-protocol/anp/HEAD/images/agent-connect-architecture.png
--------------------------------------------------------------------------------
/anp/meta_protocol/code_generator/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/anp/e2e_encryption/__init__.py:
--------------------------------------------------------------------------------
1 | from .wss_message_sdk import WssMessageSDK
2 |
3 | # Define what should be exported when using "from anp.e2e_encryption import *"
4 | __all__ = ['WssMessageSDK']
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.claude/settings.local.json:
--------------------------------------------------------------------------------
1 | {
2 | "permissions": {
3 | "allow": [
4 | "Bash(uv run:*)",
5 | "Bash(source:*)",
6 | "Bash(python:*)"
7 | ],
8 | "deny": [],
9 | "ask": []
10 | }
11 | }
--------------------------------------------------------------------------------
/anp/meta_protocol/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from .meta_protocol import MetaProtocol, ProtocolType
4 |
5 | __all__ = ['MetaProtocol', 'ProtocolType']
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/examples/python/did_wba_examples/generated/key-1_public.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEsuqRsY9MrIWrMl1ip8y4aWGgExgMYy2D
3 | a1dMqPFl3GgRCYi2WlV9L1MLidFcUSkX88/QL9sgEIZ0T3Kib57BPA==
4 | -----END PUBLIC KEY-----
5 |
--------------------------------------------------------------------------------
/tools/did_generater/user_public/private_keys.json:
--------------------------------------------------------------------------------
1 | {
2 | "did": "did:wba:didhost.cc:test:public",
3 | "created_at": "2025-07-16T11:10:30.890378",
4 | "keys": {
5 | "key-1": {
6 | "path": "key-1_private.pem",
7 | "type": "EcdsaSecp256k1"
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/docs/did_public/public-private-key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgMd0Zh3TA+KzOh+aL5g76
3 | sz34ULdhjGkv4NEYnoGe7nehRANCAATdCEe0gD06s/KzsiH4LvKmf/CjSFRFImx+
4 | 2I7QicZfdgDNy1WviB7MCCXTKuvql2BOuPeeOVTUwL82p+gzP4wj
5 | -----END PRIVATE KEY-----
6 |
--------------------------------------------------------------------------------
/tools/did_generater/user_public/key-1_private.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgKQjwMzbrZi8ehpOMxdrs
3 | Bw2/5+sE3hO7a0dyufq7mfShRANCAATmwZrQL5CLlxMh9kuo+ydPCxovSNNu6Sh0
4 | pMOwvpA/mpzyptqMs53uHfeQ2K+RcfTM149EUCG85tlSma5MFe+N
5 | -----END PRIVATE KEY-----
6 |
--------------------------------------------------------------------------------
/tools/did_generater/user_yanlq/key-1_private.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgMztmzZyUIEskwIUYpBMj
3 | gmZqRRF4XwZ4pKW+WstRFuWhRANCAAS6733j3RSZhvYzJx983FokoBeBRTlknUBD
4 | 2xAZdetyHXiEhFhEcjyrtKz+7ihZS6Ij8FOx36iE1KkjkViJMLd0
5 | -----END PRIVATE KEY-----
6 |
--------------------------------------------------------------------------------
/examples/python/did_wba_examples/generated/key-1_private.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgyLh0m5iesgb7ZspvYric
3 | e88OoeXVIKluvfutYj8U7zChRANCAASy6pGxj0yshasyXWKnzLhpYaATGAxjLYNr
4 | V0yo8WXcaBEJiLZaVX0vUwuJ0VxRKRfzz9Av2yAQhnRPcqJvnsE8
5 | -----END PRIVATE KEY-----
6 |
--------------------------------------------------------------------------------
/tools/did_generater/user_yanlq/private_keys.json:
--------------------------------------------------------------------------------
1 | {
2 | "did": "did:wba:service.agent-network-protocol.com:wba:user:yanlq",
3 | "created_at": "2025-05-25T16:52:42.380624",
4 | "keys": {
5 | "key-1": {
6 | "path": "key-1_private.pem",
7 | "type": "EcdsaSecp256k1"
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | # Azure OpenAI Configuration
2 | # Copy this file to .env and fill in your actual values.
3 |
4 | # AZURE_OPENAI_API_KEY=YOUR_AZURE_OPENAI_API_KEY
5 | # AZURE_OPENAI_ENDPOINT=YOUR_AZURE_OPENAI_ENDPOINT
6 | # AZURE_OPENAI_API_VERSION=2024-02-01
7 | # # gpt-4o or gpt4o-mini
8 | # AZURE_OPENAI_DEPLOYMENT=gpt-4o
9 | # # gpt-4o or gpt-4o-mini
10 | # AZURE_OPENAI_MODEL_NAME=gpt-4o
--------------------------------------------------------------------------------
/golang/README.cn.md:
--------------------------------------------------------------------------------
1 | # AgentConnect4Golang
2 |
3 | 这是Python AgentConnect代码库的golang实现版本。它可以提供了DID(去中心化标识符)生成、身份验证和加密操作等功能。
4 |
5 | ⭐️⭐️⭐️相关代码正在积极整理中,稍后推出,敬请期待.⭐️⭐️⭐️
6 |
7 |
8 | ## 构建项目
9 |
10 | 本项目使用go mod进行依赖管理。构建项目的命令:
11 |
12 | ```bash
13 | go mod tidy
14 | ```
15 |
16 |
17 | ## 许可证
18 |
19 | 本项目基于MIT许可证开源。
20 |
21 | ## 作者
22 |
23 | 原始Python实现:GaoWei Chang (chgaowei@gmail.com)。
24 | Golang实现:临沂市人工智能协会 (lysrgznxh@9885.net)。
--------------------------------------------------------------------------------
/anp/__init__.py:
--------------------------------------------------------------------------------
1 | # ANP Crawler
2 | from .anp_crawler.anp_client import ANPClient
3 |
4 | # e2e encryption
5 | # from .e2e_encryption.wss_message_sdk import WssMessageSDK
6 |
7 | # interfaces
8 | # from .authentication import didallclient
9 |
10 | # simple node
11 | # from .simple_node import simple_node
12 |
13 | # Define what should be exported when using "from anp import *"
14 | __all__ = ['ANPClient', 'simple_node', 'didallclient']
15 |
16 |
--------------------------------------------------------------------------------
/java/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | %d{yyyy-MM-dd HH:mm:ss} [%thread] %highlight(%-5level) %logger{36} - %msg%n
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/docs/jwt_rs256/RS256-public.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt02UXEUZVtuxV2HHz2A+
3 | 9AKeRz++eXAuXvwE/AnHLdS92IjDc/TVzyhKYU5aODzvzq3w62v65HTuZTpYozov
4 | nP+NGvERJCKpc2zDvlIPTGyrUFUOezO6NUZ3mISBpcfGewe0BKV4rMZb+zWii1zn
5 | umKRIizFAvXpgEs7cdRFIOuTS0+eyWuMbXhHJlr9iD8gcjX3PEiv1PrEB+N8KuO7
6 | hIly6ntvXCAZs/OQXVg3+Bq2BzXTjEpISGpD1CKwqlUpdhvDoWUl7zH7K4WOvFo7
7 | W1Pf2Y9Sz8srUw215q8wzez1LTcNr05bURnKCg4751J10ICeYtM6n7i6+TZOCtme
8 | aQIDAQAB
9 | -----END PUBLIC KEY-----
10 |
--------------------------------------------------------------------------------
/docs/jwt_rs256/public_key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv7krVbnKrHrRi8VNItyU
3 | S7EjfIVzJ8klLGjeDxgrYDsNL6EDkCDAnND3zU50Qp2J6giZj7IVDwpD/P1Pua6g
4 | xjhYn/3Ygsp8hvXjuypHJDyI6Ovnt/OYAmcxzE4jnzcrfjzzYv9tDNSSAblIeORT
5 | l//KRCOWBqxRO/yrzFK5LaYUslilB7yZFtYE2iUtAtRskXJawsv3wnX8Wx2BcroE
6 | Wrl8WKE57ZX+/g+wzDD0xuBk24ofTnqx2I0WTSovb0oHn6lD5yHd8bvhDM97CPHJ
7 | +56Ej2mS905jwYvucAR4Qdxr5awJANZvSXcYWS2vTFOer2MYD7KYsS/yQokGk2Yz
8 | FQIDAQAB
9 | -----END PUBLIC KEY-----
10 |
--------------------------------------------------------------------------------
/java/src/main/java/com/agentconnect/utils/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * AgentConnect: https://github.com/agent-network-protocol/AgentConnect
3 | * Original Author: GaoWei Chang
4 | * Email: chgaowei@gmail.com
5 | * Website: https://agent-network-protocol.com/
6 | *
7 | * This project is open-sourced under the MIT License.
8 | *
9 | * This package contains utility classes for cryptographic operations, DID generation, verification,
10 | * logging, and other helper functions used by the AgentConnect codebase.
11 | */
12 | package com.agentconnect.utils;
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist/
2 | .env
3 | __pycache__/
4 | *.pyc
5 | *.pyo
6 | *.venv
7 | examples/*.json
8 | *.egg-info/
9 | build/
10 | examples/python/negotiation_mode/workflow_code/
11 | examples/python/negotiation_mode/protocol_code/
12 | examples/negotiation_mode/*.json
13 | examples/simple_node_mode/*.json
14 | examples/python/did_wba_examples/did_keys/user_*/
15 | anp/java/src/test/resources/*
16 | anp/java/*
17 | .idea
18 | examples/did_wba_examples/did_keys/*
19 | examples/negotiation_mode/*
20 | .claude/
21 | .claude/settings.local.json
22 | uv.lock
23 | .DS_Store
24 |
--------------------------------------------------------------------------------
/java/src/main/java/com/agentconnect/authentication/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * AgentConnect: https://github.com/agent-network-protocol/AgentConnect
3 | * Original Author: GaoWei Chang
4 | * Email: chgaowei@gmail.com
5 | * Website: https://agent-network-protocol.com/
6 | *
7 | * This project is open-sourced under the MIT License.
8 | *
9 | * This package contains classes for DID (Decentralized Identifier) based authentication
10 | * including DID document creation, resolution, and authentication header generation and verification.
11 | */
12 | package com.agentconnect.authentication;
--------------------------------------------------------------------------------
/anp/anp_crawler/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | ANP Crawler package public API exports.
3 |
4 | Import from this package to access the core crawler components:
5 |
6 | from anp.anp_crawler import (
7 | ANPCrawler,
8 | ANPClient,
9 | ANPInterface,
10 | ANPInterfaceConverter,
11 | ANPDocumentParser,
12 | )
13 | """
14 |
15 | from .anp_client import ANPClient
16 | from .anp_crawler import ANPCrawler
17 | from .anp_interface import ANPInterface, ANPInterfaceConverter
18 | from .anp_parser import ANPDocumentParser
19 |
20 | __all__ = [
21 | "ANPCrawler",
22 | "ANPClient",
23 | "ANPInterface",
24 | "ANPInterfaceConverter",
25 | "ANPDocumentParser",
26 | ]
27 |
28 |
29 |
--------------------------------------------------------------------------------
/anp/fastanp/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | FastANP - Fast Agent Network Protocol framework.
3 |
4 | A plugin-based framework for building ANP-compliant agents with FastAPI.
5 | """
6 |
7 | from .context import Context, Session, SessionManager
8 | from .fastanp import FastANP
9 | from .models import (
10 | AgentDescription,
11 | InformationItem,
12 | InterfaceItem,
13 | OpenRPCDocument,
14 | Owner,
15 | Proof,
16 | SecurityDefinition,
17 | )
18 |
19 | __version__ = "0.2.0"
20 |
21 | __all__ = [
22 | "FastANP",
23 | "Context",
24 | "Session",
25 | "SessionManager",
26 | "AgentDescription",
27 | "InformationItem",
28 | "InterfaceItem",
29 | "OpenRPCDocument",
30 | "Owner",
31 | "Proof",
32 | "SecurityDefinition",
33 | ]
34 |
35 |
--------------------------------------------------------------------------------
/golang/README.md:
--------------------------------------------------------------------------------
1 | # AgentConnect4Golang
2 |
3 | This is the golang implementation version of the Python AgentConnect codebase.
4 |
5 | It can provide functions such as DID (decentralized identifier) generation, authentication, and encryption operations.
6 |
7 | ⭐️⭐️⭐️ The relevant code is actively being organized and will be released later. Please stay tuned ⭐️⭐️⭐️
8 |
9 | ## Building the Project
10 |
11 | This project uses go mod for dependency management. Command for building the project:
12 |
13 | ```bash
14 | go mod tidy
15 | ```
16 |
17 |
18 | ## License
19 |
20 | This project is open-sourced under the MIT License.
21 |
22 | ## Author
23 |
24 | Original Python implementation by GaoWei Chang (chgaowei@gmail.com).
25 | Golang implementation by Linyi Artificial Intelligence Association ( lysrgznxh@9885.net ).
--------------------------------------------------------------------------------
/docs/did_public/public-did-doc.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://www.w3.org/ns/did/v1",
4 | "https://w3id.org/security/suites/jws-2020/v1",
5 | "https://w3id.org/security/suites/secp256k1-2019/v1"
6 | ],
7 | "id": "did:wba:didhost.cc:public",
8 | "verificationMethod": [
9 | {
10 | "id": "did:wba:didhost.cc:public#key-1",
11 | "type": "EcdsaSecp256k1VerificationKey2019",
12 | "controller": "did:wba:didhost.cc:public",
13 | "publicKeyJwk": {
14 | "kty": "EC",
15 | "crv": "secp256k1",
16 | "x": "3QhHtIA9OrPys7Ih-C7ypn_wo0hURSJsftiO0InGX3Y",
17 | "y": "zctVr4gezAgl0yrr6pdgTrj3njlU1MC_NqfoMz-MIw",
18 | "kid": "IlNAoEa0nitp0V6cI48WUB8iTgZZym5cJLCfR79iTTQ"
19 | }
20 | }
21 | ],
22 | "authentication": [
23 | "did:wba:didhost.cc:public#key-1"
24 | ]
25 | }
--------------------------------------------------------------------------------
/CONTRIBUTING.cn.md:
--------------------------------------------------------------------------------
1 | # 贡献指南
2 |
3 | 感谢您对本项目感兴趣!我们非常欢迎来自社区的贡献。
4 |
5 | ## 谁可以贡献
6 |
7 | 我们热烈欢迎以下群体参与项目:
8 | - 对网络技术有研究的开发者
9 | - 对协议设计和实现感兴趣的工程师
10 | - 从事相关软件研发的企业
11 | - 高校和研究机构的研究人员
12 | - 其他对本项目感兴趣的贡献者
13 |
14 | ## 贡献流程
15 |
16 | ### 1. 前期讨论
17 | 在开始编写代码之前,我们建议您:
18 | - 在 GitHub Issues 中提出您的想法
19 | - 在我们的 Discord 社区中与其他开发者讨论
20 | - 充分收集社区反馈,确保方案可行
21 |
22 | ### 2. 提交 Pull Request
23 | - 请确保您的代码符合项目规范
24 | - 提供清晰的 PR 描述,说明改动的目的和实现方式
25 | - 如果 PR 关联某个 Issue,请在描述中注明
26 |
27 | ### 3. 代码审查
28 | - 我们会尽快审查您的 PR
29 | - 必要时会邀请相关领域的开发者一起参与讨论
30 | - 可能会要求您进行一些修改或优化
31 |
32 | ## 联系我们
33 |
34 | 如果您有任何问题,欢迎通过以下方式联系:
35 | - GitHub Issues:[https://github.com/agent-network-protocol/AgentConnect/issues](https://github.com/agent-network-protocol/AgentConnect/issues)
36 | - Discord 社区:[https://discord.gg/sFjBKTY7sB](https://discord.gg/sFjBKTY7sB)
37 |
38 | 再次感谢您对项目的关注与支持!
39 |
--------------------------------------------------------------------------------
/tools/did_generater/user_public/did.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://www.w3.org/ns/did/v1",
4 | "https://w3id.org/security/suites/jws-2020/v1",
5 | "https://w3id.org/security/suites/secp256k1-2019/v1"
6 | ],
7 | "id": "did:wba:didhost.cc:test:public",
8 | "verificationMethod": [
9 | {
10 | "id": "did:wba:didhost.cc:test:public#key-1",
11 | "type": "EcdsaSecp256k1VerificationKey2019",
12 | "controller": "did:wba:didhost.cc:test:public",
13 | "publicKeyJwk": {
14 | "kty": "EC",
15 | "crv": "secp256k1",
16 | "x": "5sGa0C-Qi5cTIfZLqPsnTwsaL0jTbukodKTDsL6QP5o",
17 | "y": "nPKm2oyzne4d95DYr5Fx9MzXj0RQIbzm2VKZrkwV740",
18 | "kid": "aRR_E6xLZUmH2aE71JfGBS9FjppJw_dqSh7WAw0P2Z0"
19 | }
20 | }
21 | ],
22 | "authentication": [
23 | "did:wba:didhost.cc:test:public#key-1"
24 | ]
25 | }
--------------------------------------------------------------------------------
/java/README.cn.md:
--------------------------------------------------------------------------------
1 | # AgentConnect4Java
2 |
3 | 这是Python AgentConnect代码库的Java实现版本。它提供了DID(去中心化标识符)生成、身份验证和加密操作的功能。
4 |
5 | ## 项目结构
6 |
7 | 项目按以下包进行组织:
8 |
9 | - `com.agentconnect.authentication`: 包含DID身份验证相关的类
10 | - `com.agentconnect.utils`: 包含加密操作和其他辅助功能的工具类
11 | - `test`目录中主要提供了单元测试类DIDWBAUnitTest,验证主要的几个功能方法的正确性
12 | - `test/java/com.agentconnect.test.example`:主要提供了一个DidWbaFullExample类,包含了一个完整的DID身份验证示例,包括did文档生成,密钥保存,AuthHeader生成,签名验签过程,token的验证和生成,是一个学习anp4java入门的不错的示例。
13 |
14 | ## 构建项目
15 |
16 | 本项目使用Maven进行依赖管理。构建项目的命令:
17 |
18 | ```bash
19 | mvn clean package
20 | ```
21 |
22 | ## 依赖项
23 |
24 | - BouncyCastle:用于加密操作
25 | - AsyncHttpClient:用于异步HTTP请求
26 | - Jackson:用于JSON处理
27 | - NovaCrypto Base58:用于Base58编码/解码
28 | - SLF4J和Logback:用于日志记录
29 | - JSON Canonicalization Scheme:用于JSON规范化
30 |
31 | ## 许可证
32 |
33 | 本项目基于MIT许可证开源。
34 |
35 | ## 作者
36 |
37 | 原始Python实现:GaoWei Chang (chgaowei@gmail.com)。
--------------------------------------------------------------------------------
/anp/authentication/__init__.py:
--------------------------------------------------------------------------------
1 | from .did_wba import (
2 | create_did_wba_document,
3 | extract_auth_header_parts,
4 | generate_auth_header,
5 | resolve_did_wba_document,
6 | resolve_did_wba_document_sync,
7 | verify_auth_header_signature,
8 | )
9 | from .did_wba_authenticator import DIDWbaAuthHeader
10 | from .did_wba_verifier import DidWbaVerifier, DidWbaVerifierConfig, DidWbaVerifierError
11 |
12 | # Define what should be exported when using "from anp.authentication import *"
13 | __all__ = ['create_did_wba_document', \
14 | 'resolve_did_wba_document', \
15 | 'resolve_did_wba_document_sync', \
16 | 'generate_auth_header', \
17 | 'verify_auth_header_signature', \
18 | 'extract_auth_header_parts', \
19 | 'DIDWbaAuthHeader', \
20 | 'DidWbaVerifier', \
21 | 'DidWbaVerifierConfig', \
22 | 'DidWbaVerifierError'
23 | ]
24 |
25 |
--------------------------------------------------------------------------------
/tools/did_generater/user_yanlq/did.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://www.w3.org/ns/did/v1",
4 | "https://w3id.org/security/suites/jws-2020/v1",
5 | "https://w3id.org/security/suites/secp256k1-2019/v1"
6 | ],
7 | "id": "did:wba:service.agent-network-protocol.com:wba:user:yanlq",
8 | "verificationMethod": [
9 | {
10 | "id": "did:wba:service.agent-network-protocol.com:wba:user:yanlq#key-1",
11 | "type": "EcdsaSecp256k1VerificationKey2019",
12 | "controller": "did:wba:service.agent-network-protocol.com:wba:user:yanlq",
13 | "publicKeyJwk": {
14 | "kty": "EC",
15 | "crv": "secp256k1",
16 | "x": "uu99490UmYb2MycffNxaJKAXgUU5ZJ1AQ9sQGXXrch0",
17 | "y": "eISEWERyPKu0rP7uKFlLoiPwU7HfqITUqSORWIkwt3Q",
18 | "kid": "LESLq7CM8slUVctlv8tCVXNJWgAG66bOJ93XHnkkylE"
19 | }
20 | }
21 | ],
22 | "authentication": [
23 | "did:wba:service.agent-network-protocol.com:wba:user:yanlq#key-1"
24 | ]
25 | }
--------------------------------------------------------------------------------
/examples/python/fastanp_examples/test_simple.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Test script for simple_agent.py
3 |
4 | echo "Testing Simple FastANP Agent"
5 | echo "=============================="
6 | echo
7 |
8 | # Wait for server to be ready
9 | sleep 2
10 |
11 | echo "1. Testing Agent Description endpoint..."
12 | curl -s http://localhost:8000/ad.json | jq '.' || echo "Failed to get ad.json"
13 | echo
14 |
15 | echo "2. Testing Information endpoint..."
16 | curl -s http://localhost:8000/info/capabilities.json | jq '.' || echo "Failed to get capabilities"
17 | echo
18 |
19 | echo "3. Testing hello method..."
20 | curl -s -X POST http://localhost:8000/rpc \
21 | -H "Content-Type: application/json" \
22 | -d '{"jsonrpc":"2.0","id":1,"method":"hello","params":{"name":"Alice"}}' | jq '.'
23 | echo
24 |
25 | echo "4. Testing add method..."
26 | curl -s -X POST http://localhost:8000/rpc \
27 | -H "Content-Type: application/json" \
28 | -d '{"jsonrpc":"2.0","id":2,"method":"add","params":{"a":5,"b":3}}' | jq '.'
29 | echo
30 |
31 | echo "All tests completed!"
32 |
33 |
--------------------------------------------------------------------------------
/examples/python/did_wba_examples/generated/did.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://www.w3.org/ns/did/v1",
4 | "https://w3id.org/security/suites/jws-2020/v1",
5 | "https://w3id.org/security/suites/secp256k1-2019/v1"
6 | ],
7 | "id": "did:wba:demo.agent-network:agents:demo",
8 | "verificationMethod": [
9 | {
10 | "id": "did:wba:demo.agent-network:agents:demo#key-1",
11 | "type": "EcdsaSecp256k1VerificationKey2019",
12 | "controller": "did:wba:demo.agent-network:agents:demo",
13 | "publicKeyJwk": {
14 | "kty": "EC",
15 | "crv": "secp256k1",
16 | "x": "suqRsY9MrIWrMl1ip8y4aWGgExgMYy2Da1dMqPFl3Gg",
17 | "y": "EQmItlpVfS9TC4nRXFEpF_PP0C_bIBCGdE9yom-ewTw",
18 | "kid": "_MniTRnEAhSqCag8qufA68GRIo78_PzA5ypboqt7Zac"
19 | }
20 | }
21 | ],
22 | "authentication": [
23 | "did:wba:demo.agent-network:agents:demo#key-1"
24 | ],
25 | "service": [
26 | {
27 | "id": "did:wba:demo.agent-network:agents:demo#ad",
28 | "type": "AgentDescription",
29 | "serviceEndpoint": "https://demo.agent-network/agents/demo"
30 | }
31 | ]
32 | }
--------------------------------------------------------------------------------
/examples/python/negotiation_mode/config.py:
--------------------------------------------------------------------------------
1 | # AgentConnect: https://github.com/agent-network-protocol/AgentConnect
2 | # Author: GaoWei Chang
3 | # Email: chgaowei@gmail.com
4 | # Website: https://agent-network-protocol.com/
5 | #
6 | # This project is open-sourced under the MIT License. For details, please see the LICENSE file.
7 |
8 | # Configuration file for tests
9 | import os
10 | from pathlib import Path
11 | from dotenv import load_dotenv
12 |
13 | # Get the project root directory (assuming tests folder is directly under root)
14 | ROOT_DIR = Path(__file__).parent.parent.parent.parent
15 |
16 | # Load environment variables from root .env file
17 | load_dotenv(ROOT_DIR / '.env')
18 |
19 | # Azure OpenAI configurations
20 | AZURE_OPENAI_API_KEY = os.getenv('AZURE_OPENAI_API_KEY')
21 | AZURE_OPENAI_ENDPOINT = os.getenv('AZURE_OPENAI_ENDPOINT')
22 | AZURE_OPENAI_DEPLOYMENT = os.getenv('AZURE_OPENAI_DEPLOYMENT')
23 | AZURE_OPENAI_MODEL_NAME = os.getenv('AZURE_OPENAI_MODEL_NAME')
24 |
25 | def validate_config():
26 | """Validate that all required environment variables are set"""
27 | required_vars = [
28 | 'AZURE_OPENAI_API_KEY',
29 | 'AZURE_OPENAI_ENDPOINT',
30 | 'AZURE_OPENAI_DEPLOYMENT',
31 | 'AZURE_OPENAI_MODEL_NAME'
32 | ]
33 |
34 | missing_vars = [var for var in required_vars if not os.getenv(var)]
35 |
36 | if missing_vars:
37 | raise ValueError(f"Missing required environment variables: {', '.join(missing_vars)}")
--------------------------------------------------------------------------------
/examples/python/did_wba_examples/create_did_document.py:
--------------------------------------------------------------------------------
1 | """Minimal example showing how to create a DID WBA document."""
2 |
3 | from __future__ import annotations
4 |
5 | import json
6 | from pathlib import Path
7 |
8 | from anp.authentication import create_did_wba_document
9 |
10 |
11 | def main() -> None:
12 | """Create a DID document and persist the generated artifacts."""
13 | hostname = "demo.agent-network"
14 | did_document, keys = create_did_wba_document(
15 | hostname=hostname,
16 | path_segments=["agents", "demo"],
17 | agent_description_url="https://demo.agent-network/agents/demo",
18 | )
19 |
20 | output_dir = Path(__file__).resolve().parent / "generated"
21 | output_dir.mkdir(parents=True, exist_ok=True)
22 |
23 | did_path = output_dir / "did.json"
24 | did_path.write_text(json.dumps(did_document, indent=2), encoding="utf-8")
25 | print(f"DID document saved to {did_path}")
26 |
27 | for fragment, (private_bytes, public_bytes) in keys.items():
28 | private_path = output_dir / f"{fragment}_private.pem"
29 | public_path = output_dir / f"{fragment}_public.pem"
30 | private_path.write_bytes(private_bytes)
31 | public_path.write_bytes(public_bytes)
32 | print(
33 | "Registered verification method",
34 | fragment,
35 | "→ private key:",
36 | private_path.name,
37 | "public key:",
38 | public_path.name,
39 | )
40 |
41 | print(f"Generated DID identifier: {did_document['id']}")
42 |
43 |
44 | if __name__ == "__main__":
45 | main()
46 |
--------------------------------------------------------------------------------
/examples/python/fastanp_examples/test_examples.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Quick test script for FastANP examples
3 |
4 | set -e
5 |
6 | echo "================================"
7 | echo "Testing FastANP Examples"
8 | echo "================================"
9 | echo ""
10 |
11 | # Test simple_agent
12 | echo "1. Testing simple_agent.py..."
13 | python -c "
14 | import sys
15 | sys.path.insert(0, '.')
16 | from simple_agent import app, anp
17 | assert anp.name == 'Simple Agent'
18 | assert len(anp.interface_manager.functions) == 1
19 | print(' ✓ simple_agent.py imports successfully')
20 | "
21 |
22 | # Test simple_agent_with_context
23 | echo "2. Testing simple_agent_with_context.py..."
24 | python -c "
25 | import sys
26 | sys.path.insert(0, '.')
27 | from simple_agent_with_context import app, anp
28 | assert anp.name == 'Simple Agent with Context'
29 | assert len(anp.interface_manager.functions) == 1
30 | # Check that counter has context param
31 | for func in anp.interface_manager.functions.values():
32 | assert func.has_context_param == True
33 | print(' ✓ simple_agent_with_context.py imports successfully')
34 | "
35 |
36 | # Test hotel_booking_agent
37 | echo "3. Testing hotel_booking_agent.py..."
38 | python -c "
39 | import sys
40 | sys.path.insert(0, '.')
41 | from hotel_booking_agent import app, anp
42 | assert anp.name == 'Hotel Booking Assistant'
43 | assert len(anp.interface_manager.functions) == 2
44 | print(' ✓ hotel_booking_agent.py imports successfully')
45 | "
46 |
47 | echo ""
48 | echo "================================"
49 | echo "✓ All examples passed!"
50 | echo "================================"
51 |
52 |
--------------------------------------------------------------------------------
/java/README.md:
--------------------------------------------------------------------------------
1 | # AgentConnect4Java
2 |
3 | This is a Java implementation of the Python AgentConnect codebase. It provides functionality for DID (Decentralized Identifier) generation, authentication, and cryptographic operations.
4 |
5 | ## Project Structure
6 |
7 | The project is organized into the following packages:
8 |
9 | - `com.agentconnect.authentication`: Contains classes for DID authentication
10 | - `com.agentconnect.utils`: Contains utility classes for cryptographic operations and other helper functions
11 | - `test`: This directory primarily contains the unit test class DIDWBAUnitTest, which verifies the correctness of several key functional methods.
12 | - `test/java/com.agentconnect.test.example`: This directory features the DidWbaFullExample class, which provides a comprehensive DID identity verification example. This includes DID document generation, key storage, AuthHeader creation, signature signing/verification processes, and token validation/generation. It serves as an excellent entry-level learning resource for ANP4Java.
13 | ## Building the Project
14 |
15 | This project uses Maven for dependency management. To build the project:
16 |
17 | ```bash
18 | mvn clean package
19 | ```
20 |
21 | ## Dependencies
22 |
23 | - BouncyCastle for cryptographic operations
24 | - AsyncHttpClient for asynchronous HTTP requests
25 | - Jackson for JSON processing
26 | - NovaCrypto Base58 for Base58 encoding/decoding
27 | - SLF4J and Logback for logging
28 | - JSON Canonicalization Scheme for JSON canonicalization
29 |
30 | ## License
31 |
32 | This project is open-sourced under the MIT License.
33 |
34 | ## Author
35 |
36 | Original Python implementation by GaoWei Chang (chgaowei@gmail.com).
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "anp"
3 | version = "0.4.7"
4 | description = "An SDK that enables agents to connect with each other, allowing them to perform identity authentication, end-to-end encrypted communication, automatic protocol negotiation based on LLMs, and efficient data exchange."
5 | authors = [
6 | {name = "changshan", email = "chgaowei@gmail.com"}
7 | ]
8 | license = {text = "MIT"}
9 | readme = "README.md"
10 | requires-python = ">=3.8"
11 | keywords = ["agent", "protocol", "authentication", "encryption", "communication"]
12 | classifiers = [
13 | "Programming Language :: Python :: 3",
14 | "License :: OSI Approved :: MIT License",
15 | "Operating System :: OS Independent",
16 | ]
17 |
18 | dependencies = [
19 | "ecdsa>=0.19.0",
20 | "cryptography>=43.0.3",
21 | "asn1crypto>=1.5.1",
22 | "base58>=2.1.1",
23 | "aiohttp>=3.10.10",
24 | "requests>=2.32.3",
25 | "websockets>=13.1",
26 | "pydantic>=2.9.2,<3.0.0",
27 | "python-dotenv>=1.0.1",
28 | "jsonschema>=4.23.0",
29 | "canonicaljson>=2.0.0",
30 | "jcs>=0.2.1",
31 | "pyjwt>=2.9.0",
32 | ]
33 |
34 | [project.optional-dependencies]
35 | api = [
36 | "openai>=1.54.3",
37 | "fastapi>=0.115.4,<1.0.0",
38 | "uvicorn>=0.32.0,<1.0.0",
39 | ]
40 | dev = [
41 | "pytest>=8.0.0",
42 | "pytest-asyncio>=0.23.0",
43 | ]
44 |
45 | [project.urls]
46 | Homepage = "https://agent-network-protocol.com/"
47 | Repository = "https://github.com/agent-network-protocol/AgentConnect"
48 | Documentation = "https://github.com/agent-network-protocol/AgentNetworkProtocol"
49 |
50 | [build-system]
51 | requires = ["hatchling"]
52 | build-backend = "hatchling.build"
53 |
54 | [tool.hatch.build.targets.wheel]
55 | packages = ["anp"]
56 |
57 |
58 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribution Guide
2 |
3 | Thank you for your interest in this project! We warmly welcome contributions from the community.
4 |
5 | ## Who Can Contribute
6 |
7 | We enthusiastically welcome the following groups to participate in the project:
8 | - Developers with research on network technology
9 | - Engineers interested in protocol design and implementation
10 | - Companies engaged in related software development
11 | - Researchers from universities and research institutions
12 | - Other contributors interested in this project
13 |
14 | ## Contribution Process
15 |
16 | ### 1. Preliminary Discussion
17 | Before you start writing code, we recommend that you:
18 | - Propose your ideas in GitHub Issues
19 | - Discuss with other developers in our Discord community
20 | - Fully collect community feedback to ensure the feasibility of the solution
21 |
22 | ### 2. Submit Pull Request
23 | - Please ensure your code complies with project specifications
24 | - Provide a clear PR description explaining the purpose and implementation of the changes
25 | - If the PR is related to an Issue, please mention it in the description
26 |
27 | ### 3. Code Review
28 | - We will review your PR as soon as possible
29 | - If necessary, we will invite developers from relevant fields to participate in the discussion
30 | - You may be asked to make some modifications or optimizations
31 |
32 | ## Contact Us
33 |
34 | If you have any questions, please contact us through the following ways:
35 | - GitHub Issues: [https://github.com/agent-network-protocol/AgentConnect/issues](https://github.com/agent-network-protocol/AgentConnect/issues)
36 | - Discord Community: [https://discord.gg/sFjBKTY7sB](https://discord.gg/sFjBKTY7sB)
37 |
38 | Thank you again for your attention and support to the project!
39 |
--------------------------------------------------------------------------------
/anp/utils/llm_output_processer.py:
--------------------------------------------------------------------------------
1 | # AgentConnect: https://github.com/agent-network-protocol/AgentConnect
2 | # Author: GaoWei Chang
3 | # Email: chgaowei@gmail.com
4 | # Website: https://agent-network-protocol.com/
5 | #
6 | # This project is open-sourced under the MIT License. For details, please see the LICENSE file.
7 |
8 | import re
9 | import logging
10 | import traceback
11 | from typing import Optional
12 |
13 | def extract_code_from_llm_output(content: str) -> Optional[str]:
14 | """Extract Python code from LLM output content.
15 |
16 | Args:
17 | content: The complete content string output by the LLM.
18 |
19 | Returns:
20 | str: The extracted Python code. Returns None if extraction fails.
21 |
22 | Extraction rules:
23 | 1. Look for code blocks surrounded by ```python and ```.
24 | 2. If not found, try to find code blocks surrounded by ``` and ```.
25 | """
26 | try:
27 | # First, try to match the code block surrounded by ```python and ```
28 | pattern = r"```python\s*(.*?)\s*```"
29 | matches = re.findall(pattern, content, re.DOTALL)
30 |
31 | if matches:
32 | return matches[0].strip()
33 |
34 | # If not found, try to match the code block surrounded by ``` and ```
35 | pattern = r"```\s*(.*?)\s*```"
36 | matches = re.findall(pattern, content, re.DOTALL)
37 |
38 | if matches:
39 | return matches[0].strip()
40 |
41 | logging.error("No code block found in LLM output")
42 | return None
43 |
44 | except Exception as e:
45 | logging.error(f"Failed to extract code: {str(e)}\nStack trace:\n{traceback.format_exc()}")
46 | return None
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/anp/anp_crawler/README.cn.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [English](README.md) | [中文](README.cn.md)
4 |
5 |
6 |
7 | # ANP Crawler 模块
8 |
9 | ## 模块定位
10 | ANP Crawler 为 Agent Network Protocol (ANP) 提供了一套轻量级的发现与解析 SDK,专注于可复现的数据抓取流程,不在模块内部调用任何大模型服务,适合在生产系统或离线工具中集成使用。
11 |
12 | ## 目录结构
13 | - `anp_client.py`:异步 HTTP 客户端,复用 `DIDWbaAuthHeader` 为外部请求附加 DID WBA 鉴权头。
14 | - `anp_parser.py`:规范化 JSON-LD 内容,抽取 Agent Description 文档中的元数据。
15 | - `anp_interface.py`:将接口描述(OpenRPC、JSON-RPC、自然语言描述等)转换为 OpenAI Tools 兼容的模式。
16 | - `anp_crawler.py`:兼容性保留的旧版爬虫入口,新的代码建议直接使用上述精简类。
17 | - `Interface.md`:关于目标数据模型与转换规则的补充说明。
18 | - `test/`:临时用例与集成验证脚本。
19 |
20 | 仓库中的 `meta_protocol` 与 `e2e_encryption` 模块已预留好目录,但当前 ANP Crawler 的执行流程暂未使用它们。
21 |
22 | ## 基本流程
23 | 1. 使用 DID 文档与私钥实例化 `ANPClient`,从而以 DID WBA 鉴权访问受保护的 Agent 服务。
24 | 2. 调用客户端抓取智能体描述入口(JSON 或 YAML)。
25 | 3. 将响应内容交给 `ANPDocumentParser`,收集文档内容、元数据与引用的接口 URL。
26 | 4. 对每个接口文档使用 `ANPInterfaceConverter`(位于 `anp_interface.py`)转换为 OpenAI Tools 形态,供上层代理直接调用。
27 |
28 | ## 简要示例
29 | ```python
30 | from anp import ANPClient
31 | from anp.anp_crawler.anp_parser import ANPDocumentParser
32 |
33 | client = ANPClient(
34 | did_document_path="docs/did_public/public-did-doc.json",
35 | private_key_path="docs/did_public/public-private-key.pem",
36 | )
37 |
38 | async def load_description(url: str):
39 | response = await client.fetch_url(url)
40 | if not response["success"]:
41 | raise RuntimeError(f"Request failed: {response['status_code']}")
42 |
43 | parser = ANPDocumentParser()
44 | content = parser.parse(response["text"], response["url"])
45 | return content
46 | ```
47 |
48 | ## 推荐下一步
49 | - 参考 `examples/python/anp_crawler_examples/`,了解多跳抓取的完整流程。
50 | - 将示例中的 DID 证书替换为自有配置,以访问私有的 Agent 注册中心。
51 | - 如需支持更多协议格式,可在 `anp_interface.py` 中扩展转换逻辑。
52 |
--------------------------------------------------------------------------------
/docs/jwt_rs256/RS256-private.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC3TZRcRRlW27FX
3 | YcfPYD70Ap5HP755cC5e/AT8Ccct1L3YiMNz9NXPKEphTlo4PO/OrfDra/rkdO5l
4 | OlijOi+c/40a8REkIqlzbMO+Ug9MbKtQVQ57M7o1RneYhIGlx8Z7B7QEpXisxlv7
5 | NaKLXOe6YpEiLMUC9emASztx1EUg65NLT57Ja4xteEcmWv2IPyByNfc8SK/U+sQH
6 | 43wq47uEiXLqe29cIBmz85BdWDf4GrYHNdOMSkhIakPUIrCqVSl2G8OhZSXvMfsr
7 | hY68WjtbU9/Zj1LPyytTDbXmrzDN7PUtNw2vTltRGcoKDjvnUnXQgJ5i0zqfuLr5
8 | Nk4K2Z5pAgMBAAECggEAFW1nM2YMcT/bOji+77nzgfiwYenMrUt00DurpX7LHsto
9 | qeBK4Mo1GDNAhqFvIHXXHpTsvchwmrYkjAbHB8WsfTDOYODfPRckMc78Dspu6WMm
10 | n4xh1fsVAFdNcbHDqgpxZD5hR83EDoZdiD8b0ii5GeudxZ3wJclzU0D4IPVMY22T
11 | OpGH+KlDX/5ahmkqNpwGeqS4/xwsZYEKBqAwthM58IPvrRu8zPANK+XpZg07Irqp
12 | ksuQcH8ArdtAHi/HW4vVP3OkfIoyp8IfDC+9JzdtkchQT4nO1rMSXv3POrq/3LWc
13 | 88CJIFbUH3KyoB9khfw/pyYvTVxwHLohnjsB82s1UQKBgQD4YZ25V8metFLfPLhd
14 | G4poE2zZ0lGQtdiMWNQhyJZ1qnFX7X68oed4TUkNK9RFb7VWmI8MZBsiC4/B8oIv
15 | pN742kuLG09gFY0JFHNg+d3ZiitZel28ybhCE5xydt605dE4fkE982bnvYJ0vu+K
16 | M0QburpTiDMP+QI6HUcRVEqNHQKBgQC87PG8eCyak1yXgUEH9HeZcCe6RjRbLlLJ
17 | Y4hXVZKLMuJ3YcoTcbajeXn7hpJPXSEG5eALjrkeQYi9PzqImI10TMnGCNGqHcl5
18 | 0M3mBFzgweQehRVezbQ9wTlibcbXJoN4vItRl7/fGZhmaI8M8ycxK6rgTjhk48oK
19 | SXwUXaIwvQKBgAtHY4InGmC6j4jTmQuhVIelWiwKAOoxV8QHxJpEIZD2TG9RuY+X
20 | SouL9uVCOEFu8S0dgGFvqkvBeqWz/XVsZzOltgh7FP+n+t+Ori6ZKhnWzGEjzV3l
21 | Sxi1C0WnYDWWugl2sj+97c5YLLRgd0AvU8hukkd4x9jR1egNrEx9J2WBAoGAExnZ
22 | rvZvfAleGStGSemblfXS7nBepsFeOWJIzJuoP06buvo2FhUvJAQKIzYN4NxHlIz1
23 | Q/XgHYD+tDOKVXknBBUnaVBG8m4kip5j0teqFEdGKxfFe1pM2NmKVbtHmUUZkcFu
24 | TIeNLJ9H20LDA8opsjz5/8eox/qH2NZpJx34YfkCgYEApr9XoMPoG9N2MzIh+Yf8
25 | qgGO/NaxAcnOaRiKMbqge71WLHHS3TZzHRxk64z9NA7rl58AbKsxfB7UJ9+2TC1E
26 | XNJF3JUpV2gT5FyGa4z9rHrfWajvbfveTW2YIipKq7bsCYTHzsLUVed4kI3oXtQY
27 | ab0b7yv8irlkhzf3xkJ94h8=
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/docs/jwt_rs256/private_key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC/uStVucqsetGL
3 | xU0i3JRLsSN8hXMnySUsaN4PGCtgOw0voQOQIMCc0PfNTnRCnYnqCJmPshUPCkP8
4 | /U+5rqDGOFif/diCynyG9eO7KkckPIjo6+e385gCZzHMTiOfNyt+PPNi/20M1JIB
5 | uUh45FOX/8pEI5YGrFE7/KvMUrktphSyWKUHvJkW1gTaJS0C1GyRclrCy/fCdfxb
6 | HYFyugRauXxYoTntlf7+D7DMMPTG4GTbih9OerHYjRZNKi9vSgefqUPnId3xu+EM
7 | z3sI8cn7noSPaZL3TmPBi+5wBHhB3GvlrAkA1m9JdxhZLa9MU56vYxgPspixL/JC
8 | iQaTZjMVAgMBAAECggEABvSHO21pildMScdHFJgu8w4CjQ5kTpGv/Qvy3lZQoIWT
9 | 5WHweKaPhkDYdIS/l/kSG0DjnUBnHiwPqlpgLYrFv1sk7+zsEVaaLOU3tT8D5K8j
10 | gluohNZb8d5fgptlFG4ScFpys+kzQg9mGpTnqacS10VKx60I0MYojkYMz3VCzYKU
11 | T2jU+hVlwzEqzZEh+KhnUa0C82FO0+THCqOLJ5bROw2bsZEH8q1PipdrK960N1T2
12 | Mq2XK1BsmnV/ucdG2BJkT/9oAeKwd4CABySLmSlB82OBwJLd90i88RYAcfp5YGEu
13 | T9lfkO097y24Wbv1VQsnLQkHQBZvUkofHMC8B/jskQKBgQDn1N+UmvTICA1yLHFA
14 | GvUsd/roV322yQ0qbuBUf8iBokJMRBXjaDILg7o12KgMlhaecLUdsBbmpLXC/+rw
15 | Cpw+7N1RIwiIiUSsdQekf3A2ZV2lxWmrnDEgNq40JhaemuET4V9dJrPqh9Iv/PS0
16 | 4nopvCGuen2sXU92Q8MhRDMGSQKBgQDTteL50nC5JN1a4IhrjjD6o8t5e85ds7tO
17 | kSLDaX9yebUuxPKLQoyu2EkfgNG9mc6eBhHp4upl1odbIdpzGBiA4+1hllC/t7gF
18 | 9CiqsNLOXMJIJDgpBaa973EUQRu8YU8mKNXp5SNy5Aeyhu/OGsNORjKvE0aJudoy
19 | JJV2+RBWbQKBgA5bvdk7W6vD6+lFXWJGCSdO6whW2t9mRl15boVtQKLexNJqaRyj
20 | iG30I6VQHOBir1XyzxTeohx42RURuqBRV+oBy5dJ3y5tqgYwXV/P0MhdsNYiiu/p
21 | BZXkLRfnwADkwMn1bG2dhwkgjmEQfqtxV3WcRE3FImF5igFeIwi9a5eZAoGAYgeU
22 | o+0HeRNS0+OoB3V9xHDXpNbpBYZVstmNaUKOWul0NcXIMSeNkOBha47wj4SKoa1Z
23 | 2hzSQHmHj3Erf6OmpPflUQyTM1LUiR03P2JFGnzlERaEUqplPQmEKMbFGwNL7PV3
24 | p6gMNATWc5n7rEnEKZhjm6GnRdqi6Bj8hGxrXjkCgYEA2s2a6vn9ltVucZcuPykV
25 | Tnjlx/g4CGfpHMfahg8dW4KUl5v8YDH5bLoXu/v2kMofbr2h2pbacCDydfTxDT50
26 | RXiMfS5Fy9+PL7Sm5lGT93Q3F6KoUasp6sNyrMjZoiEbQklIhtrr6PAfTr5G5MoQ
27 | HJQCcinIQxQt7T8AfKZiLSk=
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/java/src/main/java/com/agentconnect/authentication/VerificationMethod.java:
--------------------------------------------------------------------------------
1 | package com.agentconnect.authentication;
2 |
3 | import java.util.Map;
4 |
5 | /**
6 | * Abstract base class for verification methods
7 | */
8 | public abstract class VerificationMethod {
9 |
10 | /**
11 | * Verify signature
12 | * @param content The content bytes to verify
13 | * @param signature The signature string
14 | * @return true if verification succeeds, false otherwise
15 | */
16 | public abstract boolean verifySignature(byte[] content, String signature);
17 |
18 | /**
19 | * Create instance from verification method dictionary in DID document
20 | * @param methodDict The verification method dictionary
21 | * @return VerificationMethod instance
22 | */
23 | public static VerificationMethod fromDict(Map methodDict) {
24 | String methodType = (String) methodDict.get("type");
25 | if (methodType == null) {
26 | throw new IllegalArgumentException("Missing verification method type");
27 | }
28 |
29 | switch (methodType) {
30 | case "EcdsaSecp256k1VerificationKey2019":
31 | return EcdsaSecp256k1VerificationKey2019.fromDict(methodDict);
32 | case "Ed25519VerificationKey2018":
33 | return Ed25519VerificationKey2018.fromDict(methodDict);
34 | default:
35 | throw new IllegalArgumentException("Unsupported verification method type: " + methodType);
36 | }
37 | }
38 |
39 | /**
40 | * Encode signature bytes to base64url format
41 | * @param signatureBytes Raw signature bytes
42 | * @return base64url encoded signature
43 | */
44 | public abstract String encodeSignature(byte[] signatureBytes);
45 | }
--------------------------------------------------------------------------------
/anp/utils/log_base.py:
--------------------------------------------------------------------------------
1 | import logging
2 | # AgentConnect: https://github.com/agent-network-protocol/AgentConnect
3 | # Author: GaoWei Chang
4 | # Email: chgaowei@gmail.com
5 | # Website: https://agent-network-protocol.com/
6 | #
7 | # This project is open-sourced under the MIT License. For details, please see the LICENSE file.
8 |
9 | class ColoredFormatter(logging.Formatter):
10 | COLORS = {
11 | 'DEBUG': '\033[94m', # Blue
12 | 'INFO': '\033[92m', # Green
13 | 'WARNING': '\033[93m', # Yellow
14 | 'ERROR': '\033[91m', # Red
15 | 'CRITICAL': '\033[95m', # Magenta
16 | 'RESET': '\033[0m', # Reset
17 | }
18 |
19 | def format(self, record):
20 | levelname = record.levelname
21 | message = super().format(record)
22 | color = self.COLORS.get(levelname, self.COLORS['RESET'])
23 | return color + message + self.COLORS['RESET']
24 |
25 | def set_log_color_level(level):
26 | logger = logging.getLogger()
27 | logger.setLevel(level)
28 |
29 | # Check if there's already a console handler
30 | if not any(isinstance(handler, logging.StreamHandler) for handler in logger.handlers):
31 | # Create console handler
32 | console_handler = logging.StreamHandler()
33 | console_handler.setLevel(level)
34 |
35 | # Create formatter and add it to the handlers
36 | formatter = ColoredFormatter('%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s\n')
37 | console_handler.setFormatter(formatter)
38 |
39 | # Add the handlers to the logger
40 | logger.addHandler(console_handler)
41 |
42 | # Prevent log messages from propagating to the root logger
43 | logger.propagate = False
44 |
45 | # Test messages
46 | logger.debug("This is a debug message")
47 | logger.info("This is an info message")
48 | logger.warning("This is a warning message")
49 | logger.error("This is an error message")
50 | logger.critical("This is a critical message")
--------------------------------------------------------------------------------
/java/src/main/java/com/agentconnect/utils/LLMOutputProcessor.java:
--------------------------------------------------------------------------------
1 | package com.agentconnect.utils;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | import java.util.regex.Matcher;
7 | import java.util.regex.Pattern;
8 |
9 | /**
10 | * Utility class for processing output from Large Language Models (LLMs)
11 | */
12 | public class LLMOutputProcessor {
13 | private static final Logger logger = LoggerFactory.getLogger(LLMOutputProcessor.class);
14 |
15 | /**
16 | * Extract code from LLM output content.
17 | *
18 | * Extraction rules:
19 | * 1. Look for code blocks surrounded by ```java and ```
20 | * 2. If not found, try to find code blocks surrounded by ``` and ```
21 | *
22 | * @param content The complete content string output by the LLM
23 | * @return The extracted code, or null if extraction fails
24 | */
25 | public static String extractCodeFromLLMOutput(String content) {
26 | try {
27 | // First, try to match the code block surrounded by ```java and ```
28 | Pattern javaPattern = Pattern.compile("```java\\s*(.*?)\\s*```", Pattern.DOTALL);
29 | Matcher javaMatcher = javaPattern.matcher(content);
30 |
31 | if (javaMatcher.find()) {
32 | return javaMatcher.group(1).trim();
33 | }
34 |
35 | // If not found, try to match the code block surrounded by ``` and ```
36 | Pattern genericPattern = Pattern.compile("```\\s*(.*?)\\s*```", Pattern.DOTALL);
37 | Matcher genericMatcher = genericPattern.matcher(content);
38 |
39 | if (genericMatcher.find()) {
40 | return genericMatcher.group(1).trim();
41 | }
42 |
43 | logger.error("No code block found in LLM output");
44 | return null;
45 | } catch (Exception e) {
46 | logger.error("Failed to extract code: {}", e.getMessage(), e);
47 | return null;
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/anp/ap2/__init__.py:
--------------------------------------------------------------------------------
1 | """AP2 Protocol Support Module.
2 |
3 | This module provides a collection of orthogonal tools for building and
4 | verifying AP2 protocol data structures.
5 |
6 | The primary API surface is flat, providing direct access to key builders,
7 | validators, and commonly used Pydantic models so callers can simply import
8 | `from anp.ap2 import CartMandate` without digging into subpackages.
9 | """
10 |
11 | from .models import (
12 | ANPMessage,
13 | CartContents,
14 | CartMandate,
15 | CartMandateRequestData,
16 | DisplayItem,
17 | FulfillmentReceipt,
18 | FulfillmentReceiptContents,
19 | MoneyAmount,
20 | PaymentDetails,
21 | PaymentDetailsTotal,
22 | PaymentMandate,
23 | PaymentMandateContents,
24 | PaymentMethodData,
25 | PaymentProvider,
26 | PaymentReceipt,
27 | PaymentReceiptContents,
28 | PaymentRequest,
29 | PaymentRequestOptions,
30 | PaymentResponse,
31 | PaymentResponseDetails,
32 | PaymentStatus,
33 | QRCodePaymentData,
34 | ShippingAddress,
35 | ShippingInfo,
36 | )
37 | from .mandate import (
38 | b64url_no_pad,
39 | build_mandate,
40 | compute_hash,
41 | jcs_canonicalize,
42 | validate_mandate,
43 | )
44 |
45 | __all__ = [
46 | # Data Models
47 | "ANPMessage",
48 | "CartContents",
49 | "CartMandate",
50 | "CartMandateRequestData",
51 | "DisplayItem",
52 | "MoneyAmount",
53 | "PaymentDetails",
54 | "PaymentDetailsTotal",
55 | "PaymentMandate",
56 | "PaymentMandateContents",
57 | "PaymentMethodData",
58 | "PaymentReceipt",
59 | "PaymentReceiptContents",
60 | "PaymentProvider",
61 | "PaymentRequest",
62 | "PaymentRequestOptions",
63 | "PaymentResponse",
64 | "PaymentResponseDetails",
65 | "PaymentStatus",
66 | "QRCodePaymentData",
67 | "ShippingAddress",
68 | "ShippingInfo",
69 | "FulfillmentReceipt",
70 | "FulfillmentReceiptContents",
71 | # Utilities
72 | "compute_hash",
73 | "b64url_no_pad",
74 | "jcs_canonicalize",
75 | # Functional Mandate API
76 | "build_mandate",
77 | "validate_mandate",
78 | ]
79 |
--------------------------------------------------------------------------------
/examples/python/ap2_examples/README.cn.md:
--------------------------------------------------------------------------------
1 | # AP2 协议示例
2 |
3 | 本目录包含 AP2(智能体支付协议)实现的示例代码。
4 |
5 | ## 概述
6 |
7 | AP2 是基于 ANP(智能体协商协议)构建的协议,用于智能体之间的安全支付和交易流程。支持多种签名算法,包括 RS256 和 ES256K。
8 |
9 | ## 示例列表
10 |
11 | ### 完整流程(单进程)
12 |
13 | **文件**: `ap2_complete_flow.py`
14 |
15 | 同时启动商户服务与购物者客户端,快速回放从 CartMandate 创建到收据发放的完整 AP2 流程。
16 |
17 | **运行**:
18 | ```bash
19 | uv run python examples/python/ap2_examples/ap2_complete_flow.py
20 | ```
21 |
22 | ### 独立商户 & 购物者(双进程)
23 |
24 | **文件**: `merchant_server.py`, `shopper_client.py`
25 |
26 | 将职责拆分成两个独立进程,便于分别调试 HTTP API、部署到不同主机或演示真实网络交互。
27 |
28 | **运行步骤**:
29 | 1. 终端 A:启动商户服务(默认绑定本机 IP)
30 | ```bash
31 | uv run python examples/python/ap2_examples/merchant_server.py
32 | ```
33 | 可选参数:`--host 0.0.0.0`、`--port 8889`
34 |
35 | 2. 终端 B:启动购物者客户端,并指向商户 URL
36 | ```bash
37 | uv run python examples/python/ap2_examples/shopper_client.py \
38 | --merchant-url http://: \
39 | --merchant-did did:wba:didhost.cc:public
40 | ```
41 | 若使用仓库内置的公用 DID/证书,上述参数可省略,默认即为本地演示配置。
42 |
43 | ### Agent 级积木
44 |
45 | **文件**: `merchant_agent.py`, `shopper_agent.py`
46 |
47 | 封装了常用的构建/验证逻辑,不包含 HTTP 服务。可在更复杂的集成场景或测试中直接复用。
48 |
49 | ## 支持的算法
50 |
51 | | 算法 | 描述 | 密钥类型 | 签名大小 | 使用场景 |
52 | |------|------|----------|----------|----------|
53 | | **RS256** | 使用 SHA-256 的 RSASSA-PKCS1-v1_5 | RSA (2048+ 位) | ~256 字节 | 通用场景 |
54 | | **ES256K** | 使用 secp256k1 和 SHA-256 的 ECDSA | EC (secp256k1) | ~70 字节 | 区块链/加密货币 |
55 |
56 | ## 核心组件
57 |
58 | ### CartMandate(购物车授权)
59 | - 包含购物车信息
60 | - 由商户使用 `merchant_authorization` 签名
61 | - 包含二维码支付数据
62 | - 由购物者验证
63 |
64 | ### PaymentMandate(支付授权)
65 | - 包含支付确认信息
66 | - 由用户使用 `user_authorization` 签名
67 | - 通过 `cart_hash` 引用 CartMandate
68 | - 由商户验证
69 |
70 | ## 依赖项
71 |
72 | 所有示例需要:
73 | - `pyjwt` - JWT 编码/解码
74 | - `cryptography` - 加密原语
75 | - `pydantic` - 数据验证
76 |
77 | 这些依赖已包含在项目依赖中。
78 |
79 | ## 扩展阅读
80 |
81 | - [ES256K 支持文档](../../../docs/ap2/ES256K_SUPPORT.md)
82 | - [AP2 协议规范](../../../docs/ap2/流程整理.md)
83 | - [ANP 协议](../../../README.cn.md)
84 |
85 | ## 贡献指南
86 |
87 | 添加新示例时:
88 | 1. 遵循现有代码结构
89 | 2. 包含详细注释
90 | 3. 添加错误处理
91 | 4. 更新本 README
92 | 5. 提交前测试示例
93 |
94 |
--------------------------------------------------------------------------------
/examples/python/anp_crawler_examples/simple_amap_example.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """
3 | ANPCrawler简单示例 - AMAP服务
4 |
5 | 这是一个简化的示例,展示如何快速使用ANPCrawler获取和调用AMAP服务。
6 | """
7 |
8 | import asyncio
9 | import json
10 | import sys
11 | from pathlib import Path
12 |
13 | # 添加项目路径
14 | project_root = Path(__file__).parent.parent.parent.parent
15 | sys.path.insert(0, str(project_root))
16 |
17 | from anp.anp_crawler.anp_crawler import ANPCrawler
18 |
19 |
20 | async def simple_amap_example():
21 | """简单的AMAP服务示例"""
22 |
23 | # 1. 初始化爬虫
24 | crawler = ANPCrawler(
25 | did_document_path=str(project_root / "docs" / "did_public" / "public-did-doc.json"),
26 | private_key_path=str(project_root / "docs" / "did_public" / "public-private-key.pem")
27 | )
28 |
29 | # 2. 目标URL
30 | url = "https://agent-connect.ai/agents/travel/mcp/agents/amap/ad.json"
31 |
32 | print("步骤1: 获取AMAP代理描述文档")
33 | print("-" * 40)
34 |
35 | # 3. 获取代理描述
36 | content_json, interfaces_list = await crawler.fetch_text(url)
37 |
38 | # 4. 打印ad.json内容
39 | print("代理描述文档内容:")
40 | try:
41 | parsed_content = json.loads(content_json["content"])
42 | print(json.dumps(parsed_content, indent=2, ensure_ascii=False))
43 | except:
44 | print(content_json["content"])
45 |
46 | print(f"\n步骤2: 发现的接口数量: {len(interfaces_list)}")
47 | print("-" * 40)
48 |
49 | # 5. 显示可用的工具
50 | tools = crawler.list_available_tools()
51 | print(f"可用工具: {tools}")
52 |
53 | # 6. 如果有工具可用,尝试调用
54 | if tools:
55 | tool_name = tools[0]
56 | print(f"\n步骤3: 尝试调用工具 '{tool_name}'")
57 | print("-" * 40)
58 |
59 | # 示例参数 (需要根据实际接口调整)
60 | test_arguments = {
61 | "query": "天安门广场"
62 | }
63 |
64 | try:
65 | result = await crawler.execute_tool_call(tool_name, test_arguments)
66 | print("调用结果:")
67 | print(json.dumps(result, indent=2, ensure_ascii=False))
68 | except Exception as e:
69 | print(f"调用失败: {e}")
70 |
71 | print("\n会话信息:")
72 | print(f"- 访问的URL: {crawler.get_visited_urls()}")
73 | print(f"- 缓存条目数: {crawler.get_cache_size()}")
74 |
75 |
76 | if __name__ == "__main__":
77 | asyncio.run(simple_amap_example())
--------------------------------------------------------------------------------
/anp/anp_crawler/test/run_tests.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """
3 | ANP Crawler Test Runner
4 |
5 | Simple script to run all tests for the ANP Crawler module.
6 | """
7 |
8 | import sys
9 | import unittest
10 | from pathlib import Path
11 |
12 | # Add parent directory to path for imports
13 | sys.path.append(str(Path(__file__).parent.parent.parent.parent))
14 |
15 | from octopus.utils.log_base import setup_enhanced_logging
16 | from test_anp_crawler import TestANPCrawler, TestANPDocumentParser, TestANPInterface
17 |
18 |
19 | def main():
20 | """Main test runner function."""
21 | print("="*60)
22 | print("ANP Crawler Test Suite")
23 | print("="*60)
24 | print("Testing anp_crawler.py and related modules...")
25 | print()
26 |
27 | # Setup logging
28 | setup_enhanced_logging(level="INFO")
29 |
30 | try:
31 | # Create test loader
32 | loader = unittest.TestLoader()
33 |
34 | # Create test suite
35 | suite = unittest.TestSuite()
36 |
37 | # Add test cases
38 | suite.addTests(loader.loadTestsFromTestCase(TestANPCrawler))
39 | suite.addTests(loader.loadTestsFromTestCase(TestANPDocumentParser))
40 | suite.addTests(loader.loadTestsFromTestCase(TestANPInterface))
41 |
42 | # Run tests
43 | runner = unittest.TextTestRunner(verbosity=2)
44 | result = runner.run(suite)
45 |
46 | # Print summary
47 | print(f"\n{'='*50}")
48 | print(f"Tests run: {result.testsRun}")
49 | print(f"Failures: {len(result.failures)}")
50 | print(f"Errors: {len(result.errors)}")
51 | if result.testsRun > 0:
52 | success_rate = ((result.testsRun - len(result.failures) - len(result.errors)) / result.testsRun * 100)
53 | print(f"Success rate: {success_rate:.1f}%")
54 | print(f"{'='*50}")
55 |
56 | # Exit with appropriate code
57 | if result.failures or result.errors:
58 | print("\n❌ Some tests failed!")
59 | sys.exit(1)
60 | else:
61 | print("\n✅ All tests passed!")
62 | sys.exit(0)
63 |
64 | except Exception as e:
65 | print(f"\n💥 Error running tests: {str(e)}")
66 | import traceback
67 | traceback.print_exc()
68 | sys.exit(1)
69 |
70 |
71 | if __name__ == "__main__":
72 | main()
--------------------------------------------------------------------------------
/examples/python/fastanp_examples/simple_agent.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """
3 | Simple Agent Example
4 |
5 | This is the minimal FastANP agent example showing the basic usage.
6 | """
7 |
8 | import sys
9 | from pathlib import Path
10 |
11 | # Add project root to path
12 | project_root = Path(__file__).parent.parent.parent.parent
13 | sys.path.insert(0, str(project_root))
14 |
15 | from fastapi import FastAPI
16 |
17 | from anp.fastanp import FastANP
18 |
19 | # Initialize FastAPI app
20 | app = FastAPI(
21 | title="Simple Agent",
22 | description="A simple ANP agent example",
23 | version="1.0.0"
24 | )
25 |
26 | # Initialize FastANP plugin
27 | anp = FastANP(
28 | app=app,
29 | name="Simple Agent",
30 | description="A simple ANP agent built with FastANP",
31 | agent_domain="https://example.com",
32 | did="did:wba:example.com:agent:simple",
33 | enable_auth_middleware=False, # Disable middleware for simplicity
34 | )
35 |
36 |
37 | # Define ad.json route
38 | @app.get("/ad.json", tags=["agent"])
39 | def get_agent_description():
40 | """Get Agent Description."""
41 | # Get common header
42 | ad = anp.get_common_header(agent_description_path="/ad.json")
43 |
44 | # Add interfaces
45 | ad["interfaces"] = [
46 | anp.interfaces[hello].link_summary,
47 | ]
48 |
49 | return ad
50 |
51 |
52 | # Register a simple interface
53 | @anp.interface("/info/hello.json", description="Say hello")
54 | def hello(name: str) -> dict:
55 | """
56 | Greet someone by name.
57 |
58 | Args:
59 | name: The name to greet
60 |
61 | Returns:
62 | Greeting message
63 | """
64 | return {"message": f"Hello, {name}!"}
65 |
66 |
67 | def main():
68 | """Run the simple agent server."""
69 | import uvicorn
70 |
71 | print("Starting Simple Agent...")
72 | print("- Agent Description: http://localhost:8000/ad.json")
73 | print("- OpenRPC document: http://localhost:8000/info/hello.json")
74 | print("- JSON-RPC endpoint: http://localhost:8000/rpc")
75 | print("")
76 | print("Try calling the hello method:")
77 | print(' curl -X POST http://localhost:8000/rpc \\')
78 | print(' -H "Content-Type: application/json" \\')
79 | print(' -d \'{"jsonrpc": "2.0", "id": 1, "method": "hello", "params": {"name": "World"}}\'')
80 |
81 | uvicorn.run(app, host="0.0.0.0", port=8000)
82 |
83 |
84 | if __name__ == "__main__":
85 | main()
86 |
--------------------------------------------------------------------------------
/anp/utils/did_verify.py:
--------------------------------------------------------------------------------
1 | # AgentConnect: https://github.com/agent-network-protocol/AgentConnect
2 | # Author: GaoWei Chang
3 | # Email: chgaowei@gmail.com
4 | # Website: https://agent-network-protocol.com/
5 | #
6 | # This project is open-sourced under the MIT License. For details, please see the LICENSE file.
7 |
8 | from copy import deepcopy
9 | from typing import Any, Dict, Tuple
10 |
11 | from cryptography.exceptions import InvalidSignature
12 | from cryptography.hazmat.primitives.asymmetric import ec
13 |
14 | from anp.utils.crypto_tool import (
15 | verify_did_with_public_key,
16 | verify_signature_for_json,
17 | )
18 |
19 |
20 | def extract_public_key(did_document: Dict[str, Any], key_id: str) -> ec.EllipticCurvePublicKey:
21 | """Extract public key from DID document"""
22 | for vm in did_document['verificationMethod']:
23 | if vm['id'] == key_id and vm['type'] == "EcdsaSecp256r1VerificationKey2019":
24 | public_key_hex = vm['publicKeyHex']
25 | public_key_bytes = bytes.fromhex(public_key_hex[2:])
26 | return ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256R1(), public_key_bytes)
27 | raise ValueError(f"Public key {key_id} not found in DID document")
28 |
29 | def verify_did_document(did_document: dict) -> Tuple[bool, str]:
30 | """Verify DID document"""
31 | try:
32 | # Extract signature-related data
33 | proof = did_document['proof']
34 | verification_method = proof['verificationMethod']
35 | signature = proof['proofValue']
36 |
37 | # Extract public key
38 | public_key = extract_public_key(did_document, verification_method)
39 |
40 | # Extract DID
41 | did = did_document['id']
42 |
43 | # Verify public key and DID
44 | is_did_valid = verify_did_with_public_key(did, public_key)
45 | if not is_did_valid:
46 | return False, "public key is not valid"
47 |
48 | # Verify signature
49 | # Remove proof field to get original message
50 | original_message = deepcopy(did_document)
51 | del original_message['proof']['proofValue']
52 | is_signature_valid = verify_signature_for_json(public_key, original_message, signature)
53 |
54 | return is_signature_valid, "verify signature error" if not is_signature_valid else ""
55 | except ValueError as ve:
56 | return False, str(ve)
57 | except InvalidSignature:
58 | return False, "Bad Signature Error"
59 |
60 |
--------------------------------------------------------------------------------
/tools/did_generater/README_did_generater_cn.md:
--------------------------------------------------------------------------------
1 | # DID文档和私钥生成工具
2 |
3 | 这个工具用于根据DID字符串生成对应的DID文档和私钥文档。生成的文件将保存在脚本执行目录下的用户目录中。
4 |
5 | ## 功能
6 |
7 | - 解析DID字符串,提取主机名和路径段
8 | - 生成DID文档和相应的私钥
9 | - 将生成的文档保存到本地文件系统
10 |
11 | ## 使用方法
12 |
13 | ```bash
14 | python generate_did_doc.py [--agent-description-url URL] [--verbose]
15 | ```
16 |
17 | ### 参数说明
18 |
19 | - ``: 必需参数,DID字符串,例如 `did:wba:service.agent-network-protocol.com:wba:user:lkcoffe`
20 | - `--agent-description-url URL`: 可选参数,代理描述URL
21 | - `--verbose` 或 `-v`: 可选参数,启用详细日志记录
22 |
23 | ### 示例
24 |
25 | ```bash
26 | # 基本用法
27 | python generate_did_doc.py "did:wba:service.agent-network-protocol.com:wba:user:lkcoffe"
28 |
29 | # 带代理描述URL
30 | python generate_did_doc.py "did:wba:service.agent-network-protocol.com:wba:user:lkcoffe" --agent-description-url "https://example.com/agent.json"
31 |
32 | # 启用详细日志
33 | python generate_did_doc.py "did:wba:service.agent-network-protocol.com:wba:user:lkcoffe" -v
34 | ```
35 |
36 | ## 输出文件
37 |
38 | 脚本将在当前目录下创建一个名为 `user_` 的文件夹,其中 `` 是DID路径的最后一个段。在这个文件夹中,将生成以下文件:
39 |
40 | 1. `did.json` - DID文档
41 | 2. `private_keys.json` - 私钥文档,包含私钥文件的路径和类型信息
42 | 3. `_private.pem` - 私钥文件,例如 `key-1_private.pem`
43 |
44 | ### DID文档格式示例
45 |
46 | ```json
47 | {
48 | "@context": [
49 | "https://www.w3.org/ns/did/v1",
50 | "https://w3id.org/security/suites/jws-2020/v1",
51 | "https://w3id.org/security/suites/secp256k1-2019/v1"
52 | ],
53 | "id": "did:wba:service.agent-network-protocol.com:wba:user:lkcoffe",
54 | "verificationMethod": [
55 | {
56 | "id": "did:wba:service.agent-network-protocol.com:wba:user:lkcoffe#key-1",
57 | "type": "EcdsaSecp256k1VerificationKey2019",
58 | "controller": "did:wba:service.agent-network-protocol.com:wba:user:lkcoffe",
59 | "publicKeyJwk": {
60 | "kty": "EC",
61 | "crv": "secp256k1",
62 | "x": "...",
63 | "y": "...",
64 | "kid": "..."
65 | }
66 | }
67 | ],
68 | "authentication": [
69 | "did:wba:service.agent-network-protocol.com:wba:user:lkcoffe#key-1"
70 | ]
71 | }
72 | ```
73 |
74 | ### 私钥文档格式示例
75 |
76 | ```json
77 | {
78 | "did": "did:wba:service.agent-network-protocol.com:wba:user:lkcoffe",
79 | "keys": {
80 | "key-1": {
81 | "path": "key-1_private.pem",
82 | "type": "EcdsaSecp256k1"
83 | }
84 | }
85 | }
86 | ```
87 |
88 | ## 注意事项
89 |
90 | - 私钥文件包含敏感信息,请妥善保管
91 | - 当前仅支持secp256k1密钥类型
92 | - DID必须以`did:wba:`开头
93 |
--------------------------------------------------------------------------------
/AGENTS.md:
--------------------------------------------------------------------------------
1 | # Repository Guidelines
2 |
3 | ## Project Structure & Module Organization
4 | Core protocol logic lives under `anp/meta_protocol/`, with identity in `anp/authentication/`, encryption in `anp/e2e_encryption/`, shared helpers within `anp/utils/`, and interoperability tooling in `anp/anp_crawler/`. Tests shadow the package layout inside `anp/unittest//test_.py`, while docs stay in `docs/`, runnable walkthroughs in `examples/`, JVM clients in `java/`, and release bundles in `dist/`. Keep new assets alongside their feature modules to simplify discovery.
5 |
6 | ## Build, Test, and Development Commands
7 | Run `uv sync` to install pinned dependencies, then `uv run pytest` (or `uv run pytest -k "handshake"`) for targeted suites. Package releases with `uv build --wheel`. Validate negotiation flows using `uv run python examples/ping_pong.py`, and inspect the CLI via `uv run python -m anp.meta_protocol.cli --help`. Keep a clean virtual environment by preferring `uv run