यह पृष्ठ चीनी मूल से अनूदित है। दोनों में अंतर होने पर मूल पाठ मान्य है।

Confer — प्रोटोकॉल का डिज़ाइन

Confer इंस्टेंसों के बीच, और उपयोगकर्ता के क्लाइंट तथा सर्वर के बीच के सभी प्रोटोकॉल यहाँ परिभाषित हैं। सब खुले मानकों पर टिके हैं, ताकि आगे फ़ेडरेशन आसान रहे।

Agent की पहचान

DID:web प्रारूप

हर उपयोगकर्ता या कंपनी का इंस्टेंस अपना DID दस्तावेज़ खुद रखता है:

https://acme.com/.well-known/did.json

DID दस्तावेज़ की संरचना (W3C DID v1.0 के अनुकूल):

{
  "@context": ["https://www.w3.org/ns/did/v1"],
  "id": "did:web:acme.com",
  "verificationMethod": [
    {
      "id": "did:web:acme.com#key-1",
      "type": "Ed25519VerificationKey2020",
      "controller": "did:web:acme.com",
      "publicKeyMultibase": "z6MkpTHR8VNsBxYAAWHut2Geadd9jSrue..."
    }
  ],
  "service": [
    {
      "id": "did:web:acme.com#confer-agent",
      "type": "ConferAgent",
      "serviceEndpoint": "https://acme.com/a2a/v1"
    }
  ]
}

उपयोगकर्ता के Agent का DID इस रूप में होता है: did:web:acme.com:agents:laowang — मुख्य इंस्टेंस और उसके आगे एक पथ खंड। इसी से एक इंस्टेंस कई उपयोगकर्ताओं को संभाल सकता है।

did:web विनिर्देश के अनुसार, उप-पहचानकर्ता वाला DID (यानी पथ खंडों वाला) उसी पथ के दस्तावेज़ पर हल होता है, इंस्टेंस की जड़ के .well-known पर नहीं:

कुंजी बदलना

AgentFacts (NANDA के अनुकूल)

हर Agent अपना विवरण देने वाला एक AgentFacts प्रकाशित करता है। स्थान:

https://acme.com/agents/{slug}/agent.json

या well-known की सामान्य सूची:

https://acme.com/.well-known/agents.json

संरचना का उदाहरण:

{
  "@context": "https://nanda.dev/schemas/agent/v1",
  "did": "did:web:acme.com:agents:support",
  "name": "ABC Industries Support Agent",
  "description": "Technical support for X100, X200 industrial controllers",
  "owner": {
    "type": "Organization",
    "name": "ABC Industries Ltd.",
    "url": "https://acme.com"
  },
  "capabilities": [
    {
      "type": "qa",
      "scope": ["X100", "X200", "Modbus", "RTU", "TCP"],
      "languages": ["en", "zh", "de"]
    },
    {
      "type": "code-generation",
      "scope": ["python", "c", "embedded"],
      "languages": ["en", "zh"]
    }
  ],
  "endpoints": {
    "a2a": "https://acme.com/a2a/v1",
    "stream": "https://acme.com/a2a/v1/stream"
  },
  "trust": {
    "verifiedBy": ["did:web:nanda.org"],
    "issuedAt": "2024-10-01T00:00:00Z"
  },
  "publicKey": {
    "id": "did:web:acme.com#key-1",
    "type": "Ed25519VerificationKey2020"
  }
}

क्षेत्रों का अर्थ:

A2A प्रोटोकॉल

प्रोटोकॉल की परत

सारा A2A संचार HTTPS POST/GET से होता है, JSON में कूटबद्ध। /a2a/v1 के नीचे दो बाइंडिंग साथ-साथ रहती हैं:

दोनों एक ही फाटकों से गुज़रते हैं — हस्ताक्षर सत्यापन, सहमति फाटक, नीति निर्णय, थ्रेड का स्वामित्व — और वे सब a2a/inbound.ts में हैं; फ़र्क़ सिर्फ़ तार पर के प्रारूप का है। हर बाइंडिंग के लिए ये फाटक अलग से लिखना ही वह कारण है जिससे अंतर-किरायेदार थ्रेड इंजेक्शन का बग चार बार लिखा गया; इन्हें दोबारा मत बाँटिए।

मूल बात: HTTP Message Signatures (RFC 9421) इस्तेमाल होते हैं, bearer टोकन नहीं। कारण:

हस्ताक्षर जिन घटकों को ढकता है वे हैं @method, @authority और @path, साथ में @query (जब अनुरोध में क्वेरी स्ट्रिंग हो) और content-digest (जब बॉडी हो), और date। @query कोई वैकल्पिक बारीकी नहीं है: @path ? पर रुक जाता है, और REST बाइंडिंग का GET /tasks पूरी तरह क्वेरी पैरामीटरों से छाँटता और पन्ने पलटता है; उन्हें न ढकना यानी बीच के किसी को उन्हें मनमाने ढंग से बदलने देना, और हस्ताक्षर फिर भी सही निकलेगा। हस्ताक्षर के पैरामीटरों में हर अनुरोध पर एक यादृच्छिक nonce भी होता है — created की सूक्ष्मता सेकंड तक ही है, इसलिए एक ही सेकंड में दो समान अनुरोध एक जैसे बाइट पर हस्ताक्षर करते, और सामने वाले की रिप्ले कैश उन्हें हमला मानकर ठुकरा देती (किसी task की जाँच या कोई भी पुनःप्रयास इसी से टकराता है)। असली पुनःप्रेषण — वही बाइट ज्यों के त्यों दोबारा — अब भी पकड़ा जाता है, क्योंकि तब हस्ताक्षर बाइट-दर-बाइट वही होता है।

इस परत में विनिर्देश के securitySchemes नहीं हैं: वे API कुंजी, HTTP प्रमाणन, OAuth2, OIDC या mTLS हैं, और इनमें से कोई भी अनुरोध-हस्ताक्षर नहीं है। असली अपेक्षा Card पर एक अनिवार्य विस्तार के रूप में घोषित होती है, और REST बाइंडिंग उसे §3.3.4 के अनुसार लागू करती है: जो क्लाइंट वह विस्तार घोषित नहीं करता उसे ExtensionSupportRequiredError मिलता है, न कि ऐसा 401 जो कुछ समझाता ही नहीं।

आने वाले अनुरोध का उदाहरण

POST /a2a/v1/messages HTTP/1.1
Host: acme.com
Content-Type: application/json
Date: Sun, 24 Nov 2024 14:30:00 GMT
Content-Digest: sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:
Signature-Input: sig1=("@method" "@authority" "@path" "content-digest" "date");keyid="did:web:vendor-x.com#key-1";created=1732458600;alg="ed25519"
Signature: sig1=:aBcDeF...:
Authorization: Capability eyJhbGciOiJFZDI1NTE5IiwidHlwIjoiQ2FwIn0...

{
  "from": "did:web:vendor-x.com:agents:engineer-li",
  "to": "did:web:acme.com:agents:support",
  "thread_id": "thread_8f3a9c",
  "message": {
    "type": "question",
    "content": "RTU मोड में X100 की वोल्टेज सीमा क्या है?",
    "language": "hi",
    "context": {
      "via": "claude-code",
      "project_hint": "modbus integration"
    }
  }
}

सत्यापन का क्रम (प्राप्तकर्ता की ओर)

  1. Signature-Input और Signature हेडर पढ़ें।
  2. Signature-Input के keyid पैरामीटर से DID निकालें।
  3. DID दस्तावेज़ लाएँ (कैश सहित: ETag + 60s TTL)।
  4. सार्वजनिक कुंजी निकालें, RFC 9421 §2.5 के अनुसार हस्ताक्षर की आधार-श्रृंखला दोबारा बनाएँ, और हस्ताक्षर सत्यापित करें।
  5. जाँचें कि Content-Digest बॉडी के हैश से मेल खाता है।
  6. जाँचें कि Date 5 मिनट के भीतर है (पुनःप्रेषण से बचाव)।
  7. capability टोकन सत्यापित करें (macaroon शैली, नीचे विस्तार से)।
  8. संपर्क सहमति फाटक: भेजने वाला प्राप्तकर्ता के संपर्कों में पहले से है? यदि नहीं → LLM नहीं चलता; अनुरोध संपर्क-निवेदन के रूप में लंबित रह जाता है (नीचे देखें)।
  9. यदि है → नीति इंजन तय करता है कि उत्तर देना है या नहीं।

Capability टोकन

Capability टोकन से भेजने वाला Agent कह पाता है “मैं उपयोगकर्ता X की ओर से Y प्रकार का सवाल पूछने आया हूँ”, और अधिकार बारीकी से सीमित हो जाते हैं।

रूप JWT जैसा, पर विचार macaroon वाला:

{
  "iss": "did:web:vendor-x.com",
  "sub": "did:web:vendor-x.com:users:engineer-li",
  "aud": "did:web:acme.com",
  "scope": ["ask:technical", "ask:product:X100"],
  "exp": 1737000000,
  "ctx": {
    "thread_id": "thread_8f3a9c",
    "delegation_depth": 1
  }
}

धारा में उत्तर

LLM उत्तर धारा में बनाता है, और A2A भी SSE समर्थित है:

GET /a2a/v1/stream/{message_id} HTTP/1.1
Host: acme.com
Signature: ...

text/event-stream लौटाता है:

event: token
data: {"text": "X100 "}

event: token
data: {"text": "RTU मोड में "}

event: citation
data: {"source": "X100 इंस्टॉलेशन मैनुअल पृ. 12", "url": "..."}

event: done
data: {"thread_id": "thread_8f3a9c"}

अनुमति मॉडल (Claude Code से प्रेरित)

तीन स्तर:

L1 — स्वतः (पुष्टि की ज़रूरत नहीं)

L2 — एक बार पूछना

इंटरफ़ेस में: अनुमति कार्ड खुलता है, चार विकल्पों के साथ:

L3 — स्पष्ट सहमति (हर बार पूछा जाए)

इंटरफ़ेस में: मोडल विंडो + कार्रवाई की विस्तृत सूची + उलटी गिनती (ग़लती से दबने से बचाव)।

स्थायी नीतियाँ

उपयोगकर्ता पहले से नियम तय कर सकता है जो डिफ़ॉल्ट व्यवहार पर भारी पड़ें:

peer.acme-industries:
  allow:
    - read: "src/modbus/**"
    - ask: "technical:*"
  deny:
    - read: ".env"
    - read: "**/secrets/**"
    - ask: "personal:*"
  always_consult: true

peer.unknown:
  default: ask_user
  require_human_in_loop: true

संपर्क सहमति फाटक

किसी A2A संदेश का उत्तर देना प्राप्तकर्ता का LLM बजट खर्च करता है। ताकि कोई अजनबी Agent मालिक की जानकारी के बिना बेतहाशा संदेश भेजकर उसके टोकन न जला दे, इस खर्च की पूर्वशर्त है जुड़ा होना:

मॉडल LinkedIn या किसी कंपनी-फ़ेडरेशन जैसा है: खोज की परत खुली (कोई भी agents.json और AgentFacts पढ़ सकता है), मेल-जोल की परत सहमति-सापेक्ष (जुड़ने के बाद ही दूसरे की गणना-शक्ति खर्च होती है)।

«जुड़ा हुआ» होने के दो रास्ते हैं:

  1. प्राप्तकर्ता खुद POST /contacts/lookup → POST /contacts से उस peer को जोड़े;
  2. peer पहल करे और प्राप्तकर्ता पेटी में उसका निवेदन स्वीकार करे।

थ्रेड का बंधन (thread_id का दायरा)

आने वाले संदेश का thread_id peer की एक प्रार्थना है, कोई आधिकारिक आदेश नहीं। gateway उसे मूल रूप में तभी दोबारा इस्तेमाल करता है जब दो शर्तें एक साथ पूरी हों:

  1. वह peer उस संवाद का भागीदार पहले से हो;
  2. वह संवाद जिस Agent को संदेश भेजा गया है उसके मालिक का हो (conversations.created_by)।

दूसरी शर्त छोड़ी नहीं जा सकती: peer_agents DID के हिसाब से विश्व भर में अद्वितीय है, इसलिए एक ही peer कई मालिकों से एक साथ जुड़ा हो सकता है। सिर्फ़ पहली जाँचें तो A और B दोनों से जुड़ा कोई peer, B के Agent को संदेश भेजते समय A का thread_id लगा सकता है और संदेश को A के संवाद में उड़ेल सकता है — B का Agent A के इतिहास को संदर्भ मानकर उत्तर देगा, उत्तर A के थ्रेड में लिखा जाकर A तक प्रसारित होगा, और ऊपर से A के संवाद की सामग्री B की दीर्घकालिक स्मृति में जा बैठेगी।

दोनों पूरी हों तो इसका अर्थ है कि सामने वाला हमारी ओर से भेजे गए संदेश का उत्तर दे रहा है (और तब thread_id हमारे अपने संवाद की id है)। न हों तो वह peer की अपनी गिनती का थ्रेड है — यहाँ किसी चीज़ की ओर इशारा नहीं करता, पर peer के लिए स्थिर है, इसलिए हमारी संवाद-id sha256('a2a-thread:<मालिक की id>:<peer पंक्ति की id>:<peer का thread_id>') से व्युत्पन्न होती है (lib/derived-id.ts, जो 26 अक्षरों का Crockford लौटाता है, ULID जैसा ही रूप)। इस तरह उसी peer थ्रेड के आगे के संदेश हमेशा उसी संवाद में लौटते हैं।

पहले «अनजाने thread_id» को «कोई थ्रेड नहीं» मान लिया जाता था, इसलिए प्राप्तकर्ता हर आने वाले संदेश पर एक नया संवाद बना देता था: आगे का सवाल मूल सवाल के पास कभी नहीं रहता, मालिक की संवाद-सूची एक-एक पंक्ति वाले थ्रेडों से भर जाती, loadA2AHistory को कोई इतिहास नहीं मिलता, और Agent हर दौर ऐसे उत्तर देता मानो पहली बार बात हो रही हो।

«मानचित्र तालिका रखने» के बजाय व्युत्पन्न करने के दो फ़ायदे हैं: कोई माइग्रेशन नहीं चाहिए, और होड़ संभव ही नहीं — एक साथ आए दो संदेश प्राथमिक कुंजी पर टकराते हैं, बजाय इसके कि हर एक अपना संवाद बना ले (इसीलिए संवाद बनाना लेन-देन के भीतर onConflictDoNothing के साथ होता है)। जोड़ी गई श्रृंखला में केवल अंतिम खंड की लंबाई बदल सकती है और वही peer के नियंत्रण में है; बाक़ी खंड 26 अक्षरों की निश्चित id हैं, इसलिए बिना बचाव वाला कोलन कोई द्विअर्थ नहीं बनाता।

संवाद बनाते समय conversation_participants में मालिक और peer दोनों एक साथ लिखे जाते हैं। मालिक की भागीदारी वाली पंक्ति ही संवाद-सूची और प्रति-संवाद पठन फाटक का आधार है; वह न हो तो मालिक को वह थ्रेड दिखेगा ही नहीं जिसका उत्तर उसका अपना Agent दे रहा है।

इसलिए thread_id हर पक्ष की अपनी-अपनी संवाद id है, दोनों ओर एक जैसी नहीं। इससे दो नियम निकलते हैं जो छोड़े नहीं जा सकते:

उत्तर न दे पाना भी एक उत्तर है

जब जिस Agent को संदेश गया है वह यह दौर चला ही नहीं सकता (मॉडल तय नहीं, प्रदाता अनजाना, प्रदाता तय पर कुंजी नहीं, या मॉडल की कॉल में त्रुटि), तो वह type: 'notification' भेजता है जिसका context.error मशीन-पठनीय कोड लिए होता है (no_model_configured / unknown_provider / no_key_for_provider / agent_error), और जिसका content अंग्रेज़ी में एक व्याख्या-वाक्य है। notification इसलिए कि वह सामने वाले पर दोबारा स्वतः उत्तर नहीं जगाता (यह सिर्फ़ question करता है)।

ऐसा न करने का मतलब «एक सूचना कम» नहीं है: विफलता उत्तर देने वाले के यहाँ बस एक लॉग पंक्ति बनकर रह जाती है, तार पर कुछ नहीं जाता, और पूछने वाले का /api/v1/consult/{id}/reply समय-सीमा तक जाँचता रहकर pending लौटाता है — हर पुनःप्रयास पर वही, और «अभी सोच रहा है» तथा «कभी नहीं आएगा» में फ़र्क़ करने का कोई उपाय ही नहीं बचता।

सामने वाला दूसरा इंस्टेंस है और हमारी भाषा नहीं जानता, इसलिए आधार context.error का कोड है; content सिर्फ़ मनुष्य के पढ़ने लायक़ आख़िरी सहारा है। यह «सर्वर उपयोगकर्ता के लिए वाक्य नहीं बनाता» वाले नियम से नहीं टकराता: वह नियम इसी इंस्टेंस के अपने क्लाइंट को भेजे जाने वाले पाठ पर लागू होता है।

वही विफलता डेटाबेस में भी दर्ज होती है — संवाद के भीतर content_type: 'system_notice' वाले संदेश के रूप में (in_reply_to उसी सवाल की ओर, content_json में वही कोड, और वाक्य क्लाइंट i18n से बनाता है)। भेजकर दर्ज न करने के तीन परिणाम हैं, और तीनों सचमुच हो चुके हैं: मालिक को अपने IM में सामने वाले का सवाल दिखता है और उसके बाद कुछ नहीं, और उसे कभी पता ही नहीं चलता कि मॉडल तो उसी ने तय नहीं किया था; A2A REST बाइंडिंग का task FAILED के बजाय WORKING पर ठहरा रहता है, और क्लाइंट ऐसी चीज़ की जाँच करता रहता है जो कभी पूरी नहीं होगी; और GET /a2a/v1/stream/{id} अनंत काल तक pending लौटाता है। इस नोट के साथ तीनों एक ही बार में निर्णय-योग्य अंतिम अवस्था में आ जाते हैं।

पता: दो DID एक ही Agent पर जाते हैं

to Agent DID (did:web:<host>:agents:<user>:agent, जो सार्वजनिक सूची /.well-known/agents.json में दिखता है) और मालिक DID (did:web:<host>:agents:<user>) — दोनों स्वीकार करता है। बाद वाला ही एकमात्र पहचानकर्ता है जो DID दस्तावेज़ पर हल होता है, और वही क्लाइंट उपयोगकर्ता को नक़ल करने के लिए दिखाता है: सिर्फ़ पहला मानने से «DID चिपकाकर संपर्क जोड़ना» ऐसा संपर्क देता है जिससे जुड़ाव भी होता है, हस्ताक्षर भी सही निकलता है, और जवाब 404 आता है।

इसी तरह, भेजने वाला peer जुड़ा है या नहीं यह तय करते समय from (Agent DID) और हस्ताक्षर सत्यापन से मिला हस्ताक्षरकर्ता DID (मालिक DID) — दोनों मानने होंगे: peer_agents में पंक्ति DID के हिसाब से बनती है, और उनमें से कौन-सा वहाँ दर्ज हुआ यह इस पर निर्भर करता है कि संपर्क उस समय किस तरह जोड़ा गया था; सिर्फ़ from मानने से सामने वाले का उत्तर «किसी अजनबी का संपर्क-निवेदन» बन जाता है।

प्रतीक्षा-पेटी (मालिक की अनुपस्थिति में उत्तर)

जब पहले से जुड़े peer का सवाल आए और मालिक मौजूद न हो, तो नीति इंजन तय करता है (evaluatePolicy, action=ask, L2):

A2A उत्तर की क्षमता: आने वाला A2A उत्तर और वेब चैट एक ही साझा ऑर्केस्ट्रेशन से गुज़रते हैं (orchestration/agent-orchestrator.ts का runAgentTurn), पर उनकी क्षमताएँ एक जैसी नहीं हैं। runAgentTurn एक अनिवार्य audience लेता है ('owner' | 'peer' — अनिवार्य, डिफ़ॉल्ट वाला नहीं, क्योंकि डिफ़ॉल्ट मान वही होता जो ढीला है), और उसी से औज़ारों का समूह तथा पहुँच में आने वाला डेटा-तल दोनों तय होते हैं:

  • मालिक का दौर (वेब चैट): web_search, search_knowledge_base (सभी ज्ञान-कोश), list_knowledge_bases, search_memory, list_contacts, और दीर्घकालिक स्मृति स्वतः जोड़ी जाती है।
  • peer का दौर (आने वाला A2A उत्तर): केवल web_search, search_knowledge_base और list_knowledge_bases, और खोज केवल उन्हीं ज्ञान-कोशों तक सीमित है जिन पर shared_with_peers का निशान है; दीर्घकालिक स्मृति नहीं उठाई जाती, और न search_memory दिया जाता है न list_contacts — पहला मालिक की निजी बातचीत से जमे तथ्य हैं, दूसरा उसका सामाजिक जाल; किसी अजनबी के सवाल का उत्तर देने में इनमें से किसी की ज़रूरत नहीं।

सीमा डेटा-तल से बनती है, प्रॉम्प्ट से नहीं: peer का सवाल और मालिक के निर्देश मॉडल तक एक ही तरह के पाठ के रूप में पहुँचते हैं, इसलिए «Agent बताने से इनकार कर देगा» टिकता नहीं; टिकता सिर्फ़ यह है कि खोज भौतिक रूप से वहाँ पहुँच ही न सके। इसी कारण कोई औज़ार न देना पहुँच-नियंत्रण नहीं है: मॉडल ऐसे औज़ार-नाम की कॉल भी कर सकता है जो उसे कभी दिया ही नहीं गया, इसलिए मालिक-मात्र वाली शाखाएँ executeToolCall के भीतर audience दोबारा जाँचती हैं।

दोनों तरह के दौर मालिक की कुंजी इस्तेमाल करते हैं, पूछने वाले peer की नहीं। मिले हुए ज्ञान-कोश अंश messages.citations_json में उद्धरण के रूप में सहेजे जाते हैं, और उत्तर पूरा होने पर इस दौर के तथ्य अतुल्यकालिक रूप से दीर्घकालिक स्मृति में जमा होते हैं (peer के दौर से आई पंक्तियों पर a2a का निशान लगता है, और उठाते समय उनका स्रोत बताया जाता है)। मालिक के पास embedding / ज्ञान-कोश / tavily कुंजियाँ न हों तो सहजता से केवल-LLM उत्तर पर उतर आता है (कोई त्रुटि नहीं, कोई उद्धरण नहीं)। allow का और स्वीकृत ask_user का उत्तर-मार्ग यही ऑर्केस्ट्रेशन साझा करते हैं।

ask='ask' वाली लंबित अनुमति का scope_json इस रूप में होता है: { kind:'a2a_question', conversation_id, inbound_message_id, sender_did, peer_id, content } — स्वीकृति के समय उत्तर दोबारा बनाकर आगे बढ़ाने के लिए इतना काफ़ी है (agent और peer user_id/peer_id से उसी समय पढ़े जाते हैं; निष्क्रिय-दोहराव-सुरक्षित: उत्तर पहले से हो तो छोड़ दिया जाता है)। स्थायी नीति तय करने का UI, «संपादित करके उत्तर देना», और push सूचनाएँ अब भी backlog में हैं।

फ़ेडरेटेड खोज

डोमेन से खोज

डोमेन acme.com मिलने पर क्लाइंट:

  1. मुख्य DID के लिए https://acme.com/.well-known/did.json लाता है।
  2. उस डोमेन के सभी सार्वजनिक Agents की सूची के लिए https://acme.com/.well-known/agents.json लाता है।
  3. एक चुनकर संपर्क में जोड़ लेता है।

उपयोगकर्ता DID का हल

किसी उपयोगकर्ता के Agent का उप-पहचानकर्ता DID मिल जाने पर उसका DID दस्तावेज़ did:web विनिर्देश के अनुसार हल होता है:

आने वाले A2A का हस्ताक्षर सत्यापन ठीक इसी रास्ते चलता है: Signature-Input के keyid से हस्ताक्षरकर्ता DID निकालें → ऊपर वाले URL पर हल करें → verificationMethod में से keyid से मेल खाती सार्वजनिक कुंजी लेकर सत्यापित करें। वह दस्तावेज़ केवल सार्वजनिक कुंजी सामग्री उजागर करता है, और verificationMethod[*].id वही key_id है जो संग्रहीत है (अनुरोध के Host से दोबारा नहीं गढ़ा जाता), इसलिए दूसरे इंस्टेंस से हल करने पर और स्थानीय रूप से हल करने पर मिली id सदा एक ही रहती है।

सार्वजनिक रजिस्ट्री (v2+)

NANDA Index या वैसी ही किसी सार्वजनिक रजिस्ट्री से जुड़ना, जिससे संभव हो:

भरोसे का जाल (v2+)

स्पैम रोकथाम

अनुवाद नीति

प्रोटोकॉल के विकास की नीति

← Confer पर वापस A2A · DID:web · RFC 9421 · NANDA