├── 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