Full Code of a2aproject/A2A for AI

main 7b900e77be2e cached
100 files
509.1 KB
129.0k tokens
7 symbols
1 requests
Download .txt
Showing preview only (538K chars total). Download the full file or copy to clipboard to get everything.
Repository: a2aproject/A2A
Branch: main
Commit: 7b900e77be2e
Files: 100
Total size: 509.1 KB

Directory structure:
gitextract_6mxkg8fn/

├── .devcontainer/
│   ├── README.md
│   ├── devcontainer.json
│   └── setup.sh
├── .editorconfig
├── .gemini/
│   └── config.yaml
├── .git-blame-ignore-revs
├── .gitattributes
├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-report.yml
│   │   └── feature-request.yml
│   ├── PULL_REQUEST_TEMPLATE/
│   │   ├── PULL_REQUEST_TEMPLATE.md
│   │   └── become_a_repo_maintainer.md
│   ├── actions/
│   │   └── spelling/
│   │       ├── advice.md
│   │       ├── allow.txt
│   │       ├── excludes.txt
│   │       └── line_forbidden.patterns
│   ├── conventional-commit-lint.yaml
│   ├── dependabot.yml
│   ├── linters/
│   │   ├── .eslintrc.js
│   │   ├── .jscpd.json
│   │   ├── .markdownlint.json
│   │   ├── .protolint.yaml
│   │   └── .stylelintrc.json
│   ├── super-linter.env
│   └── workflows/
│       ├── check-linked-issues.yml
│       ├── conventional-commits.yml
│       ├── dispatch-a2a-update.yml
│       ├── docs.yml
│       ├── issue-metrics.yml
│       ├── links.yaml
│       ├── linter.yaml
│       ├── release-please.yml
│       ├── sort-spelling-allowlist.yml
│       ├── spelling.yaml
│       └── stale.yaml
├── .gitignore
├── .gitvote.yml
├── .mkdocs/
│   ├── macros.py
│   └── overrides/
│       └── main.html
├── .prettierrc
├── .ruff.toml
├── .vscode/
│   └── settings.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── GOVERNANCE.md
├── LICENSE
├── MAINTAINERS.md
├── README.md
├── SECURITY.md
├── adrs/
│   ├── adr-001-protojson-serialization.md
│   └── adr-template.md
├── docs/
│   ├── 404.html
│   ├── README.md
│   ├── announcing-1.0.md
│   ├── community.md
│   ├── definitions.md
│   ├── index.md
│   ├── llms.txt
│   ├── partners.md
│   ├── roadmap.md
│   ├── robots.txt
│   ├── sdk/
│   │   ├── index.md
│   │   └── python.md
│   ├── specification.md
│   ├── stylesheets/
│   │   └── custom.css
│   ├── topics/
│   │   ├── a2a-and-mcp.md
│   │   ├── agent-discovery.md
│   │   ├── enterprise-ready.md
│   │   ├── extensions.md
│   │   ├── key-concepts.md
│   │   ├── life-of-a-task.md
│   │   ├── streaming-and-async.md
│   │   └── what-is-a2a.md
│   ├── tutorials/
│   │   ├── index.md
│   │   └── python/
│   │       ├── 1-introduction.md
│   │       ├── 2-setup.md
│   │       ├── 3-agent-skills-and-card.md
│   │       ├── 4-agent-executor.md
│   │       ├── 5-start-server.md
│   │       ├── 6-interact-with-server.md
│   │       ├── 7-streaming-and-multiturn.md
│   │       └── 8-next-steps.md
│   └── whats-new-v1.md
├── lychee.toml
├── mkdocs.yml
├── requirements-docs.txt
├── scripts/
│   ├── build_docs.sh
│   ├── build_llms_full.sh
│   ├── build_sdk_docs.sh
│   ├── deploy_root_files.sh
│   ├── format.sh
│   ├── lint.sh
│   ├── proto_to_json_schema.sh
│   └── sort_spelling.sh
└── specification/
    ├── .api-linter.yaml
    ├── a2a.proto
    ├── buf.gen.yaml
    ├── buf.yaml
    └── json/
        └── README.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .devcontainer/README.md
================================================
# A2A Development Container

This devcontainer provides a fully configured development environment for the A2A project with all required dependencies pre-installed.

## What's Included

### Build Tools

- **protoc** (v28.3) - Protocol Buffers compiler
- **protoc-gen-jsonschema** (bufbuild) - JSON Schema generator for protobuf
- **jq** (latest) - JSON processor
- **googleapis** - Google API proto definitions

### Development Tools

- **Python 3.12** with all documentation dependencies
- **Go** (latest) - for protoc plugin compilation

### VS Code Extensions

- Python language support with Pylance
- Buf for Protocol Buffers
- Code Spell Checker

## Usage

### Opening in VS Code

1. Install the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
2. Open this repository in VS Code
3. When prompted, click "Reopen in Container" (or use Command Palette: "Dev Containers: Reopen in Container")
4. Wait for the container to build and dependencies to install

### Building Documentation

Once inside the container:

```bash
# Build all documentation
./scripts/build_docs.sh

# Convert proto to JSON Schema only
./scripts/proto_to_json_schema.sh specification/json/a2a.json
```

### GitHub Codespaces

This devcontainer configuration also works with GitHub Codespaces:

1. Go to the repository on GitHub
2. Click "Code" → "Codespaces" → "Create codespace on [branch]"
3. Wait for the environment to be provisioned

## Benefits

- **Reproducible builds**: Everyone uses the same tool versions
- **No local setup**: No need to install protoc, jq, etc. on your host machine
- **Quick onboarding**: New contributors can start developing immediately
- **CI/CD alignment**: Same environment as CI can use similar container

## Customization

To modify the environment:

- **Add tools**: Edit `.devcontainer/setup.sh`
- **Change Python/Go versions**: Edit `features` in `devcontainer.json`
- **Add VS Code extensions**: Edit `customizations.vscode.extensions` in `devcontainer.json`

## Troubleshooting

### Container build fails

```bash
# Rebuild without cache
Dev Containers: Rebuild Container (without cache)
```

### Tools not found after setup

```bash
# Re-run setup script manually
bash .devcontainer/setup.sh
```


================================================
FILE: .devcontainer/devcontainer.json
================================================
{
    "name": "A2A Development",
    "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
    "features": {
        "ghcr.io/devcontainers/features/python:1": {
            "version": "3.12"
        },
        "ghcr.io/devcontainers/features/go:1": {
            "version": "latest"
        },
        "ghcr.io/devcontainers/features/node:1": {
            "version": "lts"
        }
    },
    "postCreateCommand": "bash .devcontainer/setup.sh",
    "customizations": {
        "vscode": {
            "extensions": [
                "ms-python.python",
                "ms-python.vscode-pylance",
                "bufbuild.vscode-buf",
                "streetsidesoftware.code-spell-checker"
            ],
            "settings": {
                "python.defaultInterpreterPath": "/usr/local/bin/python"
            }
        }
    },
    "forwardPorts": [
        8000
    ],
    "remoteUser": "vscode"
}


================================================
FILE: .devcontainer/setup.sh
================================================
#!/bin/bash
set -euo pipefail

echo "==> Setting up A2A development environment..."

# Install system dependencies
echo "→ Installing system packages..."
sudo apt-get update
sudo apt-get install -y \
  curl \
  git \
  jq \
  unzip

# Install Protocol Buffers compiler
echo "→ Installing protoc..."
PROTOC_VERSION="28.3"
PROTOC_ZIP="protoc-${PROTOC_VERSION}-linux-x86_64.zip"
curl -fsSL -o /tmp/protoc.zip "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/${PROTOC_ZIP}"
sudo unzip -q /tmp/protoc.zip -d /usr/local
rm /tmp/protoc.zip

# Install protoc-gen-jsonschema (bufbuild)
echo "→ Installing protoc-gen-jsonschema..."
go install github.com/bufbuild/protoschema-plugins/cmd/protoc-gen-jsonschema@latest
go_bin_path="$(go env GOPATH)/bin/protoc-gen-jsonschema"
if [ -f "$go_bin_path" ]; then
  sudo cp "$go_bin_path" /usr/local/bin/
fi

# Install buf CLI
echo "→ Installing buf..."
go install github.com/bufbuild/buf/cmd/buf@latest
go_bin_path="$(go env GOPATH)/bin/buf"
if [ -f "$go_bin_path" ]; then
  sudo cp "$go_bin_path" /usr/local/bin/
fi

# Install googleapis proto files to third_party
echo "→ Installing googleapis..."
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WORKSPACE_DIR="$(dirname "$SCRIPT_DIR")"
GOOGLEAPIS_DIR="$WORKSPACE_DIR/third_party/googleapis"
if [ ! -d "$GOOGLEAPIS_DIR" ]; then
  mkdir -p "$WORKSPACE_DIR/third_party"
  cd "$WORKSPACE_DIR/third_party"
  git clone --depth 1 https://github.com/googleapis/googleapis.git
  cd "$WORKSPACE_DIR"
fi

# Install Python dependencies for documentation
echo "→ Installing Python packages..."
pip install --no-cache-dir -r requirements-docs.txt

# Verify installations
echo ""
echo "==> Verifying installations..."
echo "protoc: $(protoc --version)"
echo "protoc-gen-jsonschema: $(which protoc-gen-jsonschema)"
echo "buf: $(buf --version 2>/dev/null || echo 'not found')"
echo "jq: $(jq --version)"
echo "python: $(python --version)"
echo "go: $(go version)"

echo ""
echo "✓ Development environment ready!"
echo ""
echo "To build documentation:"
echo "  ./scripts/build_docs.sh"
echo ""
echo "To convert proto to JSON Schema:"
echo "  ./scripts/proto_to_json_schema.sh specification/json/a2a.json"


================================================
FILE: .editorconfig
================================================
# editorconfig.org
root = true

[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.sh]
indent_style = space
indent_size = 2


================================================
FILE: .gemini/config.yaml
================================================
code_review:
  comment_severity_threshold: LOW
ignore_patterns: ['CHANGELOG.md']


================================================
FILE: .git-blame-ignore-revs
================================================
# Template taken from https://github.com/v8/v8/blob/master/.git-blame-ignore-revs.
#
# This file contains a list of git hashes of revisions to be ignored by git blame. These
# revisions are considered "unimportant" in that they are unlikely to be what you are
# interested in when blaming. Most of these will probably be commits related to linting
# and code formatting.
#
# Instructions:
# - Only large (generally automated) reformatting or renaming CLs should be
#   added to this list. Do not put things here just because you feel they are
#   trivial or unimportant. If in doubt, do not put it on this list.
# - Precede each revision with a comment containing the PR title and number.
#   For bulk work over many commits, place all commits in a block with a single
#   comment at the top describing the work done in those commits.
# - Only put full 40-character hashes on this list (not short hashes or any
#   other revision reference).
# - Append to the bottom of the file (revisions should be in chronological order
#   from oldest to newest).
# - Because you must use a hash, you need to append to this list in a follow-up
#   PR to the actual reformatting PR that you are trying to ignore.
0f8d9750bcb17f6b8b9f48793b46f7b8510cae24


================================================
FILE: .gitattributes
================================================
# Documentation overrides
/docs/** linguist-documentation=true
/.mkdocs/** linguist-documentation=true
# Removed committed a2a.json; generated at build time.
noxfile.py linguist-vendored=true

# Merge and diff setting
CHANGELOG.md merge=union


================================================
FILE: .github/CODEOWNERS
================================================
# Code owners file.
# This file controls who is tagged for review for any given pull request.
#
# For syntax help see:
# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax

*                       @a2aproject/a2a-tsc
docs/                   @a2aproject/a2a-tsc
scripts/                @a2aproject/a2a-tsc
specification/          @a2aproject/a2a-tsc
docs/specification.md   @a2aproject/a2a-tsc
GOVERNANCE.md           @a2aproject/a2a-tsc
.mkdocs/                @a2aproject/a2a-tsc
.mkdocs.yml             @a2aproject/a2a-tsc
README.md               @a2aproject/a2a-tsc
.gemini/                @a2aproject/a2a-tsc
.mkdocs/                @a2aproject/a2a-tsc
.github/                @a2aproject/a2a-tsc


================================================
FILE: .github/ISSUE_TEMPLATE/bug-report.yml
================================================
name: 🐞 Bug Report
description: File a bug report
title: "[Bug]: "
type: "Bug"
body:
  - type: markdown
    attributes:
      value: |
        Thanks for stopping by to let us know something could be better!
        Private Feedback? Please use this [Google form](https://goo.gle/a2a-feedback)
  - type: textarea
    id: what-happened
    attributes:
      label: What happened?
      description: Also tell us what you expected to happen and how to reproduce the issue.
      placeholder: Tell us what you see!
      value: "A bug happened!"
    validations:
      required: true
  - type: textarea
    id: logs
    attributes:
      label: Relevant log output
      description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
      render: shell
  - type: checkboxes
    id: terms
    attributes:
      label: Code of Conduct
      description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/a2aproject/A2A?tab=coc-ov-file#readme)
      options:
        - label: I agree to follow this project's Code of Conduct
          required: true


================================================
FILE: .github/ISSUE_TEMPLATE/feature-request.yml
================================================
name: 💡 Feature Request
description: Suggest an idea for this repository
title: "[Feat]: "
type: "Feature"
body:
  - type: markdown
    attributes:
      value: |
        Thanks for stopping by to let us know something could be better!
        Private Feedback? Please use this [Google form](https://goo.gle/a2a-feedback)
  - type: textarea
    id: problem
    attributes:
      label: Is your feature request related to a problem? Please describe.
      description: A clear and concise description of what the problem is.
      placeholder: Ex. I'm always frustrated when [...]
  - type: textarea
    id: describe
    attributes:
      label: Describe the solution you'd like
      description: A clear and concise description of what you want to happen.
    validations:
      required: true
  - type: textarea
    id: alternatives
    attributes:
      label: Describe alternatives you've considered
      description: A clear and concise description of any alternative solutions or features you've considered.
  - type: textarea
    id: context
    attributes:
      label: Additional context
      description: Add any other context or screenshots about the feature request here.
  - type: checkboxes
    id: terms
    attributes:
      label: Code of Conduct
      description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/a2aproject/A2A?tab=coc-ov-file#readme)
      options:
        - label: I agree to follow this project's Code of Conduct
          required: true


================================================
FILE: .github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md
================================================
# Description

Thank you for opening a Pull Request!
Before submitting your PR, there are a few things you can do to make sure it goes smoothly:

- [ ] Follow the [`CONTRIBUTING` Guide](https://github.com/a2aproject/A2A/blob/main/CONTRIBUTING.md).
- [ ] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification.
- [ ] Ensure the tests and linter pass (Run `nox -s format` from the repository root to format)
- [ ] Appropriate docs were updated (if necessary)

Fixes #<issue_number_goes_here> 🦕


================================================
FILE: .github/PULL_REQUEST_TEMPLATE/become_a_repo_maintainer.md
================================================
---
name: Become a repo maintainer
about: Request maintainer status for the A2A repo
title: Maintainer Request
assignees: amye

---

If you'd like to become a maintainer of the Agent2Agent repo on GitHub, please submit this template with your PR to add yourself to a maintainers group in [MAINTAINERS.md](../../MAINTAINERS.md).

TSC voting majority will be required to approve maintainers.

Once accepted you'll be able to commit to this repo!

### GitHub user id

- List your GitHub user id

### Company affiliation

- List your company name, or indicate Individual if you're not affiliated with a company

### Requirements

- [ ] I have at least one merged Pull Request
- [ ] I have reviewed the [contribution guidelines](https://github.com/a2aproject/A2A/blob/main/CONTRIBUTING.md)
- [ ] I have enabled [2FA on my GitHub account](https://github.com/settings/security)
- [ ] I have joined the A2A discord


================================================
FILE: .github/actions/spelling/advice.md
================================================
<!-- See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice --> <!-- markdownlint-disable MD033 MD041 -->
<details><summary>If the flagged items are :exploding_head: false positives</summary>

If items relate to a ...

- binary file (or some other file you wouldn't want to check at all).

  Please add a file path to the `excludes.txt` file matching the containing file.

  File paths are Perl 5 Regular Expressions - you can [test](https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.

  `^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude `README.md` (on whichever branch you're using).

- well-formed pattern.

  If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it,
  try adding it to the `patterns.txt` file.

  Patterns are Perl 5 Regular Expressions - you can [test](https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.

  Note that patterns can't match multiline strings.

</details>

<!-- adoption information-->

:steam_locomotive: If you're seeing this message and your PR is from a branch that doesn't have check-spelling,
please merge to your PR's base branch to get the version configured for your repository.


================================================
FILE: .github/actions/spelling/allow.txt
================================================
AAAANSUh
AAAAUA
AAAGHMHc
ACMRTUXB
ACard
AClient
ACo
ADK
ADR
AError
AExecutor
AGP
AIP
ARequest
ASED
ASGI
AServer
AService
ASq
AStarlette
AUTOCOMMIT
Agentspace
Agno
Autogen
Bahasa
Besen
Blogs
CAs
CLIs
Camry
Cjava
Cpzuhi
DDo
DGT
DHDe
Datetimes
Debian
Djq
Dotnet
EBFF
EUR
EUg
Espa
FBT
FHIR
Fbr
GAPI
GAPIC
GBP
GVsb
Gapic
Gci
Genkit
Ghw
GitVote
HBz
HKRMw
HRA
HSTS
HXo
Hackathon
IFdvcmxk
IMPCUk
INR
Ikp
Imh
Imprd
JFUz
JHv
JIUz
JPY
JWKS
JWS
JWTs
Jhb
Jra
KGgo
KRW
LHR
LJcvt
LLM
LLMs
Lix
MSIs
MWpm
Mapr
Mvosg
Nszl
OIDC
OOa
Ollama
PLE
PLW
PMEEi
PTH
Polski
Portugu
QFdk
Qvandrcy
RFCs
RPCs
RUF
SLAs
SLF
SSLv
Solax
TJS
TMDB
Tful
URLTo
Upserting
Urke
VBORw
VHc
Vsb
WHB
WQi
WVw
Witteveen
XBs
XVCJ
Xca
YQGt
YTAKFW
YTT
YWFh
YWdlbn
ZDS
ZKHv
ZXhhb
ZXkt
Zipkin
Zms
aab
aacacac
aboutasha
achat
aconnect
adk
adr
adrs
afet
affef
agentcard
agentic
agentskill
agno
agntcy
agp
ainvoke
aip
airbnb
aldridge
alloydb
amannn
aparse
aproject
aprotocol
argjson
arxiv
askmarvin
asyncclick
autogen
automodule
autouse
backstory
backticks
bbb
beeai
boq
bufbuild
bzr
cae
canceltask
ccc
cdn
ceee
cfe
chrusty
cls
coc
codegen
codeowner
codespace
codewiki
crewai
datamodel
datapart
dbc
dcda
dcfa
dde
deepwiki
direnv
dlai
docstrings
documentai
dotnet
eaf
ebedef
efaab
efbd
embeddings
endblock
endmacro
envoyproxy
euo
evt
excinfo
faa
faf
fafd
fdebd
ffbb
fff
firewalls
flightbook
forbes
fsv
fyi
gapic
gcp
genai
geneknit
genkit
genproto
georoute
gettask
gettickets
gitleaks
gitvote
gle
googleai
googleapi
googleapis
googleblog
gpt
gstatic
gweb
hackathon
hackathons
hqdefault
hughesthe
iana
iat
ietf
inardini
inbox
inmemory
ipynb
iss
jherr
jku
jqlang
jti
jwks
kadirpekel
keystores
konami
kty
langgraph
lerhaupt
linenums
linkedin
linting
listtasks
litellm
llm
llms
lng
logtostderr
marvin
mcp
mcr
mesop
mikefarah
mindsdb
mintlify
motherlode
mozilla
msword
multiagent
multipage
mydb
myorg
nearform
nlp
notif
npush
objc
octicons
oidc
ollama
oneof
openaitx
openapis
openapiv
openapiv2
oreilly
postgres
postgresql
pqr
prefecthq
protoc
protojson
protolint
pyguide
pylance
pymdownx
pypa
pypackages
pytype
pyupgrade
qwq
rcm
regen
repomapr
reportgen
reposted
rst
rvelicheti
sandijean
scm
sllm
sourced
sourcing
squidfunk
srcs
sse
sss
stateclass
stephenh
styleguide
svn
systemctl
tablefmt
tagwords
tasksget
taskslist
taskssend
taskstate
taskstatus
textpart
threadsafe
toctree
tok
toolkits
tracestate
ugc
undoc
utm
venv-docs
versioned
vnd
voa
vscode
weavehacks
webform
webpage
whatwg
wikipedia
winget
wsgi
wwwwwwww
xxxxx
xxxxxxxx
youtube
yyyyyyyy
zzzzzzzz


================================================
FILE: .github/actions/spelling/excludes.txt
================================================
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
(?:^|/)(?i)COPYRIGHT
(?:^|/)(?i)LICEN[CS]E
(?:^|/)(?i)CODE_OF_CONDUCT.md\E$
(?:^|/)(?i).gitignore\E$
(?:^|/)3rdparty/
(?:^|/)go\.sum$
(?:^|/)package(?:-lock|)\.json$
(?:^|/)Pipfile$
(?:^|/)pyproject.toml
(?:^|/)requirements(?:-dev|-doc|-test|)\.txt$
(?:^|/)vendor/
/CODEOWNERS$
\.a$
\.ai$
\.all-contributorsrc$
\.avi$
\.bmp$
\.bz2$
\.cer$
\.class$
\.coveragerc$
\.crl$
\.crt$
\.csr$
\.dll$
\.docx?$
\.drawio$
\.DS_Store$
\.eot$
\.eps$
\.exe$
\.gif$
\.git-blame-ignore-revs$
\.gitattributes$
\.gitkeep$
\.graffle$
\.gz$
\.icns$
\.ico$
\.jar$
\.jks$
\.jpe?g$
\.key$
\.lib$
\.lock$
\.map$
\.min\..
\.mo$
\.mod$
\.mp[34]$
\.o$
\.ocf$
\.otf$
\.p12$
\.parquet$
\.pdf$
\.pem$
\.pfx$
\.png$
\.psd$
\.pyc$
\.pylintrc$
\.qm$
\.s$
\.sig$
\.so$
\.svgz?$
\.sys$
\.tar$
\.tgz$
\.tiff?$
\.ttf$
\.wav$
\.webm$
\.webp$
\.woff2?$
\.xcf$
\.xlsx?$
\.xpm$
\.xz$
\.zip$
^\.github/actions/spelling/
^\Q.github/workflows/spelling.yaml\E$
^\Q.github/workflows/linter.yaml\E$
^\Qlychee.toml\E$
\.vscode/
^\Qdocs/partners.md\E$
^\Qspecification/json/a2a.json\E$
CHANGELOG.md
\.gitignore
^\Qdocs/robots.txt\E$
CODE_OF_CONDUCT.md


================================================
FILE: .github/actions/spelling/line_forbidden.patterns
================================================
# Should be `HH:MM:SS`
\bHH:SS:MM\b

# Should probably be `YYYYMMDD`
\b[Yy]{4}[Dd]{2}[Mm]{2}(?!.*[Yy]{4}[Dd]{2}[Mm]{2}).*$

# Should be `anymore`
\bany more[,.]

# Should be `cannot` (or `can't`)
# See https://www.grammarly.com/blog/cannot-or-can-not/
# > Don't use `can not` when you mean `cannot`. The only time you're likely to see `can not` written as separate words is when the word `can` happens to precede some other phrase that happens to start with `not`.
# > `Can't` is a contraction of `cannot`, and it's best suited for informal writing.
# > In formal writing and where contractions are frowned upon, use `cannot`.
# > It is possible to write `can not`, but you generally find it only as part of some other construction, such as `not only . . . but also.`
# - if you encounter such a case, add a pattern for that case to patterns.txt.
\b[Cc]an not\b

# Should be `GitHub`
(?<![&*.]|// |\btype |\bimport )\bGithub\b(?![{()])
\b[Gg]it\s[Hh]ub\b

# Should be `GitLab`
(?<![&*.]|// |\btype )\bGitlab\b(?![{)])

# Should be `JavaScript`
\bJavascript\b

# Should be `macOS` or `Mac OS X` or ...
\bMacOS\b

# Should be `Microsoft`
\bMicroSoft\b

# Should be `OAuth`
(?:^|[^-/*$])[ '"]oAuth(?: [a-z]|\d+ |[^ a-zA-Z0-9:;_.()])

# Should be `TypeScript`
\bTypescript\b

# Should be `another`
\ban[- ]other\b

# Should be `case-(in)sensitive`
\bcase (?:in|)sensitive\b

# Should be `coinciding`
\bco-inciding\b

# Should be `deprecation warning(s)`
\b[Dd]epreciation [Ww]arnings?\b

# Should be `greater than`
\bgreater then\b

# Should be `ID`
#\bId\b

# Should be `in front of`
\bin from of\b

# Should be `use`
\sin used by\b

# Should be `is obsolete`
\bis obsolescent\b

# Should be `it's` or `its`
\bits[']

# Should be `its`
\bit's(?= own\b)

# Should be `perform its`
\bperform it's\b

# Should be `less than`
\bless then\b

# Should be `load balancer`
\b[Ll]oud balancer

# Should be `one of`
\bon of\b

# Should be `otherwise`
\bother[- ]wise\b

# Should be `or (more|less)`
\bore (?:more|less)\b

# Should be `rather than`
\brather then\b

# Should be `regardless, ...` or `regardless of (whether)`
\b[Rr]egardless if you\b

# Should be `no longer needed`
\bno more needed\b(?! than\b)

# Should be `did not exist`
\bwere not existent\b

# Should be `nonexistent`
\bnon existing\b

# Should be `nonexistent`
\b[Nn]o[nt][- ]existent\b

# Should be `@brief` / `@details` / `@param` / `@return` / `@retval`
(?:^\s*|(?:\*|//|/*)\s+`)[\\@](?:breif|(?:detail|detials)|(?:params(?!\.)|prama?)|ret(?:uns?)|retvl)\b

# Should be `preexisting`
[Pp]re[- ]existing

# Should be `preempt`
[Pp]re[- ]empt\b

# Should be `preemptively`
[Pp]re[- ]emptively

# Should be `recently changed` or `recent changes`
[Rr]ecent changed

# Should be `reentrancy`
[Rr]e[- ]entrancy

# Should be `reentrant`
[Rr]e[- ]entrant

# Should be `understand`
\bunder stand\b

# Should be `workarounds`
\bwork[- ]arounds\b

# Should be `workaround`
(?:(?:[Aa]|[Tt]he|ugly)\swork[- ]around\b|\swork[- ]around\s+for)

# Should be `(coarse|fine)-grained`
\b(?:coarse|fine) grained\b

# Should be `neither/nor` -- or reword
\bnot\b[^.?!"/(]+\bnor\b

# Should be `neither/nor` (plus rewording the beginning)
# This is probably a double negative...
\bnot\b[^.?!"/]*\bneither\b[^.?!"/(]*\bnor\b

# In English, duplicated words are generally mistakes
# There are a few exceptions (e.g. "that that").
# If the highlighted doubled word pair is in:
# * code, write a pattern to mask it.
# * prose, have someone read the English before you dismiss this error.
\s([A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})\s\g{-1}\s

# Should be `Gen AI`
\b[gG]enAI\b

# Should be LangChain
\b(?!LangChain\b)(?!langchain\b)[Ll]ang\s?[Cc]hain?\b

# Should be LangGraph
\b(?!LangGraph\b)(?!langgraph\b)[Ll]ang\s?[Gg]raph?\b

# Should be LangServe
\b(?!LangServe\b)(?!langserve\b)[Ll]ang\s?[Ss]erve?\b

# Should be LlamaIndex
\b(?!LlamaIndex\b)[Ll][Ll]ama\s?[Ii]ndex?\s

# Should be Hugging Face
\s(?!Hugging Face\b)[Hh]ugging\s?[Ff]ace?\b

# Should be DeepSeek
\b(?!DeepSeek\b)(?!deepseek\b)[Dd]eep\s?[Ss]eek?\b

# Should be Vertex AI
\b(?!Vertex AI\b)(?!.*[\(\)\{\},])(?<!import\s)(?<!\.)(?<!,\s)Vertex\s?[Aa]?[Ii]?\b

# Should be Vertex AI
\b[Vv]ertext\b

# Should be Gemini
\sgemini\s\w

# Should be `Gemini Version Size` (e.g. `Gemini 2.0 Flash`)
\bGemini\s(Pro|Flash|Ultra)\s?\d\.\d\b

# Gemini Size should be capitalized (e.g. `Gemini 2.0 Flash`)
\bGemini\s?\d\.\d\s(pro|flash|ultra)\b

# Don't say "Google Gemini" or "Google Gemini"
\b[Gg]oogle(?: [Cc]loud| [Dd]eep[Mm]ind)?'s [Gg]emini\b

# Don't say "Powered by Gemini", instead say "with Gemini"
\b[Pp]owered\s[Bb]y\s[Gg]emini\b

# Should be Gemini API in Vertex AI
\b[Vv]ertex\s[Aa][Ii]\s[Gg]emini\s[Aa][Pp][Ii]\b

# Should be Agentspace
\b(?!Agentspace\b)[Aa]gent\s?[Ss]pace?\b

# Should be Imagen
\simagen\s\w

# Should be Imagen 2 or Imagen 3
\bImagen\d\b

# Should be BigQuery
\b(?!BigQuery\b)(?!bigquery\b)[Bb]ig\s?[Qq]uery\b

# Should be DataFrame or DataFrames
\b(?!DataFrames?\b)(?!.*[\(\)\{\}\.,=])(?<!")\b[Dd]ata\s?[Ff]rames?\b(?!")

# Should be Google Cloud
\s[Gg][Cc][Pp]\s

# Should be Google Cloud
\b(?!Google\sCloud\b)[Gg]oogle\s?[Cc]loud\b

# Should be DeepMind
\b(?!DeepMind\b)[Dd]eep\s?[Mm]ind\b

# Should be TensorFlow
\b(?!TensorFlow\b)(?!tensorflow\b)[Tt]ensor\s?[Ff]low\b

# Should be AlloyDB
\b(?!AlloyDB\b)(?!alloydb\b)[Aa]lloy\s?[Dd]\s?[Bb]\b

# Should be Translation API
\bTranslate\s?API\b

# Should be Dialogflow
\bDialogFlow\b

# Should be Firebase
\b(?!Firebase\b)Fire\s?[Bb]ase\b

# Should be Firestore
\b(?!Firestore\b)Fire\s?[Ss]tore\b

# Should be Memorystore
\b(?!Memorystore\b)Memory\s?[Ss]tore\b

# Should be Document AI
\bDoc\s?AI\b

# Should be Vertex AI Search
\bVertex\s?Search\b

# Should be Vertex AI Vector Search
\bVertex\sVector\sSearch\b

# Should be Colab
\s(?!Colab)[Cc]o[Ll][Ll]?abs?\b

# Should be Kaggle
\skaggle\b

# Should be TPU or TPUs
\btpus?\b

# Should be GKE
\sgke\s

# Should be GCS
\sgcs\s

# Should be Dataflow ML
\b[Dd]ataflowML\b

# Should be API
\s(?!API)(?!.*[\(\)\{\},=#]+)[Aa][Pp][Ii]\s

# Should be arXiv
\bAr[Xx]iv\b

# Should be DeepEval
\b(?!DeepEval\b)(?!deepeval\b)[Dd]eep\s?[Ee]val\b

# Invalid Space Character
\w \w

# Don't use "smart quotes"
(?!'")[‘’“”]

# "an" should only be before vowels.
\ban\s+(?![FHLMNRSX][A-Z0-9]+\b)(?!hour\b)(?!honest\b)(?!npm\b)([b-df-hj-np-tv-zB-DF-HJ-NP-TV-Z]{1}\w*)

# Don't use Google internal links
((corp|prod|sandbox).google.com|googleplex.com|https?://(?!localhost/)[0-9a-z][0-9a-z-]+/|(?:^|[^/.-])\b(?:go|b|cl|cr)/[a-z0-9_.-]+\b)

# Use `%pip` instead of `!pip` or `!pip3`
!\s?pip3?

# Don't use embedded images, upload to Google Cloud Storage
\(data:image/(?:jpeg|png);base64,[^{]


================================================
FILE: .github/conventional-commit-lint.yaml
================================================
enabled: true
always_check_pr_title: true


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: 'npm'
    directory: '/types'
    schedule:
      interval: 'monthly'
    groups:
      npm-dependencies:
        patterns:
          - '*'
  - package-ecosystem: 'github-actions'
    directory: '/'
    schedule:
      interval: 'monthly'
    groups:
      github-actions:
        patterns:
          - '*'
  - package-ecosystem: 'pip'
    directory: '/'
    schedule:
      interval: 'monthly'
    groups:
      pip-dependencies:
        patterns:
          - '*'


================================================
FILE: .github/linters/.eslintrc.js
================================================
/** @type {import('eslint').Linter.Config} */
module.exports = {
    root: true,
    parser: '@typescript-eslint/parser',
    plugins: ['@typescript-eslint', 'n'],
    extends: [
      'eslint:recommended',
      'plugin:@typescript-eslint/recommended',
      'plugin:n/recommended',
    ],
    rules: {
      '@typescript-eslint/no-explicit-any': 'off',
      'n/no-unsupported-features/es-syntax': 'off',
    },
    overrides: [
      {
        files: ['*.ts', '*.tsx'],
        parserOptions: {
          ecmaVersion: 'latest',
          sourceType: 'module',
        },
      },
    ],
  };


================================================
FILE: .github/linters/.jscpd.json
================================================
{
  "ignore": [
      "**/.github/**",
      "**/demo/**",
      "**/images/**",
      "**/samples/**",
      "**/tests/**",
      "**/.git/**"
  ],
  "threshold": 3,
  "reporters": ["html", "markdown"]
}


================================================
FILE: .github/linters/.markdownlint.json
================================================
{
    "default": true,
    "MD013": false,
    "MD007": {
        "indent": 4
    },
    "MD033": false,
    "MD046": false,
    "MD024": false
}


================================================
FILE: .github/linters/.protolint.yaml
================================================
lint:
  rules:
    remove:
      - MAX_LINE_LENGTH


================================================
FILE: .github/linters/.stylelintrc.json
================================================
{
    "extends": ["stylelint-config-standard"],
    "rules": {
        "custom-property-pattern": null
    },
    "overrides": [
        {
            "extends": ["stylelint-config-recommended-scss"],
            "files": ["*.scss", "**/*.scss"],
            "customSyntax": "postcss-scss"
        }
    ]
}


================================================
FILE: .github/super-linter.env
================================================
SHELLCHECK_OPTS=-e SC1091 -e SC2086
VALIDATE_ALL_CODEBASE=false
FILTER_REGEX_EXCLUDE=^(\\.github/|\\.vscode/).*|CODE_OF_CONDUCT.md|CHANGELOG.md|GOVERNANCE.md|MAINTAINERS.md
VALIDATE_BASH=true
VALIDATE_BASH_EXEC=true
VALIDATE_CSS=true
VALIDATE_EDITORCONFIG=true
VALIDATE_GIT_MERGE_CONFLICT_MARKERS=true
VALIDATE_GITHUB_ACTIONS=true
VALIDATE_GITLEAKS=true
VALIDATE_JSCPD=true
VALIDATE_JSON=true
VALIDATE_MARKDOWN=true
VALIDATE_PROTOBUF=true
VALIDATE_PYTHON_RUFF=true
VALIDATE_SHELL_SHFMT=true
VALIDATE_TOML=true
VALIDATE_TYPESCRIPT_ES=true
VALIDATE_YAML=true
TYPESCRIPT_ES_CONFIG_FILE=.eslintrc.js
MARKDOWN_CONFIG_FILE=.markdownlint.json
PROTOBUF_CONFIG_FILE=.protolint.yaml


================================================
FILE: .github/workflows/check-linked-issues.yml
================================================
name: Check for Linked Issues

on:
  pull_request_target:
    types: [opened, edited, reopened, synchronize]

jobs:
  check_pull_requests:
    runs-on: ubuntu-latest
    name: Check linked issues
    permissions:
      issues: read
      pull-requests: write
    steps:
      - uses: nearform-actions/github-action-check-linked-issues@v1
        id: check-linked-issues
        with:
          exclude-branches: 'release/**, dependabot/**, release-please--branches--main'
          comment: false

      # OPTIONAL: Use the output from the `check-linked-issues` step
      - name: Get the output
        run: echo "How many linked issues? ${{ steps.check-linked-issues.outputs.linked_issues_count }}"


================================================
FILE: .github/workflows/conventional-commits.yml
================================================
name: "Conventional Commits"

on:
  pull_request:
    types:
      - opened
      - edited
      - synchronize

permissions:
  contents: read

jobs:
  main:
    permissions:
      pull-requests: read
      statuses: write
    name: Validate PR Title
    runs-on: ubuntu-latest
    steps:
      - name: semantic-pull-request
        uses: amannn/action-semantic-pull-request@v6
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          validateSingleCommit: false


================================================
FILE: .github/workflows/dispatch-a2a-update.yml
================================================
name: Dispatch A2A JSON Update

on:
  push:
    branches:
      - main
    paths:
      - "specification/**/*"

jobs:
  dispatch:
    runs-on: ubuntu-latest
    if: github.repository_owner == 'a2aproject'

    steps:
      - name: Dispatch repository_dispatch to a2a-python
        uses: peter-evans/repository-dispatch@v4
        with:
          token: ${{ secrets.A2A_BOT_PAT }}
          repository: a2aproject/a2a-python
          event-type: a2a_json_update
          client-payload: |
            {
              "ref": "${{ github.ref }}",
              "sha": "${{ github.sha }}",
              "message": "Update to specification from ${{ github.sha }}"
            }


================================================
FILE: .github/workflows/docs.yml
================================================
name: Docs Build and Deploy

on:
  push:
    branches:
      - main
    paths:
      - ".github/workflows/docs.yml"
      - "scripts/deploy_root_files.sh"
      - "requirements-docs.txt"
      - "mkdocs.yml"
      - "docs/**"
  pull_request:
    branches:
      - main
    paths:
      - ".github/workflows/docs.yml"
      - "scripts/deploy_root_files.sh"
      - "requirements-docs.txt"
      - "mkdocs.yml"
      - "docs/**"
  release:
    types:
      - published
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to deploy to (e.g., v1.0.0)'
        required: true
        default: 'dev'

jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      actions: read

    if: github.repository == 'a2aproject/A2A'

    steps:
      - name: Checkout Code
        uses: actions/checkout@v6
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          fetch-depth: 0

      - name: Configure Git Credentials
        run: |
          git config --global user.name github-actions[bot]
          git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com

      - name: Setup Python
        uses: actions/setup-python@v6
        with:
          python-version: 3.13

      - name: Setup uv
        uses: astral-sh/setup-uv@v7

      - name: Restore pip cache
        uses: actions/cache@v5
        with:
          key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements-docs.txt') }}
          path: ~/.cache/pip
          restore-keys: |
            ${{ runner.os }}-pip-

      - name: Install documentation dependencies
        run: pip install --upgrade -r requirements-docs.txt

      - name: Setup Go
        uses: actions/setup-go@v6
        with:
          go-version: '1.25'

      - name: Install build tools
        run: |
          # Install protoc
          PROTOC_VERSION="28.3"
          PROTOC_ZIP="protoc-${PROTOC_VERSION}-linux-x86_64.zip"
          curl -fsSL -o /tmp/protoc.zip "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/${PROTOC_ZIP}"
          sudo unzip -q /tmp/protoc.zip -d /usr/local
          rm /tmp/protoc.zip

          # Install protoc-gen-jsonschema
          go install github.com/bufbuild/protoschema-plugins/cmd/protoc-gen-jsonschema@latest
          sudo cp "$(go env GOPATH)/bin/protoc-gen-jsonschema" /usr/local/bin/

          # Install buf CLI
          go install github.com/bufbuild/buf/cmd/buf@latest
          sudo cp "$(go env GOPATH)/bin/buf" /usr/local/bin/

          # Clone googleapis
          mkdir -p third_party
          cd third_party
          git clone --depth 1 https://github.com/googleapis/googleapis.git
          cd ..

      - name: Generate protocol specification files
        run: ./scripts/build_docs.sh

      - name: Generate consolidated llms-full.txt file
        run: bash scripts/build_llms_full.sh

      - name: Build Documentation (PR Check)
        if: github.event_name == 'pull_request'
        run: mkdocs build

      - name: Deploy development version from main branch
        if: github.event_name == 'push' && github.ref == 'refs/heads/main'
        run: |
          mike deploy --push --update-aliases dev latest

          echo "Setting 'latest' as the default version for the site..."
          mike set-default --push latest

          # Deploy 404 page
          bash scripts/deploy_root_files.sh ${{ github.repository }} ${{ secrets.GITHUB_TOKEN }}

      - name: Deploy new release version and set as latest
        if: github.event_name == 'release'
        run: |
          # The release tag (e.g., v0.2.2) is used as the version number
          export MIKE_VERSION=${GITHUB_EVENT_RELEASE_TAG_NAME}
          echo "Deploying docs for version $MIKE_VERSION and setting it as 'latest'..."
          mike deploy --push --update-aliases $MIKE_VERSION latest

          echo "Setting 'latest' as the default version for the site..."
          mike set-default --push latest

          # Call the reusable script to deploy the 404 page, passing the token
          bash scripts/deploy_root_files.sh ${{ github.repository }} ${{ secrets.GITHUB_TOKEN }}
        env:
          GITHUB_EVENT_RELEASE_TAG_NAME: ${{ github.event.release.tag_name }}

      - name: Manually deploy specific version from main
        if: github.event_name == 'workflow_dispatch'
        run: |
          mike deploy --push --update-aliases ${{ github.event.inputs.version }} latest

          echo "Setting 'latest' as the default version for the site..."
          mike set-default --push latest
          
          # Re-deploy 404 page
          bash scripts/deploy_root_files.sh ${{ github.repository }} ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/issue-metrics.yml
================================================
name: Monthly issue metrics
on:
  workflow_dispatch:
  schedule:
    - cron: "3 2 1 * *"

permissions:
  contents: read

jobs:
  build:
    name: issue metrics
    runs-on: ubuntu-latest
    permissions:
      issues: write
      pull-requests: read
    steps:
      - name: Get dates for last month
        shell: bash
        run: |
          # Calculate the first day of the previous month
          first_day=$(date -d "last month" +%Y-%m-01)

          # Calculate the last day of the previous month
          last_day=$(date -d "$first_day +1 month -1 day" +%Y-%m-%d)

          # Set an environment variable with the date range
          echo "$first_day..$last_day"
          echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV"

      - name: Run issue-metrics tool
        uses: github/issue-metrics@v3
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SEARCH_QUERY: 'repo:a2aproject/A2A is:issue created:${{ env.last_month }} -reason:"not planned"'

      - name: Create issue
        uses: peter-evans/create-issue-from-file@v6
        with:
          title: Monthly issue metrics report
          token: ${{ secrets.GITHUB_TOKEN }}
          content-filepath: ./issue_metrics.md


================================================
FILE: .github/workflows/links.yaml
================================================
name: Lychee Link Checker

on:
  repository_dispatch:
  workflow_dispatch:
  schedule:
    - cron: "00 18 * * *"
  pull_request:

jobs:
  check_links:
    name: Check for Broken Links
    runs-on: ubuntu-latest
    if: |
      github.repository == 'a2aproject/A2A'

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v6

      - name: Get relevant changed files
        id: changed-files
        if: github.event_name == 'pull_request'
        uses: tj-actions/changed-files@v47
        with:
          files: |
            **/*.md
            **/*.mdx
            **/*.html
            **/*.htm
            **/*.rst
            **/*.txt

      - name: Run Lychee on changed files (PR)
        if: github.event_name == 'pull_request' && steps.changed-files.outputs.all_changed_files != ''
        uses: lycheeverse/lychee-action@v2
        with:
          args: --no-progress ${{ steps.changed-files.outputs.all_changed_files }}
          failIfEmpty: false

      - name: Run Lychee on all files (Scheduled/Manual)
        if: github.event_name != 'pull_request'
        uses: lycheeverse/lychee-action@v2
        with:
          args: --no-progress .
          failIfEmpty: false

      - name: Create Issue on Failure
        if: failure() && github.event_name != 'pull_request'
        uses: peter-evans/create-issue-from-file@v6
        with:
          title: Link Checker Report
          content-filepath: ./lychee/out.md
          labels: report, automated issue


================================================
FILE: .github/workflows/linter.yaml
================================================
name: Lint Code Base

on:
  pull_request:
    branches: [main]

jobs:
  lint:
    name: Lint Code Base
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: read
      statuses: write

    steps:
      - name: Checkout Code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Load Super Linter Environment Variables into GITHUB_ENV
        run: |
          grep -v '^\\(#.*\\|\\s\\?\\)$' .github/super-linter.env >> "${GITHUB_ENV}"

      - name: GitHub Super Linter
        uses: super-linter/super-linter/slim@v8
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  api-linter:
    name: API Linter
    runs-on: ubuntu-latest
    permissions:
      contents: read

    steps:
      - name: Checkout Code
        uses: actions/checkout@v6

      - name: Install buf
        run: |
          curl -sSL "https://github.com/bufbuild/buf/releases/latest/download/buf-Linux-x86_64" -o buf
          sudo mv buf /usr/local/bin/buf
          sudo chmod +x /usr/local/bin/buf

      - name: Download proto dependencies
        working-directory: specification
        run: |
          buf dep update
          buf export buf.build/googleapis/googleapis --output=.googleapis

      - name: Install api-linter
        run: |
          curl -L https://github.com/googleapis/api-linter/releases/download/v1.67.6/api-linter-1.67.6-linux-amd64.tar.gz -o api-linter.tar.gz
          tar -xzf api-linter.tar.gz
          sudo mv api-linter /usr/local/bin/
          sudo chmod +x /usr/local/bin/api-linter

      - name: Run API Linter
        run: |
          # Run api-linter with exported googleapis protos
          api-linter --config specification/.api-linter.yaml --output-format github --set-exit-status --proto-path specification --proto-path specification/.googleapis specification/a2a.proto


================================================
FILE: .github/workflows/release-please.yml
================================================
on:
  push:
    branches:
      - main

permissions:
  contents: write
  pull-requests: write

name: release-please

jobs:
  release-please:
    runs-on: ubuntu-latest
    if: github.repository_owner == 'a2aproject'

    steps:
      - uses: googleapis/release-please-action@v4
        with:
          token: ${{ secrets.A2A_BOT_PAT }}
          release-type: simple


================================================
FILE: .github/workflows/sort-spelling-allowlist.yml
================================================
name: Auto-sort and update spelling allowlist

on:
  pull_request:
    paths:
      - ".github/actions/spelling/allow.txt"
    types:
      - opened
      - synchronize
      - reopened

jobs:
  sort_and_commit:
    name: Sort and Commit Allowlist
    runs-on: ubuntu-latest
    permissions:
      contents: write

    steps:
      - name: Checkout Code
        uses: actions/checkout@v6
        with:
          repository: ${{ github.event.pull_request.head.repo.full_name }}
          ref: ${{ github.event.pull_request.head.ref }}
          persist-credentials: false

      - name: Sort allow.txt
        run: |
          bash scripts/sort_spelling.sh

      - name: Configure Git
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

      - name: Check for changes
        id: git_status
        run: |
          if ! git diff --quiet .github/actions/spelling/allow.txt; then
            echo "changes=true" >> $GITHUB_OUTPUT
          fi

      - name: Commit and push changes
        if: steps.git_status.outputs.changes == 'true' && github.event.pull_request.head.repo.full_name == github.repository
        run: |
          git add .github/actions/spelling/allow.txt
          git commit -m "ci: sort and unique allow.txt"
          git push

      - name: Fail on fork with changes
        if: steps.git_status.outputs.changes == 'true' && github.event.pull_request.head.repo.full_name != github.repository
        run: |
          echo "::error::The 'allow.txt' file is not sorted correctly. Please run 'bash scripts/sort_spelling.sh' and commit the changes."
          exit 1


================================================
FILE: .github/workflows/spelling.yaml
================================================
name: Check Spelling

on:
  pull_request:
    branches:
      - "**"
    types:
      - "opened"
      - "reopened"
      - "synchronize"

jobs:
  spelling:
    name: Check Spelling
    permissions:
      contents: read
      actions: read
      security-events: write
    outputs:
      followup: ${{ steps.spelling.outputs.followup }}
    if: ${{ contains(github.event_name, 'pull_request') || github.event_name == 'push' }}
    runs-on: ubuntu-latest
    concurrency:
      group: spelling-${{ github.event.pull_request.number || github.ref }}
      # note: If you use only_check_changed_files, you do not want cancel-in-progress
      cancel-in-progress: false
    steps:
      - name: check-spelling
        id: spelling
        uses: check-spelling/check-spelling@main
        with:
          suppress_push_for_open_pull_request: ${{ github.actor != 'dependabot[bot]' && 1 }}
          checkout: true
          check_file_names: 1
          spell_check_this: check-spelling/spell-check-this@main
          post_comment: 0
          use_magic_file: 1
          report-timing: 1
          warnings: bad-regex,binary-file,deprecated-feature,ignored-expect-variant,large-file,limited-references,no-newline-at-eof,noisy-file,non-alpha-in-dictionary,token-is-substring,unexpected-line-ending,whitespace-in-dictionary,minified-file,unsupported-configuration,no-files-to-check,unclosed-block-ignore-begin,unclosed-block-ignore-end
          experimental_apply_changes_via_bot: 1
          dictionary_source_prefixes: '{"cspell": "https://raw.githubusercontent.com/streetsidesoftware/cspell-dicts/main/dictionaries/"}'
          extra_dictionaries: |
            cspell:aws/dict/aws.txt
            cspell:bash/samples/bash-words.txt
            cspell:companies/dict/companies.txt
            cspell:css/dict/css.txt
            cspell:data-science/dict/data-science-models.txt
            cspell:data-science/dict/data-science.txt
            cspell:data-science/dict/data-science-tools.txt
            cspell:en_shared/dict/acronyms.txt
            cspell:en_shared/dict/shared-additional-words.txt
            cspell:en_GB/en_GB.trie
            cspell:en_US/en_US.trie
            cspell:filetypes/src/filetypes.txt
            cspell:fonts/dict/fonts.txt
            cspell:fullstack/dict/fullstack.txt
            cspell:golang/dict/go.txt
            cspell:google/dict/google.txt
            cspell:html/dict/html.txt
            cspell:java/src/java.txt
            cspell:k8s/dict/k8s.txt
            cspell:mnemonics/dict/mnemonics.txt
            cspell:monkeyc/src/monkeyc_keywords.txt
            cspell:node/dict/node.txt
            cspell:npm/dict/npm.txt
            cspell:people-names/dict/people-names.txt
            cspell:python/dict/python.txt
            cspell:python/dict/python-common.txt
            cspell:shell/dict/shell-all-words.txt
            cspell:software-terms/dict/softwareTerms.txt
            cspell:software-terms/dict/webServices.txt
            cspell:sql/src/common-terms.txt
            cspell:sql/src/sql.txt
            cspell:sql/src/tsql.txt
            cspell:terraform/dict/terraform.txt
            cspell:typescript/dict/typescript.txt
          check_extra_dictionaries: ""
          only_check_changed_files: true
          longest_word: "10"


================================================
FILE: .github/workflows/stale.yaml
================================================
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
#
# You can adjust the behavior by modifying this file.
# For more information, see:
# https://github.com/actions/stale
name: Mark stale issues and pull requests

on:
  schedule:
    # Scheduled to run at 10.30PM UTC every day (1530PDT/1430PST)
    - cron: "30 22 * * *"
  workflow_dispatch:

jobs:
  stale:
    runs-on: ubuntu-latest
    permissions:
      issues: write
      pull-requests: write
      actions: write

    steps:
      - uses: actions/stale@v10
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          days-before-issue-stale: 14
          days-before-issue-close: 13
          stale-issue-label: "status:stale"
          close-issue-reason: not_planned
          any-of-labels: "status:awaiting response,status:more data needed"
          stale-issue-message: >
            Marking this issue as stale since it has been open for 14 days with no activity.
            This issue will be closed if no further activity occurs.
          close-issue-message: >
            This issue was closed because it has been inactive for 27 days.
            Please post a new issue if you need further assistance. Thanks!
          days-before-pr-stale: 14
          days-before-pr-close: 13
          stale-pr-label: "status:stale"
          stale-pr-message: >
            Marking this pull request as stale since it has been open for 14 days with no activity.
            This PR will be closed if no further activity occurs.
          close-pr-message: >
            This pull request was closed because it has been inactive for 27 days.
            Please open a new pull request if you need further assistance. Thanks!
          # Label that can be assigned to issues to exclude them from being marked as stale
          exempt-issue-labels: "override-stale"
          # Label that can be assigned to PRs to exclude them from being marked as stale
          exempt-pr-labels: "override-stale"


================================================
FILE: .gitignore
================================================
# Added: ignore local documentation virtualenv and generated proto-derived artifacts
venv-docs/
.venv/
venv/
ENV/
.doc-venv

# Ephemeral schema artifacts (never commit)
specification/json/a2a.json
specification/json/*.json
!specification/json/README.md
docs/spec/

# Generated SDK docs
docs/sdk/*
!docs/sdk/index.md
!docs/sdk/python.md
!docs/sdk/python/
docs/sdk/python/*
!docs/sdk/python/conf.py
!docs/sdk/python/index.rst

# Third-party dependencies (generated by setup)
third_party/

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*.pyc
*$py.class
**/dist
/tmp
/out-tsc
/bazel-out

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
#   install all needed dependencies.
Pipfile.lock
Pipfile

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
.venv*
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json
.ruff_cache/

# Pyre type checker
.pyre/

# macOS
.DS_Store

# PyCharm
.idea

# User-specific files
language/examples/prompt-design/train.csv
README-TOC*.md

# Terraform
terraform.tfstate**
.terraform*
.Terraform*

tmp*

# Node
**/node_modules
npm-debug.log
yarn-error.log

# IDEs and editors
.idea/
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# Miscellaneous
**/.angular/*
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
testem.log
/typings

# System files
.DS_Store
Thumbs.db

# Sphinx build artifacts
docs/sdk/python/_build/
docs/sdk/python/api/
docs/sdk/python/generated/

specification/.googleapis/


================================================
FILE: .gitvote.yml
================================================
# GitVote configuration file
#
# GitVote will look for it in the following locations (in order of precedence):
#
#   - At the root of the repository where the vote was created
#   - At the root of the .github repository, for organization wide configuration
#

# Automation (optional)
#
# Create votes automatically on PRs when any of the files affected by the PR
# match any of the patterns provided. Patterns must follow the gitignore
# format (https://git-scm.com/docs/gitignore#_pattern_format).
#
# Each automation rule must include a list of patterns and the profile to use
# when creating the vote. This allows creating votes automatically using the
# desired configuration based on the patterns matched. Rules are processed in
# the order provided, and the first match wins.
#
# automation:
#   enabled: true
#   rules:
#     - patterns:
#         - "README.md"
#         - "*.txt"
#       profile: default
profiles:
  default:
    duration: 52w
    pass_threshold: 51
    periodic_status_check: "1 day"
    allowed_voters:
      teams:
        - a2a-tsc
      exclude_team_maintainers: false
    close_on_passing: true
    announcements:
      discussions:
        category: announcements


================================================
FILE: .mkdocs/macros.py
================================================
"""Custom MkDocs macros for A2A documentation.

This module provides macros for rendering Protocol Buffer definitions
as markdown tables.
"""

from pathlib import Path
from typing import Any

from proto_schema_parser.ast import (
    Comment,
    Enum,
    EnumValue,
    Field,
    MapField,
    Message,
    Method,
    OneOf,
    Service,
)
from proto_schema_parser.parser import Parser
from tabulate import tabulate


# -----------------------------------------------------------------------------
# Configuration & Helpers
# -----------------------------------------------------------------------------

TYPE_MAP = {
    'string': 'string',
    'int32': 'integer',
    'int64': 'integer',
    'bool': 'boolean',
    'bytes': 'bytes',
    'double': 'float',
    'float': 'float',
    'google.protobuf.Struct': 'object',
    'google.protobuf.Timestamp': 'timestamp',
    'google.protobuf.Value': 'any',
    'google.protobuf.Empty': 'empty',
}

# -----------------------------------------------------------------------------
# Main Macros
# -----------------------------------------------------------------------------


def define_env(env):
    """Define custom macros for MkDocs."""

    def _parse_proto(file_path: str):
        """Parses a .proto file and returns the AST with comments attached."""
        full_path = Path(env.conf['docs_dir']).parent / file_path
        if not full_path.exists():
            raise FileNotFoundError(f'Proto not found: {file_path}')
        ast = Parser().parse(full_path.read_text(encoding='utf-8'))
        _attach_comments(ast.file_elements)
        return ast.file_elements

    @env.macro
    def proto_to_table(
        message_name: str, proto_file: str = 'specification/a2a.proto'
    ) -> str:
        """Parses a .proto file and renders a message table."""
        try:
            elements = _parse_proto(proto_file)
        except FileNotFoundError as e:
            return f'**Error:** {e}'

        # Find the specific message object
        target_message = _find_type(elements, message_name, Message)
        if not target_message:
            return f'**Error:** Message `{message_name}` not found.'

        # Extract data
        rows = []
        oneof_groups = {}  # Map[oneof_name] -> List[field_names]

        # Iterate over elements inside the message
        # elements can be Field, MapField, OneOf, Enum, Message, etc.
        for el in target_message.elements:
            # Handle Standard/Map Fields
            if isinstance(el, Field | MapField):
                rows.append(_process_field(el))
            elif isinstance(el, OneOf):
                for oneof_el in el.elements:
                    if isinstance(oneof_el, Field):
                        # Process field normally
                        row = _process_field(oneof_el, is_oneof=True)
                        rows.append(row)
                        # Add display name to group tracker
                        oneof_groups.setdefault(el.name, []).append(
                            row[0].strip('`')  # Remove code ticks for the note
                        )

        if not rows:
            return 'None'

        # Generate Output
        output = []

        # Message Description
        msg_desc = _extract_comments(target_message)
        if msg_desc:
            output.append(msg_desc)
            output.append('')

        # Render Table
        headers = ['Field', 'Type', 'Required', 'Description']
        output.append(tabulate(rows, headers, tablefmt='github'))

        # Add OneOf Notes
        if oneof_groups:
            output.append('')
            for _, fields in oneof_groups.items():
                if len(fields) > 1:
                    field_list = ', '.join(f'`{f}`' for f in fields)
                    output.append(
                        f'**Note:** A `{message_name}` MUST contain exactly one of the following: {field_list}'
                    )

        return '\n'.join(output)

    @env.macro
    def proto_enum_to_table(
        enum_name: str, proto_file: str = 'specification/a2a.proto'
    ):
        """Parses a .proto file and renders an Enum table."""
        try:
            elements = _parse_proto(proto_file)
            el = _find_type(elements, enum_name, Enum)
            if not el:
                return f'**Error:** Enum `{enum_name}` not found.'

            rows = [
                [f'`{e.name}`', _extract_comments(e)]
                for e in el.elements
                if isinstance(e, EnumValue)
            ]
            return f'{_extract_comments(el)}\n\n' + tabulate(
                rows, ['Value', 'Description'], tablefmt='github'
            )
        except Exception as e:
            return f'**Error:** {e}'

    @env.macro
    def proto_service_to_table(
        service_name: str, proto_file: str = 'specification/a2a.proto'
    ) -> str:
        """Parses a .proto file and renders a Service table."""
        try:
            elements = _parse_proto(proto_file)
            service = _find_type(elements, service_name, Service)
            if not service:
                return f'**Error:** Service `{service_name}` not found.'

            rows = []
            for el in service.elements:
                if isinstance(el, Method):
                    # Request Type
                    # input_type is a MessageType(type='...', stream=True/False)
                    req_str = _format_type_for_docs(el.input_type.type)
                    if el.input_type.stream:
                        req_str = f'stream {req_str}'

                    # Response Type
                    res_str = _format_type_for_docs(el.output_type.type)
                    if el.output_type.stream:
                        res_str = f'stream {res_str}'

                    rows.append(
                        [
                            f'`{el.name}`',
                            req_str,
                            res_str,
                            _extract_comments(el),
                        ]
                    )

            if not rows:
                return 'None'

            headers = ['Method', 'Request', 'Response', 'Description']
            return tabulate(rows, headers, tablefmt='github')

        except Exception as e:
            return f'**Error:** {e}'


# -----------------------------------------------------------------------------
# Helper Functions
# -----------------------------------------------------------------------------


def _extract_comments(element: Any) -> str:
    """Clean and combine comments from an AST element."""
    cleaned_parts = []
    raw_comments = getattr(element, 'comments', [])

    for comment in raw_comments:
        text = (
            comment.strip()
            .removeprefix('//')
            .removeprefix('/*')
            .removesuffix('*/')
        )
        lines = (
            line.strip().removeprefix('*').strip() for line in text.splitlines()
        )
        combined = ' '.join(filter(None, lines))

        if combined and not combined.startswith(
            (
                'protolint:',
                '--8<--',
                'Next ID:',
                '(-- api-linter',
                'api-linter',
                'aip.dev/not-precedent',
            )
        ):
            cleaned_parts.append(combined)

    return ' '.join(cleaned_parts)


def _attach_comments(elements: list[Any]) -> None:
    """Recursively attach preceding comments to each non-comment element."""
    buffer = []
    for el in elements:
        if isinstance(el, Comment):
            buffer.append(el.text)
        else:
            # Attach collected comments to this element
            el.comments = buffer
            buffer = []
            # Recursively handle nested elements (e.g. inside Message or OneOf)
            if hasattr(el, 'elements'):
                _attach_comments(el.elements)


def _format_type_for_docs(
    proto_type: str, is_repeated: bool = False, map_key: str | None = None
) -> str:
    """Formats the type name with Markdown links for non-primitive types."""
    # Handle fully qualified names by taking only the last part for the link label,
    # but keep it if it's a known google.protobuf type we mapped.
    display_name = TYPE_MAP.get(proto_type, proto_type.split('.')[-1])
    is_primitive = proto_type in TYPE_MAP or proto_type.startswith(
        'google.protobuf'
    )

    # Create a slug for the link. Messages are usually CamelCase, so lowercase it.
    label = f'`{display_name}`'
    if not is_primitive:
        label = f'[{label}](#{display_name.lower()})'

    if map_key:
        key_label = TYPE_MAP.get(map_key, map_key)
        return f'map of {key_label} to {label}'

    if is_repeated:
        return f'array of {label}'

    return label


def _find_type(elements: list[Any], name: str, target_cls: type) -> Any | None:
    """Recursively searches for a Message or Enum by name."""
    for el in elements:
        if getattr(el, 'name', None) == name and isinstance(el, target_cls):
            return el
        if isinstance(el, Message):
            found = _find_type(el.elements, name, target_cls)
            if found:
                return found
    return None


def _process_field(field: Field, is_oneof: bool = False) -> list[str]:
    """Converts a Field or MapField object into a table row."""
    options = getattr(field, 'options', [])
    cardinality_obj = getattr(field, 'cardinality', None)
    cardinality = (
        getattr(cardinality_obj, 'value', None) if cardinality_obj else None
    )

    # Determine Display Name (json_name vs snake_case)
    json_name = next(
        (o.value.strip('"') for o in options if o.name == 'json_name'), None
    )
    display_name = json_name or _snake_to_camel_case(field.name)

    # Determine Type
    is_map = isinstance(field, MapField)
    is_repeated = cardinality == 'REPEATED'

    type_to_format = field.value_type if is_map else field.type
    map_key = getattr(field, 'key_type', None)

    type_str = _format_type_for_docs(type_to_format, is_repeated, map_key)

    # Determine Required/Optional
    has_required_behavior = any(
        'REQUIRED' in str(opt.value)
        for opt in options
        if 'field_behavior' in opt.name
    )

    if is_oneof:
        req_val = 'Optional (OneOf)'
    elif cardinality == 'REQUIRED' or has_required_behavior:
        req_val = 'Yes'
    else:
        req_val = 'No'

    desc = _extract_comments(field)

    return [f'`{display_name}`', type_str, req_val, desc]


def _snake_to_camel_case(snake_str: str) -> str:
    """Convert snake_case to camelCase."""
    components = snake_str.split('_')
    return components[0] + ''.join(x.title() for x in components[1:])


================================================
FILE: .mkdocs/overrides/main.html
================================================
{% extends "base.html" %}

{% block announce %}
  Join the new DeepLearning.AI short course: <strong>A2A: The Agent2Agent Protocol</strong>!
  <a href="https://goo.gle/dlai-a2a" class="md-button">
    Enroll for free
  </a>
{% endblock %}


================================================
FILE: .prettierrc
================================================
{
    "tabWidth": 2,
    "useTabs": false,
    "trailingComma": "es5",
    "bracketSameLine": true,
    "overrides": [
        {
            "files": "*.md",
            "options": {
                "tabWidth": 4,
                "useTabs": false,
                "trailingComma": "es5"
            }
        }
    ]
}


================================================
FILE: .ruff.toml
================================================
#################################################################################
#
# Ruff linter and code formatter for A2A
#
# This file follows the standards in Google Python Style Guide
# https://google.github.io/styleguide/pyguide.html

line-length = 80 # Google Style Guide §3.2: 80 columns
indent-width = 4 # Google Style Guide §3.4: 4 spaces

target-version = "py312" # Minimum Python version

[lint]
ignore = [
    "COM812",
    "FBT001",
    "FBT002",
    "D203",
    "D213",
    "ANN001",
    "ANN201",
    "ANN204",
    "D100", # Ignore Missing docstring in public module (often desired at top level __init__.py)
    "D102", # Ignore return type annotation in public method
    "D104", # Ignore Missing docstring in public package (often desired at top level __init__.py)
    "D107", # Ignore Missing docstring in __init__ (use class docstring)
    "TD002", # Ignore Missing author in TODOs (often not required)
    "TD003", # Ignore Missing issue link in TODOs (often not required/available)
    "T201", # Ignore print presence
    "RUF012", # Ignore Mutable class attributes should be annotated with `typing.ClassVar`
    "RUF013", # Ignore implicit optional
]

select = [
    "E",  # pycodestyle errors (PEP 8)
    "W",  # pycodestyle warnings (PEP 8)
    "F",  # Pyflakes (logical errors, unused imports/variables)
    "I",  # isort (import sorting - Google Style §3.1.2)
    "D",  # pydocstyle (docstring conventions - Google Style §3.8)
    "N",  # pep8-naming (naming conventions - Google Style §3.16)
    "UP", # pyupgrade (use modern Python syntax)
    "ANN",# flake8-annotations (type hint usage/style - Google Style §2.22)
    "A",  # flake8-builtins (avoid shadowing builtins)
    "B",  # flake8-bugbear (potential logic errors & style issues - incl. mutable defaults B006, B008)
    "C4", # flake8-comprehensions (unnecessary list/set/dict comprehensions)
    "ISC",# flake8-implicit-str-concat (disallow implicit string concatenation across lines)
    "T20",# flake8-print (discourage `print` - prefer logging)
    "SIM",# flake8-simplify (simplify code, e.g., `if cond: return True else: return False`)
    "PTH",# flake8-use-pathlib (use pathlib instead of os.path where possible)
    "PL", # Pylint rules ported to Ruff (PLC, PLE, PLR, PLW)
    "PIE",# flake8-pie (misc code improvements, e.g., no-unnecessary-pass)
    "RUF",# Ruff-specific rules (e.g., RUF001-003 ambiguous unicode)
    "RET",# flake8-return (consistency in return statements)
    "SLF",# flake8-self (check for private member access via `self`)
    "TID",# flake8-tidy-imports (relative imports, banned imports - configure if needed)
    "YTT",# flake8-boolean-trap (checks for boolean positional arguments, truthiness tests - Google Style §3.10)
    "TD", # flake8-todos (check TODO format - Google Style §3.7)
]

exclude = [
    ".bzr",
    ".direnv",
    ".eggs",
    ".git",
    ".hg",
    ".mypy_cache",
    ".nox",
    ".pants.d",
    ".pytype",
    ".ruff_cache",
    ".svn",
    ".tox",
    ".venv",
    "__pypackages__",
    "_build",
    "buck-out",
    "build",
    "dist",
    "node_modules",
    "venv",
    "*/migrations/*",
]

[lint.isort]
#force-sort-within-sections = true
#combine-as-imports = true
case-sensitive = true
#force-single-line = false
#known-first-party = []
#known-third-party = []
lines-after-imports = 2
lines-between-types = 1
#no-lines-before = ["LOCALFOLDER"]
#required-imports = []
#section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]

[lint.pydocstyle]
convention = "google"

[lint.flake8-annotations]
mypy-init-return = true
allow-star-arg-any = false

[lint.pep8-naming]
ignore-names = ["test_*", "setUp", "tearDown", "mock_*"]
classmethod-decorators = ["classmethod", "pydantic.validator", "pydantic.root_validator"]
staticmethod-decorators = ["staticmethod"]

[lint.flake8-tidy-imports]
ban-relative-imports = "all" # Google generally prefers absolute imports (§3.1.2)

[lint.flake8-quotes]
docstring-quotes = "double"
inline-quotes = "single"

[lint.per-file-ignores]
"__init__.py" = ["F401"]  # Ignore unused imports in __init__.py
"*_test.py" = ["D", "ANN"]  # Ignore docstring and annotation issues in test files
"test_*.py" = ["D", "ANN"]  # Ignore docstring and annotation issues in test files

[format]
docstring-code-format = true
docstring-code-line-length = "dynamic" # Or set to 80
quote-style = "single"
indent-style = "space"


================================================
FILE: .vscode/settings.json
================================================
{
    "editor.formatOnSave": true,
    "[python]": {
        "editor.defaultFormatter": "charliermarsh.ruff",
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
            "source.organizeImports": "explicit"
        }
    },
    "ruff.importStrategy": "fromEnvironment",
    "markdownlint.configFile": ".github/linters/.markdownlint.json",
    "[json]": {
        "editor.defaultFormatter": "vscode.json-language-features",
        "editor.formatOnSave": true
    },
    "files.trimTrailingWhitespace": true,
    "files.insertFinalNewline": true,
    "codeQL.githubDatabase.download": "never"
}


================================================
FILE: CHANGELOG.md
================================================
# Changelog

## [1.0.0](https://github.com/a2aproject/A2A/compare/v0.3.0...v1.0.0) (2026-03-12)


### ⚠ BREAKING CHANGES

* **spec:** Combine `TaskPushNotificationConfig` and `PushNotificationConfig` ([#1500](https://github.com/a2aproject/A2A/issues/1500))
* **spec:** remove duplicated ID from the create task push config request ([#1487](https://github.com/a2aproject/A2A/issues/1487))
* **spec:** pluralize configs in `ListTaskPushNotificationConfigs` ([#1486](https://github.com/a2aproject/A2A/issues/1486))
* **spec:** Add LF prefix to the package. ([#1474](https://github.com/a2aproject/A2A/issues/1474))
* **spec:** Switch to non-complex IDs in requests ([#1389](https://github.com/a2aproject/A2A/issues/1389))
* **spec:** Standardize spelling of "canceled" to use American Spelling throughout ([#1283](https://github.com/a2aproject/A2A/issues/1283))
* **spec:** Align enum format with ADR-001 ProtoJSON specification ([#1384](https://github.com/a2aproject/A2A/issues/1384))
* **spec:** Remove redundant `final` field from `TaskStatusUpdateEvent` ([#1308](https://github.com/a2aproject/A2A/issues/1308))
* **spec:** Move `extendedAgentCard` field to `AgentCapabilities` ([#1307](https://github.com/a2aproject/A2A/issues/1307))
* **spec:** Fixes for the last_updated_after field ([#1358](https://github.com/a2aproject/A2A/issues/1358))
* **spec:** modernize oauth 2.0 flows - remove implicit/password, add device code / pkce ([#1303](https://github.com/a2aproject/A2A/issues/1303))
* **spec:** Make "message" field name consistent between protocol bindings ([#1302](https://github.com/a2aproject/A2A/issues/1302))
* **spec:** Remove deprecated fields from a2a.proto for v1.0 release ([#1301](https://github.com/a2aproject/A2A/issues/1301))
* **spec:** Rename `supportsAuthenticatedExtendedCard` to `supportsExtendedAgentCard` ([#1222](https://github.com/a2aproject/A2A/issues/1222))
* **spec:** Remove v1s from a2a url http bindings
* **spec:** Large refactor of specification to separate application protocol definition from mapping to transports

### Features

* **spec:** Add `tasks/list` method with filtering and pagination to the specification ([0a9f629](https://github.com/a2aproject/A2A/commit/0a9f629e801d4ae89f94991fc28afe9429c91cbc))
* **spec:** modernize oauth 2.0 flows - remove implicit/password, add device code / pkce ([#1303](https://github.com/a2aproject/A2A/issues/1303)) ([525ff38](https://github.com/a2aproject/A2A/commit/525ff38e5fe2a118f5be5d25189708b590616dd4))
* **spec:** Natively Support Multi-tenancy on gRPC through an additional scope field on the request. ([#1195](https://github.com/a2aproject/A2A/issues/1195)) ([cfbce32](https://github.com/a2aproject/A2A/commit/cfbce32cb0ac2a630597eb8b771691cac5b20a4b)), closes [#1148](https://github.com/a2aproject/A2A/issues/1148)
* **spec:** Provide ability for SDKs to be backwards compatible. ([#1401](https://github.com/a2aproject/A2A/issues/1401)) ([227e249](https://github.com/a2aproject/A2A/commit/227e2493c317004b7e6f7ef4a484e220ffd0b77e))
* **spec:** Remove v1s from a2a url http bindings ([1bd263f](https://github.com/a2aproject/A2A/commit/1bd263f5373fdc8fa7c17ec8bdb24088996b6828))


### Bug Fixes

* Add missing metadata field to Part message in gRPC specification ([#1019](https://github.com/a2aproject/A2A/issues/1019)) ([b3b266d](https://github.com/a2aproject/A2A/commit/b3b266d127dde3d1000ec103b252d1de81289e83)), closes [#1005](https://github.com/a2aproject/A2A/issues/1005)
* Add name field to FilePart protobuf message ([#983](https://github.com/a2aproject/A2A/issues/983)) ([2b7cb6f](https://github.com/a2aproject/A2A/commit/2b7cb6f8408e6324c48fb82c71839c67a18f1fab)), closes [#984](https://github.com/a2aproject/A2A/issues/984)
* Clarify blocking calls return on interrupted states ([#1403](https://github.com/a2aproject/A2A/issues/1403)) ([0655ff3](https://github.com/a2aproject/A2A/commit/0655ff324a93b7e0eaebc108666e6703998b4a9c))
* **doc:** Makes JSON-RPC SendMessage response clearer ([#1241](https://github.com/a2aproject/A2A/issues/1241)) ([5792804](https://github.com/a2aproject/A2A/commit/57928043727e5e002a1395dadfb5f699d0626b1c))
* **docs:** Clearer wording around context id. ([#1588](https://github.com/a2aproject/A2A/issues/1588)) ([dec790a](https://github.com/a2aproject/A2A/commit/dec790aa063943e3ac70e972f9da513c25ab420c))
* **grpc:** Fix inconsistent property name between gRPC and JSON-RPC in Message object ([#1100](https://github.com/a2aproject/A2A/issues/1100)) ([2a1f819](https://github.com/a2aproject/A2A/commit/2a1f819aaa2540602ee81498e159ebe0192be818))
* **grpc:** missing field in gRPC spec - state_transition_history  ([#1138](https://github.com/a2aproject/A2A/issues/1138)) ([a2de798](https://github.com/a2aproject/A2A/commit/a2de7981cadeaa5197bee56cbd6ab7b2c5da2541)), closes [#1139](https://github.com/a2aproject/A2A/issues/1139)
* **grpc:** Update `CreateTaskPushNotificationConfig` endpoint to `/v1/{parent=tasks/*/pushNotificationConfigs}` ([#979](https://github.com/a2aproject/A2A/issues/979)) ([911f9b0](https://github.com/a2aproject/A2A/commit/911f9b059c52dd65497b76ccf63d196ca84c7f0e))
* **proto:** Add icon_url to a2a.proto ([#986](https://github.com/a2aproject/A2A/issues/986)) ([17e7f62](https://github.com/a2aproject/A2A/commit/17e7f62df9a3e4ca0768ab8d4f0bb7573b3d73e1))
* **proto:** Adds metadata field to A2A DataPart proto ([#1004](https://github.com/a2aproject/A2A/issues/1004)) ([a8b45dc](https://github.com/a2aproject/A2A/commit/a8b45dcc429a5571ef8a24c36336bf84b89bbd7f))
* Remove unimplemented state_transition_history capability field ([#1396](https://github.com/a2aproject/A2A/issues/1396)) ([c768a44](https://github.com/a2aproject/A2A/commit/c768a44da0f719595e375636f3cab9898ff6df75)), closes [#1228](https://github.com/a2aproject/A2A/issues/1228)
* Restore CreateTaskPushNotificationConfig method naming ([#1402](https://github.com/a2aproject/A2A/issues/1402)) ([d14f410](https://github.com/a2aproject/A2A/commit/d14f4107119bf0fe0dff9e2c577eb4ab70b51793))
* Revert "chore(gRPC): Update a2a.proto to include metadata on GetTaskRequest" ([#1000](https://github.com/a2aproject/A2A/issues/1000)) ([e6b8c65](https://github.com/a2aproject/A2A/commit/e6b8c654a86a6ee461bb5c7be5d5b81004b80a92))
* Simplify Part message structure by flattening FilePart and DataPart ([#1411](https://github.com/a2aproject/A2A/issues/1411)) ([bfae8f7](https://github.com/a2aproject/A2A/commit/bfae8f7791e019f21f6662dd73fce0b3ab261cd6))
* **spec:** Add LF prefix to the package. ([#1474](https://github.com/a2aproject/A2A/issues/1474)) ([a54e809](https://github.com/a2aproject/A2A/commit/a54e80904aa32c74a14bc2c3d21bf82936ccbbdd))
* **spec:** add metadata to `CancelTaskRequest` ([#1485](https://github.com/a2aproject/A2A/issues/1485)) ([c441b91](https://github.com/a2aproject/A2A/commit/c441b910b64d45514ae929a42e7367c2a9a2f6c3)), closes [#1484](https://github.com/a2aproject/A2A/issues/1484)
* **spec:** Added clarification on timestamps in HTTP query params ([#1425](https://github.com/a2aproject/A2A/issues/1425)) ([6292104](https://github.com/a2aproject/A2A/commit/6292104e359efca05bd8703174517b6f961ae4e1))
* **spec:** Added clarifying text around messages and artifacts ([#1424](https://github.com/a2aproject/A2A/issues/1424)) ([b03d141](https://github.com/a2aproject/A2A/commit/b03d141aeab6abd71a229e85c81f7e4c00b537ec))
* **spec:** Adjust field number for `ListTasksRequest.tenant` to prevent missing number ([#1470](https://github.com/a2aproject/A2A/issues/1470)) ([cd16c52](https://github.com/a2aproject/A2A/commit/cd16c5276b4c662ca1823678d07487a624cad606))
* **spec:** Clarify contextId behavior when message is sent with taskId but without contextId ([#1309](https://github.com/a2aproject/A2A/issues/1309)) ([a336a5a](https://github.com/a2aproject/A2A/commit/a336a5a4846fdf85079d4e310339ea0128922ee7))
* **spec:** Clarify versioning strategy and client responsibilities in protocol specification ([#1259](https://github.com/a2aproject/A2A/issues/1259)) ([a4afeea](https://github.com/a2aproject/A2A/commit/a4afeea788b3877101f7a63c2e50091709490058))
* **spec:** Fix/1251 clarify authentication scheme ([#1256](https://github.com/a2aproject/A2A/issues/1256)) ([3e6c7db](https://github.com/a2aproject/A2A/commit/3e6c7db90790c2d05dad3ab1a313de26debe5cb7))
* **spec:** Fixes for the last_updated_after field ([#1358](https://github.com/a2aproject/A2A/issues/1358)) ([0e204bf](https://github.com/a2aproject/A2A/commit/0e204bf878eb63619e205d3419ebc48d4cd35849))
* **spec:** Make "message" field name consistent between protocol bindings ([#1302](https://github.com/a2aproject/A2A/issues/1302)) ([1e5f462](https://github.com/a2aproject/A2A/commit/1e5f46206403982cc629a0dad535856b28c269aa)), closes [#1230](https://github.com/a2aproject/A2A/issues/1230)
* **spec:** make `history_length` optional ([#1071](https://github.com/a2aproject/A2A/issues/1071)) ([0572953](https://github.com/a2aproject/A2A/commit/057295311b8ddda63bdda56c82a694c76d307e37))
* **spec:** pluralize configs in `ListTaskPushNotificationConfigs` ([#1486](https://github.com/a2aproject/A2A/issues/1486)) ([cf735cb](https://github.com/a2aproject/A2A/commit/cf735cb87056ff6d62abd21a1a66ccb14a23c38e))
* **spec:** Remove config from binding. ([#1587](https://github.com/a2aproject/A2A/issues/1587)) ([010b9cc](https://github.com/a2aproject/A2A/commit/010b9cc936fbafd66610282ad66070da2cb28855))
* **spec:** Remove deprecated fields from a2a.proto for v1.0 release ([#1301](https://github.com/a2aproject/A2A/issues/1301)) ([60f83c3](https://github.com/a2aproject/A2A/commit/60f83c3faac4770b231f038406c9e02282887a25)), closes [#1227](https://github.com/a2aproject/A2A/issues/1227)
* **spec:** remove duplicated ID from the create task push config request ([#1487](https://github.com/a2aproject/A2A/issues/1487)) ([393898d](https://github.com/a2aproject/A2A/commit/393898dfeefa37186aced5b61733c5d2c0d9c34a))
* **spec:** Remove metadata field from ListTasksRequest ([#1235](https://github.com/a2aproject/A2A/issues/1235)) ([b6ef9ee](https://github.com/a2aproject/A2A/commit/b6ef9eec558c877fb69024df090a8bb63c542a1c))
* **spec:** Remove reserved and fix tags ordering ([#1494](https://github.com/a2aproject/A2A/issues/1494)) ([1997c9d](https://github.com/a2aproject/A2A/commit/1997c9d63058ca0b89361a7d6e508f4641a6f68b))
* **spec:** Rename `supportsAuthenticatedExtendedCard` to `supportsExtendedAgentCard` ([#1222](https://github.com/a2aproject/A2A/issues/1222)) ([c196824](https://github.com/a2aproject/A2A/commit/c196824396bb4af4c595f30e2c503a5ab1dbac4b)), closes [#1215](https://github.com/a2aproject/A2A/issues/1215)
* **spec:** Standardize spelling of "canceled" to use American Spelling throughout ([#1283](https://github.com/a2aproject/A2A/issues/1283)) ([4dd980f](https://github.com/a2aproject/A2A/commit/4dd980f6ff1989177faffa631a695aba811c56ad))
* **spec:** Suggest Unique Identifier fields to be UUID ([#966](https://github.com/a2aproject/A2A/issues/966)) ([00cf76e](https://github.com/a2aproject/A2A/commit/00cf76e7bbc752842ef254f3d4136ed1b5751f6e))
* **spec:** Switch to non-complex IDs in requests ([#1389](https://github.com/a2aproject/A2A/issues/1389)) ([2596c1c](https://github.com/a2aproject/A2A/commit/2596c1c5e0effd941880e8487d38d78b74b9c0bf)), closes [#1390](https://github.com/a2aproject/A2A/issues/1390)
* **spec:** Update security schemes example ([#1364](https://github.com/a2aproject/A2A/issues/1364)) ([f9a8f5b](https://github.com/a2aproject/A2A/commit/f9a8f5b85d5b07824c52d55d63f7d71ccc6303c5))
* Update the Java tutorials and descriptions ([#1181](https://github.com/a2aproject/A2A/issues/1181)) ([202aa06](https://github.com/a2aproject/A2A/commit/202aa069e66f701bacf2156d42d8916fc96a5188))


### Documentation

* **spec:** Align enum format with ADR-001 ProtoJSON specification ([#1384](https://github.com/a2aproject/A2A/issues/1384)) ([810eaa1](https://github.com/a2aproject/A2A/commit/810eaa1c6e6462f845a00774f8622b998272116e)), closes [#1344](https://github.com/a2aproject/A2A/issues/1344)


### Code Refactoring

* **spec:** Combine `TaskPushNotificationConfig` and `PushNotificationConfig` ([#1500](https://github.com/a2aproject/A2A/issues/1500)) ([d1ed0da](https://github.com/a2aproject/A2A/commit/d1ed0da587d2d634ba0b81a40d082cee0850b81b))
* **spec:** Large refactor of specification to separate application protocol definition from mapping to transports ([b078419](https://github.com/a2aproject/A2A/commit/b0784199543eebf2e95dcb02e9336cb213923506))
* **spec:** Move `extendedAgentCard` field to `AgentCapabilities` ([#1307](https://github.com/a2aproject/A2A/issues/1307)) ([40d6286](https://github.com/a2aproject/A2A/commit/40d6286fbe29fb083d416b77e84122df8d70ae9d))
* **spec:** Remove redundant `final` field from `TaskStatusUpdateEvent` ([#1308](https://github.com/a2aproject/A2A/issues/1308)) ([5b101cc](https://github.com/a2aproject/A2A/commit/5b101cce0fff449c1120ad50ce360acf7c90bac3))

## [0.3.0](https://github.com/a2aproject/A2A/compare/v0.2.6...v0.3.0) (2025-07-30)


### ⚠ BREAKING CHANGES

* Add mTLS to SecuritySchemes, add oauth2 metadata url field, allow Skills to specify Security ([#901](https://github.com/a2aproject/A2A/issues/901))
* Change Well-Known URI for Agent Card hosting from `agent.json` to `agent-card.json` ([#841](https://github.com/a2aproject/A2A/issues/841))
* Add method for fetching extended card ([#929](https://github.com/a2aproject/A2A/issues/929))

### Features

* Add `signatures` to the `AgentCard` ([#917](https://github.com/a2aproject/A2A/issues/917)) ([ef4a305](https://github.com/a2aproject/A2A/commit/ef4a30505381e99b20103724cabef024389bacef))
* Add method for fetching extended card ([#929](https://github.com/a2aproject/A2A/issues/929)) ([2cd7d98](https://github.com/a2aproject/A2A/commit/2cd7d98bc8566601b9a18ca8afe92a0b4d203248))
* Add mTLS to SecuritySchemes, add oauth2 metadata url field, allow Skills to specify Security ([#901](https://github.com/a2aproject/A2A/issues/901)) ([e162c0c](https://github.com/a2aproject/A2A/commit/e162c0c6c4f609d2f4eef9042466d176ec75ebda))


### Bug Fixes

* **spec:** Add `SendMessageRequest.request` `json_name` mapping to `message` ([#904](https://github.com/a2aproject/A2A/issues/904)) ([2eef3f6](https://github.com/a2aproject/A2A/commit/2eef3f6113851e690cee70a1b1643e1ffd6d2a60))
* **spec:** Add Transport enum to specification ([#909](https://github.com/a2aproject/A2A/issues/909)) ([e834347](https://github.com/a2aproject/A2A/commit/e834347c279186d9d7873b352298e8b19737dd5a))


### Code Refactoring

* Change Well-Known URI for Agent Card hosting from `agent.json` to `agent-card.json` ([#841](https://github.com/a2aproject/A2A/issues/841)) ([0858ddb](https://github.com/a2aproject/A2A/commit/0858ddb884dc4671681fd819648dfd697176abb3))

## [0.2.6](https://github.com/a2aproject/A2A/compare/v0.2.5...v0.2.6) (2025-07-17)


### Bug Fixes

* Type fix and doc clarification ([#877](https://github.com/a2aproject/A2A/issues/877)) ([6f1d17b](https://github.com/a2aproject/A2A/commit/6f1d17ba806c32f2b6fbe465be93ec13bfe7d83c))
* Update json names of gRPC objects for proper transcoding  ([#847](https://github.com/a2aproject/A2A/issues/847)) ([6ba72f0](https://github.com/a2aproject/A2A/commit/6ba72f0d51c2e3d0728f84e9743b6d0e88730b51))

## [0.2.5](https://github.com/a2aproject/A2A/compare/v0.2.4...v0.2.5) (2025-06-30)


### ⚠ BREAKING CHANGES

* **spec:** Add a required protocol version to the agent card. ([#802](https://github.com/a2aproject/A2A/issues/802))
* Support for multiple pushNotification config per task ([#738](https://github.com/a2aproject/A2A/issues/738)) ([f355d3e](https://github.com/a2aproject/A2A/commit/f355d3e922de61ba97873fe2989a8987fc89eec2))


### Features

* **spec:** Add a required protocol version to the agent card. ([#802](https://github.com/a2aproject/A2A/issues/802)) ([90fa642](https://github.com/a2aproject/A2A/commit/90fa64209498948b329a7b2ac6ec38942369157a))
* **spec:** Support for multiple pushNotification config per task ([#738](https://github.com/a2aproject/A2A/issues/738)) ([f355d3e](https://github.com/a2aproject/A2A/commit/f355d3e922de61ba97873fe2989a8987fc89eec2))


### Documentation

* update spec & doc topic with non-restartable tasks ([#770](https://github.com/a2aproject/A2A/issues/770)) ([ebc4157](https://github.com/a2aproject/A2A/commit/ebc4157ca87ae08d1c55e38e522a1a17201f2854))

## [0.2.4](https://github.com/a2aproject/A2A/compare/v0.2.3...v0.2.4) (2025-06-30)


### Features

* feat: Add support for multiple transport announcement in AgentCard ([#749](https://github.com/a2aproject/A2A/issues/749)) ([b35485e](https://github.com/a2aproject/A2A/commit/b35485e02e796d15232dec01acfab93fc858c3ec))

## [0.2.3](https://github.com/a2aproject/A2A/compare/v0.2.2...v0.2.3) (2025-06-12)


### Bug Fixes

* Address some typos in gRPC annotations ([#747](https://github.com/a2aproject/A2A/issues/747)) ([f506881](https://github.com/a2aproject/A2A/commit/f506881c9b8ff0632d7c7107d5c426646ae31592))

## [0.2.2](https://github.com/a2aproject/A2A/compare/v0.2.1...v0.2.2) (2025-06-09)


### ⚠ BREAKING CHANGES

* Resolve spec inconsistencies with JSON-RPC 2.0

### Features

* Add gRPC and REST definitions to A2A protocol specifications ([#695](https://github.com/a2aproject/A2A/issues/695)) ([89bb5b8](https://github.com/a2aproject/A2A/commit/89bb5b82438b74ff7bb0fafbe335db7100a0ac57))
* Add protocol support for extensions ([#716](https://github.com/a2aproject/A2A/issues/716)) ([70f1e2b](https://github.com/a2aproject/A2A/commit/70f1e2b0c68a3631888091ce9460a9f7fbfbdff2))
* **spec:** Add an optional iconUrl field to the AgentCard ([#687](https://github.com/a2aproject/A2A/issues/687)) ([9f3bb51](https://github.com/a2aproject/A2A/commit/9f3bb51257f008bd878d85e00ec5e88357016039))


### Bug Fixes

* Protocol should be released as 0.2.2 ([22e7541](https://github.com/a2aproject/A2A/commit/22e7541be082c4f0845ff7fa044992cda05b437e))
* Resolve spec inconsistencies with JSON-RPC 2.0 ([628380e](https://github.com/a2aproject/A2A/commit/628380e7e392bc8f1778ae991d4719bd787c17a9))

## [0.2.1](https://github.com/a2aproject/A2A/compare/v0.2.0...v0.2.1) (2025-05-27)

### Features

* Add a new boolean for supporting authenticated extended cards ([#618](https://github.com/a2aproject/A2A/issues/618)) ([e0a3070](https://github.com/a2aproject/A2A/commit/e0a3070fc289110d43faf2e91b4ffe3c29ef81da))
* Add optional referenceTaskIds for task followups ([#608](https://github.com/a2aproject/A2A/issues/608)) ([5368e77](https://github.com/a2aproject/A2A/commit/5368e7728cb523caf1a9218fda0b1646325f524b))


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of
experience, education, socio-economic status, nationality, personal appearance,
race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

*   Using welcoming and inclusive language
*   Being respectful of differing viewpoints and experiences
*   Gracefully accepting constructive criticism
*   Focusing on what is best for the community
*   Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

*   The use of sexualized language or imagery and unwelcome sexual attention or
    advances
*   Trolling, insulting/derogatory comments, and personal or political attacks
*   Public or private harassment
*   Publishing others' private information, such as a physical or electronic
    address, without explicit permission
*   Other conduct which could reasonably be considered inappropriate in a
    professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban temporarily or permanently any
contributor for other behaviors that they deem inappropriate, threatening,
offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

This Code of Conduct also applies outside the project spaces when the Project
Steward has a reasonable belief that an individual's behavior may have a
negative impact on the project or its community.

## Conflict Resolution

We do not believe that all conflict is bad; healthy debate and disagreement
often yield positive results. However, it is never okay to be disrespectful or
to engage in behavior that violates the project’s code of conduct.

If you see someone violating the code of conduct, you are encouraged to address
the behavior directly with those involved. Many issues can be resolved quickly
and easily, and this gives people more control over the outcome of their
dispute. If you are unable to resolve the matter for any reason, or if the
behavior is threatening or harassing, report it. We are dedicated to providing
an environment where participants feel welcome and safe.

Reports should be directed to [a2a-coc@googlegroups.com](mailto:a2a-coc@googlegroups.com), the
Project Steward(s) for A2A. It is the Project Steward’s duty to
receive and address reported violations of the code of conduct. They will then
work with a committee consisting of representatives from the A2A project and leadership.

We will investigate every complaint, but you may not receive a direct response.
We will use our discretion in determining when and how to follow up on reported
incidents, which may range from not taking action to permanent expulsion from
the project and project-sponsored spaces. We will notify the accused of the
report and provide them an opportunity to discuss it before any action is taken.
The identity of the reporter will be omitted from the details of the report
supplied to the accused. In potentially harmful situations, such as ongoing
harassment or threats to anyone's safety, we may take action without notice.

## Attribution

This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
available at
https://www.contributor-covenant.org/version/1/4/code-of-conduct/


================================================
FILE: CONTRIBUTING.md
================================================
# How to contribute

We'd love to accept your patches and contributions to this project.

## Contribution process

### Code reviews

All submissions, including submissions by project members, require review. We
use GitHub pull requests for this purpose. Consult
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
information on using pull requests.

### Contributor Guide

You may follow these steps to contribute:

1. **Fork the official repository.** This will create a copy of the official repository in your own account.
2. **Sync the branches.** This will ensure that your copy of the repository is up-to-date with the latest changes from the official repository.
3. **Work on your forked repository's feature branch.** This is where you will make your changes to the code.
4. **Commit your updates on your forked repository's feature branch.** This will save your changes to your copy of the repository.
5. **Submit a pull request to the official repository's main branch.** This will request that your changes be merged into the official repository.
6. **Resolve any linting errors.** This will ensure that your changes are formatted correctly.

Here are some additional things to keep in mind during the process:

- **Test your changes.** Before you submit a pull request, make sure that your changes work as expected.
- **Be patient.** It may take some time for your pull request to be reviewed and merged.


================================================
FILE: GOVERNANCE.md
================================================
# Agent2Agent (A2A) Governance

The Agent2Agent project is governed by the Technical Steering Committee. The Committee has eight seats, each held by the following companies:

| Company | Representative | Title | Contact |
| :--- | :--- | :--- | :--- |
| **Google** | Todd Segal | Principal Engineer | [@ToddSegal](https://github.com/ToddSegal) |
| **Microsoft** | Darrel Miller | Partner API Architect | [@darrelmiller](https://github.com/darrelmiller) |
| **Cisco** | Luca Muscariello | Principal Engineer | [@muscariello](https://github.com/muscariello) |
| **Amazon Web Services** | Abhimanyu Siwach | Senior Software Engineer | [@siwachabhi](https://github.com/siwachabhi) |
| **Salesforce** | Stephen Petschulat | Principal Architect | [@spetschulatSFDC](https://github.com/spetschulatSFDC) |
| **ServiceNow** | Sean Hughes | Director of Open Science | [@hughesthe1st](https://github.com/hughesthe1st) |
| **SAP** | Sivakumar N. | Vice President | [@SivaNSAP](https://github.com/SivaNSAP) |
| **IBM Research** | Kate Blair | Director of Incubation | [@geneknit](https://github.com/geneknit) |

## Mission and Scope of the Project

1. The mission of the Project is to help AI agents across different ecosystems communicate with each other. The Project includes collaborative development of the following components:

   1. the Agent2Agent Protocol (the "Protocol");

   2. a SDK for designing implementations of the Protocol and related software components; and

   3. documentation and other artifacts related to the Project.

2. The scope of the Project includes collaborative development under the Project License (as defined herein) supporting the mission, including documentation, testing, integration and the creation of other artifacts that aid the development, deployment, operation or adoption of the open source project.

## Technical Steering Committee

1. The Technical Steering Committee (the "TSC") will be responsible for all technical oversight of the open source Project.
2. **TSC Composition**

    a. **"Startup Phase."** At the inception of the Project, each organization listed in the [`GOVERNANCE`](GOVERNANCE.md) file in the governance repository of the Project will have the right to appoint (and remove and replace) one employee to serve as a voting member of the TSC.

    b. **"Steady State."** The TSC will decide upon a "steady state" composition of the TSC (whether by election, subproject technical leads, or other method as determined by the TSC), to take effect from the date that is 18 months following the inception of the Project, or at such other point as determined by the TSC.

    c. The TSC may choose an alternative approach for determining the voting members of the TSC, and any such alternative approach will be documented in the GOVERNANCE file. Any meetings of the Technical Steering Committee are intended to be open to the public, and can be conducted electronically, via teleconference, or in person.

3. TSC projects generally will involve Contributors and Maintainers. The TSC may adopt or modify roles so long as the roles are documented in the CONTRIBUTING file. Unless otherwise documented:

    a. **Contributors** include anyone in the technical community that contributes code, documentation, or other technical artifacts to the Project;

    b. **Maintainers** are Contributors who have earned the ability to modify ("commit") source code, documentation or other technical artifacts in a project's repository; and

    c. A Contributor may become a Maintainer by a vote of the TSC. A Maintainer may be removed by a vote of the TSC.

    d. Participation in the Project through becoming a Contributor and Maintainer is open to anyone so long as they abide by the terms of this Charter.
4. The TSC may:
    1. establish work flow procedures for the submission, approval, and closure/archiving of projects,
    2. set requirements for the promotion of Contributors to Maintainer status, as applicable, and
    3. amend, adjust, refine and/or eliminate the roles of Contributors, and Maintainer, and create new roles, and publicly document any TSC roles, as it sees fit.
5. The TSC may elect a TSC Chair, who will preside over meetings of the TSC and will serve until their resignation or replacement by the TSC.
6. **Responsibilities:** The TSC will be responsible for all aspects of oversight relating to the Project, which may include:
    1. coordinating the technical direction of the Project;
    2. approving project or system proposals (including, but not limited to, incubation, deprecation, and changes to a subproject's scope);
    3. organizing subprojects and removing subprojects;
    4. creating subcommittees or working groups to focus on cross-project technical issues and requirements;
    5. appointing representatives to work with other open source or open standards communities;
    6. establishing community norms, workflows, issuing releases, and security issue reporting policies;
    7. approving and implementing policies and processes for contributing (to be published in the [`CONTRIBUTING`](CONTRIBUTING.md) file) and coordinating with the series manager of the Project (as provided for in the Series Agreement, the "Series Manager") to resolve matters or concerns that may arise as set forth in Section 7 of this Charter;
    8. discussions, seeking consensus, and where necessary, voting on technical matters relating to the code base that affect multiple projects; and
    9. coordinating any marketing, events, or communications regarding the Project.

### TSC Voting

While the Project aims to operate as a consensus-based community, if any TSC decision requires a vote to move the Project forward, the voting members of the TSC will vote on a one vote per voting member basis. 

Quorum for TSC meetings requires at least fifty percent of all voting members of the TSC to be present. The TSC may continue to meet if quorum is not met but will be prevented from making any decisions at the meeting. Except as provided in Section 7.c. and 8.a, decisions by vote at a meeting require a majority vote of those in attendance, provided quorum is met. Decisions made by electronic vote without a meeting require a majority vote of all voting members of the TSC.

### TSC Meetings
TSC Meetings are held on the Linux Foundation's meeting platform. [https://zoom-lfx.platform.linuxfoundation.org/meetings/agent2agent](https://zoom-lfx.platform.linuxfoundation.org/meetings/agent2agent) has meeting details and recordings of past meetings. 
Our [working doc for TSC Meeting Agendas](https://docs.google.com/document/d/1Dx6qYfCjSChHKRMwLJcvtDjq6igYTAKFW9Vg1IMPCUk/view) is in Google Docs.

## Project Communications

The A2A project utilizes Discord for chat conversations about the project. All are welcome and encouraged to join the [A2A Discord](http://discord.gg/a2aprotocol). Discussion is encouraged however we do remind the community that chat is ephemeral, and not all members of the project are active in chat at the same time.

Therefore, any discussions about feature proposals, significant changes to the project architecture or governance, etc. should be held in GitHub with adequate notice and time for comment. Look for specifics on that timing coming soon as the TSC ramps up. Just keep in mind - our goal is that GitHub is the source of truth for significant project decisions.

Additional communication avenues will likely be added - stay tuned.


================================================
FILE: LICENSE
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: MAINTAINERS.md
================================================
# Maintainers

This document lists the maintainers of various repositories within the project.

## Repository Maintainers

### a2a-dotnet

- role:maintain
  - @aalina23
  - @adamsitnik
  - @Blackhex
  - @iremyux
  - @karelz
  - @rokonec

- role:admin
  - @brandonh-msft
  - @darrelmiller
  - @markwallace-microsoft
  - @SergeyMenshykh
  - @stephentoub

### a2a-go

- role:maintain
  - @yarolegovich

- role:admin
  - @hyangah
  - @mazas-google

### a2a-java

- role:maintain
  - @Doris26
  - @ehsavoie
  - @kabir
  - @maeste

- role:admin
  - @ddobrin
  - @fjuma
  - @holtskinner

### a2a-js

- role:admin
  - @swapydapy

### a2a-python

- role:maintain
  - @aneeshgarg
  - @chitra-venkatesh
  - @dmandar
  - @holtskinner
  - @kthota-g
  - @lkawka
  - @mikeas1
  - @mindpower
  - @mvakoc
  - @pstephengoogle
  - @pwwpche
  - @rajeshvelicheti
  - @swapydapy
  - @ToddSegal

- role:admin
  - @DJ-os
  - @holtskinner
  - @koverholt
  - @kthota-g
  - @ToddSegal
  - @zeroasterisk

### a2a-samples

- role:admin
  - @zeroasterisk
  - @holtskinner
  - @kthota-g




================================================
FILE: README.md
================================================
# Agent2Agent (A2A) Protocol

[![PyPI - Version](https://img.shields.io/pypi/v/a2a-sdk)](https://pypi.org/project/a2a-sdk)
[![Apache License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
<a href="https://codewiki.google/github.com/a2aproject/a2a">
  <img src="https://www.gstatic.com/_/boq-sdlc-agents-ui/_/r/Mvosg4klCA4.svg" alt="Ask Code Wiki" height="20">
</a>

<div style="text-align: left;">
  <details>
    <summary>🌐 Language</summary>
    <div>
      <div style="text-align: center;">
        <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=en">English</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=zh-CN">简体中文</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=zh-TW">繁體中文</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=ja">日本語</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=ko">한국어</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=hi">हिन्दी</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=th">ไทย</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=fr">Français</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=de">Deutsch</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=es">Español</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=it">Italiano</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=ru">Русский</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=pt">Português</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=nl">Nederlands</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=pl">Polski</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=ar">العربية</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=fa">فارسی</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=tr">Türkçe</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=vi">Tiếng Việt</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=id">Bahasa Indonesia</a>
        | <a href="https://openaitx.github.io/view.html?user=a2aproject&project=A2A&lang=as">অসমীয়া</a>
      </div>
    </div>
  </details>
</div>

<!-- markdownlint-disable MD041 -->
<div style="text-align: center;">
  <div class="centered-logo-text-group">
    <img src="docs/assets/a2a-logo-black.svg" alt="Agent2Agent Protocol Logo" width="100">
    <h1>Agent2Agent (A2A) Protocol</h1>
  </div>
</div>

**An open protocol enabling communication and interoperability between opaque agentic applications.**

The Agent2Agent (A2A) protocol addresses a critical challenge in the AI landscape: enabling gen AI agents, built on diverse frameworks by different companies running on separate servers, to communicate and collaborate effectively - as agents, not just as tools. A2A aims to provide a common language for agents, fostering a more interconnected, powerful, and innovative AI ecosystem.

With A2A, agents can:

- Discover each other's capabilities.
- Negotiate interaction modalities (text, forms, media).
- Securely collaborate on long-running tasks.
- Operate without exposing their internal state, memory, or tools.

## DeepLearning.AI Course

[![A2A DeepLearning.AI](https://img.youtube.com/vi/4gYm0Rp7VHc/maxresdefault.jpg)](https://goo.gle/dlai-a2a)

Join this short course on [A2A: The Agent2Agent Protocol](https://goo.gle/dlai-a2a), built in partnership with Google Cloud and IBM Research, and taught by [Holt Skinner](https://github.com/holtskinner), [Ivan Nardini](https://github.com/inardini), and [Sandi Besen](https://github.com/sandijean90).

**What you'll learn:**

- **Make agents A2A-compliant:** Expose agents built with frameworks like Google ADK, LangGraph, or BeeAI as A2A servers.
- **Connect agents:** Create A2A clients from scratch or using integrations to connect to A2A-compliant agents.
- **Orchestrate workflows:** Build sequential and hierarchical workflows of A2A-compliant agents.
- **Multi-agent systems:** Build a healthcare multi-agent system using different frameworks and see how A2A enables collaboration.
- **A2A and MCP:** Learn how A2A complements MCP by enabling agents to collaborate with each other.

## Why A2A?

As AI agents become more prevalent, their ability to interoperate is crucial for building complex, multi-functional applications. A2A aims to:

- **Break Down Silos:** Connect agents across different ecosystems.
- **Enable Complex Collaboration:** Allow specialized agents to work together on tasks that a single agent cannot handle alone.
- **Promote Open Standards:** Foster a community-driven approach to agent communication, encouraging innovation and broad adoption.
- **Preserve Opacity:** Allow agents to collaborate without needing to share internal memory, proprietary logic, or specific tool implementations, enhancing security and protecting intellectual property.

### Key Features

- **Standardized Communication:** JSON-RPC 2.0 over HTTP(S).
- **Agent Discovery:** Via "Agent Cards" detailing capabilities and connection info.
- **Flexible Interaction:** Supports synchronous request/response, streaming (SSE), and asynchronous push notifications.
- **Rich Data Exchange:** Handles text, files, and structured JSON data.
- **Enterprise-Ready:** Designed with security, authentication, and observability in mind.

## Getting Started

- 📚 **Explore the Documentation:** Visit the [Agent2Agent Protocol Documentation Site](https://a2a-protocol.org) for a complete overview, the full protocol specification, tutorials, and guides.
- 📝 **View the Specification:** [A2A Protocol Specification](https://a2a-protocol.org/latest/specification/)
- Use the SDKs:
    - [🐍 A2A Python SDK](https://github.com/a2aproject/a2a-python) `pip install a2a-sdk`
    - [🐿️ A2A Go SDK](https://github.com/a2aproject/a2a-go) `go get github.com/a2aproject/a2a-go`
    - [🧑‍💻 A2A JS SDK](https://github.com/a2aproject/a2a-js) `npm install @a2a-js/sdk`
    - [☕️ A2A Java SDK](https://github.com/a2aproject/a2a-java) using maven
    - [🔷 A2A .NET SDK](https://github.com/a2aproject/a2a-dotnet) using [NuGet](https://www.nuget.org/packages/A2A) `dotnet add package A2A`
- 🎬 Use our [samples](https://github.com/a2aproject/a2a-samples) to see A2A in action

## Contributing

We welcome community contributions to enhance and evolve the A2A protocol!

- **Questions & Discussions:** Join our [GitHub Discussions](https://github.com/a2aproject/A2A/discussions).
- **Issues & Feedback:** Report issues or suggest improvements via [GitHub Issues](https://github.com/a2aproject/A2A/issues).
- **Contribution Guide:** See our [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute.
- **Private Feedback:** Use this [Google Form](https://goo.gle/a2a-feedback).
- **Partner Program:** Google Cloud customers can join our partner program via this [form](https://goo.gle/a2a-partner).

## What's next

### Protocol Enhancements

- **Agent Discovery:**
    - Formalize inclusion of authorization schemes and optional credentials directly within the `AgentCard`.
- **Agent Collaboration:**
    - Investigate a `QuerySkill()` method for dynamically checking unsupported or unanticipated skills.
- **Task Lifecycle & UX:**
    - Support for dynamic UX negotiation _within_ a task (e.g., agent adding audio/video mid-conversation).
- **Client Methods & Transport:**
    - Explore extending support to client-initiated methods (beyond task management).
    - Improvements to streaming reliability and push notification mechanisms.

## About

The A2A Protocol is an open source project under the Linux Foundation, contributed by Google. It is licensed under the [Apache License 2.0](LICENSE) and is open to contributions from the community.


================================================
FILE: SECURITY.md
================================================
# Security Policy

To report a security issue, please use email <security@lists.a2aproject.org>.

We use a mailing list for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue.


================================================
FILE: adrs/adr-001-protojson-serialization.md
================================================
# ADR-001: Leverage ProtoJSON Specification for JSON Serialization

**Status:** Accepted

**Date:** 2025-11-18

**Decision Makers:** Technical Steering Committee (TSC)

**Technical Story:** JSON serialization approach for A2A specification

## Context

The A2A specification defines message structures using Protocol Buffers (proto definitions) but also needs to support JSON serialization for HTTP/REST-based communication and JSONRPC payloads. We needed to establish a normative approach for how JSON payloads should be serialized based on the proto definitions referenced by the specification.

Without a clearly specified approach to JSON serialization from proto definitions, implementers could create incompatible JSON representations, leading to interoperability issues across different A2A implementations.

## Decision Drivers

* Need for a standardized, well-documented approach to JSON serialization
* Ability to leverage existing Protocol Buffer tooling
* Clear specification for handling edge cases and type mappings
* Idiomatic use of JSON conventions
* Coupling of specification to tool chain

## Considered Options

* ProtoJSON (canonical JSON encoding for Protocol Buffers)
* Explicit transformation rules defined in the A2A specification

## Decision Outcome

**Chosen option:** "ProtoJSON specification"

The TSC has decided to leverage the ProtoJSON specification as the normative approach to serializing JSON based on the proto definition referenced by the specification. This provides a well-defined, standardized way to convert Protocol Buffer messages to JSON format.

This decision was made with some reservation due to the dependency on ProtoJSON mechanisms and potential impact on protocol bindings unrelated to protobuf and gRPC. However, the decision is reversible if we identify significant issues during implementation, at which point we can duplicate the ProtoJSON conventions in the A2A specification where applicable and describe differences as needed.

### Consequences

#### Positive

* Standardized approach with clear documentation and specification
* Wide ecosystem support with mature libraries across multiple languages
* Consistent behavior across different implementations
* Reduced ambiguity in JSON representation
* Built-in handling for proto3 types and conventions
* Provides well-defined rules for wire-unsafe changes
* Removes the need to define data type handling rules for dates and numbers in the A2A specification

#### Negative

* **Breaking change**: This decision will result in breaking changes to existing JSON payloads, specifically relating to the casing of enum values (ProtoJSON uses SCREAMING_SNAKE_CASE for enums)
* **Loss of roundtrip capability**: We will not be able to roundtrip unknown values because ProtoJSON doesn't support preserving unknown fields in the JSON representation
* Migration effort required for existing implementations
* **Ugly enums** Developers are not used to seeing enum values in SCREAMING_SNAKE_CASE in JSON, which may lead to confusion or errors during implementation
* Changes to the ProtoJSON specification for the benefit of gRPC could have an impact on other protocol bindings.
* Enums require a "unspecified" value even when they are only used for required fields to meet Proto best practices.
* Certain field names need to have less than optimal names to avoid conflicts with proto keywords. e.g. message.

#### Neutral

* Implementations must follow ProtoJSON specification strictly
* Documentation must clearly communicate the breaking changes

## References

* [ProtoJSON format](https://protobuf.dev/programming-guides/json/)

## Notes

This decision was made to ensure long-term interoperability and maintainability of the A2A specification. While it introduces breaking changes in the short term, the benefits of standardization and ecosystem alignment outweigh the migration costs.

Implementers should be aware that the enum casing change is the most visible breaking change and should plan accordingly for version transitions.


================================================
FILE: adrs/adr-template.md
================================================
# ADR-[number]: [Title]

**Status:** [Proposed | Accepted | Deprecated | Superseded]

**Date:** YYYY-MM-DD

**Decision Makers:** [List of people involved in the decision]

**Technical Story:** [Optional: Link to related issue/story]

## Context

[Describe the context and problem statement. What is the issue that we're seeing that is motivating this decision or change?]

## Decision Drivers

* [Driver 1: e.g., performance requirements]
* [Driver 2: e.g., maintainability concerns]
* [Driver 3: e.g., team expertise]
* [Driver 4: e.g., cost considerations]

## Considered Options

* [Option 1]
* [Option 2]
* [Option 3]

## Decision Outcome

**Chosen option:** "[Option X]"

[Describe why this option was selected. What are the expected positive outcomes?]

### Consequences

#### Positive

* [Positive consequence 1]
* [Positive consequence 2]

#### Negative

* [Negative consequence 1]
* [Negative consequence 2]

#### Neutral

* [Neutral consequence 1]

## [Optional] Pros and Cons of the Options

### [Option 1]

[Brief description of option 1]

**Pros:**

* [Advantage 1]
* [Advantage 2]

**Cons:**

* [Disadvantage 1]
* [Disadvantage 2]

### [Option 2]

[Brief description of option 2]

**Pros:**

* [Advantage 1]
* [Advantage 2]
* [Advantage 2]

**Cons:**

* [Disadvantage 1]
* [Disadvantage 2]

### [Option 3]

[Brief description of option 3]

**Pros:**

* [Advantage 1]
* [Advantage 2]
* [Advantage 2]

**Cons:**

* [Disadvantage 1]
* [Disadvantage 2]

## Implementation

[Optional: Describe the implementation plan, timeline, and any specific technical details]

## Related Decisions

* [Link to related ADR 1]
* [Link to related ADR 2]

## References

* [Link to resource 1]
* [Link to resource 2]
* [Link to resource 3]

## Notes

[Any additional notes, follow-up items, or context that doesn't fit elsewhere]


================================================
FILE: docs/404.html
================================================
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Redirecting...</title>
    <script>
        (function () {
            const basePath = '/A2A/';
            const latestVersion = 'latest';

            const path = window.location.pathname;
            const redirected = sessionStorage.getItem('redirected');

            if (redirected) {
                sessionStorage.removeItem('redirected');
                console.warn('Redirect loop detected. Stopping redirect.');
                return;
            }

            if (path.endsWith('/sdk/python/')) {
                window.location.replace('https://a2a-protocol.org/latest/sdk/python/api');
            }

            // Check if the path is an asset or already a versioned path
            const isAsset = path.includes('/assets/') || path.includes('/stylesheets/');
            const isVersioned = new RegExp(`${basePath}(v?(\d+\.\d+(\.\d+)?)|${latestVersion})/`).test(path);

            if (!isVersioned && !isAsset) {
                // Construct the new URL.
                // Example: /A2A/specification.md -> /A2A/latest/specification.md
                const newPath = path.replace(basePath, basePath + latestVersion + '/');

                // Store a marker in sessionStorage to prevent loops
                sessionStorage.setItem('redirected', 'true');

                // Perform the redirect
                window.location.replace(newPath + window.location.search + window.location.hash);
            } else {
                window.location.replace('https://a2a-protocol.org/');
            }
        })();
    </script>
</head>

<body>
    <h1>A2A - Page Not Found</h1>
    <p>We are attempting to redirect you to the latest version of this page.</p>
    <p>If you are not redirected automatically, please navigate to the <a href="https://a2a-protocol.org/">A2A project homepage</a>.</p>
</body>

</html>


================================================
FILE: docs/README.md
================================================
# A2A Docs

<https://a2a-protocol.org>

## Developing A2A docs

1. Clone this repository and `cd` into the repository directory
2. Run `pip install -r requirements-docs.txt`
3. Run `mkdocs serve`, edit `.md` files, and live preview
4. Contribute docs changes as usual

## How it works

- The A2A docs use [mkdocs](https://www.mkdocs.org/) and the
  [mkdocs-material theme](https://squidfunk.github.io/mkdocs-material/)
- All of the source documentation / Markdown files related to the A2A docs are
  in the `docs/` directory in the A2A repository
- `mkdocs.yml` in the repository root contains all of the docs config, including
  the site navigation and organization
- There is a GitHub Action in `.github/workflows/docs.yml` that builds and
  publishes the docs and pushes the built assets to the `gh-pages` branch in
  this repository using `mkdocs gh-deploy --force`. This happens automatically for all
  commits / merges to `main`.
- The A2A documentation is hosted in GitHub pages, and the settings for this are
  in the A2A repository settings in GitHub.

## Building the Python SDK Documentation

The Python SDK documentation is built using [Sphinx](https://www.sphinx-doc.org/).

### Prerequisites

Ensure you have installed the documentation dependencies:

```bash
pip install -r ../../requirements-docs.txt
```

### Building the Docs

1. Run the following command to build the HTML documentation:

   ```bash
   sphinx-build -b html docs/sdk/python docs/sdk/python/api
   ```

2. The generated HTML files will be in the `sdk/python/api` directory. You can open `sdk/python/api/index.html` in your browser to view the documentation.


================================================
FILE: docs/announcing-1.0.md
================================================
# A2A Protocol Ships v1.0: Production-Ready Standard for Agent-to-Agent Communication

The A2A Protocol community today are announcing the release of A2A Protocol v1.0, marking the first stable, production-ready version of the open standard for communication between AI agents. The protocol is guided by a technical steering committee with representatives from eight major technology companies.

As organizations build increasingly sophisticated multi-agent systems, interoperability has become the defining challenge. Teams can coordinate agents effectively within a single platform, but connecting those systems across technology stacks and organizational boundaries remains difficult. A2A addresses that challenge by combining support for multiple protocol bindings, seamless version negotiation, and a common semantic model so agents can interoperate across systems with predictable behavior.

The v1.0 release emphasizes maturity rather than reinvention: the core ideas remain intact, while rough edges have been removed, ambiguous areas clarified, and enterprise deployment requirements addressed more directly. The official SDKs ensure v1.0 A2A agents work seamlessly with older versions.

## Delivering on enterprise requirements

The v1.0 release introduces several capabilities aimed at production environments where trust, scale, and operational control are non-negotiable.

- **Heterogeneous environment support** enables interoperability across diverse technology stacks through multi-protocol bindings and version negotiation, so enterprises are not tied to a single vendor or platform.
- **Multi-tenancy support** allows a single endpoint to securely host many agents.
- **Signed Agent Cards** provide cryptographic verification of agent identity and metadata, establishing trust before interaction across organizational boundaries.
- **Improved security posture** modernizes security flows and removes legacy patterns that are no longer aligned with current best practices.

Together, these changes move A2A from early adopter implementations toward broader enterprise confidence, especially in regulated or multi-party scenarios.

## Web-aligned architecture for scale

A2A v1.0 aligns with core architectural principles of the web: stateless, layered architecture, standard protocol bindings, and infrastructure-friendly communication patterns. That alignment matters operationally because organizations can scale agent interactions with the same proven load balancing, gateway, security and observability patterns they already use for web systems.

The standard builds on industry-proven protocols, including JSON+HTTP, gRPC, and JSON-RPC. It also keeps the barrier to entry low: in its simplest form, an A2A interaction can begin with a single HTTP request.

A2A also gives consumers flexibility in how they receive results. Depending on workload and operational needs, clients can use polling, streaming, or webhooks to consume task updates and responses.

## Complementary to MCP, not a replacement

The release also reinforces A2A's relationship with the Model Context Protocol (MCP), a point that has generated confusion in early ecosystem discussions.

MCP and A2A solve different layers of the problem. MCP is commonly used for tool and context integration at the individual agent level. A2A focuses on communication and coordination between agents. In practice, many systems will use both: MCP inside agents, A2A between agents.

## Smooth migration from earlier versions

The v1.0 release tightens specification behavior, which includes breaking changes in the interaction protocol. AgentCard, however, has evolved in a backward-compatible way and now allows agents to advertise support for both existing v0.3 protocol behavior and v1.0 simultaneously. This enables clients to migrate progressively rather than through a single cutover.

That approach is intended to protect current investments while still delivering the benefits of a cleaner, more durable standard.

## Why this release matters now

AI agents are increasingly deployed across departments, products, and partner ecosystems. At that scale, the key question is no longer whether agents can coordinate within one stack, but whether they can collaborate reliably across organizational and platform boundaries. Open protocols determine whether organizations can compose best-of-breed systems or become locked into isolated stacks.

A2A v1.0 gives the market a stronger foundation for open multi-agent collaboration. The community is now focused on delivering multi-language v1.0 SDK support to help developers build conformant solutions with ease.

The complete v1.0 materials, including specification and migration documentation, are available at [a2a-protocol.org](https://a2a-protocol.org) and on [GitHub](https://github.com/a2aproject/A2A).

---

**About A2A Protocol**
The Agent-to-Agent (A2A) Protocol is an open standard that enables AI agents to discover capabilities, communicate, and delegate tasks across teams, products, and organizations. The A2A Technical Steering Committee includes representatives from AWS, Cisco, Google, IBM Research, Microsoft, Salesforce, SAP, and ServiceNow.

**Media Contact**
A2A Protocol Community
[https://a2a-protocol.org](https://a2a-protocol.org)


================================================
FILE: docs/community.md
================================================
# A2A Community Hub

Welcome to the official community hub for the **Agent2Agent (A2A) protocol**! A2A is an open, standardized protocol that enables seamless interoperability and collaboration between AI agents across all frameworks and vendors.

---

## Recent News & Blog Posts

Stay up-to-date with the latest announcements, tutorials, and insights from the A2A team and our community.

- **[Announcing Agent Payments Protocol (AP2)](https://cloud.google.com/blog/products/ai-machine-learning/announcing-agent-payments-protocol-ap2)** - *September 16*
- **[A2A Extensions Empowering Custom Agent Functionality](https://developers.googleblog.com/en/a2a-extensions-empowering-custom-agent-functionality/)** - *September 9*
- **[A2A protocol: Demystifying Tasks vs Messages](https://discuss.google.dev/t/a2a-protocol-demystifying-tasks-vs-messages/255879)** - *August 18*
- **[End-to-end evaluation of multi-agent systems on Vertex AI](https://discuss.google.dev/t/end-to-end-evaluation-of-multi-agent-systems-on-vertex-ai-with-cloud-run-deployment-for-a2a-agents/250552)** - *August 7*
- **[Agent2Agent (A2A) protocol is getting an upgrade](https://cloud.google.com/blog/products/ai-machine-learning/agent2agent-protocol-is-getting-an-upgrade?e=48754805)** - *July 26*

---

## Use Case Highlights

A2A unlocks powerful new ways for AI agents to collaborate and solve complex problems. Here are a few examples of what's possible:

- **Multi-Agent Workflows:** Chain specialized agents together to automate complex processes, like candidate sourcing for hiring or streamlining supply chain logistics.
- **Agent Marketplaces:** Create platforms where agents can discover and utilize the capabilities of other agents from different providers.
- **Cross-Platform Integration:** Connect agents built on different frameworks—like LangGraph, BeeAI, and more—to work together seamlessly.
- **Evaluating Multi-Agent Systems:** Use frameworks like Vertex AI to assess the performance and success of collaborative agent trajectories.

---

## Community Spotlight

### Featured Contributions

A2A is an open-source protocol, and we thrive on community contributions. A huge thank you to everyone who has helped build and improve A2A! Here are some recent highlights:

- [Python Quickstart Tutorial (PR#202)](https://github.com/a2aproject/A2A/pull/202)
- [LlamaIndex sample implementation (PR#179)](https://github.com/a2aproject/A2A/pull/179)
- [Autogen sample server (PR#232)](https://github.com/a2aproject/A2A/pull/232)
- [AG2 + MCP example (PR#230)](https://github.com/a2aproject/A2A/pull/230)
- [PydanticAI example (PR#127)](https://github.com/a2aproject/A2A/pull/127)

### The Word on the Street

The launch of A2A has sparked lively discussions and positive reactions across various social and video platforms.

- **Microsoft's Semantic Kernel:** Asha Sharma, Head of AI Platform Product at Microsoft, [announced on LinkedIn](https://www.linkedin.com/posts/aboutasha_a2a-ugcPost-7318649411704602624-0C_8) that "Semantic Kernel now speaks A2A," enabling instant, secure interoperability.
- **Matt Pocock's Diagramming:** Well-known developer educator Matt Pocock [shared diagrams on X](https://x.com/mattpocockuk/status/1910002033018421400) explaining the A2A protocol, which were liked and reposted hundreds of times.
- **Craig McLuckie's "Hot Take":** Craig McLuckie shared his thoughts on [LinkedIn](https://www.linkedin.com/posts/craigmcluckie_hot-take-on-agent2agent-vs-mcp-google-just-activity-7315939233792176128-4rGQ), highlighting A2A's focus on interactions *between* agentic systems as a sensible approach.
- **Zachary Huang's Deep Dive:** In his [YouTube video](https://www.youtube.com/watch?v=wrCF8MoXC_I), Zachary explains how A2A complements MCP, with A2A handling communication between agents and MCP connecting agents to tools.

---

## A2A Integrations

These agentic frameworks have built-in A2A integration, making it easy to get started:

- [Agent Development Kit (ADK)](https://google.github.io/adk-docs/a2a/)
- [Agno](https://docs.agno.com/agent-os/interfaces/a2a/introduction)
- [AG2](https://docs.ag2.ai/latest/docs/user-guide/a2a/)
- [BeeAI Framework](https://framework.beeai.dev/integrations/a2a)
- [CrewAI](https://docs.crewai.com/en/learn/a2a-agent-delegation)
- [Hector](https://github.com/kadirpekel/hector)
- [LangGraph](https://docs.langchain.com/langsmith/server-a2a)
- [LiteLLM](https://docs.litellm.ai/docs/a2a)
- [Microsoft Agent Framework](https://learn.microsoft.com/en-us/agent-framework/user-guide/agents/agent-types/a2a-agent)
- [Pydantic AI](https://ai.pydantic.dev/a2a/)
- [Slide (Tyler)](https://slide.mintlify.app/guides/a2a-integration)
- [Strands Agents](https://strandsagents.com/latest/documentation/docs/user-guide/concepts/multi-agent/agent-to-agent/)

## The Future is Interoperable

The excitement surrounding Google's A2A protocol clearly indicates a strong belief in its potential to revolutionize multi-agent AI systems. By providing a standardized way for AI agents to communicate and collaborate, A2A is poised to unlock new levels of automation and innovation. As enterprises increasingly adopt AI agents, A2A represents a crucial step towards realizing the full power of interconnected AI ecosystems.

**Join the growing community building the future of AI interoperability with A2A!**


================================================
FILE: docs/definitions.md
================================================
# A2A Definition/Schema

=== "Protobuf"
    <h3>Protobuf</h3>
    The normative A2A protocol definition in Protocol Buffers (proto3 syntax).
    This is the source of truth for the A2A protocol specification.

    <h3>Download</h3>

    You can download the proto file directly: [`a2a.proto`](spec/a2a.proto)

    <h3>Definition</h3>

    ```protobuf
    --8<-- "docs/spec/a2a.proto"
    ```

=== "JSON"
    <h3>JSON</h3>
    The A2A protocol JSON Schema definition (JSON Schema 2020-12 compliant).
    This schema is automatically generated from the protocol buffer definitions and bundled into a single file with all message definitions.

    <h3>Download</h3>

    You can download the schema file directly: [`a2a.json`](spec/a2a.json)

    <h3>Definition</h3>

    ```json
    --8<-- "docs/spec/a2a.json"
    ```


================================================
FILE: docs/index.md
================================================
---
hide:
  - toc
---

<!-- markdownlint-disable MD041 -->
<div style="text-align: center;">
  <div class="centered-logo-text-group">
    <img src="assets/a2a-logo-black.svg" alt="Agent2Agent Protocol Logo" width="100">
    <h1>Agent2Agent (A2A) Protocol</h1>
  </div>
</div>

## What is A2A Protocol?

Welcome to the **official documentation** for the **Agent2Agent (A2A) Protocol**, an open standard designed to enable seamless communication and collaboration between AI agents.

Originally developed by Google and now donated to the Linux Foundation, A2A provides the definitive common language for agent interoperability in a world where agents are built using diverse frameworks and by different vendors.

!!! abstract ""
    Build with
    **[![ADK Logo](https://google.github.io/adk-docs/assets/agent-development-kit.png){class="twemoji lg middle"} ADK](https://google.github.io/adk-docs/)** _(or any framework)_,
    equip with **[![MCP Logo](https://modelcontextprotocol.io/mcp.png){class="twemoji lg middle"} MCP](https://modelcontextprotocol.io)** _(or any tool)_,
    and communicate with
    **![A2A Logo](./assets/a2a-logo-black.svg){class="twemoji lg middle"} A2A**,
    to remote agents, local agents, and humans.

## Get started with A2A

<div class="grid cards" markdown>

- :material-play-circle:{ .lg .middle } **Video** Intro in <8 min

    <iframe class="video-container" src="https://www.youtube.com/embed/Fbr_Solax1w?si=QxPMEEiO5kLr5_0F" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

- :material-play-circle:{ .lg .middle } **Course** [DeepLearning.AI](https://deeplearning.ai) - Intro to A2A

    [![A2A DeepLearning.AI](https://img.youtube.com/vi/4gYm0Rp7VHc/maxresdefault.jpg)](https://goo.gle/dlai-a2a)

- :material-book-open:{ .lg .middle } **Read the Introduction**

    Understand the core ideas behind A2A.

    [:octicons-arrow-right-24: What is A2A?](./topics/what-is-a2a.md)

    [:octicons-arrow-right-24: Key Concepts](./topics/key-concepts.md)

- :material-file-document-outline:{ .lg .middle } **Dive into the Specification**

    Explore the detailed technical definition of the A2A protocol.

    [:octicons-arrow-right-24: Protocol Specification](./specification.md)

- :material-application-cog-outline:{ .lg .middle } **Follow the Tutorials**

    Build your first A2A-compliant agent with our step-by-step Python quickstart.

    [:octicons-arrow-right-24: Python Tutorial](./tutorials/python/1-introduction.md)

    [:octicons-arrow-right-24: Walkthrough with AI Agent Frameworks](https://github.com/holtskinner/A2AWalkthrough)

- :material-code-braces:{ .lg .middle } **Explore Code Samples**

    See A2A in action with sample clients, servers, and agent framework integrations.

    [:fontawesome-brands-github: GitHub Samples](https://github.com/a2aproject/a2a-samples)

- :material-code-braces:{ .lg .middle } **Download the Official SDKs**

    [:fontawesome-brands-python: Python](https://github.com/a2aproject/a2a-python)

    [:fontawesome-brands-js: JavaScript](https://github.com/a2aproject/a2a-js)

    [:fontawesome-brands-java: Java](https://github.com/a2aproject/a2a-java)

    [:octicons-code-24: C#/.NET](https://github.com/a2aproject/a2a-dotnet)

    [:fontawesome-brands-golang: Golang](https://github.com/a2aproject/a2a-go)

</div>

## Why use the A2A Protocol

<div style="text-align:center">

```mermaid
graph LR
    User(🧑‍💻 User) <--> ClientAgent(🤖 Client Agent)
    ClientAgent --> A2A1(**↔️ A2A**) --> RemoteAgent1(🤖 Remote Agent 1)
    ClientAgent --> A2A2(**↔️ A2A**) --> RemoteAgent2(🤖 Remote Agent 2)

    style User fill:#fdebd0,stroke:#e67e22,stroke-width:2px
    style ClientAgent fill:#d6eaf8,stroke:#3498db,stroke-width:2px
    style RemoteAgent1 fill:#d6eaf8,stroke:#3498db,stroke-width:2px
    style RemoteAgent2 fill:#d6eaf8,stroke:#3498db,stroke-width:2px
    style A2A1 fill:#ebedef,stroke:#909497,stroke-width:2px
    style A2A2 fill:#ebedef,stroke:#909497,stroke-width:2px
```

</div>

<div class="grid cards" markdown>

- :material-account-group-outline:{ .lg .middle } **Interoperability**

    Connect agents built on different platforms (LangGraph, CrewAI, Semantic Kernel, custom solutions) to create powerful, composite AI systems.

- :material-lan-connect:{ .lg .middle } **Complex Workflows**

    Enable agents to delegate sub-tasks, exchange information, and coordinate actions to solve complex problems that a single agent cannot.

- :material-shield-key-outline:{ .lg .middle } **Secure & Opaque**

    Agents interact without needing to share internal memory, tools, or proprietary logic, ensuring security and preserving intellectual property.

</div>

---

## How does A2A work with MCP?

![A2A MCP Graphic](assets/a2a-mcp-readme.png){width="60%"}
{style="text-align: center; margin-bottom:1em; margin-top:1em;"}

A2A and [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) are complementary standards for building robust agentic applications:

- **Model Context Protocol (MCP)**: Provides [agent-to-tool communication](https://cloud.google.com/discover/what-is-model-context-protocol). It's a complementary standard that standardizes how an agent connects to its tools, APIs, and resources to get information.
- **IBM ACP**: [Incorporated into the A2A Protocol](https://github.com/orgs/i-am-bee/discussions/5)
- **Cisco agntcy**: A framework that provides components to the Internet of Agents with discovery, group communication, identity and observability and leverages A2A and MCP for agent communication and tool calling.
- **A2A**: Provides agent-to-agent communication. As a universal, decentralized standard, A2A acts as the public internet that allows [ai agents](https://cloud.google.com/discover/what-are-ai-agents)—including those using MCP, or built with frameworks like agntcy—to interoperate, collaborate, and share their findings.


================================================
FILE: docs/llms.txt
================================================
# A2A (Agent2Agent) Protocol High-Level Summary

This project defines the **Agent2Agent (A2A) protocol**, an open standard initiated by Google and donated to the Linux Foundation, designed to enable communication and interoperability between disparate AI agent systems. It allows agents built on different frameworks (e.g., LangGraph, CrewAI, Google ADK, Genkit) to discover each other's capabilities, negotiate interaction modes, and collaborate on tasks securely without exposing internal state.

The repository contains:
1.  **Formal Specification:** Protobuf definitions (`specification/a2a.proto`) and JSON Schema (`specification/json/a2a.json`).
2.  **Core Concepts Documentation:** Guides on discovery, task lifecycle, streaming, and enterprise-readiness (`docs/topics/`).
3.  **SDKs:** Production-ready SDKs for Python, JS/TS, Java, Go, and .NET.
4.  **Sample Implementations:** Real-world examples integrated with various agent frameworks.

## Key Files & Directories

- `specification/a2a.proto`: The authoritative Protobuf definition of the protocol.
- `docs/topics/`: Detailed conceptual guides (Discovery, Lifecycle, Security, etc.).
- `docs/tutorials/`: Step-by-step guides for building A2A-compliant agents.
- `scripts/`: Utility scripts for building documentation and formatting.

# A2A (Agent2Agent) Protocol Reference

## 1. Overview

- **Purpose:** Open standard for agent-to-agent interoperability.
- **Communication Bindings:** Supports JSON-RPC 2.0 (HTTP/SSE), gRPC, and HTTP/REST.
- **Key Concepts:** Agent Cards for discovery, Task-based execution, Multi-turn Messages, and Artifact outputs.

## 2. Core Data Objects

### 2.1 AgentCard (`/.well-known/agent-card.json`)
Describes an agent's identity and capabilities.
- `name`, `description`, `version`: Identity metadata.
- `supported_interfaces`: List of `AgentInterface` (URL, protocol binding, tenant, protocol version).
- `capabilities`: `streaming`, `push_notifications`, `extended_agent_card`, `extensions`.
- `skills`: List of `AgentSkill` (id, name, description, tags, examples).
- `security_schemes`, `security_requirements`: Authentication configuration (API Key, OAuth2, OIDC, mTLS, HTTP Auth).
- `default_input_modes`, `default_output_modes`: Supported MIME types (e.g., `text/plain`, `application/json`).

### 2.2 Task
Represents a stateful unit of work.
- `id`, `context_id`: Identifiers for the task and its conversational context.
- `status`: `TaskStatus` (state, message, timestamp).
- `artifacts`: List of `Artifact` (outputs produced).
- `history`: List of `Message` (conversation history).
- `metadata`: Custom structured data.

### 2.3 TaskState (Enum)
- `SUBMITTED`, `WORKING`, `COMPLETED` (terminal), `FAILED` (terminal), `CANCELED` (terminal), `REJECTED` (terminal), `INPUT_REQUIRED` (interrupted), `AUTH_REQUIRED` (interrupted).

### 2.4 Message & Part
- `Message`: Contains `message_id`, `role` (USER/AGENT), `parts`, `context_id`, `task_id`, `reference_task_ids`.
- `Part`: Union type containing `text`, `raw` (bytes), `url`, or `data` (JSON). Includes `media_type` and `filename`.

### 2.5 Artifact
- A tangible output from a task, containing one or more `Part`s and metadata.

## 3. RPC Methods

| Method | Request | Response | Description |
| :--- | :--- | :--- | :--- |
| `SendMessage` | `SendMessageRequest` | `SendMessageResponse` | Initiates or continues a task. |
| `SendStreamingMessage` | `SendMessageRequest` | `stream StreamResponse` | Sends message and receives real-time SSE updates. |
| `GetTask` | `GetTaskRequest` | `Task` | Retrieves current task state. |
| `ListTasks` | `ListTasksRequest` | `ListTasksResponse` | Filter and paginate tasks. |
| `CancelTask` | `CancelTaskRequest` | `Task` | Requests cancellation of a task. |
| `SubscribeToTask` | `SubscribeToTaskRequest` | `stream StreamResponse` | Subscribes to updates for an existing task. |
| `GetExtendedAgentCard` | `GetExtendedAgentCardRequest` | `AgentCard` | Fetches detailed metadata after authentication. |

### 3.1 Streaming Events (`StreamResponse`)
Streams return a payload containing one of:
- `task`: Full task state.
- `message`: A discrete message part.
- `status_update`: `TaskStatusUpdateEvent` (taskId, contextId, status).
- `artifact_update`: `TaskArtifactUpdateEvent` (taskId, artifact, append, last_chunk).

## 4. Security & Authentication
- **Transport:** HTTPS/TLS required for production.
- **Authentication:** Declared in `AgentCard` via OpenAPI-style security schemes.
- **Push Notifications:** Webhooks secured via authentication tokens/schemes configured per task.

## 5. Implementation Status
- **Official SDKs:** Python (`a2a-sdk`), JS/TS (`@a2a-js/sdk`), Java, Go, C#/.NET.
- **Integrations:** LangGraph, CrewAI, Google ADK, Genkit, AG2, BeeAI, PydanticAI, and more.


================================================
FILE: docs/partners.md
================================================
# Partners

Below is a list of partners (and a link to their A2A announcement or blog post,
if available) who are part of the A2A community and are helping build, codify,
and adopt A2A as the standard protocol for AI agents to communicate and
collaborate effectively with each other and with users.

- [A2A Net](https://a2anet.com)
- [Accelirate Inc](https://www.accelirate.com)
- [Accenture](https://www.accenture.com)
- [Activeloop](https://www.activeloop.ai/)
- [Adobe](https://www.adobe.com)
- [AG2AI](https://ag2.ai)
- [AgentTrust](https://agenttrust.ai/)
- [AI21 Labs](https://www.ai21.com/)
- [AI71](https://ai71.ai/)
- [Aisera](https://aisera.com/)
- [AliCloud](http://www.alibabacloud.com)
- [Almawave.it](https://www.almawave.com/it/)
- [AmikoNet](https://amikonet.ai)
- [ArcBlock](http://www.arcblock.io)
- [Arize](https://arize.com/blog/arize-ai-and-future-of-agent-interoperability-embracing-googles-a2a-protocol/)
- [Articul8](https://www.articul8.ai/blog/unleashing-the-next-frontier-of-enterprise-ai-introducing-model-mesh-dock-and-inter-lock-and-our-a2-a-partnership-with-google)
- [ask-ai.com](https://ask-ai.com)
- [Atlassian](https://www.atlassian.com)
- [Auth0](https://auth0.com/blog/auth0-google-a2a/)
- [Autodesk](https://www.autodesk.com)
- [AWS](https://aws.amazon.com/)
- [Beekeeper](http://beekeeper.io)
- [BCG](https://www.bcg.com)
- [Block Inc](https://block.xyz/)
- [Bloomberg LP](https://techatbloomberg.com/)
- [BLUEISH Inc](https://www.blueish.co.jp/)
- [BMC Software Inc](https://www.bmc.com/it-solutions/bmc-helix.html)
- [Boomi](https://boomi.com/)
- [Box](https://www.box.com)
- [Bridge2Things Automation Process GmbH](http://bridge2things.at)
- [Cafe 24](https://www.cafe24corp.com/en/company/about)
- [C3 AI](https://c3.ai)
- [Capgemini](https://www.capgemini.com)
- [Chronosphere](https://chronosphere.io)
- [Cisco](https://www.cisco.com/)
- [Codimite PTE LTD](https://codimite.ai/)
- [Cognigy](https://www.cognigy.com/)
- [Cognizant](https://www.cognizant.com)
- [Cohere](https://cohere.com)
- [Collibra](https://www.collibra.com)
- [Confluent](https://developer.confluent.io)
- [Contextual](https://contextual.ai)
- [Cotality](https://cotality.com) (fka Corelogic)
- [Crubyt](https://www.crubyt.com)
- [Cyderes](http://www.cyderes.com)
- [Datadog](https://www.datadoghq.com)
- [DataRobot](https://www.datarobot.com)
- [DataStax](https://www.datastax.com)
- [Decagon.ai](https://decagon.ai)
- [Deloitte](https://www.prnewswire.com/news-releases/deloitte-expands-alliances-with-google-cloud-and-servicenow-to-accelerate-agentic-ai-adoption-in-the-enterprise-302423941.html)
- [Devnagri](https://devnagri.com)
- [Deutsche Telekom](https://www.telekom.com/en)
- [Dexter Tech Labs](http://www.dextertechlabs.com)
- [Distyl.ai](https://distyl.ai)
- [Elastic](https://www.elastic.co)
- [Ema.co](https://ema.co)
- [EPAM](https://www.epam.com)
- [Eviden (Atos Group)](https://atos.net/)
- [fractal.ai](https://fractal.ai/new)
- [GenAI Nebula9.ai Solutions Pvt Ltd](http://nebula9.ai)
- [Glean](https://www.glean.com)
- [Global Logic](https://www.globallogic.com/)
- [Gravitee](https://www.gravitee.io/)
- [GrowthLoop](https://growthloop.com)
- [Guru](http://www.getguru.com)
- [Harness](https://harness.io)
- [HCLTech](https://www.hcltech.com)
- [Headwaters](https://www.headwaters.co.jp)
- [Hellotars](https://hellotars.com)
- [Hexaware](https://hexaware.com/)
- [HUMAN](https://www.humansecurity.com/)
- [IBM Research](https://lfaidata.foundation/communityblog/2025/08/29/acp-joins-forces-with-a2a-under-the-linux-foundations-lf-ai-data/)
- [Incorta](https://www.incorta.com)
- [Infinitus](https://www.infinitus.ai/)
- [InfoSys](https://www.infosys.com)
- [Intuit](https://www.intuit.com)
- [Iron Mountain](https://www.ironmountain.com/)
- [JamJet](https://github.com/jamjet-labs/jamjet)
- [JetBrains](https://www.jetbrains.com)
- [JFrog](https://jfrog.com)
- [Kakao](https://www.kakaocorp.com)
- [King's College London](https://www.kcl.ac.uk/informatics)
- [KPMG](https://kpmg.com/us/en/media/news/kpmg-google-cloud-alliance-expansion-agentspace-adoption.html)
- [Kyndryl](http://www.kyndryl.com)
- [LabelBox](https://labelbox.com)
- [LangChain](https://www.langchain.com)
- [LG CNS](http://www.lgcns.com)
- [Livex.ai](https://livex.ai)
- [LlamaIndex](https://x.com/llama_index/status/1912949446322852185)
- [LTIMindTtree](https://www.ltimindtree.com)
- [Lumeris](https://www.lumeris.com/)
- [Lyzr.ai](https://lyzr.ai)
- [Magyar Telekom](https://www.telekom.hu/)
- [MasOrange](https://masorange.es/en/)
- [Microsoft](https://www.microsoft.com/en-us/microsoft-cloud/blog/2025/05/07/empowering-multi-agent-apps-with-the-open-agent2agent-a2a-protocol/)
- [MindsDB](https://mindsdb.com/blog/mindsdb-now-supports-the-agent2agent-(a2a)-protocol)
- [McKinsey](https://www.mckinsey.com)
- [MongoDB](https://www.mongodb.com)
- [Monite](https://monite.com/)
- [Neo4j](https://neo4j.com)
- [New Relic](https://newrelic.com)
- [Nisum](http://www.nisum.com)
- [Noorle Inc](http://www.noorle.com)
- [NTT DATA](https://www.nttdata.com)
- [Optimizely Inc](https://www.optimizely.com/)
- [Oracle / NetSuite](https://www.oracle.com/netsuite)
- [Palo Alto Networks](https://www.paloaltonetworks.com/)
- [PancakeAI](https://www.pancakeai.tech/)
- [ParkourSC](https://www.parkoursc.com/)
- [Pendo](https://www.pendo.io)
- [PerfAI.ai](https://perfai.ai)
- [Personal AI](https://personal.ai)
- [Pinchwork](https://pinchwork.dev)
- [Poppulo](https://www.poppulo.com/blog/poppulo-google-a2a-the-future-of-workplace-communication)
- [Productive Edge](https://www.productiveedge.com/)
- [Proofs](https://proofs.io)
- [Publicis Sapient](https://www.publicissapient.com/)
- [PWC](https://www.pwc.com)
- [Quantiphi](https://www.quantiphi.com)
- [Radix](https://radix.website/)
- [RagaAI Inc](https://raga.ai/)
- [Red Hat](https://www.redhat.com)
- [Reltio Inc](http://www.reltio.com)
- [S&P](https://www.spglobal.com)
- [Sage](https://www.sage.com/en-us/)
- [Salesforce](https://www.salesforce.com)
- [SAP](https://news.sap.com/2025/04/sap-google-cloud-enterprise-ai-open-agent-collaboration-model-choice-multimodal-intelligence/)
- [Sayone Technologies](https://www.sayonetech.com/)
- [ServiceNow](https://www.servicenow.com)
- [Siemens AG](https://siemens.com/)
- [SoftBank Corp](https://www.softbank.jp/en//)
- [Solace](https://solace.com/products/agent-mesh/)
- [Solo.io](https://www.solo.io/)
- [Stacklok, Inc](https://stacklok.com)
- [Supertab](https://www.supertab.co/post/supertab-connect-partners-with-google-cloud-to-enable-ai-agents)
- [Suzega](https://suzega.com/)
- [TCS](https://www.tcs.com)
- [Tech Mahindra](https://www.techmahindra.com/)
- [Telefonica](https://www.telefonica.com/)
- [Test Innovation Technology](https://www.test-it.com)
- [the artinet project](https://artinet.io/)
- [Think41](http://www.think41.com)
- [Thoughtworks](https://www.thoughtworks.com/)
- [Tredence](http://www.tredence.com)
- [Two Tall Totems Ltd. DBA TTT Studios](https://ttt.studio)
- [Typeface](https://typeface.ai)
- [UKG](https://www.ukg.com)
- [UiPath](https://www.uipath.com/newsroom/uipath-launches-first-enterprise-grade-platform-for-agentic-automation)
- [Upwork, Inc.](https://www.upwork.com/)
- [Ushur, Inc.](http://ushur.ai)
- [Valle AI](http://www.valleai.com.br)
- [Valtech](https://www.valtech.com/)
- [Vervelo](https://www.vervelo.com/)
- [VoltAgent](https://voltagent.dev/)
- [Weights & Biases](https://wandb.ai/wandb_fc/product-announcements-fc/reports/Powering-Agent-Collaboration-Weights-Biases-Partners-with-Google-Cloud-on-Agent2Agent-Interoperability-Protocol---VmlldzoxMjE3NDg3OA)
- [Wipro](https://www.wipro.com)
- [Workday](https://www.workday.com)
- [WritBase](https://github.com/Writbase/writbase)
- [Writer](https://writer.com)
- [Zenity](https://zenity.io)
- [Zeotap](https://www.zeotap.com)
- [Zocket Technologies , Inc.](https://zocket.ai)
- [Zoom](https://www.zoom.us)
- [zyprova](http://www.zyprova.com)


================================================
FILE: docs/roadmap.md
================================================
# A2A protocol roadmap

**Last updated:** March 10, 2026

## Near-term initiatives

- Release `1.0` version of the protocol which represents significant maturation of the protocol with enhanced clarity, stronger specifications, and important structural improvements.
- [What's New in A2A Protocol v1.0](https://a2a-protocol.org/latest/whats-new-v1/) has further updates. 
- Continue to support additional [A2A extensions](topics/extensions.md) with SDK support. 
- Prioritize community-led development with standardized processes for contributing to the specification, SDKs and tooling.

To review recent protocol changes see [Release Notes](https://github.com/a2aproject/A2A/releases).

## Longer term (3-6 month period) roadmap

### Governance

The TSC looks to streamline opportunities for contribution through [A2A extensions](topics/extensions.md), [Samples](https://github.com/a2aproject/a2a-samples) and participation.


### Validation

As the A2A ecosystem matures, it becomes critical for the A2A community to have tools to validate their agents. The community has launched two efforts to help with validation. Learn more about [A2A Inspector](https://github.com/a2aproject/a2a-inspector) and the [A2A Protocol Technology Compatibility Kit](https://github.com/a2aproject/a2a-tck) (TCK).

### SDKs

A2A Project currently hosts SDKs in five languages (Python, Go, JS, Java, .NET).

### Community best practices

As companies and individuals deploy A2A systems at an increasing pace, we are looking to accelerate the learning of the community by collecting and sharing the best practices and success stories that A2A enabled.


================================================
FILE: docs/robots.txt
================================================
# Allow all crawlers to access the entire site.
User-agent: *
Allow: /

# Generative AI and LLM crawlers
User-agent: GPTBot
Allow: /

User-agent: ChatGPT-User
Allow: /

User-agent: ClaudeBot
Allow: /

User-agent: Claude-Web
Allow: /

User-agent: PerplexityBot
Allow: /

User-agent: FacebookBot
Allow: /

User-agent: Applebot
Allow: /

User-agent: PerplexityBot
Allow: /

User-agent: Google-Extended
Allow: /

User-agent: GoogleOther
Allow: /

User-agent: DuckAssistBot
Allow: /

Sitemap: https://a2a-protocol.org/latest/sitemap.xml


================================================
FILE: docs/sdk/index.md
================================================
# A2A SDK

A2A currently hosts SDKs in five languages (Python, Go, JS, Java, .NET).

The following table lists the supported languages and their stability.

| Language   | Support  |
| :--------- | :------- |
| Python     | [Stable](https://github.com/a2aproject/a2a-python) |
| Go         | [Stable](https://github.com/a2aproject/a2a-go)     |
| Java       | [Stable](https://github.com/a2aproject/a2a-java)   |
| JavaScript | [Stable](https://github.com/a2aproject/a2a-js)     |
| C#/.NET    | [Stable](https://github.com/a2aproject/a2a-dotnet) |

The A2A project provides numerous samples across supported languages in the [a2a-samples repository](https://github.com/a2aproject/a2a-samples).


================================================
FILE: docs/sdk/python.md
================================================
---
redirect: python/api/index.html
---

# Python SDK

Redirecting to [API reference](python/api/index.html)...


================================================
FILE: docs/specification.md
================================================
# Agent2Agent (A2A) Protocol Specification

??? note "**Latest Released Version** [`1.0.0`](https://a2a-protocol.org/v1.0.0/specification)"

    **Previous Versions**

    - [`0.3.0`](https://a2a-protocol.org/v0.3.0/specification)
    - [`0.2.6`](https://a2a-protocol.org/v0.2.6/specification)
    - [`0.1.0`](https://a2a-protocol.org/v0.1.0/specification)

See [Release Notes](https://github.com/a2aproject/A2A/releases) for changes made between versions.

## 1. Introduction

The Agent2Agent (A2A) Protocol is an open standard designed to facilitate communication and interoperability between independent, potentially opaque AI agent systems. In an ecosystem where agents might be built using different frameworks, languages, or by different vendors, A2A provides a common language and interaction model.

This document provides the detailed technical specification for the A2A protocol. Its primary goal is to enable agents to:

- Discover each other's capabilities.
- Negotiate interaction modalities (text, files, structured data).
- Manage collaborative tasks.
- Securely exchange information to achieve user goals **without needing access to each other's internal state, memory, or tools.**

### 1.1. Key Goals of A2A

- **Interoperability:** Bridge the communication gap between disparate agentic systems.
- **Collaboration:** Enable agents to delegate tasks, exchange context, and work together on complex user requests.
- **Discovery:** Allow agents to dynamically find and understand the capabilities of other agents.
- **Flexibility:** Support various interaction modes including synchronous request/response, streaming for real-time updates, and asynchronous push notifications for long-running tasks.
- **Security:** Facilitate secure communication patterns suitable for enterprise environments, relying on standard web security practices.
- **Asynchronicity:** Natively support long-running tasks and interactions that may involve human-in-the-loop scenarios.

### 1.2. Guiding Principles

- **Simple:** Reuse existing, well-understood standards (HTTP, JSON-RPC 2.0, Server-Sent Events).
- **Enterprise Ready:** Address authentication, authorization, security, privacy, tracing, and monitoring by aligning with established enterprise practices.
- **Async First:** Designed for (potentially very) long-running tasks and human-in-the-loop interactions.
- **Modality Agnostic:** Support exchange of diverse content types including text, audio/video (via file references), structured data/forms, and potentially embedded UI components (e.g., iframes referenced in parts).
- **Opaque Execution:** Agents collaborate based on declared capabilities and exchanged information, without needing to share their internal thoughts, plans, or tool implementations.

For a broader understanding of A2A's purpose and benefits, see [What is A2A?](./topics/what-is-a2a.md).

### 1.3. Specification Structure

This specification is organized into three distinct layers that work together to provide a complete protocol definition:

```mermaid
graph TB
    subgraph L1 ["A2A Data Model"]
        direction LR
        A[Task] ~~~ B[Message] ~~~ C[AgentCard] ~~~ D[Part] ~~~ E[Artifact] ~~~ F[Extension]
    end

    subgraph L2 ["A2A Operations"]
        direction LR
        G[Send Message] ~~~ H[Stream Message] ~~~ I[Get Task] ~~~ J[List Tasks] ~~~ K[Cancel Task] ~~~ L[Get Agent Card]
    end

    subgraph L3 ["Protocol Bindings"]
        direction LR
        M[JSON-RPC Methods] ~~~ N[gRPC RPCs] ~~~ O[HTTP/REST Endpoints] ~~~ P[Custom Bindings]
    end

    %% Dependencies between layers
    L1 --> L2
    L2 --> L3


    style A fill:#e1f5fe
    style B fill:#e1f5fe
    style C fill:#e1f5fe
    style D fill:#e1f5fe
    style E fill:#e1f5fe
    style F fill:#e1f5fe

    style G fill:#f3e5f5
    style H fill:#f3e5f5
    style I fill:#f3e5f5
    style J fill:#f3e5f5
    style K fill:#f3e5f5
    style L fill:#f3e5f5

    style M fill:#e8f5e8
    style N fill:#e8f5e8
    style O fill:#e8f5e8

    style L1 fill:#f0f8ff,stroke:#333,stroke-width:2px
    style L2 fill:#faf0ff,stroke:#333,stroke-width:2px
    style L3 fill:#f0fff0,stroke:#333,stroke-width:2px
```

**Layer 1: Canonical Data Model** defines the core data structures and message formats that all A2A implementations must understand. These are protocol agnostic definitions expressed as Protocol Buffer messages.

**Layer 2: Abstract Operations** describes the fundamental capabilities and behaviors that A2A agents must support, independent of how they are exposed over specific protocols.

**Layer 3: Protocol Bindings** provides concrete mappings of the abstract operations and data structures to specific protocol bindings (JSON-RPC, gRPC, HTTP/REST), including method names, endpoint patterns, and protocol-specific behaviors.

This layered approach ensures that:

- Core semantics remain consistent across all protocol bindings
- New protocol bindings can be added without changing the fundamental data model
- Developers can reason about A2A operations independently of binding concerns
- Interoperability is maintained through shared understanding of the canonical data model

### 1.4 Normative Content

In addition to the protocol requirements defined in this document, the file `spec/a2a.proto` is the single authoritative normative definition of all protocol data objects and request/response messages. A generated JSON artifact (`spec/a2a.json`, produced at build time and not committed) MAY be published for convenience to tooling and the website, but it is a non-normative build artifact. SDK language bindings, schemas, and any other derived forms **MUST** be regenerated from the proto (directly or via code generation) rather than edited manually.

**Change Control and Deprecation Lifecycle:**

- Introduction: When a proto message or field is renamed, the new name is added while existing published names remain available, but marked deprecated, until the next major release.
- Documentation: Migration guidance MUST be provided via an ancillary document when introducing major breaking changes.
- Anchors: Legacy documentation anchors MUST be preserved (as hidden HTML anchors) to avoid breaking inbound links.
- SDK/Schema Aliases: SDKs and JSON Schemas SHOULD provide deprecated alias types/definitions to maintain backward compatibility.
- Removal: A deprecated name SHOULD NOT be removed earlier than the next major version after introduction of its replacement.

**Automated Generation:**

The documentation build generates `specification/json/a2a.json` on-the-fly (the file is not tracked in source control). Future improvements may publish an OpenAPI v3 + JSON Schema bundle for enhanced tooling.

**Rationale:**

Centering the proto file as the normative source ensures protocol neutrality, reduces specification drift, and provides a deterministic evolution path for the ecosystem.

## 2. Terminology

### 2.1. Requirements Language

The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119).

### 2.2. Core Concepts

A2A revolves around several key concepts. For detailed explanations, please refer to the [Key Concepts guide](./topics/key-concepts.md).

- **A2A Client:** An application or agent that initiates requests to an A2A Server on behalf of a user or another system.
- **A2A Server (Remote Agent):** An agent or agentic system that exposes an A2A-compliant endpoint, processing tasks and providing responses.
- **Agent Card:** A JSON metadata document published by an A2A Server, describing its identity, capabilities, skills, service endpoint, and authentication requirements.
- **Message:** A communication turn between a client and a remote agent, having a `role` ("user" or "agent") and containing one or more `Parts`.
- **Task:** The fundamental unit of work managed by A2A, identified by a unique ID. Tasks are stateful and progress through a defined lifecycle.
- **Part:** The smallest unit of content within a Message or Artifact. Parts can contain text, file references, or structured data.
- **Artifact:** An output (e.g., a document, image, structured data) generated by the agent as a result of a task, composed of `Parts`.
- **Streaming:** Real-time, incremental updates for tasks (status changes, artifact chunks) delivered via protocol-specific streaming mechanisms.
- **Push Notifications:** Asynchronous task updates delivered via server-initiated HTTP POST requests to a client-provided webhook URL, for long-running or disconnected scenarios.
- **Context:** An optional identifier to logically group related tasks and messages.
- **Extension:** A mechanism for agents to provide additional functionality or data beyond the core A2A specification.

## 3. A2A Protocol Operations

This section describes the core operations of the A2A protocol in a binding-independent manner. These operations define the fundamental capabilities that all A2A implementations must support, regardless of the underlying binding mechanism.

### 3.1. Core Operations

The following operations define the fundamental capabilities that all A2A implementations must support, independent of the specific protocol binding used. For a quick reference mapping of these operations to protocol-specific method names and endpoints, see [Section 5.3 (Method Mapping Reference)](#53-method-mapping-reference). For detailed protocol-specific implementation details, see:

- [Section 9: JSON-RPC Protocol Binding](#9-json-rpc-protocol-binding)
- [Section 10: gRPC Protocol Binding](#10-grpc-protocol-binding)
- [Section 11: HTTP+JSON/REST Protocol Binding](#11-httpjsonrest-protocol-binding)

#### 3.1.1. Send Message

The primary operation for initiating agent interactions. Clients send a message to an agent and receive either a task that tracks the processing or a direct response message.

**Inputs:**

- [`SendMessageRequest`](#321-sendmessagerequest): Request object containing the message, configuration, and metadata

**Outputs:**

- [`Task`](#411-task): A task object representing the processing of the message, OR
- [`Message`](#414-message): A direct response message (for simple interactions that don't require task tracking)

**Errors:**

- [`ContentTypeNotSupportedError`](#332-error-handling): A Media Type provided in the request's message parts is not supported by the agent.
- [`UnsupportedOperationError`](#332-error-handling): Messages sent to Tasks that are in a terminal state (e.g., completed, canceled, rejected) cannot accept further messages.
- [`TaskNotFoundError`](#332-error-handling): The task ID does not exist or is not accessible.

**Behavior:**

The agent MAY create a new `Task` to process the provided message asynchronously or MAY return a direct `Message` response for simple interactions. The operation MUST return immediately with either task information or response message. Task processing MAY continue asynchronously after the response when a [`Task`](#411-task) is returned.

#### 3.1.2. Send Streaming Message

Similar to Send Message but with real-time streaming of updates during processing.

**Inputs:**

- [`SendMessageRequest`](#321-sendmessagerequest): Request object containing the message, configuration, and metadata

**Outputs:**

- [`Stream Response`](#323-stream-response) object containing:
    - Initial response: [`Task`](#411-task) object OR [`Message`](#414-message) object
    - Subsequent events following a `Task` MAY include stream of [`TaskStatusUpdateEvent`](#421-taskstatusupdateevent) and [`TaskArtifactUpdateEvent`](#422-taskartifactupdateevent) objects
- Final completion indicator

**Errors:**

- [`UnsupportedOperationError`](#332-error-handling): Streaming is not supported by the agent (see [Capability Validation](#334-capability-validation)).
- [`UnsupportedOperationError`](#332-error-handling): Messages sent to Tasks that are in a terminal state (e.g., completed, canceled, rejected) cannot accept further messages.
- [`ContentTypeNotSupportedError`](#332-error-handling): A Media Type provided in the request's message parts is not supported by the agent.
- [`TaskNotFoundError`](#332-error-handling): The task ID does not exist or is not accessible.

**Behavior:**

The operation MUST establish a streaming connection for real-time updates. The stream MUST follow one of these patterns:

1. **Message-only stream:** If the agent returns a [`Message`](#414-message), the stream MUST contain exactly one `Message` object and then close immediately. No task tracking or updates are provided.

2. **Task lifecycle stream:** If the agent returns a [`Task`](#411-task), the stream MUST begin with the Task object, followed by zero or more [`TaskStatusUpdateEvent`](#421-taskstatusupdateevent) or [`TaskArtifactUpdateEvent`](#422-taskartifactupdateevent) objects. The stream MUST close when the task reaches a terminal state (e.g. completed, failed, canceled, rejected).

The agent MAY return a `Task` for complex processing with status/artifact updates or MAY return a `Message` for direct streaming responses without task overhead. The implementation MUST provide immediate feedback on progress and intermediate results.

#### 3.1.3. Get Task

Retrieves the current state (including status, artifacts, and optionally history) of a previously initiated task. This is typically used for polling the status of a task initiated with message/send, or for fetching the final state of a task after being notified via a push notification or after a stream has ended.

**Inputs:**

{{ proto_to_table("GetTaskRequest") }}

See [History Length Semantics](#324-history-length-semantics) for details about `historyLength`.

**Outputs:**

- [`Task`](#411-task): Current state and artifacts of the requested task

**Errors:**

- [`TaskNotFoundError`](#332-error-handling): The task ID does not exist or is not accessible.

#### 3.1.4. List Tasks

Retrieves a list of tasks with optional filtering and pagination capabilities. This method allows clients to discover and manage multiple tasks across different contexts or with specific status criteria.

**Inputs:**

{{ proto_to_table("ListTasksRequest") }}

When `includeArtifacts` is false (the default), the artifacts field MUST be omitted entirely from each Task object in the response. The field should not be present as an empty array or null value. When `includeArtifacts` is true, the artifacts field should be included with its actual content (which may be an empty array if the task has no artifacts).

**Outputs:**

{{ proto_to_table("ListTasksResponse") }}

Note on `nextPageToken`: The `nextPageToken` field MUST always be present in the response. When there are no more results to retrieve (i.e., this is the final page), the field MUST be set to an empty string (""). Clients should check for an empty string to determine if more pages are available.

**Errors:**

None specific to this operation beyond standard protocol errors.

**Behavior:**

The operation MUST return only tasks visible to the authenticated client and MUST use cursor-based pagination for performance and consistency. Tasks MUST be sorted by last update time in descending order. Implementations MUST implement appropriate authorization scoping to ensure clients can only access authorized tasks. See [Section 13.1 Data Access and Authorization Scoping](#131-data-access-and-authorization-scoping) for detailed security requirements.

***Pagination Strategy:***

This method uses cursor-based pagination (via `pageToken`/`nextPageToken`) rather than offset-based pagination for better performance and consistency, especially with large datasets. Cursor-based pagination avoids the "deep pagination problem" where skipping large numbers of records becomes inefficient for databases. This approach is consistent with the gRPC specification, which also uses cursor-based pagination (page_token/next_page_token).

***Ordering:***

Implementations MUST return tasks sorted by their status timestamp time in descending order (most recently updated tasks first). This ensures consistent pagination and allows clients to efficiently monitor recent task activity.

#### 3.1.5. Cancel Task

Requests the cancellation of an ongoing task. The server will attempt to cancel the task, but success is not guaranteed (e.g., the task might have already completed or failed, or cancellation might not be supported at its current stage).

**Inputs:**

{{ proto_to_table("CancelTaskRequest") }}

**Outputs:**

- Updated [`Task`](#411-task) with cancellation status

**Errors:**

- [`TaskNotCancelableError`](#332-error-handling): The task is not in a cancelable state (e.g., already completed, failed, or canceled).
- [`TaskNotFoundError`](#332-error-handling): The task ID does not exist or is not accessible.

**Behavior:**

The operation attempts to cancel the specified task and returns its updated state.

#### 3.1.6. Subscribe to Task

<span id="79-taskssubscribe"></span>

Establishes a streaming connection to receive updates for an existing task.

**Inputs:**

{{ proto_to_table("SubscribeToTaskRequest") }}

**Outputs:**

- [`Stream Response`](#323-stream-response) object containing:
    - Initial response: [`Task`](#411-task) object with current state
    - Stream of [`TaskStatusUpdateEvent`](#421-taskstatusupdateevent) and [`TaskArtifactUpdateEvent`](#422-taskartifactupdateevent) objects

**Errors:**

- [`UnsupportedOperationError`](#332-error-handling): Streaming is not supported by the agent (see [Capability Validation](#334-capability-validation)).
- [`TaskNotFoundError`](#332-error-handling): The task ID does not exist or is not accessible.
- [`UnsupportedOperationError`](#332-error-handling): The operation is attempted on a task that is in a terminal state (`completed`, `failed`, `canceled`, or `rejected`).

**Behavior:**

The operation enables real-time monitoring of task progress and can be used with any task that is not in a terminal state. The stream MUST terminate when the task reaches a terminal state (`completed`, `failed`, `canceled`, or `rejected`).

The operation MUST return a `Task` object as the first event in the stream, representing the current state of the task at the time of subscription. This prevents a potential loss of information between a call to `GetTask` and calling `SubscribeToTask`.

#### 3.1.7. Create Push Notification Config

<span id="75-taskspushnotificationconfigset"></span>
<span id="317-create-push-notification-config"></span>

Creates a push notification configuration for a task to receive asynchronous updates via webhook.

**Inputs:**

{{ proto_to_table("CreateTaskPushNotificationConfigRequest") }}

**Outputs:**

- [`PushNotificationConfig`](#431-pushnotificationconfig): Created configuration with assigned ID

**Errors:**

- [`PushNotificationNotSupportedError`](#332-error-handling): Push notifications are not supported by the agent (see [Capability Validation](#334-capability-validation)).
- [`TaskNotFoundError`](#332-error-handling): The task ID does not exist or is not accessible.

**Behavior:**

The operation MUST establish a webhook endpoint for task update notifications. When task updates occur, the agent will send HTTP POST requests to the configured webhook URL with [`StreamResponse`](#323-stream-response) payloads (see [Push Notification Payload](#433-push-notification-payload) for details). This operation is only available if the agent supports push notifications capability. The configuration MUST persist until task completion or explicit deletion.

 <span id="tasks-push-notification-config-operations"></span><span id="grpc-push-notification-operations"></span><span id="push-notification-operations"></span>

#### 3.1.8. Get Push Notification Config

<span id="76-taskspushnotificationconfigget"></span>

Retrieves an existing push notification configuration for a task.

**Inputs:**

{{ proto_to_table("GetTaskPushNotificationConfigRequest") }}

**Outputs:**

- [`PushNotificationConfig`](#431-pushnotificationconfig): The requested configuration

**Errors:**

- [`PushNotificationNotSupportedError`](#332-error-handling): Push notifications are not supported by the agent (see [Capability Validation](#334-capability-validation)).
- [`TaskNotFoundError`](#332-error-handling): The push notification configuration does not exist.

**Behavior:**

The operation MUST return configuration details including webhook URL and notification settings. The operation MUST fail if the configuration does not exist or the client lacks access.

#### 3.1.9. List Push Notification Configs

Retrieves all push notification configurations for a task.

**Inputs:**

{{ proto_to_table("ListTaskPushNotificationConfigsRequest") }}

**Outputs:**

{{ proto_to_table("ListTaskPushNotificationConfigsResponse") }}

**Errors:**

- [`PushNotificationNotSupportedError`](#332-error-handling): Push notifications are not supported by the agent (see [Capability Validation](#334-capability-validation)).
- [`TaskNotFoundError`](#332-error-handling): The task ID does not exist or is not accessible.

**Behavior:**

The operation MUST return all active push notification configurations for the specified task and MAY support pagination for tasks with many configurations.

#### 3.1.10. Delete Push Notification Config

Removes a push notification configuration for a task.

**Inputs:**

{{ proto_to_table("DeleteTaskPushNotificationConfigRequest") }}

**Outputs:**

- Confirmation of deletion (implementation-specific)

**Errors:**

- [`PushNotificationNotSupportedError`](#332-error-handling): Push notifications are not supported by the agent (see [Capability Validation](#334-capability-validation)).
- [`TaskNotFoundError`](#332-error-handling): The task ID does not exist.

**Behavior:**

The operation MUST permanently remove the specified push notification configuration. No further notifications will be sent to the configured webhook after deletion. This operation MUST be idempotent - multiple deletions of the same config have the same effect.

#### 3.1.11. Get Extended Agent Card

Retrieves a potentially more detailed version of the Agent Card after the client has authenticated. This endpoint is available only if `AgentCard.capabilities.extendedAgentCard` is `true`.

**Inputs:**

{{ proto_to_table("GetExtendedAgentCardRequest") }}

**Outputs:**

- [`AgentCard`](#441-agentcard): A complete Agent Card object, which may contain additional details or skills not present in the public card

**Errors:**

- [`UnsupportedOperationError`](#332-error-handling): The agent does not support authenticated extended cards (see [Capability Validation](#334-capability-validation)).
- [`ExtendedAgentCardNotConfiguredError`](#332-error-handling): The agent declares support but does not have an extended agent card configured.

**Behavior:**

- **Authentication**: The client MUST authenticate the request using one of the schemes declared in the public `AgentCard.securitySchemes` and `AgentCard.security` fields.
- **Extended Information**: The operation MAY return different details based on client authentication level, including additional skills, capabilities, or configuration not available in the public Agent Card.
- **Card Replacement**: Clients retrieving this extended card SHOULD replace their cached public Agent Card with the content received from this endpoint for the duration of their authenticated session or until the card's version changes.
- **Availability**: This operation is only available if the public Agent Card declares `capabilities.extendedAgentCard: true`.

For detailed security guidance on extended agent cards, see [Section 13.3 Extended Agent Card Access Control](#133-extended-agent-card-access-control).

### 3.2. Operation Parameter Objects

This section defines common parameter objects used across multiple operations.

#### 3.2.1. SendMessageRequest

{{ proto_to_table("SendMessageRequest") }}

#### 3.2.2. SendMessageConfiguration

{{ proto_to_table("SendMessageConfiguration") }}

**Execution Mode:**

The `return_immediately` field in [`SendMessageConfiguration`](#322-sendmessageconfiguration) controls whether the operation returns immediately or waits for task completion. Operations are blocking by default:

- **Blocking (`return_immediately: false` or unset)**: The operation MUST wait until the task reaches a terminal state (`COMPLETED`, `FAILED`, `CANCELED`, `REJECTED`) or an interrupted state (`INPUT_REQUIRED`, `AUTH_REQUIRED`) before returning. The response MUST include the latest task state with all artifacts and status information. This is the default behavior.

- **Non-Blocking (`return_immediately: true`)**: The operation MUST return immediately after creating the task, even if processing is still in progress. The returned task will have an in-progress state (e.g., `working`, `input_required`). It is the caller's responsibility to poll for updates using [Get Task](#313-get-task), subscribe via [Subscribe to Task](#316-subscribe-to-task), or receive updates via push notifications.

The `return_immediately` field has no effect:

- when the operation returns a direct [`Message`](#414-message) response instead of a task.
- for streaming operations, which always return updates in real-time.
- on configured push notification configurations, which operates independently of execution mode.

#### 3.2.3. Stream Response

<span id="323-stream-response"></span>
<span id="72-messagestream"></span>

{{ proto_to_table("StreamResponse") }}

This wrapper allows streaming endpoints to return different types of updates through a single response stream while maintaining type safety.

#### 3.2.4. History Length Semantics

The `historyLength` parameter appears in multiple operations and controls how much task history is returned in responses. This parameter follows consistent semantics across all operations:

- **Unset/undefined**: No limit imposed; server returns its default amount of history (implementation-defined, may be all history)
- **0**: No history should be returned; the `history` field SHOULD be omitted
- **> 0**: Return at most this many recent messages from the task's history

#### 3.2.5. Metadata

A flexible key-value map for passing additional context or parameters with operations. Metadata keys and are strings and values can be any valid value that can be represented in JSON. [`Extensions`](#46-extensions) can be used to strongly type metadata values for specific use cases.

#### 3.2.6 Service Parameters

A key-value map for passing horizontally applicable context or parameters with case-insensitive string keys and case-sensitive string values. The transmission mechanism for these service parameter key-value pairs is defined by the specific protocol binding (e.g., HTTP headers for HTTP-based bindings, gRPC metadata for gRPC bindings). Custom protocol bindings **MUST** specify how service parameters are transmitted in their binding specification.

**Standard A2A Service Parameters:**

| Name             | Description                                                                                                                                             | Example Value                                                                                 |
| :--------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | :-------------------------------------------------------------------------------------------- |
| `A2A-Extensions` | Comma-separated list of extension URIs that the client wants to use for the request                                                                     | `https://example.com/extensions/geolocation/v1,https://standards.org/extensions/citations/v1` |
| `A2A-Version`    | The A2A protocol version that the client is using. If the version is not supported, the agent returns [`VersionNotSupportedError`](#332-error-handling) | `0.3`                                                                                         |

As service parameter names MAY need to co-exist with other parameters defined by the underlying transport protocol or infrastructure, all service parameters defined by this specification will be prefixed with `a2a-`.

### 3.3. Operation Semantics

#### 3.3.1. Idempotency

- **Get operations** (Get Task, List Tasks, Get Extended Agent Card) are naturally idempotent
- **Send Message** operations MAY be idempotent. Agents may utilize the messageId to detect duplicate messages.
- **Cancel Task** operations are idempotent - multiple cancellation requests have the same effect. A duplicate cancellation request MAY return `TaskNotFoundError` if the task has already been canceled and purged.

#### 3.3.2. Error Handling

All operations may return errors in the following categories. Servers **MUST** return appropriate errors and **SHOULD** provide actionable information to help clients resolve issues.

**Error Categories and Server Requirements:**

- **Authentication Errors**: Invalid or missing credentials
    - Servers **MUST** reject requests with invalid or missing authentication credentials
    - Servers **SHOULD** include authentication challenge information in the error response
    - Servers **SHOULD** specify which authentication scheme is required
    - Example error codes: HTTP `401 Unauthorized`, gRPC `UNAUTHENTICATED`, JSON-RPC custom error
    - Example scenarios: Missing bearer token, expired API key, invalid OAuth token

- **Authorization Errors**: Insufficient permissions for requested operation
    - Servers **MUST** return an authorization error when the authenticated client lacks required permissions
    - Servers **SHOULD** indicate what permission or scope is missing (without leaking sensitive information about resources the client cannot access)
    - Servers **MUST NOT** reveal the existence of resources the client is not authorized to access
    - Example error codes: HTTP `403 Forbidden`, gRPC `PERMISSION_DENIED`, JSON-RPC custom error
    - Example scenarios: Attempting to access a task created by another user, insufficient OAuth scopes

- **Validation Errors**: Invalid input parameters or message format
    - Servers **MUST** validate all input parameters before processing
    - Servers **SHOULD** specify which parameter(s) failed validation and why
    - Servers **SHOULD** provide guidance on valid parameter values or formats
    - Example error codes: HTTP `400 Bad Request`, gRPC `INVALID_ARGUMENT`, JSON-RPC `-32602 Invalid params`
    - Example scenarios: Invalid task ID format, missing required message parts, unsupported content type

- **Resource Error
Download .txt
gitextract_6mxkg8fn/

├── .devcontainer/
│   ├── README.md
│   ├── devcontainer.json
│   └── setup.sh
├── .editorconfig
├── .gemini/
│   └── config.yaml
├── .git-blame-ignore-revs
├── .gitattributes
├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-report.yml
│   │   └── feature-request.yml
│   ├── PULL_REQUEST_TEMPLATE/
│   │   ├── PULL_REQUEST_TEMPLATE.md
│   │   └── become_a_repo_maintainer.md
│   ├── actions/
│   │   └── spelling/
│   │       ├── advice.md
│   │       ├── allow.txt
│   │       ├── excludes.txt
│   │       └── line_forbidden.patterns
│   ├── conventional-commit-lint.yaml
│   ├── dependabot.yml
│   ├── linters/
│   │   ├── .eslintrc.js
│   │   ├── .jscpd.json
│   │   ├── .markdownlint.json
│   │   ├── .protolint.yaml
│   │   └── .stylelintrc.json
│   ├── super-linter.env
│   └── workflows/
│       ├── check-linked-issues.yml
│       ├── conventional-commits.yml
│       ├── dispatch-a2a-update.yml
│       ├── docs.yml
│       ├── issue-metrics.yml
│       ├── links.yaml
│       ├── linter.yaml
│       ├── release-please.yml
│       ├── sort-spelling-allowlist.yml
│       ├── spelling.yaml
│       └── stale.yaml
├── .gitignore
├── .gitvote.yml
├── .mkdocs/
│   ├── macros.py
│   └── overrides/
│       └── main.html
├── .prettierrc
├── .ruff.toml
├── .vscode/
│   └── settings.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── GOVERNANCE.md
├── LICENSE
├── MAINTAINERS.md
├── README.md
├── SECURITY.md
├── adrs/
│   ├── adr-001-protojson-serialization.md
│   └── adr-template.md
├── docs/
│   ├── 404.html
│   ├── README.md
│   ├── announcing-1.0.md
│   ├── community.md
│   ├── definitions.md
│   ├── index.md
│   ├── llms.txt
│   ├── partners.md
│   ├── roadmap.md
│   ├── robots.txt
│   ├── sdk/
│   │   ├── index.md
│   │   └── python.md
│   ├── specification.md
│   ├── stylesheets/
│   │   └── custom.css
│   ├── topics/
│   │   ├── a2a-and-mcp.md
│   │   ├── agent-discovery.md
│   │   ├── enterprise-ready.md
│   │   ├── extensions.md
│   │   ├── key-concepts.md
│   │   ├── life-of-a-task.md
│   │   ├── streaming-and-async.md
│   │   └── what-is-a2a.md
│   ├── tutorials/
│   │   ├── index.md
│   │   └── python/
│   │       ├── 1-introduction.md
│   │       ├── 2-setup.md
│   │       ├── 3-agent-skills-and-card.md
│   │       ├── 4-agent-executor.md
│   │       ├── 5-start-server.md
│   │       ├── 6-interact-with-server.md
│   │       ├── 7-streaming-and-multiturn.md
│   │       └── 8-next-steps.md
│   └── whats-new-v1.md
├── lychee.toml
├── mkdocs.yml
├── requirements-docs.txt
├── scripts/
│   ├── build_docs.sh
│   ├── build_llms_full.sh
│   ├── build_sdk_docs.sh
│   ├── deploy_root_files.sh
│   ├── format.sh
│   ├── lint.sh
│   ├── proto_to_json_schema.sh
│   └── sort_spelling.sh
└── specification/
    ├── .api-linter.yaml
    ├── a2a.proto
    ├── buf.gen.yaml
    ├── buf.yaml
    └── json/
        └── README.md
Download .txt
SYMBOL INDEX (7 symbols across 1 files)

FILE: .mkdocs/macros.py
  function define_env (line 48) | def define_env(env):
  function _extract_comments (line 195) | def _extract_comments(element: Any) -> str:
  function _attach_comments (line 227) | def _attach_comments(elements: list[Any]) -> None:
  function _format_type_for_docs (line 242) | def _format_type_for_docs(
  function _find_type (line 268) | def _find_type(elements: list[Any], name: str, target_cls: type) -> Any ...
  function _process_field (line 280) | def _process_field(field: Field, is_oneof: bool = False) -> list[str]:
  function _snake_to_camel_case (line 322) | def _snake_to_camel_case(snake_str: str) -> str:
Condensed preview — 100 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (545K chars).
[
  {
    "path": ".devcontainer/README.md",
    "chars": 2279,
    "preview": "# A2A Development Container\n\nThis devcontainer provides a fully configured development environment for the A2A project w"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "chars": 913,
    "preview": "{\n    \"name\": \"A2A Development\",\n    \"image\": \"mcr.microsoft.com/devcontainers/base:ubuntu\",\n    \"features\": {\n        \""
  },
  {
    "path": ".devcontainer/setup.sh",
    "chars": 2215,
    "preview": "#!/bin/bash\nset -euo pipefail\n\necho \"==> Setting up A2A development environment...\"\n\n# Install system dependencies\necho "
  },
  {
    "path": ".editorconfig",
    "chars": 174,
    "preview": "# editorconfig.org\nroot = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newlin"
  },
  {
    "path": ".gemini/config.yaml",
    "chars": 81,
    "preview": "code_review:\n  comment_severity_threshold: LOW\nignore_patterns: ['CHANGELOG.md']\n"
  },
  {
    "path": ".git-blame-ignore-revs",
    "chars": 1240,
    "preview": "# Template taken from https://github.com/v8/v8/blob/master/.git-blame-ignore-revs.\n#\n# This file contains a list of git "
  },
  {
    "path": ".gitattributes",
    "chars": 243,
    "preview": "# Documentation overrides\n/docs/** linguist-documentation=true\n/.mkdocs/** linguist-documentation=true\n# Removed committ"
  },
  {
    "path": ".github/CODEOWNERS",
    "chars": 764,
    "preview": "# Code owners file.\n# This file controls who is tagged for review for any given pull request.\n#\n# For syntax help see:\n#"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.yml",
    "chars": 1153,
    "preview": "name: 🐞 Bug Report\ndescription: File a bug report\ntitle: \"[Bug]: \"\ntype: \"Bug\"\nbody:\n  - type: markdown\n    attributes:\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request.yml",
    "chars": 1517,
    "preview": "name: 💡 Feature Request\ndescription: Suggest an idea for this repository\ntitle: \"[Feat]: \"\ntype: \"Feature\"\nbody:\n  - typ"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md",
    "chars": 526,
    "preview": "# Description\n\nThank you for opening a Pull Request!\nBefore submitting your PR, there are a few things you can do to mak"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE/become_a_repo_maintainer.md",
    "chars": 907,
    "preview": "---\nname: Become a repo maintainer\nabout: Request maintainer status for the A2A repo\ntitle: Maintainer Request\nassignees"
  },
  {
    "path": ".github/actions/spelling/advice.md",
    "chars": 1390,
    "preview": "<!-- See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice --> <!-- markdownlint-di"
  },
  {
    "path": ".github/actions/spelling/allow.txt",
    "chars": 2495,
    "preview": "AAAANSUh\nAAAAUA\nAAAGHMHc\nACMRTUXB\nACard\nAClient\nACo\nADK\nADR\nAError\nAExecutor\nAGP\nAIP\nARequest\nASED\nASGI\nAServer\nAService"
  },
  {
    "path": ".github/actions/spelling/excludes.txt",
    "chars": 1194,
    "preview": "# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes\n(?:^|/)(?i)COPYRIGHT\n(?:^|/"
  },
  {
    "path": ".github/actions/spelling/line_forbidden.patterns",
    "chars": 6696,
    "preview": "# Should be `HH:MM:SS`\n\\bHH:SS:MM\\b\n\n# Should probably be `YYYYMMDD`\n\\b[Yy]{4}[Dd]{2}[Mm]{2}(?!.*[Yy]{4}[Dd]{2}[Mm]{2})."
  },
  {
    "path": ".github/conventional-commit-lint.yaml",
    "chars": 42,
    "preview": "enabled: true\nalways_check_pr_title: true\n"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 508,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: 'npm'\n    directory: '/types'\n    schedule:\n      interval: 'monthly'\n    gro"
  },
  {
    "path": ".github/linters/.eslintrc.js",
    "chars": 595,
    "preview": "/** @type {import('eslint').Linter.Config} */\nmodule.exports = {\n    root: true,\n    parser: '@typescript-eslint/parser'"
  },
  {
    "path": ".github/linters/.jscpd.json",
    "chars": 205,
    "preview": "{\n  \"ignore\": [\n      \"**/.github/**\",\n      \"**/demo/**\",\n      \"**/images/**\",\n      \"**/samples/**\",\n      \"**/tests/"
  },
  {
    "path": ".github/linters/.markdownlint.json",
    "chars": 146,
    "preview": "{\n    \"default\": true,\n    \"MD013\": false,\n    \"MD007\": {\n        \"indent\": 4\n    },\n    \"MD033\": false,\n    \"MD046\": fa"
  },
  {
    "path": ".github/linters/.protolint.yaml",
    "chars": 51,
    "preview": "lint:\n  rules:\n    remove:\n      - MAX_LINE_LENGTH\n"
  },
  {
    "path": ".github/linters/.stylelintrc.json",
    "chars": 308,
    "preview": "{\n    \"extends\": [\"stylelint-config-standard\"],\n    \"rules\": {\n        \"custom-property-pattern\": null\n    },\n    \"overr"
  },
  {
    "path": ".github/super-linter.env",
    "chars": 673,
    "preview": "SHELLCHECK_OPTS=-e SC1091 -e SC2086\nVALIDATE_ALL_CODEBASE=false\nFILTER_REGEX_EXCLUDE=^(\\\\.github/|\\\\.vscode/).*|CODE_OF_"
  },
  {
    "path": ".github/workflows/check-linked-issues.yml",
    "chars": 701,
    "preview": "name: Check for Linked Issues\n\non:\n  pull_request_target:\n    types: [opened, edited, reopened, synchronize]\n\njobs:\n  ch"
  },
  {
    "path": ".github/workflows/conventional-commits.yml",
    "chars": 494,
    "preview": "name: \"Conventional Commits\"\n\non:\n  pull_request:\n    types:\n      - opened\n      - edited\n      - synchronize\n\npermissi"
  },
  {
    "path": ".github/workflows/dispatch-a2a-update.yml",
    "chars": 677,
    "preview": "name: Dispatch A2A JSON Update\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"specification/**/*\"\n\njobs:\n  "
  },
  {
    "path": ".github/workflows/docs.yml",
    "chars": 4734,
    "preview": "name: Docs Build and Deploy\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \".github/workflows/docs.yml\"\n    "
  },
  {
    "path": ".github/workflows/issue-metrics.yml",
    "chars": 1217,
    "preview": "name: Monthly issue metrics\non:\n  workflow_dispatch:\n  schedule:\n    - cron: \"3 2 1 * *\"\n\npermissions:\n  contents: read\n"
  },
  {
    "path": ".github/workflows/links.yaml",
    "chars": 1496,
    "preview": "name: Lychee Link Checker\n\non:\n  repository_dispatch:\n  workflow_dispatch:\n  schedule:\n    - cron: \"00 18 * * *\"\n  pull_"
  },
  {
    "path": ".github/workflows/linter.yaml",
    "chars": 1865,
    "preview": "name: Lint Code Base\n\non:\n  pull_request:\n    branches: [main]\n\njobs:\n  lint:\n    name: Lint Code Base\n    runs-on: ubun"
  },
  {
    "path": ".github/workflows/release-please.yml",
    "chars": 367,
    "preview": "on:\n  push:\n    branches:\n      - main\n\npermissions:\n  contents: write\n  pull-requests: write\n\nname: release-please\n\njob"
  },
  {
    "path": ".github/workflows/sort-spelling-allowlist.yml",
    "chars": 1692,
    "preview": "name: Auto-sort and update spelling allowlist\n\non:\n  pull_request:\n    paths:\n      - \".github/actions/spelling/allow.tx"
  },
  {
    "path": ".github/workflows/spelling.yaml",
    "chars": 3300,
    "preview": "name: Check Spelling\n\non:\n  pull_request:\n    branches:\n      - \"**\"\n    types:\n      - \"opened\"\n      - \"reopened\"\n    "
  },
  {
    "path": ".github/workflows/stale.yaml",
    "chars": 2034,
    "preview": "# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.\n#\n# You c"
  },
  {
    "path": ".gitignore",
    "chars": 2965,
    "preview": "# Added: ignore local documentation virtualenv and generated proto-derived artifacts\nvenv-docs/\n.venv/\nvenv/\nENV/\n.doc-v"
  },
  {
    "path": ".gitvote.yml",
    "chars": 1197,
    "preview": "# GitVote configuration file\n#\n# GitVote will look for it in the following locations (in order of precedence):\n#\n#   - A"
  },
  {
    "path": ".mkdocs/macros.py",
    "chars": 10730,
    "preview": "\"\"\"Custom MkDocs macros for A2A documentation.\n\nThis module provides macros for rendering Protocol Buffer definitions\nas"
  },
  {
    "path": ".mkdocs/overrides/main.html",
    "chars": 239,
    "preview": "{% extends \"base.html\" %}\n\n{% block announce %}\n  Join the new DeepLearning.AI short course: <strong>A2A: The Agent2Agen"
  },
  {
    "path": ".prettierrc",
    "chars": 319,
    "preview": "{\n    \"tabWidth\": 2,\n    \"useTabs\": false,\n    \"trailingComma\": \"es5\",\n    \"bracketSameLine\": true,\n    \"overrides\": [\n "
  },
  {
    "path": ".ruff.toml",
    "chars": 4422,
    "preview": "#################################################################################\n#\n# Ruff linter and code formatter for"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 621,
    "preview": "{\n    \"editor.formatOnSave\": true,\n    \"[python]\": {\n        \"editor.defaultFormatter\": \"charliermarsh.ruff\",\n        \"e"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 18553,
    "preview": "# Changelog\n\n## [1.0.0](https://github.com/a2aproject/A2A/compare/v0.3.0...v1.0.0) (2026-03-12)\n\n\n### ⚠ BREAKING CHANGES"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 4346,
    "preview": "# Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1443,
    "preview": "# How to contribute\n\nWe'd love to accept your patches and contributions to this project.\n\n## Contribution process\n\n### C"
  },
  {
    "path": "GOVERNANCE.md",
    "chars": 7444,
    "preview": "# Agent2Agent (A2A) Governance\n\nThe Agent2Agent project is governed by the Technical Steering Committee. The Committee h"
  },
  {
    "path": "LICENSE",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "MAINTAINERS.md",
    "chars": 1058,
    "preview": "# Maintainers\n\nThis document lists the maintainers of various repositories within the project.\n\n## Repository Maintainer"
  },
  {
    "path": "README.md",
    "chars": 8306,
    "preview": "# Agent2Agent (A2A) Protocol\n\n[![PyPI - Version](https://img.shields.io/pypi/v/a2a-sdk)](https://pypi.org/project/a2a-sd"
  },
  {
    "path": "SECURITY.md",
    "chars": 247,
    "preview": "# Security Policy\n\nTo report a security issue, please use email <security@lists.a2aproject.org>.\n\nWe use a mailing list "
  },
  {
    "path": "adrs/adr-001-protojson-serialization.md",
    "chars": 4036,
    "preview": "# ADR-001: Leverage ProtoJSON Specification for JSON Serialization\n\n**Status:** Accepted\n\n**Date:** 2025-11-18\n\n**Decisi"
  },
  {
    "path": "adrs/adr-template.md",
    "chars": 1824,
    "preview": "# ADR-[number]: [Title]\n\n**Status:** [Proposed | Accepted | Deprecated | Superseded]\n\n**Date:** YYYY-MM-DD\n\n**Decision M"
  },
  {
    "path": "docs/404.html",
    "chars": 1907,
    "preview": "<!DOCTYPE html>\n<html>\n\n<head>\n    <meta charset=\"utf-8\">\n    <title>Redirecting...</title>\n    <script>\n        (functi"
  },
  {
    "path": "docs/README.md",
    "chars": 1642,
    "preview": "# A2A Docs\n\n<https://a2a-protocol.org>\n\n## Developing A2A docs\n\n1. Clone this repository and `cd` into the repository di"
  },
  {
    "path": "docs/announcing-1.0.md",
    "chars": 5283,
    "preview": "# A2A Protocol Ships v1.0: Production-Ready Standard for Agent-to-Agent Communication\n\nThe A2A Protocol community today "
  },
  {
    "path": "docs/community.md",
    "chars": 5341,
    "preview": "# A2A Community Hub\n\nWelcome to the official community hub for the **Agent2Agent (A2A) protocol**! A2A is an open, stand"
  },
  {
    "path": "docs/definitions.md",
    "chars": 817,
    "preview": "# A2A Definition/Schema\n\n=== \"Protobuf\"\n    <h3>Protobuf</h3>\n    The normative A2A protocol definition in Protocol Buff"
  },
  {
    "path": "docs/index.md",
    "chars": 6045,
    "preview": "---\nhide:\n  - toc\n---\n\n<!-- markdownlint-disable MD041 -->\n<div style=\"text-align: center;\">\n  <div class=\"centered-logo"
  },
  {
    "path": "docs/llms.txt",
    "chars": 4773,
    "preview": "# A2A (Agent2Agent) Protocol High-Level Summary\n\nThis project defines the **Agent2Agent (A2A) protocol**, an open standa"
  },
  {
    "path": "docs/partners.md",
    "chars": 7944,
    "preview": "# Partners\n\nBelow is a list of partners (and a link to their A2A announcement or blog post,\nif available) who are part o"
  },
  {
    "path": "docs/roadmap.md",
    "chars": 1632,
    "preview": "# A2A protocol roadmap\n\n**Last updated:** March 10, 2026\n\n## Near-term initiatives\n\n- Release `1.0` version of the proto"
  },
  {
    "path": "docs/robots.txt",
    "chars": 532,
    "preview": "# Allow all crawlers to access the entire site.\nUser-agent: *\nAllow: /\n\n# Generative AI and LLM crawlers\nUser-agent: GPT"
  },
  {
    "path": "docs/sdk/index.md",
    "chars": 695,
    "preview": "# A2A SDK\n\nA2A currently hosts SDKs in five languages (Python, Go, JS, Java, .NET).\n\nThe following table lists the suppo"
  },
  {
    "path": "docs/sdk/python.md",
    "chars": 112,
    "preview": "---\nredirect: python/api/index.html\n---\n\n# Python SDK\n\nRedirecting to [API reference](python/api/index.html)...\n"
  },
  {
    "path": "docs/specification.md",
    "chars": 152531,
    "preview": "# Agent2Agent (A2A) Protocol Specification\n\n??? note \"**Latest Released Version** [`1.0.0`](https://a2a-protocol.org/v1."
  },
  {
    "path": "docs/stylesheets/custom.css",
    "chars": 2037,
    "preview": "/**\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
  },
  {
    "path": "docs/topics/a2a-and-mcp.md",
    "chars": 6872,
    "preview": "# A2A and MCP: Detailed Comparison\n\nIn AI agent development, two key protocol types emerge to facilitate\ninteroperabilit"
  },
  {
    "path": "docs/topics/agent-discovery.md",
    "chars": 7398,
    "preview": "# Agent Discovery in A2A\n\nTo collaborate using the Agent2Agent (A2A) protocol, AI agents need to first find each other a"
  },
  {
    "path": "docs/topics/enterprise-ready.md",
    "chars": 7827,
    "preview": "# Enterprise Implementation of A2A\n\nThe Agent2Agent (A2A) protocol is designed with enterprise requirements at its\ncore."
  },
  {
    "path": "docs/topics/extensions.md",
    "chars": 19504,
    "preview": "# Extensions in A2A\n\nThe Agent2Agent (A2A) protocol provides a strong foundation for inter-agent\ncommunication. However,"
  },
  {
    "path": "docs/topics/key-concepts.md",
    "chars": 6724,
    "preview": "# Core Concepts and Components in A2A\n\nA2A uses a set of core concepts that define how agents interact.\nUnderstand these"
  },
  {
    "path": "docs/topics/life-of-a-task.md",
    "chars": 10635,
    "preview": "# Life of a Task\n\nIn the Agent2Agent (A2A) Protocol, interactions can range from simple, stateless\nexchanges to complex,"
  },
  {
    "path": "docs/topics/streaming-and-async.md",
    "chars": 10111,
    "preview": "# Streaming and Asynchronous Operations for Long-Running Tasks\n\nThe Agent2Agent (A2A) protocol is explicitly designed to"
  },
  {
    "path": "docs/topics/what-is-a2a.md",
    "chars": 11262,
    "preview": "# What is A2A?\n\nThe A2A protocol is an open standard that enables seamless communication and\ncollaboration between AI ag"
  },
  {
    "path": "docs/tutorials/index.md",
    "chars": 4121,
    "preview": "# Tutorials\n\n## Python\n\nTutorial | Description | Difficulty\n:--------|:------------|:-----------\n[A2A and Python Quickst"
  },
  {
    "path": "docs/tutorials/python/1-introduction.md",
    "chars": 1811,
    "preview": "# Python Quickstart Tutorial: Building an A2A Agent\n\nWelcome to the Agent2Agent (A2A) Python Quickstart Tutorial!\n\nIn th"
  },
  {
    "path": "docs/tutorials/python/2-setup.md",
    "chars": 1371,
    "preview": "# 2. Setup Your Environment\n\n## Prerequisites\n\n- Python 3.10 or higher.\n- Access to a terminal or command prompt.\n- Git,"
  },
  {
    "path": "docs/tutorials/python/3-agent-skills-and-card.md",
    "chars": 2543,
    "preview": "# 3. Agent Skills & Agent Card\n\nBefore an A2A agent can do anything, it needs to define what it _can_ do (its skills) an"
  },
  {
    "path": "docs/tutorials/python/4-agent-executor.md",
    "chars": 3386,
    "preview": "# 4. The Agent Executor\n\nThe core logic of how an A2A agent processes requests and generates responses/events is handled"
  },
  {
    "path": "docs/tutorials/python/5-start-server.md",
    "chars": 2864,
    "preview": "# 5. Starting the Server\n\nNow that we have an Agent Card and an Agent Executor, we can set up and start the A2A server.\n"
  },
  {
    "path": "docs/tutorials/python/6-interact-with-server.md",
    "chars": 4480,
    "preview": "# 6. Interacting with the Server\n\nWith the Helloworld A2A server running, let's send some requests to it. The SDK includ"
  },
  {
    "path": "docs/tutorials/python/7-streaming-and-multiturn.md",
    "chars": 6289,
    "preview": "# 7. Streaming & Multi-Turn Interactions (LangGraph Example)\n\nThe Hello World example demonstrates the basic mechanics o"
  },
  {
    "path": "docs/tutorials/python/8-next-steps.md",
    "chars": 3032,
    "preview": "# Next Steps\n\nCongratulations on completing the A2A Python SDK Tutorial! You've learned how to:\n\n- Set up your environme"
  },
  {
    "path": "docs/whats-new-v1.md",
    "chars": 28492,
    "preview": "# What's New in A2A Protocol v1.0\n\nThis document provides a comprehensive overview of changes from A2A Protocol v0.3.0 t"
  },
  {
    "path": "lychee.toml",
    "chars": 513,
    "preview": "exclude = [\n    'https://fonts.gstatic.com/',\n    'https://fonts.googleapis.com/',\n    'https://medium.com/',\n    'https"
  },
  {
    "path": "mkdocs.yml",
    "chars": 6515,
    "preview": "# Project information\nsite_name: A2A Protocol\nsite_url: https://a2a-protocol.org/\nsite_description: >-\n  The official do"
  },
  {
    "path": "requirements-docs.txt",
    "chars": 125,
    "preview": "mkdocs-material\nmkdocs-redirects\na2a-sdk[all]\nmike\nmkdocs-macros-plugin\nsphinx\nfuro\nmyst-parser\nproto-schema-parser\ntabu"
  },
  {
    "path": "scripts/build_docs.sh",
    "chars": 2695,
    "preview": "#!/bin/bash\nset -euo pipefail\n\n# Unified docs build script that ensures the non-normative JSON artifact is\n# regenerated"
  },
  {
    "path": "scripts/build_llms_full.sh",
    "chars": 3041,
    "preview": "#!/bin/bash\nset -e\n\n# This script concatenates all documentation and specification files\n# into a single file for LLM co"
  },
  {
    "path": "scripts/build_sdk_docs.sh",
    "chars": 2081,
    "preview": "#!/bin/bash\nset -e # Exit immediately if a command exits with a non-zero status.\n\n# --- Configuration ---\nPACKAGE_NAME=\""
  },
  {
    "path": "scripts/deploy_root_files.sh",
    "chars": 2230,
    "preview": "#!/bin/bash\n\n# Exit immediately if a command exits with a non-zero status.\nset -e\n\n# This script deploys a list of speci"
  },
  {
    "path": "scripts/format.sh",
    "chars": 1082,
    "preview": "#!/bin/bash\n\nset -euo pipefail\n# Determine the repository root directory based on the script's location.\nSCRIPT_DIR=$(cd"
  },
  {
    "path": "scripts/lint.sh",
    "chars": 989,
    "preview": "#!/bin/bash\n\n# Exit on error (-e), undefined variable usage (-u), or failed pipe command (-o pipefail).\nset -euo pipefai"
  },
  {
    "path": "scripts/proto_to_json_schema.sh",
    "chars": 4099,
    "preview": "#!/bin/bash\nset -euo pipefail\n# Convert proto files to JSON Schema in a single operation.\n# Usage: proto_to_json_schema."
  },
  {
    "path": "scripts/sort_spelling.sh",
    "chars": 480,
    "preview": "#!/bin/bash\n\nset -euo pipefail\n\n# Determine the repository root directory based on the script's location.\nSCRIPT_DIR=$(c"
  },
  {
    "path": "specification/.api-linter.yaml",
    "chars": 2086,
    "preview": "# API Linter Configuration\n# https://linter.aip.dev/\n\n- included_paths:\n    - \"**/*.proto\"\n  disabled_rules:\n    - \"core"
  },
  {
    "path": "specification/a2a.proto",
    "chars": 34461,
    "preview": "// Older protoc compilers don't understand edition yet.\nsyntax = \"proto3\";\npackage lf.a2a.v1;\n\nimport \"google/api/annota"
  },
  {
    "path": "specification/buf.gen.yaml",
    "chars": 666,
    "preview": "# buf generate\n# Configuration for the buf generate command\n# Uses remote plugins, no separate install required.\n# This "
  },
  {
    "path": "specification/buf.yaml",
    "chars": 557,
    "preview": "version: v2\ndeps:\n  # Common Protobuf types.\n  - buf.build/googleapis/googleapis\nlint:\n  use:\n    # Indicates that all t"
  },
  {
    "path": "specification/json/README.md",
    "chars": 5730,
    "preview": "# A2A JSON Artifact\n\n`a2a.json` is a **non-normative build artifact** derived from the canonical proto definition at `sp"
  }
]

About this extraction

This page contains the full source code of the a2aproject/A2A GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 100 files (509.1 KB), approximately 129.0k tokens, and a symbol index with 7 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!