├── .git-blame-ignore-revs
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug-report.yml
│ └── feature-request.yml
├── PULL_REQUEST_TEMPLATE.md
├── actions
│ └── spelling
│ │ ├── advice.md
│ │ ├── allow.txt
│ │ ├── excludes.txt
│ │ └── line_forbidden.patterns
├── conventional-commit-lint.yaml
├── linters
│ ├── .eslintrc.js
│ ├── .jscpd.json
│ ├── .markdownlint.json
│ └── .stylelintrc.json
├── release-please.yml
├── release-trigger.yml
└── workflows
│ ├── dispatch-a2a-update.yml
│ ├── docs.yml
│ ├── generate-a2a-json.yml
│ ├── issue-metrics.yml
│ ├── links.yaml
│ ├── linter.yaml
│ ├── spelling.yaml
│ └── stale.yaml
├── .gitignore
├── .prettierrc
├── .ruff.toml
├── .vscode
└── settings.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── docs
├── README.md
├── assets
│ ├── a2a-actors.png
│ ├── a2a-banner.png
│ ├── a2a-logo-black.svg
│ ├── a2a-logo-white.svg
│ ├── a2a-main.png
│ ├── a2a-mcp-readme.png
│ └── a2a-mcp.png
├── community.md
├── index.md
├── llms.txt
├── partners.md
├── robots.txt
├── sdk
│ └── python
│ │ └── index.md
├── specification.md
├── stylesheets
│ └── custom.css
├── topics
│ ├── a2a-and-mcp.md
│ ├── agent-discovery.md
│ ├── enterprise-ready.md
│ ├── key-concepts.md
│ ├── streaming-and-async.md
│ └── what-is-a2a.md
└── tutorials
│ └── 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
├── lychee.toml
├── mkdocs.yml
├── noxfile.py
├── requirements-docs.txt
├── specification
├── grpc
│ └── a2a.proto
└── json
│ ├── README.md
│ └── a2a.json
└── types
├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── src
└── types.ts
└── tsconfig.json
/.git-blame-ignore-revs:
--------------------------------------------------------------------------------
1 | # Template taken from https://github.com/v8/v8/blob/master/.git-blame-ignore-revs.
2 | #
3 | # This file contains a list of git hashes of revisions to be ignored by git blame. These
4 | # revisions are considered "unimportant" in that they are unlikely to be what you are
5 | # interested in when blaming. Most of these will probably be commits related to linting
6 | # and code formatting.
7 | #
8 | # Instructions:
9 | # - Only large (generally automated) reformatting or renaming CLs should be
10 | # added to this list. Do not put things here just because you feel they are
11 | # trivial or unimportant. If in doubt, do not put it on this list.
12 | # - Precede each revision with a comment containing the PR title and number.
13 | # For bulk work over many commits, place all commits in a block with a single
14 | # comment at the top describing the work done in those commits.
15 | # - Only put full 40-character hashes on this list (not short hashes or any
16 | # other revision reference).
17 | # - Append to the bottom of the file (revisions should be in chronological order
18 | # from oldest to newest).
19 | # - Because you must use a hash, you need to append to this list in a follow-up
20 | # PR to the actual reformatting PR that you are trying to ignore.
21 | 0f8d9750bcb17f6b8b9f48793b46f7b8510cae24
22 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Code owners file.
2 | # This file controls who is tagged for review for any given pull request.
3 | #
4 | # For syntax help see:
5 | # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax
6 |
7 | * @google-a2a/googlers
8 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug-report.yml:
--------------------------------------------------------------------------------
1 | name: 🐞 Bug Report
2 | description: File a bug report
3 | title: "[Bug]: "
4 | type: "Bug"
5 | body:
6 | - type: markdown
7 | attributes:
8 | value: |
9 | Thanks for stopping by to let us know something could be better!
10 | Private Feedback? Please use this [Google form](https://goo.gle/a2a-feedback)
11 | - type: textarea
12 | id: what-happened
13 | attributes:
14 | label: What happened?
15 | description: Also tell us what you expected to happen and how to reproduce the issue.
16 | placeholder: Tell us what you see!
17 | value: "A bug happened!"
18 | validations:
19 | required: true
20 | - type: textarea
21 | id: logs
22 | attributes:
23 | label: Relevant log output
24 | description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
25 | render: shell
26 | - type: checkboxes
27 | id: terms
28 | attributes:
29 | label: Code of Conduct
30 | description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/google-a2a/A2A?tab=coc-ov-file#readme)
31 | options:
32 | - label: I agree to follow this project's Code of Conduct
33 | required: true
34 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature-request.yml:
--------------------------------------------------------------------------------
1 | name: 💡 Feature Request
2 | description: Suggest an idea for this repository
3 | title: "[Feat]: "
4 | type: "Feature"
5 | body:
6 | - type: markdown
7 | attributes:
8 | value: |
9 | Thanks for stopping by to let us know something could be better!
10 | Private Feedback? Please use this [Google form](https://goo.gle/a2a-feedback)
11 | - type: textarea
12 | id: problem
13 | attributes:
14 | label: Is your feature request related to a problem? Please describe.
15 | description: A clear and concise description of what the problem is.
16 | placeholder: Ex. I'm always frustrated when [...]
17 | - type: textarea
18 | id: describe
19 | attributes:
20 | label: Describe the solution you'd like
21 | description: A clear and concise description of what you want to happen.
22 | validations:
23 | required: true
24 | - type: textarea
25 | id: alternatives
26 | attributes:
27 | label: Describe alternatives you've considered
28 | description: A clear and concise description of any alternative solutions or features you've considered.
29 | - type: textarea
30 | id: context
31 | attributes:
32 | label: Additional context
33 | description: Add any other context or screenshots about the feature request here.
34 | - type: checkboxes
35 | id: terms
36 | attributes:
37 | label: Code of Conduct
38 | description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/google-a2a/A2A?tab=coc-ov-file#readme)
39 | options:
40 | - label: I agree to follow this project's Code of Conduct
41 | required: true
42 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | Thank you for opening a Pull Request!
4 | Before submitting your PR, there are a few things you can do to make sure it goes smoothly:
5 |
6 | - [ ] Follow the [`CONTRIBUTING` Guide](https://github.com/google-a2a/A2A/blob/main/CONTRIBUTING.md).
7 | - [ ] Make your Pull Request title in the specification.
8 | - [ ] Ensure the tests and linter pass (Run `nox -s format` from the repository root to format)
9 | - [ ] Appropriate docs were updated (if necessary)
10 |
11 | Fixes # 🦕
12 |
--------------------------------------------------------------------------------
/.github/actions/spelling/advice.md:
--------------------------------------------------------------------------------
1 |
2 | If the flagged items are :exploding_head: false positives
3 |
4 | If items relate to a ...
5 |
6 | - binary file (or some other file you wouldn't want to check at all).
7 |
8 | Please add a file path to the `excludes.txt` file matching the containing file.
9 |
10 | 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.
11 |
12 | `^` 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).
13 |
14 | - well-formed pattern.
15 |
16 | If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it,
17 | try adding it to the `patterns.txt` file.
18 |
19 | 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.
20 |
21 | Note that patterns can't match multiline strings.
22 |
23 |
24 |
25 |
26 |
27 | :steam_locomotive: If you're seeing this message and your PR is from a branch that doesn't have check-spelling,
28 | please merge to your PR's base branch to get the version configured for your repository.
29 |
--------------------------------------------------------------------------------
/.github/actions/spelling/allow.txt:
--------------------------------------------------------------------------------
1 | AAAANSUh
2 | AAAAUA
3 | AAAGHMHc
4 | ACMRTUXB
5 | ACard
6 | AClient
7 | ACo
8 | ADK
9 | AError
10 | AIP
11 | ARequest
12 | ASED
13 | ASGI
14 | AServer
15 | AService
16 | AStarlette
17 | Autogen
18 | CAs
19 | CLIs
20 | Camry
21 | Cjava
22 | DDo
23 | DGT
24 | Dotnet
25 | EBFF
26 | EUR
27 | EUg
28 | FBT
29 | GAPI
30 | GAPIC
31 | GBP
32 | GVsb
33 | Gapic
34 | Genkit
35 | Ghw
36 | IFdvcmxk
37 | INR
38 | JHv
39 | JPY
40 | JWKS
41 | JWTs
42 | KGgo
43 | KRW
44 | LHR
45 | LLM
46 | LLMs
47 | MWpm
48 | OIDC
49 | OOa
50 | Ollama
51 | PLE
52 | PLW
53 | PTH
54 | RPCs
55 | RUF
56 | SLAs
57 | SLF
58 | TMDB
59 | URLTo
60 | Upserting
61 | Urke
62 | VBORw
63 | Vsb
64 | WVw
65 | Witteveen
66 | Xca
67 | YTT
68 | YWFh
69 | Zipkin
70 | aab
71 | aacacac
72 | aboutasha
73 | achat
74 | aconnect
75 | adk
76 | agentcard
77 | agentic
78 | agentskill
79 | ainvoke
80 | aparse
81 | arxiv
82 | askmarvin
83 | asyncclick
84 | autogen
85 | autouse
86 | backstory
87 | backticks
88 | bbb
89 | bzr
90 | cae
91 | ccc
92 | cdn
93 | ceee
94 | cfe
95 | cls
96 | coc
97 | codegen
98 | codeowner
99 | crewai
100 | datamodel
101 | datapart
102 | dbc
103 | dcda
104 | dcfa
105 | dde
106 | direnv
107 | documentai
108 | dotnet
109 | efaab
110 | efbd
111 | embeddings
112 | envoyproxy
113 | evt
114 | excinfo
115 | faa
116 | fafd
117 | ffbb
118 | firewalls
119 | flightbook
120 | fsv
121 | fyi
122 | gapic
123 | gcp
124 | genai
125 | genkit
126 | genproto
127 | georoute
128 | gettickets
129 | gle
130 | googleai
131 | googleapi
132 | googleblog
133 | gpt
134 | gstatic
135 | gweb
136 | iat
137 | ietf
138 | inbox
139 | inmemory
140 | iss
141 | jherr
142 | jti
143 | jwks
144 | kty
145 | langgraph
146 | linenums
147 | linkedin
148 | llm
149 | llms
150 | lng
151 | marvin
152 | mcp
153 | mesop
154 | mindsdb
155 | mozilla
156 | msword
157 | multiagent
158 | multipage
159 | nlp
160 | notif
161 | noxfile
162 | npush
163 | objc
164 | octicons
165 | ollama
166 | oneof
167 | prefecthq
168 | protolint
169 | pyguide
170 | pymdownx
171 | pypackages
172 | pytype
173 | pyupgrade
174 | qwq
175 | rcm
176 | reportgen
177 | reposted
178 | rvelicheti
179 | sllm
180 | squidfunk
181 | srcs
182 | sse
183 | stateclass
184 | styleguide
185 | svn
186 | systemctl
187 | tagwords
188 | taskssend
189 | taskstate
190 | taskstatus
191 | textpart
192 | threadsafe
193 | tok
194 | tracestate
195 | ugc
196 | utm
197 | versioned
198 | vnd
199 | voa
200 | webpage
201 | whatwg
202 | wikipedia
203 | wsgi
204 | wwwwwwww
205 | xxxxx
206 | xxxxxxxx
207 | youtube
208 | yyyyyyyy
209 | zzzzzzzz
210 |
--------------------------------------------------------------------------------
/.github/actions/spelling/excludes.txt:
--------------------------------------------------------------------------------
1 | # See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
2 | (?:^|/)(?i)COPYRIGHT
3 | (?:^|/)(?i)LICEN[CS]E
4 | (?:^|/)(?i)CODE_OF_CONDUCT.md\E$
5 | (?:^|/)(?i).gitignore\E$
6 | (?:^|/)3rdparty/
7 | (?:^|/)go\.sum$
8 | (?:^|/)package(?:-lock|)\.json$
9 | (?:^|/)Pipfile$
10 | (?:^|/)pyproject.toml
11 | (?:^|/)requirements(?:-dev|-doc|-test|)\.txt$
12 | (?:^|/)vendor/
13 | /CODEOWNERS$
14 | \.a$
15 | \.ai$
16 | \.all-contributorsrc$
17 | \.avi$
18 | \.bmp$
19 | \.bz2$
20 | \.cer$
21 | \.class$
22 | \.coveragerc$
23 | \.crl$
24 | \.crt$
25 | \.csr$
26 | \.dll$
27 | \.docx?$
28 | \.drawio$
29 | \.DS_Store$
30 | \.eot$
31 | \.eps$
32 | \.exe$
33 | \.gif$
34 | \.git-blame-ignore-revs$
35 | \.gitattributes$
36 | \.gitkeep$
37 | \.graffle$
38 | \.gz$
39 | \.icns$
40 | \.ico$
41 | \.jar$
42 | \.jks$
43 | \.jpe?g$
44 | \.key$
45 | \.lib$
46 | \.lock$
47 | \.map$
48 | \.min\..
49 | \.mo$
50 | \.mod$
51 | \.mp[34]$
52 | \.o$
53 | \.ocf$
54 | \.otf$
55 | \.p12$
56 | \.parquet$
57 | \.pdf$
58 | \.pem$
59 | \.pfx$
60 | \.png$
61 | \.psd$
62 | \.pyc$
63 | \.pylintrc$
64 | \.qm$
65 | \.s$
66 | \.sig$
67 | \.so$
68 | \.svgz?$
69 | \.sys$
70 | \.tar$
71 | \.tgz$
72 | \.tiff?$
73 | \.ttf$
74 | \.wav$
75 | \.webm$
76 | \.webp$
77 | \.woff2?$
78 | \.xcf$
79 | \.xlsx?$
80 | \.xpm$
81 | \.xz$
82 | \.zip$
83 | ^\.github/actions/spelling/
84 | ^\Q.github/workflows/spelling.yaml\E$
85 | ^\Q.github/workflows/linter.yaml\E$
86 | ^\Qdemo/ui/service/server/test_image.py\E$
87 | ^\Qlychee.toml\E$
88 | \.vscode/
89 | ^\Qdocs/partners.md\E$
90 | ^\Qspecification/json/a2a.json\E$
91 | CHANGELOG.md
92 | \.gitignore
93 | ^\Qdocs/robots.txt\E$
94 |
--------------------------------------------------------------------------------
/.github/actions/spelling/line_forbidden.patterns:
--------------------------------------------------------------------------------
1 | # Should be `HH:MM:SS`
2 | \bHH:SS:MM\b
3 |
4 | # Should probably be `YYYYMMDD`
5 | \b[Yy]{4}[Dd]{2}[Mm]{2}(?!.*[Yy]{4}[Dd]{2}[Mm]{2}).*$
6 |
7 | # Should be `anymore`
8 | \bany more[,.]
9 |
10 | # Should be `cannot` (or `can't`)
11 | # See https://www.grammarly.com/blog/cannot-or-can-not/
12 | # > 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`.
13 | # > `Can't` is a contraction of `cannot`, and it's best suited for informal writing.
14 | # > In formal writing and where contractions are frowned upon, use `cannot`.
15 | # > 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.`
16 | # - if you encounter such a case, add a pattern for that case to patterns.txt.
17 | \b[Cc]an not\b
18 |
19 | # Should be `GitHub`
20 | (?> $GITHUB_ENV
38 | - uses: actions/cache@v4
39 | with:
40 | key: mkdocs-material-${{ env.cache_id }}
41 | path: .cache
42 | restore-keys: |
43 | mkdocs-material-
44 |
45 | - name: Install documentation dependencies
46 | run: pip install -r requirements-docs.txt && pip install a2a-sdk
47 |
48 | - name: Build Documentation (PR Check)
49 | if: github.event_name == 'pull_request'
50 | run: mkdocs build
51 |
52 | - name: Build and Deploy Documentation (Push to main)
53 | if: github.event_name == 'push' && github.ref == 'refs/heads/main'
54 | run: mkdocs gh-deploy --force
55 |
--------------------------------------------------------------------------------
/.github/workflows/generate-a2a-json.yml:
--------------------------------------------------------------------------------
1 | name: Auto-generate A2A JSON Schema
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - main
7 | paths:
8 | - "types/src/types.ts"
9 | types:
10 | - opened
11 | - synchronize
12 | - reopened
13 |
14 | jobs:
15 | generate_json:
16 | name: Generate JSON Schema
17 | runs-on: ubuntu-latest
18 | permissions:
19 | contents: write
20 |
21 | steps:
22 | - name: Checkout Code
23 | uses: actions/checkout@v4
24 | with:
25 | fetch-depth: 0
26 | ref: ${{ github.event.pull_request.head.ref }}
27 | repository: ${{ github.event.pull_request.head.repo.full_name }}
28 |
29 | - name: Setup Node.js
30 | uses: actions/setup-node@v4
31 | with:
32 | node-version: "20"
33 |
34 | - name: Install dependencies and generate a2a.json
35 | working-directory: types
36 | run: |
37 | npm install
38 | npm run generate
39 | id: generate_schema
40 |
41 | - name: Configure Git for Bot
42 | if: github.event.pull_request.head.repo.full_name == github.repository
43 | run: |
44 | git config user.name "a2a-bot"
45 | git config user.email "a2a-bot@google.com"
46 |
47 | - name: Check for Changes
48 | id: git_status
49 | run: |
50 | git add specification/json/a2a.json
51 | if ! git diff --cached --quiet --exit-code; then
52 | echo "changes_detected=true" >> "$GITHUB_OUTPUT"
53 | echo "a2a.json is not up-to-date with types.ts"
54 | else
55 | echo "a2a.json is up-to-date."
56 | fi
57 |
58 | - name: Commit and Push Changes (if on base repository)
59 | if: steps.git_status.outputs.changes_detected == 'true' && github.event.pull_request.head.repo.full_name == github.repository
60 | run: |
61 | git commit -m "chore: Auto-generate a2a.json from types.ts changes"
62 | git push
63 |
64 | - name: Fail on Fork PR if Changes Required
65 | if: steps.git_status.outputs.changes_detected == 'true' && github.event.pull_request.head.repo.full_name != github.repository
66 | run: |
67 | echo "::error::a2a.json is out of date."
68 | echo "Please run 'npm install' then 'npm run generate' in the 'types' directory of your branch and commit the updated 'specification/json/a2a.json' file."
69 | exit 1 # Exit with a non-zero code to fail the workflow
70 |
--------------------------------------------------------------------------------
/.github/workflows/issue-metrics.yml:
--------------------------------------------------------------------------------
1 | name: Monthly issue metrics
2 | on:
3 | workflow_dispatch:
4 | schedule:
5 | - cron: "3 2 1 * *"
6 |
7 | permissions:
8 | contents: read
9 |
10 | jobs:
11 | build:
12 | name: issue metrics
13 | runs-on: ubuntu-latest
14 | permissions:
15 | issues: write
16 | pull-requests: read
17 | steps:
18 | - name: Get dates for last month
19 | shell: bash
20 | run: |
21 | # Calculate the first day of the previous month
22 | first_day=$(date -d "last month" +%Y-%m-01)
23 |
24 | # Calculate the last day of the previous month
25 | last_day=$(date -d "$first_day +1 month -1 day" +%Y-%m-%d)
26 |
27 | # Set an environment variable with the date range
28 | echo "$first_day..$last_day"
29 | echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV"
30 |
31 | - name: Run issue-metrics tool
32 | uses: github/issue-metrics@v3
33 | env:
34 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35 | SEARCH_QUERY: 'repo:google-a2a/A2A is:issue created:${{ env.last_month }} -reason:"not planned"'
36 |
37 | - name: Create issue
38 | uses: peter-evans/create-issue-from-file@v5
39 | with:
40 | title: Monthly issue metrics report
41 | token: ${{ secrets.GITHUB_TOKEN }}
42 | content-filepath: ./issue_metrics.md
43 |
--------------------------------------------------------------------------------
/.github/workflows/links.yaml:
--------------------------------------------------------------------------------
1 | name: Links
2 |
3 | on:
4 | repository_dispatch:
5 | workflow_dispatch:
6 | schedule:
7 | - cron: "00 18 * * *"
8 |
9 | jobs:
10 | linkChecker:
11 | runs-on: ubuntu-latest
12 | if: |
13 | github.repository == 'google-a2a/A2A'
14 |
15 | steps:
16 | - uses: actions/checkout@v4
17 |
18 | - name: Link Checker
19 | id: lychee
20 | uses: lycheeverse/lychee-action@v2
21 |
22 | - name: Create Issue From File
23 | if: env.lychee_exit_code != 0
24 | uses: peter-evans/create-issue-from-file@v5
25 | with:
26 | title: Link Checker Report
27 | content-filepath: ./lychee/out.md
28 | labels: report, automated issue
29 |
--------------------------------------------------------------------------------
/.github/workflows/linter.yaml:
--------------------------------------------------------------------------------
1 | #################################
2 | #################################
3 | ## Super Linter GitHub Actions ##
4 | #################################
5 | #################################
6 | name: Lint Code Base
7 |
8 | #
9 | # Documentation:
10 | # https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
11 | #
12 |
13 | #############################
14 | # Start the job on all push #
15 | #############################
16 | on:
17 | pull_request:
18 | branches: [main]
19 |
20 | ###############
21 | # Set the Job #
22 | ###############
23 | jobs:
24 | build:
25 | # Name the Job
26 | name: Lint Code Base
27 | # Set the agent to run on
28 | runs-on: ubuntu-latest
29 | # if on repo to avoid failing runs on forks
30 | if: |
31 | github.repository == 'google-a2a/A2A'
32 |
33 | ##################
34 | # Load all steps #
35 | ##################
36 | steps:
37 | ##########################
38 | # Checkout the code base #
39 | ##########################
40 | - name: Checkout Code
41 | uses: actions/checkout@v4
42 | with:
43 | # Full git history is needed to get a proper list of changed files within `super-linter`
44 | fetch-depth: 0
45 |
46 | ################################
47 | # Run Linter against code base #
48 | ################################
49 | - name: Lint Code Base
50 | uses: super-linter/super-linter/slim@v7
51 | env:
52 | DEFAULT_BRANCH: main
53 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54 | LOG_LEVEL: WARN
55 | SHELLCHECK_OPTS: -e SC1091 -e 2086
56 | VALIDATE_ALL_CODEBASE: false
57 | FILTER_REGEX_EXCLUDE: "^(\\.github/|\\.vscode/).*|CODE_OF_CONDUCT.md|CHANGELOG.md"
58 | VALIDATE_PYTHON_BLACK: false
59 | VALIDATE_PYTHON_FLAKE8: false
60 | VALIDATE_PYTHON_ISORT: false
61 | VALIDATE_PYTHON_MYPY: false
62 | VALIDATE_PYTHON_PYLINT: false
63 | VALIDATE_PYTHON_PYINK: false
64 | VALIDATE_CHECKOV: false
65 | VALIDATE_JAVASCRIPT_STANDARD: false
66 | VALIDATE_TYPESCRIPT_STANDARD: false
67 | VALIDATE_NATURAL_LANGUAGE: false
68 | MARKDOWN_CONFIG_FILE: ".markdownlint.json"
69 | VALIDATE_MARKDOWN_PRETTIER: false
70 | TYPESCRIPT_ES_CONFIG_FILE: ".eslintrc.js"
71 | VALIDATE_JAVASCRIPT_PRETTIER: false
72 | VALIDATE_JSON_PRETTIER: false
73 | VALIDATE_YAML_PRETTIER: false
74 | VALIDATE_GIT_COMMITLINT: false
75 |
--------------------------------------------------------------------------------
/.github/workflows/spelling.yaml:
--------------------------------------------------------------------------------
1 | name: Check Spelling
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - "**"
7 | types:
8 | - "opened"
9 | - "reopened"
10 | - "synchronize"
11 | issue_comment:
12 | types:
13 | - "created"
14 |
15 | jobs:
16 | spelling:
17 | name: Check Spelling
18 | permissions:
19 | contents: read
20 | actions: read
21 | security-events: write
22 | outputs:
23 | followup: ${{ steps.spelling.outputs.followup }}
24 | runs-on: ubuntu-latest
25 | # if on repo to avoid failing runs on forks
26 | if: |
27 | github.repository == 'google-a2a/A2A'
28 | && (contains(github.event_name, 'pull_request') || github.event_name == 'push')
29 | concurrency:
30 | group: spelling-${{ github.event.pull_request.number || github.ref }}
31 | # note: If you use only_check_changed_files, you do not want cancel-in-progress
32 | cancel-in-progress: false
33 | steps:
34 | - name: check-spelling
35 | id: spelling
36 | uses: check-spelling/check-spelling@main
37 | with:
38 | suppress_push_for_open_pull_request: ${{ github.actor != 'dependabot[bot]' && 1 }}
39 | checkout: true
40 | check_file_names: 1
41 | spell_check_this: check-spelling/spell-check-this@main
42 | post_comment: 0
43 | use_magic_file: 1
44 | report-timing: 1
45 | 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
46 | experimental_apply_changes_via_bot: 1
47 | dictionary_source_prefixes: '{"cspell": "https://raw.githubusercontent.com/streetsidesoftware/cspell-dicts/main/dictionaries/"}'
48 | extra_dictionaries: |
49 | cspell:aws/dict/aws.txt
50 | cspell:bash/samples/bash-words.txt
51 | cspell:companies/dict/companies.txt
52 | cspell:css/dict/css.txt
53 | cspell:data-science/dict/data-science-models.txt
54 | cspell:data-science/dict/data-science.txt
55 | cspell:data-science/dict/data-science-tools.txt
56 | cspell:en_shared/dict/acronyms.txt
57 | cspell:en_shared/dict/shared-additional-words.txt
58 | cspell:en_GB/en_GB.trie
59 | cspell:en_US/en_US.trie
60 | cspell:filetypes/src/filetypes.txt
61 | cspell:fonts/dict/fonts.txt
62 | cspell:fullstack/dict/fullstack.txt
63 | cspell:golang/dict/go.txt
64 | cspell:google/dict/google.txt
65 | cspell:html/dict/html.txt
66 | cspell:java/src/java.txt
67 | cspell:k8s/dict/k8s.txt
68 | cspell:mnemonics/dict/mnemonics.txt
69 | cspell:monkeyc/src/monkeyc_keywords.txt
70 | cspell:node/dict/node.txt
71 | cspell:npm/dict/npm.txt
72 | cspell:people-names/dict/people-names.txt
73 | cspell:python/dict/python.txt
74 | cspell:python/dict/python-common.txt
75 | cspell:shell/dict/shell-all-words.txt
76 | cspell:software-terms/dict/softwareTerms.txt
77 | cspell:software-terms/dict/webServices.txt
78 | cspell:sql/src/common-terms.txt
79 | cspell:sql/src/sql.txt
80 | cspell:sql/src/tsql.txt
81 | cspell:terraform/dict/terraform.txt
82 | cspell:typescript/dict/typescript.txt
83 | check_extra_dictionaries: ""
84 | only_check_changed_files: true
85 | longest_word: "10"
86 |
--------------------------------------------------------------------------------
/.github/workflows/stale.yaml:
--------------------------------------------------------------------------------
1 | # This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
2 | #
3 | # You can adjust the behavior by modifying this file.
4 | # For more information, see:
5 | # https://github.com/actions/stale
6 | name: Mark stale issues and pull requests
7 |
8 | on:
9 | schedule:
10 | # Scheduled to run at 10.30PM UTC everyday (1530PDT/1430PST)
11 | - cron: "30 22 * * *"
12 | workflow_dispatch:
13 |
14 | jobs:
15 | stale:
16 | runs-on: ubuntu-latest
17 | permissions:
18 | issues: write
19 | pull-requests: write
20 | actions: write
21 |
22 | steps:
23 | - uses: actions/stale@v9
24 | with:
25 | repo-token: ${{ secrets.GITHUB_TOKEN }}
26 | days-before-issue-stale: 14
27 | days-before-issue-close: 13
28 | stale-issue-label: "status:stale"
29 | close-issue-reason: not_planned
30 | any-of-labels: "status:awaiting response,status:more data needed"
31 | stale-issue-message: >
32 | Marking this issue as stale since it has been open for 14 days with no activity.
33 | This issue will be closed if no further activity occurs.
34 | close-issue-message: >
35 | This issue was closed because it has been inactive for 27 days.
36 | Please post a new issue if you need further assistance. Thanks!
37 | days-before-pr-stale: 14
38 | days-before-pr-close: 13
39 | stale-pr-label: "status:stale"
40 | stale-pr-message: >
41 | Marking this pull request as stale since it has been open for 14 days with no activity.
42 | This PR will be closed if no further activity occurs.
43 | close-pr-message: >
44 | This pull request was closed because it has been inactive for 27 days.
45 | Please open a new pull request if you need further assistance. Thanks!
46 | # Label that can be assigned to issues to exclude them from being marked as stale
47 | exempt-issue-labels: "override-stale"
48 | # Label that can be assigned to PRs to exclude them from being marked as stale
49 | exempt-pr-labels: "override-stale"
50 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *.pyc
5 | *$py.class
6 | **/dist
7 | /tmp
8 | /out-tsc
9 | /bazel-out
10 |
11 | # C extensions
12 | *.so
13 |
14 | # Distribution / packaging
15 | .Python
16 | build/
17 | develop-eggs/
18 | dist/
19 | downloads/
20 | eggs/
21 | .eggs/
22 | lib/
23 | lib64/
24 | parts/
25 | sdist/
26 | var/
27 | wheels/
28 | pip-wheel-metadata/
29 | share/python-wheels/
30 | *.egg-info/
31 | .installed.cfg
32 | *.egg
33 | MANIFEST
34 |
35 | # PyInstaller
36 | # Usually these files are written by a python script from a template
37 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
38 | *.manifest
39 | *.spec
40 |
41 | # Installer logs
42 | pip-log.txt
43 | pip-delete-this-directory.txt
44 |
45 | # Unit test / coverage reports
46 | htmlcov/
47 | .tox/
48 | .nox/
49 | .coverage
50 | .coverage.*
51 | .cache
52 | nosetests.xml
53 | coverage.xml
54 | *.cover
55 | *.py,cover
56 | .hypothesis/
57 | .pytest_cache/
58 |
59 | # Translations
60 | *.mo
61 | *.pot
62 |
63 | # Django stuff:
64 | *.log
65 | local_settings.py
66 | db.sqlite3
67 | db.sqlite3-journal
68 |
69 | # Flask stuff:
70 | instance/
71 | .webassets-cache
72 |
73 | # Scrapy stuff:
74 | .scrapy
75 |
76 | # Sphinx documentation
77 | docs/_build/
78 |
79 | # PyBuilder
80 | target/
81 |
82 | # Jupyter Notebook
83 | .ipynb_checkpoints
84 |
85 | # IPython
86 | profile_default/
87 | ipython_config.py
88 |
89 | # pyenv
90 | .python-version
91 |
92 | # pipenv
93 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
94 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
95 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
96 | # install all needed dependencies.
97 | Pipfile.lock
98 | Pipfile
99 |
100 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
101 | __pypackages__/
102 |
103 | # Celery stuff
104 | celerybeat-schedule
105 | celerybeat.pid
106 |
107 | # SageMath parsed files
108 | *.sage.py
109 |
110 | # Environments
111 | .env
112 | .venv
113 | .venv*
114 | env/
115 | venv/
116 | ENV/
117 | env.bak/
118 | venv.bak/
119 |
120 | # Spyder project settings
121 | .spyderproject
122 | .spyproject
123 |
124 | # Rope project settings
125 | .ropeproject
126 |
127 | # mkdocs documentation
128 | /site
129 |
130 | # mypy
131 | .mypy_cache/
132 | .dmypy.json
133 | dmypy.json
134 | .ruff_cache/
135 |
136 | # Pyre type checker
137 | .pyre/
138 |
139 | # macOS
140 | .DS_Store
141 |
142 | # PyCharm
143 | .idea
144 |
145 | # User-specific files
146 | language/examples/prompt-design/train.csv
147 | README-TOC*.md
148 |
149 | # Terraform
150 | terraform.tfstate**
151 | .terraform*
152 | .Terraform*
153 |
154 | tmp*
155 |
156 | # Node
157 | **/node_modules
158 | npm-debug.log
159 | yarn-error.log
160 |
161 | # IDEs and editors
162 | .idea/
163 | .project
164 | .classpath
165 | .c9/
166 | *.launch
167 | .settings/
168 | *.sublime-workspace
169 |
170 | # Miscellaneous
171 | **/.angular/*
172 | /.angular/cache
173 | .sass-cache/
174 | /connect.lock
175 | /coverage
176 | /libpeerconnection.log
177 | testem.log
178 | /typings
179 |
180 | # System files
181 | .DS_Store
182 | Thumbs.db
183 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "tabWidth": 2,
3 | "trailingComma": "es5",
4 | "bracketSameLine": true
5 | }
6 |
--------------------------------------------------------------------------------
/.ruff.toml:
--------------------------------------------------------------------------------
1 | #################################################################################
2 | #
3 | # Ruff linter and code formatter for A2A
4 | #
5 | # This file follows the standards in Google Python Style Guide
6 | # https://google.github.io/styleguide/pyguide.html
7 | #
8 | # The settings below are for the IDE configuration, and are optional.
9 | #{
10 | # "editor.formatOnSave": true,
11 | # "[python]": {
12 | # "editor.defaultFormatter": "charliermarsh.ruff",
13 | # "editor.formatOnSave": true,
14 | # "editor.codeActionsOnSave": {
15 | # "source.organizeImports": "true"
16 | # },
17 | # },
18 | # "ruff.importStrategy": "fromEnvironment",
19 | #}
20 |
21 | line-length = 80 # Google Style Guide §3.2: 80 columns
22 | indent-width = 4 # Google Style Guide §3.4: 4 spaces
23 |
24 | target-version = "py312" # Minimum Python version
25 |
26 | [lint]
27 | ignore = [
28 | "COM812",
29 | "FBT001",
30 | "FBT002",
31 | "D203",
32 | "D213",
33 | "ANN001",
34 | "ANN201",
35 | "ANN204",
36 | "D100", # Ignore Missing docstring in public module (often desired at top level __init__.py)
37 | "D102", # Ignore return type annotation in public method
38 | "D104", # Ignore Missing docstring in public package (often desired at top level __init__.py)
39 | "D107", # Ignore Missing docstring in __init__ (use class docstring)
40 | "TD002", # Ignore Missing author in TODOs (often not required)
41 | "TD003", # Ignore Missing issue link in TODOs (often not required/available)
42 | "T201", # Ignore print presence
43 | "RUF012", # Ignore Mutable class attributes should be annotated with `typing.ClassVar`
44 | "RUF013", # Ignore implicit optional
45 | ]
46 |
47 | select = [
48 | "E", # pycodestyle errors (PEP 8)
49 | "W", # pycodestyle warnings (PEP 8)
50 | "F", # Pyflakes (logical errors, unused imports/variables)
51 | "I", # isort (import sorting - Google Style §3.1.2)
52 | "D", # pydocstyle (docstring conventions - Google Style §3.8)
53 | "N", # pep8-naming (naming conventions - Google Style §3.16)
54 | "UP", # pyupgrade (use modern Python syntax)
55 | "ANN",# flake8-annotations (type hint usage/style - Google Style §2.22)
56 | "A", # flake8-builtins (avoid shadowing builtins)
57 | "B", # flake8-bugbear (potential logic errors & style issues - incl. mutable defaults B006, B008)
58 | "C4", # flake8-comprehensions (unnecessary list/set/dict comprehensions)
59 | "ISC",# flake8-implicit-str-concat (disallow implicit string concatenation across lines)
60 | "T20",# flake8-print (discourage `print` - prefer logging)
61 | "SIM",# flake8-simplify (simplify code, e.g., `if cond: return True else: return False`)
62 | "PTH",# flake8-use-pathlib (use pathlib instead of os.path where possible)
63 | "PL", # Pylint rules ported to Ruff (PLC, PLE, PLR, PLW)
64 | "PIE",# flake8-pie (misc code improvements, e.g., no-unnecessary-pass)
65 | "RUF",# Ruff-specific rules (e.g., RUF001-003 ambiguous unicode)
66 | "RET",# flake8-return (consistency in return statements)
67 | "SLF",# flake8-self (check for private member access via `self`)
68 | "TID",# flake8-tidy-imports (relative imports, banned imports - configure if needed)
69 | "YTT",# flake8-boolean-trap (checks for boolean positional arguments, truthiness tests - Google Style §3.10)
70 | "TD", # flake8-todos (check TODO format - Google Style §3.7)
71 | ]
72 |
73 | exclude = [
74 | ".bzr",
75 | ".direnv",
76 | ".eggs",
77 | ".git",
78 | ".hg",
79 | ".mypy_cache",
80 | ".nox",
81 | ".pants.d",
82 | ".pytype",
83 | ".ruff_cache",
84 | ".svn",
85 | ".tox",
86 | ".venv",
87 | "__pypackages__",
88 | "_build",
89 | "buck-out",
90 | "build",
91 | "dist",
92 | "node_modules",
93 | "venv",
94 | "*/migrations/*",
95 | ]
96 |
97 | [lint.isort]
98 | #force-sort-within-sections = true
99 | #combine-as-imports = true
100 | case-sensitive = true
101 | #force-single-line = false
102 | #known-first-party = []
103 | #known-third-party = []
104 | lines-after-imports = 2
105 | lines-between-types = 1
106 | #no-lines-before = ["LOCALFOLDER"]
107 | #required-imports = []
108 | #section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]
109 |
110 | [lint.pydocstyle]
111 | convention = "google"
112 |
113 | [lint.flake8-annotations]
114 | mypy-init-return = true
115 | allow-star-arg-any = false
116 |
117 | [lint.pep8-naming]
118 | ignore-names = ["test_*", "setUp", "tearDown", "mock_*"]
119 | classmethod-decorators = ["classmethod", "pydantic.validator", "pydantic.root_validator"]
120 | staticmethod-decorators = ["staticmethod"]
121 |
122 | [lint.flake8-tidy-imports]
123 | ban-relative-imports = "all" # Google generally prefers absolute imports (§3.1.2)
124 |
125 | [lint.flake8-quotes]
126 | docstring-quotes = "double"
127 | inline-quotes = "single"
128 |
129 | [lint.per-file-ignores]
130 | "__init__.py" = ["F401"] # Ignore unused imports in __init__.py
131 | "*_test.py" = ["D", "ANN"] # Ignore docstring and annotation issues in test files
132 | "test_*.py" = ["D", "ANN"] # Ignore docstring and annotation issues in test files
133 |
134 | [format]
135 | docstring-code-format = true
136 | docstring-code-line-length = "dynamic" # Or set to 80
137 | quote-style = "single"
138 | indent-style = "space"
139 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true,
3 | "[python]": {
4 | "editor.defaultFormatter": "charliermarsh.ruff",
5 | "editor.formatOnSave": true,
6 | "editor.codeActionsOnSave": {
7 | "source.organizeImports": "explicit"
8 | }
9 | },
10 | "ruff.importStrategy": "fromEnvironment",
11 | "markdownlint.configFile": ".github/linters/.markdownlint.json"
12 | }
13 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## [0.2.1](https://github.com/google-a2a/A2A/compare/v0.2.0...v0.2.1) (2025-05-27)
4 |
5 | ### Features
6 |
7 | * Add a new boolean for supporting authenticated extended cards ([#618](https://github.com/google-a2a/A2A/issues/618)) ([e0a3070](https://github.com/google-a2a/A2A/commit/e0a3070fc289110d43faf2e91b4ffe3c29ef81da))
8 | * Add optional referenceTaskIds for task followups ([#608](https://github.com/google-a2a/A2A/issues/608)) ([5368e77](https://github.com/google-a2a/A2A/commit/5368e7728cb523caf1a9218fda0b1646325f524b))
9 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, gender identity and expression, level of
9 | experience, education, socio-economic status, nationality, personal appearance,
10 | race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or reject
41 | comments, commits, code, wiki edits, issues, and other contributions that are
42 | not aligned to this Code of Conduct, or to ban temporarily or permanently any
43 | contributor for other behaviors that they deem inappropriate, threatening,
44 | offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | This Code of Conduct also applies outside the project spaces when the Project
56 | Steward has a reasonable belief that an individual's behavior may have a
57 | negative impact on the project or its community.
58 |
59 | ## Conflict Resolution
60 |
61 | We do not believe that all conflict is bad; healthy debate and disagreement
62 | often yield positive results. However, it is never okay to be disrespectful or
63 | to engage in behavior that violates the project’s code of conduct.
64 |
65 | If you see someone violating the code of conduct, you are encouraged to address
66 | the behavior directly with those involved. Many issues can be resolved quickly
67 | and easily, and this gives people more control over the outcome of their
68 | dispute. If you are unable to resolve the matter for any reason, or if the
69 | behavior is threatening or harassing, report it. We are dedicated to providing
70 | an environment where participants feel welcome and safe.
71 |
72 | Reports should be directed to *[PROJECT STEWARD NAME(s) AND EMAIL(s)]*, the
73 | Project Steward(s) for *[PROJECT NAME]*. It is the Project Steward’s duty to
74 | receive and address reported violations of the code of conduct. They will then
75 | work with a committee consisting of representatives from the Open Source
76 | Programs Office and the Google Open Source Strategy team. If for any reason you
77 | are uncomfortable reaching out to the Project Steward, please email
78 | opensource@google.com.
79 |
80 | We will investigate every complaint, but you may not receive a direct response.
81 | We will use our discretion in determining when and how to follow up on reported
82 | incidents, which may range from not taking action to permanent expulsion from
83 | the project and project-sponsored spaces. We will notify the accused of the
84 | report and provide them an opportunity to discuss it before any action is taken.
85 | The identity of the reporter will be omitted from the details of the report
86 | supplied to the accused. In potentially harmful situations, such as ongoing
87 | harassment or threats to anyone's safety, we may take action without notice.
88 |
89 | ## Attribution
90 |
91 | This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
92 | available at
93 | https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
94 |
95 | Note: A version of this file is also available in the
96 | [New Project repo](https://github.com/google/new-project/blob/master/docs/code-of-conduct.md).
97 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 |
3 | We'd love to accept your patches and contributions to this project.
4 |
5 | ## Before you begin
6 |
7 | ### Sign our Contributor License Agreement
8 |
9 | Contributions to this project must be accompanied by a
10 | [Contributor License Agreement](https://cla.developers.google.com/about) (CLA).
11 | You (or your employer) retain the copyright to your contribution; this simply
12 | gives us permission to use and redistribute your contributions as part of the
13 | project.
14 |
15 | If you or your current employer have already signed the Google CLA (even if it
16 | was for a different project), you probably don't need to do it again.
17 |
18 | Visit to see your current agreements or to
19 | sign a new one.
20 |
21 | ### Review our community guidelines
22 |
23 | This project follows
24 | [Google's Open Source Community Guidelines](https://opensource.google/conduct/).
25 |
26 | ## Contribution process
27 |
28 | ### Code reviews
29 |
30 | All submissions, including submissions by project members, require review. We
31 | use GitHub pull requests for this purpose. Consult
32 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
33 | information on using pull requests.
34 |
35 | ### Contributor Guide
36 |
37 | You may follow these steps to contribute:
38 |
39 | 1. **Fork the official repository.** This will create a copy of the official repository in your own account.
40 | 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.
41 | 3. **Work on your forked repository's feature branch.** This is where you will make your changes to the code.
42 | 4. **Commit your updates on your forked repository's feature branch.** This will save your changes to your copy of the repository.
43 | 5. **Submit a pull request to the official repository's main branch.** This will request that your changes be merged into the official repository.
44 | 6. **Resolve any linting errors.** This will ensure that your changes are formatted correctly.
45 |
46 | Here are some additional things to keep in mind during the process:
47 |
48 | - **Test your changes.** Before you submit a pull request, make sure that your changes work as expected.
49 | - **Be patient.** It may take some time for your pull request to be reviewed and merged.
50 |
51 | ---
52 |
53 | ## For Google Employees
54 |
55 | Complete the following steps to register your GitHub account and be added as a contributor to this repository.
56 |
57 | 1. Register your GitHub account at [go/GitHub](http://go/github)
58 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Agent2Agent (A2A) Protocol
2 |
3 | 
4 | [](LICENSE)
5 |
6 | 
7 |
8 | **An open protocol enabling communication and interoperability between opaque agentic applications.**
9 |
10 | 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.
11 |
12 | With A2A, agents can:
13 |
14 | - Discover each other's capabilities.
15 | - Negotiate interaction modalities (text, forms, media).
16 | - Securely collaborate on long running tasks.
17 | - Operate without exposing their internal state, memory, or tools.
18 |
19 | ## See A2A in Action
20 |
21 | Watch [this demo video](https://storage.googleapis.com/gweb-developer-goog-blog-assets/original_videos/A2A_demo_v4.mp4) to see how A2A enables seamless communication between different agent frameworks.
22 |
23 | ## Why A2A?
24 |
25 | As AI agents become more prevalent, their ability to interoperate is crucial for building complex, multi-functional applications. A2A aims to:
26 |
27 | - **Break Down Silos:** Connect agents across different ecosystems.
28 | - **Enable Complex Collaboration:** Allow specialized agents to work together on tasks that a single agent cannot handle alone.
29 | - **Promote Open Standards:** Foster a community-driven approach to agent communication, encouraging innovation and broad adoption.
30 | - **Preserve Opacity:** Allow agents to collaborate without needing to share internal memory, proprietary logic, or specific tool implementations, enhancing security and protecting intellectual property.
31 |
32 | ### Key Features
33 |
34 | - **Standardized Communication:** JSON-RPC 2.0 over HTTP(S).
35 | - **Agent Discovery:** Via "Agent Cards" detailing capabilities and connection info.
36 | - **Flexible Interaction:** Supports synchronous request/response, streaming (SSE), and asynchronous push notifications.
37 | - **Rich Data Exchange:** Handles text, files, and structured JSON data.
38 | - **Enterprise-Ready:** Designed with security, authentication, and observability in mind.
39 |
40 | ## Getting Started
41 |
42 | - 📚 **Explore the Documentation:** Visit the [Agent2Agent Protocol Documentation Site](https://goo.gle/a2a) for a complete overview, the full protocol specification, tutorials, and guides.
43 | - 📝 **View the Specification:** [A2A Protocol Specification](https://google-a2a.github.io/A2A/specification/)
44 | - 🐍 Use the [A2A Python SDK](https://github.com/google-a2a/a2a-python)
45 | - `pip install a2a-sdk`
46 | - 🎬 Use our [samples](https://github.com/google-a2a/a2a-samples) to see A2A in action
47 |
48 | ## Contributing
49 |
50 | We welcome community contributions to enhance and evolve the A2A protocol!
51 |
52 | - **Questions & Discussions:** Join our [GitHub Discussions](https://github.com/google-a2a/A2A/discussions).
53 | - **Issues & Feedback:** Report issues or suggest improvements via [GitHub Issues](https://github.com/google-a2a/A2A/issues).
54 | - **Contribution Guide:** See our [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute.
55 | - **Private Feedback:** Use this [Google Form](https://goo.gle/a2a-feedback).
56 | - **Partner Program:** Google Cloud customers can join our partner program via this [form](https://goo.gle/a2a-partner).
57 |
58 | ## What's next
59 |
60 | ### Protocol Enhancements
61 |
62 | - **Agent Discovery:**
63 | - Formalize inclusion of authorization schemes and optional credentials directly within the `AgentCard`.
64 | - **Agent Collaboration:**
65 | - Investigate a `QuerySkill()` method for dynamically checking unsupported or unanticipated skills.
66 | - **Task Lifecycle & UX:**
67 | - Support for dynamic UX negotiation _within_ a task (e.g., agent adding audio/video mid-conversation).
68 | - **Client Methods & Transport:**
69 | - Explore extending support to client-initiated methods (beyond task management).
70 | - Improvements to streaming reliability and push notification mechanisms.
71 |
72 | ## About
73 |
74 | The A2A Protocol is an open-source project by Google LLC, under the [Apache License 2.0](LICENSE), and is open to contributions from the community.
75 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | To report a security issue, please use [g.co/vulnz](https://g.co/vulnz).
4 |
5 | The Google Security Team will respond within 5 working days of your report on g.co/vulnz.
6 |
7 | We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue.
8 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # A2A Docs
2 |
3 | ## Published A2A docs
4 |
5 | [`https://google-a2a.github.io/A2A`](https://google-a2a.github.io/A2A)
6 |
7 | ## Developing A2A docs
8 |
9 | 1. Clone this repository and `cd` into the repository directory
10 | 2. Run `pip install -r requirements-docs.txt`
11 | 3. Run `mkdocs serve`, edit `.md` files, and live preview
12 | 4. Contribute docs changes as usual
13 |
14 | ## How it works
15 |
16 | - The A2A docs use [mkdocs](https://www.mkdocs.org/) and the
17 | [mkdocs-material theme](https://squidfunk.github.io/mkdocs-material/)
18 | - All of the source documentation / Markdown files related to the A2A docs are
19 | in the `docs/` directory in the A2A repository
20 | - `mkdocs.yml` in the repository root contains all of the docs config, including
21 | the site navigation and organization
22 | - There is a GitHub Action in `.github/workflows/docs.yml` that builds and
23 | publishes the docs and pushes the built assets to the `gh-pages` branch in
24 | this repository using `mkdocs gh-deploy --force`. This happens automatically for all
25 | commits / merges to `main`.
26 | - The A2A documentation is hosted in GitHub pages, and the settings for this are
27 | in the A2A repository settings in GitHub.
28 |
--------------------------------------------------------------------------------
/docs/assets/a2a-actors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-a2a/A2A/2e889e25b7ef61079a381a46cb870b3fdd4b3e98/docs/assets/a2a-actors.png
--------------------------------------------------------------------------------
/docs/assets/a2a-banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-a2a/A2A/2e889e25b7ef61079a381a46cb870b3fdd4b3e98/docs/assets/a2a-banner.png
--------------------------------------------------------------------------------
/docs/assets/a2a-logo-black.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/docs/assets/a2a-logo-white.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/docs/assets/a2a-main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-a2a/A2A/2e889e25b7ef61079a381a46cb870b3fdd4b3e98/docs/assets/a2a-main.png
--------------------------------------------------------------------------------
/docs/assets/a2a-mcp-readme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-a2a/A2A/2e889e25b7ef61079a381a46cb870b3fdd4b3e98/docs/assets/a2a-mcp-readme.png
--------------------------------------------------------------------------------
/docs/assets/a2a-mcp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-a2a/A2A/2e889e25b7ef61079a381a46cb870b3fdd4b3e98/docs/assets/a2a-mcp.png
--------------------------------------------------------------------------------
/docs/community.md:
--------------------------------------------------------------------------------
1 | ---
2 | hide:
3 | - navigation
4 | ---
5 |
6 | # Welcome to the A2A Community
7 |
8 | The **Agent2Agent (A2A) protocol** is generating significant buzz across the
9 | tech world, and for good reason! This open interoperability protocol is designed
10 | to enable **seamless collaboration between AI agents across diverse frameworks
11 | and vendors**. By standardizing communication, A2A aims to unlock complex
12 | workflows, enhance productivity, and foster a new era of **"Agent
13 | Interoperability"**. Don't just take our word for it – see what the community is
14 | saying!
15 |
16 | ## The Word on the Street: Social Highlights
17 |
18 | The launch of A2A has sparked lively discussions and positive reactions on various social platforms. Here's a glimpse of the excitement:
19 |
20 | - **Rapid Interest and Adoption:** The A2A [GitHub repository](https://github.com/google-a2a/A2A) has seen an **explosive surge in popularity**. This rapid interest underscores the industry's eagerness for a standardized agent communication protocol, with many companies collaborating and contributing.
21 |
22 | - **Microsoft's interest via Semantic Kernel:** [Asha Sharma](https://www.linkedin.com/in/aboutasha/), 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: a lightweight JSON-RPC protocol that lets agents swap context, not code or credentials, over plain HTTP. Drop it into your Foundry stack for instant, secure, async interoperability with any A2A-compliant agent, regardless of modality**". The post received numerous positive reactions, including "**A2A support in Semantic Kernel is a key unlock — context-level interoperability without sharing code or creds is how agent ecosystems scale securely across clouds**".
23 |
24 | - **Matt Pocock's Diagramming Intent:** [Matt Pocock](https://x.com/mattpocockuk), a well-known developer educator, [shared on X](https://x.com/mattpocockuk/status/1910002033018421400) "**I've just been reading the Agent2Agent technical docs - Google's new protocol for agent to agent communication. You know what that means. Let's diagram them:**". This tweet, liked and reposted hundreds of times, includes some great diagrams explaining the A2A protocol.
25 |
26 | - **Craig McLuckie's "Hot Take":** [Craig McLuckie](https://www.linkedin.com/in/craigmcluckie/) shared his initial thoughts on [LinkedIn](https://www.linkedin.com/posts/craigmcluckie_hot-take-on-agent2agent-vs-mcp-google-just-activity-7315939233792176128-4rGQ) "**Hot take on Agent2Agent vs MCP**". His post highlighted Google's careful positioning of A2A as focused on interactions _between_ agentic systems, rather than agents interacting with resources (the focus of MCP). This distinction is crucial for improving models' ability to understand expectations from other agents. McLuckie also pointed out the potential for A2A to enable systems to **advertise specific capabilities and specialities**, which is seen as "**sensible**".
27 |
28 | ## Community deep dive videos
29 |
30 | - [Zachary Huang](https://www.youtube.com/@ZacharyLLM) explains in his [YouTube video](https://www.youtube.com/watch?v=wrCF8MoXC_I), A2A "**complements**" MCP. While MCP acts as a "**USB-C port for AI applications**" connecting agents to tools, A2A acts as a communication standard **between the intelligent agents themselves**. This layered approach allows for building powerful systems where agents use A2A to coordinate and MCP to access necessary tools.
31 | - [Jack Herrington](https://www.youtube.com/@jherr) on his [YouTube video](https://www.youtube.com/watch?v=voaKr_JHvF4) walks through some of the provided examples and closes with his opinion that **"Having a specific protocol for agents to talk to other agents is valuable"** and reiterates, **"LLM plus tools are agents. MCP gives agents those tools. So that's why A2A and MCP play really nicely together**".
32 | - [Cole Medin](https://www.youtube.com/@ColeMedin) suggested on his [YouTube video](https://www.youtube.com/watch?v=ywMWpmOOaSo) that "**A2A was released very recently but it's already looking like it's going to follow a similar path**" to MCP in terms of growing interest. He also demonstrates the samples step by step and provides a summary of core concepts.
33 | - [Sam Witteveen](https://www.youtube.com/@samwitteveenai) covered A2A on his [YouTube video](https://www.youtube.com/watch?v=rAeqTaYj_aI) immediately after Google Cloud Next, discussing the value of making protocols open and not ending up with conflicting protocols.
34 |
35 | ## Community Contributions to A2A
36 |
37 | - Python Quickstart Tutorial [PR\#202](https://github.com/google-a2a/A2A/pull/202)
38 | - LlamaIndex submitted a sample implementation [PR\#179](https://github.com/google-a2a/A2A/pull/179)
39 | - Autogen sample server [PR\#232](https://github.com/google-a2a/A2A/pull/232)
40 | - AG2 \+ MCP example [PR\#230](https://github.com/google-a2a/A2A/pull/230)
41 | - PydanticAI example [PR\#127](https://github.com/google-a2a/A2A/pull/127)
42 | - Go example [PR\#52](https://github.com/google-a2a/A2A/pull/52)
43 | - Daytona sandbox running agent [PR\#170](https://github.com/google-a2a/A2A/pull/170)
44 |
45 | ## What is Driving This Excitement?
46 |
47 | The enthusiasm surrounding A2A stems from its potential to address key challenges in building sophisticated AI applications:
48 |
49 | - **Breaking Down Silos:** A2A aims to overcome the limitations of siloed AI systems by providing a **universal framework for agents built on different platforms to communicate and collaborate securely**.
50 |
51 | - **Enabling Complex Collaboration:** For tasks that require the expertise of multiple specialized agents, A2A provides a standardized way for them to **delegate tasks, exchange information, and coordinate actions**. This mirrors how human teams work together, distributing responsibilities for greater efficiency.
52 |
53 | - **Dynamic Agent Discovery:** A key feature of A2A is the ability for agents to **discover the capabilities of other agents** through standardized "**Agent Cards**". This dynamic discovery allows for more flexible and adaptable multi-agent systems.
54 |
55 | - **Complementary to MCP:** As stated on our [A2A ❤️ MCP topic page](topics/a2a-and-mcp.md) and affirmed by many community, A2A "**complements**" MCP. MCP acts as a communication standard between models and resources, providing tools for agents. A2A acts as a communication standard **between the intelligent agents themselves**. This layered approach allows for building powerful systems where agents use A2A to coordinate and MCP to access necessary tools.
56 |
57 | - **Open and Community-Driven:** Google has released A2A as **open source**, inviting contributions from the broader community to refine and expand its functionality. This commitment to open collaboration fosters innovation and broad adoption.
58 |
59 | ## The Future is Interoperable
60 |
61 | The social media buzz surrounding Google's A2A protocol clearly indicates a strong interest and belief in its potential to revolutionize the development of 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, efficiency, and innovation. As enterprises increasingly adopt AI agents for a wide range of tasks, A2A represents a crucial step towards realizing the full power of interconnected AI ecosystems.
62 |
63 | Stay tuned for more updates and join the growing community building the future of AI interoperability with A2A!
64 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | hide:
3 | - navigation
4 | - toc
5 | ---
6 |
7 | # Agent2Agent (A2A) Protocol
8 |
9 | {width="70%"}
10 | {style="text-align: center; margin-bottom:1em; margin-top:1em;"}
11 |
12 | ## Unlock Collaborative Agent Scenarios
13 |
14 | The **Agent2Agent (A2A) Protocol** is an open standard designed to enable seamless communication and collaboration between AI agents. In a world where agents are built using diverse frameworks and by different vendors, A2A provides a common language, breaking down silos and fostering interoperability.
15 |
16 | - [Blog Post: Announcing the Agent2Agent Protocol (A2A)](https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability/)
17 | - [Watch the A2A Demo Video](https://storage.googleapis.com/gweb-developer-goog-blog-assets/original_videos/A2A_demo_v4.mp4)
18 |
19 | {width="50%"}
20 | {style="text-align: center; margin-bottom:1em; margin-top:2em;"}
21 |
22 | ---
23 |
24 | ### Why A2A Matters
25 |
26 |
27 |
28 | - :material-account-group-outline:{ .lg .middle } **Interoperability**
29 |
30 | Connect agents built on different platforms (LangGraph, CrewAI, Semantic Kernel, custom solutions) to create powerful, composite AI systems.
31 |
32 | - :material-lan-connect:{ .lg .middle } **Complex Workflows**
33 |
34 | Enable agents to delegate sub-tasks, exchange information, and coordinate actions to solve complex problems that a single agent cannot.
35 |
36 | - :material-shield-key-outline:{ .lg .middle } **Secure & Opaque**
37 |
38 | Agents interact without needing to share internal memory, tools, or proprietary logic, ensuring security and preserving intellectual property.
39 |
40 |
41 |
42 | ---
43 |
44 | ### A2A and MCP: Complementary Protocols
45 |
46 | {width="60%"}
47 | {style="text-align: center; margin-bottom:1em; margin-top:1em;"}
48 |
49 | A2A and the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) are complementary standards for building robust agentic applications:
50 |
51 | - **MCP (Model Context Protocol):** Connects agents to **tools, APIs, and resources** with structured inputs/outputs. Think of it as the way agents access their capabilities.
52 | - **A2A (Agent2Agent Protocol):** Facilitates **dynamic, multimodal communication between different agents** as peers. It's how agents collaborate, delegate, and manage shared tasks.
53 |
54 | [Learn more about A2A and MCP](./topics/a2a-and-mcp.md)
55 |
56 | ---
57 |
58 | ### Get Started with A2A
59 |
60 |
61 |
62 | - :material-book-open:{ .lg .middle } **Read the Introduction**
63 |
64 | Understand the core ideas behind A2A.
65 |
66 | [:octicons-arrow-right-24: What is A2A?](./topics/what-is-a2a.md)
67 |
68 | [:octicons-arrow-right-24: Key Concepts](./topics/key-concepts.md)
69 |
70 | - :material-file-document-outline:{ .lg .middle } **Dive into the Specification**
71 |
72 | Explore the detailed technical definition of the A2A protocol.
73 |
74 | [:octicons-arrow-right-24: Protocol Specification](./specification.md)
75 |
76 | - :material-application-cog-outline:{ .lg .middle } **Follow the Tutorials**
77 |
78 | Build your first A2A-compliant agent with our step-by-step Python quickstart.
79 |
80 | [:octicons-arrow-right-24: Python Tutorial](./tutorials/python/1-introduction.md)
81 |
82 | - :material-code-braces:{ .lg .middle } **Explore Code Samples**
83 |
84 | See A2A in action with sample clients, servers, and agent framework integrations.
85 |
86 | [:fontawesome-brands-github: GitHub Samples](https://github.com/google-a2a/a2a-samples)
87 |
88 |
89 |
--------------------------------------------------------------------------------
/docs/llms.txt:
--------------------------------------------------------------------------------
1 | # A2A (Agent2Agent) Protocol High-Level Summary
2 |
3 | This project defines and demonstrates the **Agent2Agent (A2A) protocol**, an open standard initiated by Google designed to enable communication and interoperability between disparate AI agent systems. The core goal is to allow agents built on different frameworks (e.g., LangGraph, CrewAI, Google ADK, Genkit) or by different vendors to discover each other's capabilities, negotiate interaction modes (text, forms, files, potentially audio/video later), and collaborate on tasks.
4 |
5 | The repository provides:
6 |
7 | 1. **Formal Specification:** A detailed JSON Schema (`specification/json/a2a.json`) defining the structure of A2A messages, including requests, responses, task states, artifacts, and agent metadata (Agent Cards).
8 | 2. **Core Concepts Documentation (Implied):** Links in the main README suggest documentation covering agent discovery, task lifecycle, artifact exchange, streaming updates, push notifications, and enterprise readiness.
9 | 3. **Sample Implementations:**
10 | - **Common Libraries:** Reusable Python (`samples/python/common`) and JavaScript/TypeScript (`samples/js/src`) code for building A2A clients and servers, handling JSON-RPC communication, task management, and potentially authentication.
11 | - **Example Agents:** Demonstrations of integrating A2A into various agent frameworks:
12 | - **Python:** LangGraph (currency conversion, streaming), CrewAI (image generation, file artifacts), Google ADK (expense reports, form handling).
13 | - **JavaScript/TypeScript:** Genkit (movie info via API, code generation with file artifacts).
14 | - **Example Hosts:** Applications that *consume* A2A services:
15 | - CLIs in both Python and JS for direct interaction.
16 | - A Python-based multi-agent orchestrator (using Google ADK) that delegates tasks to other A2A agents.
17 | 4. **Demo Web Application:** A web UI (`demo/ui`, likely using Mesop) demonstrating multi-agent interactions facilitated by the A2A protocol, including visualization of conversations, tasks, events, and agent discovery. It features a backend service coordinating with the host agent.
18 |
19 | Key features of the A2A protocol highlighted by the specification and samples include: agent discovery via Agent Cards, standardized task management (send, get, cancel), support for different content types (text, files, structured data) via `Parts` and `Artifacts`, streaming updates for long-running tasks, and mechanisms for push notifications. The project is open source and encourages community contribution.
20 |
21 | # A2A (Agent2Agent) Protocol
22 |
23 | ## 1. Overview
24 |
25 | - **Project Name:** Agent2Agent (A2A) Protocol
26 | - **Purpose:** An open protocol by Google enabling communication and interoperability between AI agents built on different frameworks or by different vendors.
27 | - **Core Goal:** Allow agents to discover capabilities, negotiate interaction, and collaborate securely on tasks.
28 | - **Communication:** Uses JSON-RPC 2.0 over HTTP(S). Supports standard request/response and Server-Sent Events (SSE) for streaming.
29 | - **Key Components:** Specification (JSON Schema), Common Libraries (Python, JS/TS), Sample Agents (LangGraph, CrewAI, ADK, Genkit), Sample Hosts (CLI, Orchestrator), Demo Web App (Mesop).
30 |
31 | ## 2. Protocol Specification (`specification/json/a2a.json`)
32 |
33 | ### 2.1. Core JSON-RPC Structures
34 |
35 | - **`JSONRPCMessage`:** Base for requests/responses. Contains `jsonrpc: "2.0"` and optional `id`.
36 | - **`JSONRPCRequest`:** Represents a request.
37 | - `method`: String identifying the operation (e.g., "tasks/send").
38 | - `params`: Object or Array containing parameters for the method.
39 | - `id`: Unique identifier (string/number) for request/response correlation. Omitted/null for notifications.
40 | - **`JSONRPCResponse`:** Represents a response.
41 | - `result`: Contains the successful result data (can be `null`). Mutually exclusive with `error`.
42 | - `error`: Contains an error object if the request failed. Mutually exclusive with `result`.
43 | - `id`: Must match the corresponding request `id`.
44 | - **`JSONRPCError`:** Represents an error.
45 | - `code`: Integer error code.
46 | - `message`: String description of the error.
47 | - `data`: Optional additional error details.
48 |
49 | ### 2.2. Key A2A Data Objects
50 |
51 | - **`AgentCard`:** Metadata describing an agent. Found typically at `/.well-known/agent.json`.
52 | - `name`: (string) Human-readable name.
53 | - `description`: (string) Agent description.
54 | - `url`: (string) Base URL endpoint for the agent's A2A service.
55 | - `provider`: (`AgentProvider`) Organization details (optional).
56 | - `version`: (string) Agent/API version.
57 | - `documentationUrl`: (string) Link to documentation (optional).
58 | - `capabilities`: (`AgentCapabilities`) Features supported (streaming, push).
59 | - `securitySchemes`: (Object) Security scheme details for authentication (optional).
60 | - `security`: (Array) Security requirements for contacting the agent (optional).
61 | - `defaultInputModes`: (string[]) Default supported input types (e.g., "text/plain", "application/json").
62 | - `defaultOutputModes`: (string[]) Default supported output types.
63 | - `skills`: (`AgentSkill[]`) List of specific capabilities.
64 | - `supportsAuthenticatedExtendedCard`: (boolean) Indicates support for retrieving a more detailed Agent Card via an authenticated endpoint (optional).
65 | - **`AgentCapabilities`:**
66 | - `streaming`: (boolean) Supports `message/stream` and `tasks/resubscribe` for real-time updates via Server-Sent Events (SSE). Default: `false`.
67 | - `pushNotifications`: (boolean) Supports `tasks/pushNotificationConfig/set|get` for asynchronous task updates via webhooks. Default: `false`.
68 | - `stateTransitionHistory`: (boolean) Supports providing detailed history of status changes within the Task object (future enhancement). Default: `false`.
69 | - **`AgentSkill`:**
70 | - `id`: (string) Unique skill ID within this agent.
71 | - `name`: (string) Human-readable skill name.
72 | - `description`: (string) Detailed skill description. CommonMark may be used.
73 | - `tags`: (string[]) Keywords/categories for discoverability.
74 | - `examples`: (string[]) Example prompts or use cases demonstrating skill usage (optional).
75 | - `inputModes`: (string[]) Overrides `defaultInputModes` for this specific skill. Accepted Media Types (optional).
76 | - `outputModes`: (string[]) Overrides `defaultOutputModes` for this specific skill. Produced Media Types (optional).
77 | - **`Task`:** Represents a unit of work processed by an agent.
78 | - `id`: (string) Unique task identifier.
79 | - `contextId`: (string) Groups related tasks in a conversation or session.
80 | - `status`: (`TaskStatus`) Current state information.
81 | - `artifacts`: (`Artifact[]`) Files/data produced by the agent (optional).
82 | - `history`: (`TaskStatus[]`) Status transition history (optional, requires `stateTransitionHistory` capability).
83 | - `metadata`: (object) Custom key-value data for client use (optional).
84 | - `kind`: ("task") Type discriminator.
85 | - **`TaskStatus`:**
86 | - `state`: (`TaskState`) Current lifecycle state (enum).
87 | - `message`: (string) Human-readable status message (optional).
88 | - `timestamp`: (string) ISO-8601 timestamp of when this status was set.
89 | - `kind`: ("status") Type discriminator.
90 | - **`TaskState`:** (enum)
91 | - `submitted`: Task received but not yet processing (non-terminal).
92 | - `working`: Task is actively being processed (non-terminal).
93 | - `input_required`: Task requires additional input from the client to proceed (non-terminal).
94 | - `completed`: Task completed successfully (terminal).
95 | - `failed`: Task encountered an error (terminal).
96 | - `canceled`: Task was canceled by client request (terminal).
97 | - `rejected`: Task was rejected by the agent (terminal).
98 | - `auth-required`: Authentication required from client/user to proceed (non-terminal).
99 | - `unknown`: Task state cannot be determined (terminal).
100 | - **`Message`:** Communication unit between user and agent.
101 | - `role`: ("user" | "agent") Sender role.
102 | - `parts`: (`Part[]`) Content parts (text, file, data).
103 | - `metadata`: (object | null) Message-specific metadata.
104 | - `messageId`: (string) Unique identifier for the message.
105 | - `parentMessageId`: (string) Reference to a previous message being replied to (optional).
106 | - `rootMessageId`: (string) Reference to the first message in a thread (optional).
107 | - `referenceTaskIds`: (string[]) List of tasks referenced as contextual hint by this message (optional).
108 | - `taskId`: (string) Task identifier the current message is related to (optional).
109 | - `contextId`: (string) Context identifier the message is associated with (optional).
110 | - `kind`: ("message") Type discriminator.
111 | - **`Part` (Union Type):** Represents a piece of content within a Message or Artifact.
112 | - **`TextPart`:**
113 | - `type`: "text"
114 | - `text`: (string) Text content.
115 | - `mimeType`: (string) Format specification (default: "text/plain").
116 | - **`FilePart`:**
117 | - `type`: "file"
118 | - `file`: (`FileWithUri`) File reference with URI.
119 | - `inline`: (boolean) Whether the file content should be displayed inline (optional).
120 | - **`DataPart`:**
121 | - `type`: "data"
122 | - `data`: (any) Structured data in JSON-serializable format.
123 | - `mimeType`: (string) Format specification (e.g., "application/json").
124 | - `inline`: (boolean) Whether the data should be displayed inline (optional).
125 | - `metadata`: (object | null) Optional metadata for the specific part.
126 | - **`FileWithUri`:** Represents a file reference with URI.
127 | - `name`: (string) Filename with extension.
128 | - `mimeType`: (string) Content type (Media Type).
129 | - `uri`: (string) URI to access the file content.
130 | - **`Artifact`:** An output generated by a task.
131 | - `artifactId`: (string) Unique identifier for the artifact.
132 | - `name`: (string) Human-readable artifact name (optional).
133 | - `description`: (string) Detailed description of the artifact (optional).
134 | - `parts`: (`Part[]`) Content segments in the artifact.
135 | - `metadata`: (object) Custom key-value data (optional).
136 | - `kind`: ("artifact") Type discriminator.
137 | - **`AuthenticationInfo`:** Authentication details for push notifications.
138 | - `schemes`: (string[]) Array of authentication scheme names the caller must use.
139 | - `credentials`: (string) Optional static credentials or scheme-specific configuration info.
140 | - **`PushNotificationConfig`:** Configuration for push notifications.
141 | - `url`: (string) Endpoint URL for the agent to POST notifications to.
142 | - `token`: (string) Optional authentication token for the agent to include in requests (optional).
143 | - `authentication`: (`AuthenticationInfo`) Authentication details the agent needs to call the URL (optional).
144 | - **`TaskPushNotificationConfig`:** Associates a `PushNotificationConfig` with a task ID.
145 | - `taskId`: (string) The task ID to receive push notifications for.
146 | - `config`: (`PushNotificationConfig`) The push notification configuration to use.
147 | - `metadata`: (object) Custom key-value data for client use (optional).
148 | - **`MessageSendParams`:** Parameters for sending a message.
149 | - `message`: (`Message`) The message to send.
150 | - `configuration`: (`MessageSendConfiguration`) Optional configuration for the message.
151 | - `metadata`: (object) Custom key-value data for client use (optional).
152 | - **`agent/authenticatedExtendedCard`:** (HTTP GET)
153 | - Retrieves a potentially more detailed version of the Agent Card after the client has authenticated.
154 | - Available only if `AgentCard.supportsAuthenticatedExtendedCard` is `true`.
155 | - Endpoint URL: `{AgentCard.url}/../agent/authenticatedExtendedCard`
156 | - Authentication: Required using one of the schemes declared in the public `AgentCard.securitySchemes`.
157 | - Response: Complete `AgentCard` object with potentially additional details.
158 |
159 | ### 2.3. A2A RPC Methods
160 |
161 | - **`message/send`:** (Request/Response)
162 | - Sends a message to initiate or continue a task.
163 | - `params`: `MessageSendParams` (includes `taskId`, `contextId`, `message`, optionally `configuration`).
164 | - `result`: `Task` (final state after synchronous processing).
165 | - **`message/stream`:** (Request/Stream)
166 | - Sends a message and subscribes to real-time updates via Server-Sent Events (SSE).
167 | - `params`: `MessageSendParams`.
168 | - `result` (stream events): `SendStreamingMessageResponse` containing one of: `MessageEvent`, `TaskStatusUpdateEvent`, `TaskArtifactUpdateEvent`. Final event has `final: true`.
169 | - **`tasks/get`:** (Request/Response)
170 | - Retrieves the current state of a task.
171 | - `params`: `TaskQueryParams` (includes `id`, optionally `historyLength`).
172 | - `result`: `Task`.
173 | - **`tasks/cancel`:** (Request/Response)
174 | - Requests cancellation of a running task.
175 | - `params`: `TaskIdParams` (includes `id`).
176 | - `result`: `Task` (updated state, likely 'canceled') or error if not cancelable.
177 | - **`tasks/pushNotificationConfig/set`:** (Request/Response)
178 | - Sets or updates the push notification configuration for a task.
179 | - `params`: `TaskPushNotificationConfig`.
180 | - `result`: `TaskPushNotificationConfig` (confirmed configuration).
181 | - **`tasks/pushNotificationConfig/get`:** (Request/Response)
182 | - Retrieves the current push notification configuration for a task.
183 | - `params`: `TaskIdParams` (includes `taskId`).
184 | - `result`: `TaskPushNotificationConfig`.
185 | - **`tasks/resubscribe`:** (Request/Stream)
186 | - Resubscribes to task updates after a connection interruption (SSE).
187 | - `params`: `TaskQueryParams`.
188 | - `result` (stream events): `TaskStatusUpdateEvent` or `TaskArtifactUpdateEvent`.
189 |
190 | ### 2.4. Streaming Update Events (Result of `message/stream` or `tasks/resubscribe`)
191 |
192 | - **`SendStreamingMessageResponse`:** Contains a message from the agent.
193 | - `type`: "message"
194 | - `message`: (`Message`) The message content.
195 | - `contextId`: (string) Context identifier the message is associated with.
196 | - `kind`: ("streaming-response") Type discriminator.
197 | - `final`: (boolean) True if this is the final message for the task.
198 | - **`TaskStatusUpdateEvent`:** Signals a change in task status.
199 | - `type`: "task-status"
200 | - `taskId`: (string) Task ID.
201 | - `contextId`: (string) Context identifier the task is associated with.
202 | - `kind`: ("status-update") Type discriminator.
203 | - `status`: (`TaskStatus`) The new status object.
204 | - `final`: (boolean) True if this is the terminal update for the task.
205 | - **`TaskArtifactUpdateEvent`:** Signals a new or updated artifact.
206 | - `type`: "task-artifact"
207 | - `taskId`: (string) Task ID.
208 | - `artifact`: (`Artifact`) The artifact data.
209 | - `append`: (boolean) If true, append parts to artifact; if false (default), replace.
210 | - `lastChunk`: (boolean) If true, indicates this is the final update for the artifact.
211 | - `final`: (boolean) Usually false for artifacts, can signal end concurrently with status.
212 |
213 | ### 2.5. Standard Error Codes
214 |
215 | - `-32700`: `JSONParseError` - Invalid JSON payload.
216 | - `-32600`: `InvalidRequestError` - Invalid JSON-RPC request object.
217 | - `-32601`: `MethodNotFoundError` - Method does not exist.
218 | - `-32602`: `InvalidParamsError` - Invalid method parameters.
219 | - `-32603`: `InternalError` - Internal server error.
220 |
221 | ### 2.6. A2A Specific Error Codes
222 |
223 | - `-32001`: `TaskNotFoundError` - Specified task ID not found.
224 | - `-32002`: `TaskNotCancelableError` - Task is in a terminal state and cannot be canceled.
225 | - `-32003`: `PushNotificationNotSupportedError` - Agent does not support push notifications.
226 | - `-32004`: `UnsupportedOperationError` - The requested operation is not supported.
227 | - `-32005`: `ContentTypeNotSupportedError` - Mismatch in supported content types.
228 | - `-32006`: `InvalidAgentResponseError` - Agent generated an invalid response for the requested method.
229 |
230 | ## 3. Core Concepts
231 |
232 | - **Agent Discovery:** Clients find agents and their capabilities by fetching the `AgentCard` JSON, typically from `/.well-known/agent.json`.
233 | - **Task Lifecycle:** Tasks progress through states defined in `TaskState` (submitted -> working -> [input_required] -> completed/failed/canceled/rejected/unknown).
234 | - **Communication:** Uses `Message` objects containing `Part`s (text, file, data). Task outputs are represented as `Artifact`s, also containing `Part`s.
235 | - **Streaming:** Long-running tasks can provide real-time updates using Server-Sent Events (SSE) via `message/stream`. Updates are sent as `MessageEvent`, `TaskStatusUpdateEvent` and `TaskArtifactUpdateEvent`. Reconnection after interruptions is supported via `tasks/resubscribe`.
236 | - **Push Notifications:** Agents can proactively notify clients about task updates using webhook URLs provided via `tasks/pushNotificationConfig/set`. Authentication mechanisms (e.g., Bearer tokens via JWT signed with keys from agent's JWKS endpoint) are supported for secure communication.
237 | - **Authentication:** Defined in `AgentCard` (via `securitySchemes` and `security` fields) and `PushNotificationConfig`. Can involve various schemes (e.g., API keys, OAuth, JWT). The protocol supports authenticated extended Agent Card retrieval via the `agent/authenticatedExtendedCard` endpoint. Samples use JWT for push notifications and secure communication.
238 | - **Forms:** Structured data can be requested and submitted using `DataPart` within Messages/Artifacts (demonstrated in ADK sample).
239 |
240 | ## 4. Security Considerations
241 |
242 | - **Transport Security:** Always use HTTPS with strong TLS configurations in production environments.
243 | - **Authentication:**
244 | - Handled via standard HTTP mechanisms (e.g., `Authorization` header with Bearer tokens, API keys).
245 | - Requirements are declared in the `AgentCard`.
246 | - Credentials MUST be obtained out-of-band by the client.
247 | - A2A Servers MUST authenticate every request.
248 | - **Authorization:**
249 | - A server-side responsibility based on the authenticated identity.
250 | - Implement the principle of least privilege.
251 | - Can be granular, based on skills, actions, or data.
252 | - **Push Notification Security:**
253 | - Webhook URL validation (by the A2A Server sending notifications) is crucial to prevent SSRF.
254 | - Authentication of the A2A Server to the client's webhook is essential.
255 | - Authentication of the notification by the client's webhook receiver (verifying it came from the legitimate A2A Server and is relevant) is critical.
256 | - **Input Validation:** Servers MUST rigorously validate all RPC parameters and the content/structure of data in `Message` and `Artifact` parts to prevent injection attacks or processing errors.
257 | - **Resource Management:** Implement rate limiting, concurrency controls, and resource limits to protect agents from abuse or overload.
258 | - **Data Privacy:** Adhere to all applicable privacy regulations for data exchanged in `Message` and `Artifact` parts. Minimize sensitive data transfer.
259 |
260 | ## 4. Implementations & Samples
261 |
262 | ### 4.1. Common Libraries
263 |
264 | - **Python (`samples/python/common`)**:
265 | - `client/`: `A2AClient` for making requests, `A2ACardResolver` for discovery.
266 | - `server/`: `A2AServer` (Starlette-based), `TaskManager` base class, `InMemoryTaskManager`.
267 | - `types.py`: Pydantic models mirroring the JSON schema.
268 | - `utils/`: Helpers for push notification auth (JWT signing/verification, JWKS endpoint).
269 | - **JavaScript/TypeScript (`samples/js/src`)**:
270 | - `client/`: `A2AClient` implementation using `fetch`.
271 | - `server/`: `A2AServer` (Express-based), `TaskStore` interface, `InMemoryTaskStore`, `FileStore`.
272 | - `schema.ts`: TypeScript interfaces matching the JSON schema.
273 | - `handler.ts`, `error.ts`, `utils.ts`: Support code for the server.
274 |
275 | ### 4.2. Python Samples
276 |
277 | - **Location:** `samples/python/agents/` & `samples/python/hosts/`
278 | - **Setup:** Uses `uv` and `pyproject.toml`. Requires Python >= 3.12/3.13. API keys via `.env`.
279 | - **Agents:**
280 | - **LangGraph (`agents/langgraph`)**: Currency conversion agent. Demonstrates tool use, multi-turn (`input-required`), and **streaming** (`tasks/sendSubscribe`).
281 | - **CrewAI (`agents/crewai`)**: Image generation agent. Demonstrates multi-turn and handling **file artifacts** (images).
282 | - **Google ADK (`agents/google_adk`)**: Expense reimbursement agent. Demonstrates multi-turn and handling **forms** using `DataPart`.
283 | - **Hosts:**
284 | - **CLI (`hosts/cli`)**: Simple command-line client to interact with any A2A agent. Supports streaming and optional push notification listening.
285 | - **Multi-Agent Orchestrator (`hosts/multiagent`)**: An ADK-based "Host Agent" that manages connections (`RemoteAgentConnections`) to other A2A agents and delegates tasks based on instructions.
286 |
287 | ### 4.3. JavaScript/TypeScript Samples
288 |
289 | - **Location:** `samples/js/`
290 | - **Setup:** Uses `npm`/`pnpm`, `tsx`, `tsconfig.json`. Requires Node.js >= 18. API keys via environment variables. Framework: **Genkit**.
291 | - **Agents (`src/agents/`)**:
292 | - **Movie Agent (`movie-agent`)**: Uses TMDB API via Genkit tools to answer movie questions. Demonstrates tool use and multi-turn (`AWAITING_USER_INPUT` mapped to `input-required`).
293 | - **Coder Agent (`coder`)**: Generates code files. Demonstrates producing multiple **file artifacts** via streaming updates. Uses custom Genkit format (`code-format.ts`).
294 | - **Hosts:**
295 | - **CLI (`src/cli.ts`)**: Command-line client for interacting with JS agents.
296 |
297 | ### 4.4. Demo Application (`demo/`)
298 |
299 | - **UI (`demo/ui`)**: Web application built with **Mesop**.
300 | - Visualizes conversations with multiple agents via the host orchestrator.
301 | - Renders text, images, forms.
302 | - Allows dynamic agent registration via URL.
303 | - Provides views for task list and event logs.
304 | - **Service (`demo/ui/service`)**: Backend service for the Mesop UI.
305 | - `server/`: Manages conversations, routes messages, interfaces with the host agent (`ADKHostManager` or `InMemoryFakeAgentManager`).
306 | - `client/`: Client used by the UI to talk to its *own* backend service.
307 |
308 | ## 5. Development & Setup
309 |
310 | - **Prerequisites:** Python (>=3.12 or 3.13), Node.js (>=18), `uv` (for Python), `npm`/`pnpm` (for JS).
311 | - **API Keys:** Required for LLM access (e.g., `GOOGLE_API_KEY`, `TMDB_API_KEY`), typically set via `.env` files or environment variables.
312 | - **Running Samples:** Generally involves running an agent server (`uv run ...` or `npm run ...`) and then a host client/app (e.g., `uv run hosts/cli --agent `).
313 |
314 | ## 6. Contribution
315 |
316 | - See `CONTRIBUTING.md`.
317 | - GitHub discussion available as the primary means of communication.
318 | - GitHub issues for bugs and feature requests.
319 | - Google Form for private feedback.
320 |
--------------------------------------------------------------------------------
/docs/partners.md:
--------------------------------------------------------------------------------
1 | ---
2 | hide:
3 | - navigation
4 | ---
5 |
6 | # Partners
7 |
8 | Below is a list of partners (and a link to their A2A announcement or blog post,
9 | if available) who are part of the A2A community and are helping build, codify,
10 | and adopt A2A as the standard protocol for AI agents to communicate and
11 | collaborate effectively with each other and with users.
12 |
13 | !!! note
14 |
15 | If you're interested in becoming a partner of A2A and getting your listing added to or updated on this page, let us know by [submitting this form](https://forms.gle/BuQQ2zvXfFUA1bu98), and we'll contact you soon!
16 |
17 | - [Accelirate Inc](https://www.accelirate.com)
18 | - [Accenture](https://www.accenture.com)
19 | - [Activeloop](https://www.activeloop.ai/)
20 | - [Adobe](https://www.adobe.com)
21 | - [AI21 Labs](https://www.ai21.com/)
22 | - [AI71](https://ai71.ai/)
23 | - [Aisera](https://aisera.com/)
24 | - [Almawave.it](http://www.almawave.it)
25 | - [AliCloud](http://www.alibabacloud.com)
26 | - [ArcBlock](http://www.arcblock.io)
27 | - [Arize](https://arize.com/blog/arize-ai-and-future-of-agent-interoperability-embracing-googles-a2a-protocol/)
28 | - [Articul8](https://www.articul8.ai/news/unleashing-the-next-frontier-of-enterprise-ai-introducing-model-mesh-dock-and-inter-lock-and-our-a2-a-partnership-with-google)
29 | - [ask-ai.com](https://ask-ai.com)
30 | - [Atlassian](https://www.atlassian.com)
31 | - [Auth0](https://auth0.com/blog/auth0-google-a2a/)
32 | - [Autodesk](https://www.autodesk.com)
33 | - [Beekeeper](http://beekeeper.io)
34 | - [BCG](https://www.bcg.com)
35 | - [Block Inc](https://block.xyz/)
36 | - [Bloomberg LP](http://techatbloomberg.com/)
37 | - [BLUEISH Inc](https://www.blueish.co.jp/)
38 | - [BMC Software Inc](https://www.bmc.com/it-solutions/bmc-helix.html)
39 | - [Boomi](https://boomi.com/)
40 | - [Box](https://www.box.com)
41 | - [Bridge2Things Automation Process GmbH](http://bridge2things.at)
42 | - [Cafe 24](https://www.cafe24corp.com/en/company/about)
43 | - [C3 AI](https://c3.ai)
44 | - [Capgemini](https://www.capgemini.com)
45 | - [Chronosphere](https://chronosphere.io)
46 | - [Codimite PTE LTD](https://codimite.ai/)
47 | - [Cognigy](https://www.cognigy.com/)
48 | - [Cognizant](https://www.cognizant.com)
49 | - [Cohere](https://cohere.com)
50 | - [Collibra](https://www.collibra.com)
51 | - [Confluent](https://developer.confluent.io)
52 | - [Contextual](https://contextual.ai)
53 | - [Cotality](https://cotality.com) (fka Corelogic)
54 | - [Crubyt](https://www.crubyt.com)
55 | - [Cyderes](http://www.cyderes.com)
56 | - [Datadog](https://www.datadoghq.com)
57 | - [DataRobot](https://www.datarobot.com)
58 | - [DataStax](https://www.datastax.com)
59 | - [Decagon.ai](https://decagon.ai)
60 | - [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)
61 | - [Devnagri](https://devnagri.com)
62 | - [Deutsche Telekom](https://www.telekom.com/en)
63 | - [Dexter Tech Labs](http://www.dextertechlabs.com)
64 | - [Distyl.ai](https://distyl.ai)
65 | - [Elastic](https://www.elastic.co)
66 | - [Ema.co](https://ema.co)
67 | - [EPAM](https://www.epam.com)
68 | - [Eviden (Atos Group)](https://atos.net/)
69 | - [fractal.ai](https://fractal.ai/new)
70 | - [GenAI Nebula9.ai Solutions Pvt Ltd](http://nebula9.ai)
71 | - [Glean](https://www.glean.com)
72 | - [Global Logic](https://www.globallogic.com/)
73 | - [Gravitee](https://www.gravitee.io/)
74 | - [GrowthLoop](https://growthloop.com)
75 | - [Guru](http://www.getguru.com)
76 | - [Harness](https://harness.io)
77 | - [HCLTech](https://www.hcltech.com)
78 | - [Headwaters](https://www.headwaters.co.jp)
79 | - [Hellotars](https://hellotars.com)
80 | - [Hexaware](https://hexaware.com/)
81 | - [HUMAN](https://www.humansecurity.com/)
82 | - [Incorta](https://www.incorta.com)
83 | - [InfoSys](https://www.infosys.com)
84 | - [Intuit](https://www.intuit.com)
85 | - [Iron Mountain](https://www.ironmountain.com/)
86 | - [JetBrains](https://www.jetbrains.com)
87 | - [JFrog](https://jfrog.com)
88 | - [King's College London](https://www.kcl.ac.uk/informatics)
89 | - [KPMG](https://kpmg.com/us/en/media/news/kpmg-google-cloud-alliance-expansion-agentspace-adoption.html)
90 | - [Kyndryl](http://www.kyndryl.com)
91 | - [LabelBox](https://labelbox.com)
92 | - [LangChain](https://www.langchain.com)
93 | - [LG CNS](http://www.lgcns.com)
94 | - [Livex.ai](https://livex.ai)
95 | - [LlamaIndex](https://x.com/llama_index/status/1912949446322852185)
96 | - [LTIMindTtree](https://www.ltimindtree.com)
97 | - [Lumeris](https://www.lumeris.com/)
98 | - [Lyzr.ai](https://lyzr.ai)
99 | - [Magyar Telekom](https://www.telekom.hu/)
100 | - [Microsoft](https://www.microsoft.com/en-us/microsoft-cloud/blog/2025/05/07/empowering-multi-agent-apps-with-the-open-agent2agent-a2a-protocol/)
101 | - [McKinsey](https://www.mckinsey.com)
102 | - [MongoDB](https://www.mongodb.com)
103 | - [Neo4j](https://neo4j.com)
104 | - [New Relic](https://newrelic.com)
105 | - [Nisum](http://www.nisum.com)
106 | - [Noorle Inc](http://www.noorle.com)
107 | - [Optimizely Inc](https://www.optimizely.com/)
108 | - [Oracle / NetSuite](https://www.oracle.com/netsuite)
109 | - [PancakeAI](https://www.pancakeai.tech/)
110 | - [Pendo](https://www.pendo.io)
111 | - [PerfAI.ai](https://perfai.ai)
112 | - [Personal AI](https://personal.ai)
113 | - [Productive Edge](https://www.productiveedge.com/)
114 | - [Proofs](https://proofs.io)
115 | - [Publicis Sapient](https://www.publicissapient.com/)
116 | - [PWC](https://www.pwc.com)
117 | - [Quantiphi](https://www.quantiphi.com)
118 | - [Radix](https://radix.website/)
119 | - [RagaAI Inc](https://raga.ai/)
120 | - [Red Hat](https://www.redhat.com)
121 | - [Reltio Inc](http://www.reltio.com)
122 | - [S&P](https://www.spglobal.com)
123 | - [Sage](https://www.sage.com/en-us/)
124 | - [Salesforce](https://www.salesforce.com)
125 | - [SAP](https://news.sap.com/2025/04/sap-google-cloud-enterprise-ai-open-agent-collaboration-model-choice-multimodal-intelligence/)
126 | - [Sayone Technologies](https://www.sayonetech.com/)
127 | - [ServiceNow](https://www.servicenow.com)
128 | - [Siemens AG](https://siemens.com/)
129 | - [SoftBank Corp](https://www.softbank.jp/en//)
130 | - [Solace](https://solace.com/products/agent-mesh/)
131 | - [Stacklok, Inc](https://stacklok.com)
132 | - [Supertab](https://www.supertab.co/post/supertab-connect-partners-with-google-cloud-to-enable-ai-agents)
133 | - [Suzega](https://suzega.com/)
134 | - [TCS](https://www.tcs.com)
135 | - [Tech Mahindra](https://www.techmahindra.com/)
136 | - [Test Innovation Technology](https://www.test-it.com)
137 | - [the artinet project](https://artinet.io/)
138 | - [Think41](http://www.think41.com)
139 | - [Thoughtworks](https://www.thoughtworks.com/)
140 | - [Tredence](http://www.tredence.com)
141 | - [Two Tall Totems Ltd. DBA TTT Studios](https://ttt.studio)
142 | - [Typeface](https://typeface.ai)
143 | - [UKG](https://www.ukg.com)
144 | - [UiPath](https://www.uipath.com/newsroom/uipath-launches-first-enterprise-grade-platform-for-agentic-automation)
145 | - [Upwork, Inc.](https://www.upwork.com/)
146 | - [Ushur, Inc.](http://ushur.ai)
147 | - [Valle AI](http://www.valleai.com.br)
148 | - [Valtech](https://www.valtech.com/)
149 | - [Vervelo](https://www.vervelo.com/)
150 | - [VoltAgent](https://voltagent.dev/)
151 | - [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)
152 | - [Wipro](https://www.wipro.com)
153 | - [Workday](https://www.workday.com)
154 | - [Writer](https://writer.com)
155 | - [Zenity](https://zenity.io)
156 | - [Zeotap](https://www.zeotap.com)
157 | - [Zocket Technologies , Inc.](https://zocket.ai)
158 | - [Zoom](https://www.zoom.us)
159 | - [zyprova](http://www.zyprova.com)
160 |
--------------------------------------------------------------------------------
/docs/robots.txt:
--------------------------------------------------------------------------------
1 | # robots.txt for the A2A open-source project documentation site on Google GitHub Pages
2 | # This file guides web crawlers on which parts of the site to crawl and index.
3 |
4 | # Apply these rules to all web crawlers for maximum discoverability
5 | User-agent: *
6 |
7 | # Allow crawling of all public content by default.
8 | # We'll explicitly disallow specific paths below that aren't meant for public indexing.
9 |
10 | # Disallow common build, temporary, and configuration directories/files
11 | Disallow: /_site/ # Common Jekyll build directory
12 | Disallow: /_temp/ # General temporary directory
13 | Disallow: /build/ # General build output directory
14 | Disallow: /dist/ # Distribution/output directory
15 | Disallow: /.cache/ # Caching directory
16 | Disallow: /.git/ # Git repository files (if somehow exposed by accident)
17 | Disallow: /.github/ # GitHub Actions workflows and internal configuration files
18 | Disallow: /node_modules/ # Node.js dependencies (often large and irrelevant for indexing)
19 | Disallow: /vendor/ # Third-party libraries or assets
20 |
21 | # Disallow common configuration files that are not part of the public documentation
22 | Disallow: /_config.yml # Jekyll configuration file
23 | Disallow: /package.json # Node.js package configuration
24 | Disallow: /package-lock.json # Node.js package lock file
25 | Disallow: /yarn.lock # Yarn package lock file
26 |
27 | # Disallow specific file types that are often internal, temporary, or not meant for indexing
28 | Disallow: /*.bak$ # Backup files
29 | Disallow: /*.tmp$ # Temporary files
30 | Disallow: /*.log$ # Log files
31 | Disallow: /*.swp$ # Vim swap files
32 |
33 | # Disallow draft content if your static site generator supports it and these are not published
34 | Disallow: /_drafts/
35 |
36 | # Specify the location of your XML sitemap.
37 | # This helps search engines discover all the pages on your site.
38 | Sitemap: https://google-a2a.github.io/A2A/sitemap.xml
39 |
--------------------------------------------------------------------------------
/docs/sdk/python/index.md:
--------------------------------------------------------------------------------
1 | # Python SDK Reference
2 |
3 | This page contains SDK documentation for the [`a2a-sdk`](https://github.com/google-a2a/a2a-python) Python package.
4 |
5 | ```sh
6 | pip install a2a-sdk
7 | ```
8 |
9 | ::: a2a
10 | options:
11 | show_root_heading: false
12 | show_source: false
13 | show_submodules: true
14 | members_order: alphabetical
15 | inherited_members: true
16 |
17 |
22 |
--------------------------------------------------------------------------------
/docs/stylesheets/custom.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2025 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /* Index page styling */
18 |
19 | .md-grid {
20 | max-width: 80%;
21 | }
22 |
23 | .footer {
24 | padding-bottom: 30vh;
25 | }
26 |
27 | .centered-logo-text-group {
28 | display: inline-flex;
29 | align-items: center;
30 | gap: 1.5em;
31 | margin-bottom: 0.5em;
32 | vertical-align: middle;
33 | }
34 |
35 | .centered-logo-text-group img {
36 | height: auto;
37 | }
38 |
39 | .centered-logo-text-group h1 {
40 | margin: 0;
41 | text-align: left;
42 | }
43 |
44 | .install-command-container {
45 | max-width: 600px;
46 | margin: 2.5em auto;
47 | padding: 1.5em 2em;
48 | background-color: var(--md-code-bg-color, #f5f5f5);
49 | border-radius: 8px;
50 | text-align: center;
51 | box-shadow: 0 3px 6px rgb(0 0 0 / 5%);
52 | border-left: 5px solid var(--md-primary-fg-color, #526cfe);
53 | margin-top: 30px;
54 | }
55 |
56 | .install-command-container p {
57 | font-size: 1.1em;
58 | color: var(--md-default-fg-color);
59 | margin-bottom: -10px;
60 | margin-top: -10px;
61 | }
62 |
63 | .install-command-container p code {
64 | font-size: 1.1em;
65 | font-weight: 600;
66 | padding: 0.3em 0.6em;
67 | background-color: var(--md-code-fg-color--light);
68 | border-radius: 4px;
69 | display: inline-block;
70 | line-height: 1.4;
71 | }
72 |
--------------------------------------------------------------------------------
/docs/topics/a2a-and-mcp.md:
--------------------------------------------------------------------------------
1 | # A2A and MCP: Complementary Protocols for Agentic Systems
2 |
3 | ## A2A ❤️ MCP
4 |
5 | In the landscape of AI agent development, two key types of protocols are emerging to facilitate interoperability: those for connecting agents to **tools and resources**, and those for enabling **agent-to-agent collaboration**. The Agent2Agent (A2A) Protocol and the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) address these distinct but related needs.
6 |
7 | **TL;DR;** Agentic applications need both A2A and MCP. We recommend MCP for tools and A2A for agents.
8 |
9 | ## Why Different Protocols?
10 |
11 | The distinction arises from the nature of what an agent interacts with:
12 |
13 | - **Tools & Resources:**
14 |
15 | - These are typically primitives with well-defined, structured inputs and outputs. They perform specific, often stateless, functions (e.g., a calculator, a database query API, a weather lookup service).
16 | - Their behavior is generally predictable and transactional.
17 | - Interaction is often a single request-response cycle.
18 |
19 | - **Agents:**
20 | - These are more autonomous systems. They can reason, plan, use multiple tools, maintain state over longer interactions, and engage in complex, often multi-turn dialogues to achieve novel or evolving tasks.
21 | - Their behavior can be emergent and less predictable than a simple tool.
22 | - Interaction often involves ongoing tasks, context sharing, and negotiation.
23 |
24 | Agentic applications need to leverage both: agents use tools to gather information and perform actions, and agents collaborate with other agents to tackle broader, more complex goals.
25 |
26 | ## Model Context Protocol (MCP)
27 |
28 | - **Focus:** MCP standardizes how AI models and agents connect to and interact with **tools, APIs, data sources, and other external resources.**
29 | - **Mechanism:** It defines a structured way to describe tool capabilities (akin to function calling in Large Language Models), pass inputs to them, and receive structured outputs.
30 | - **Use Cases:**
31 | - Enabling an LLM to call an external API (e.g., fetch current stock prices).
32 | - Allowing an agent to query a database with specific parameters.
33 | - Connecting an agent to a set of predefined functions or services.
34 | - **Ecosystem:** MCP aims to create an ecosystem where tool providers can easily expose their services to various AI models and agent frameworks, and agent developers can easily consume these tools in a standardized way.
35 |
36 | ## Agent2Agent Protocol (A2A)
37 |
38 | - **Focus:** A2A standardizes how independent, often opaque, **AI agents communicate and collaborate with each other as peers.**
39 | - **Mechanism:** It provides an application-level protocol for agents to:
40 | - Discover each other's high-level skills and capabilities (via Agent Cards).
41 | - Negotiate interaction modalities (text, files, structured data).
42 | - Manage shared, stateful, and potentially long-running tasks.
43 | - Exchange conversational context, instructions, and complex, multi-part results.
44 | - **Use Cases:**
45 | - A customer service agent delegating a complex billing inquiry to a specialized billing agent, maintaining context of the customer interaction.
46 | - A travel planning agent coordinating with separate flight, hotel, and activity booking agents, managing a multi-stage booking process.
47 | - Agents exchanging information and status updates for a collaborative project that evolves over time.
48 | - **Key Difference from Tool Interaction:** A2A allows for more dynamic, stateful, and potentially multi-modal interactions than typically seen with simple tool calls. Agents using A2A communicate _as agents_ (or on behalf of users) rather than just invoking a discrete function.
49 |
50 | ## How A2A and MCP Complement Each Other
51 |
52 | A2A and MCP are not mutually exclusive; they are highly complementary and address different layers of an agentic system's interaction needs.
53 |
54 |
55 |
56 | {width="80%"}
57 |
58 | _An agentic application might use A2A to communicate with other agents, while each agent internally uses MCP to interact with its specific tools and resources._
59 |
60 |
61 |
62 | ### Example Scenario: The Auto Repair Shop
63 |
64 | > Consider an auto repair shop staffed by autonomous AI agent "mechanics" who use special-purpose tools (such as vehicle jacks, multimeters, and socket wrenches) to diagnose and repair problems. The workers often have to diagnose and repair problems they have not seen before. The repair process can involve extensive conversations with a customer, research, and working with part suppliers.
65 |
66 | 1. **Customer Interaction (User-to-Agent via A2A):**
67 |
68 | - A customer (or their primary assistant agent) uses A2A to communicate with the "Shop Manager" agent: _"My car is making a rattling noise."_
69 | - The Shop Manager agent uses A2A for a multi-turn diagnostic conversation: _"Can you send a video of the noise?"_, _"I see some fluid leaking. How long has this been happening?"_
70 |
71 | 2. **Internal Tool Usage (Agent-to-Tool via MCP):**
72 |
73 | - The Mechanic agent, assigned the task by the Shop Manager, needs to diagnose the issue. It uses MCP to interact with its specialized tools:
74 | - MCP call to a "Vehicle Diagnostic Scanner" tool: `scan_vehicle_for_error_codes(vehicle_id='XYZ123')`.
75 | - MCP call to a "Repair Manual Database" tool: `get_repair_procedure(error_code='P0300', vehicle_make='Toyota', vehicle_model='Camry')`.
76 | - MCP call to a "Platform Lift" tool: `raise_platform(height_meters=2)`.
77 |
78 | 3. **Supplier Interaction (Agent-to-Agent via A2A):**
79 | - The Mechanic agent determines a specific part is needed. It uses A2A to communicate with a "Parts Supplier" agent: _"Do you have part #12345 in stock for a Toyota Camry 2018?"_
80 | - The Parts Supplier agent, also an A2A-compliant system, responds, potentially leading to an order.
81 |
82 | In this example:
83 |
84 | - **A2A** facilitates the higher-level, conversational, and task-oriented interactions between the customer and the shop, and between the shop's agents and external supplier agents.
85 | - **MCP** enables the mechanic agent to use its specific, structured tools to perform its diagnostic and repair functions.
86 |
87 | ## Representing A2A Agents as MCP Resources
88 |
89 | It's conceivable that an A2A Server (a remote agent) could also expose some of its skills as MCP-compatible resources, especially if those skills are well-defined and can be invoked in a more tool-like, stateless manner. In such a case, another agent might "discover" this A2A agent's specific skill via an MCP-style tool description (perhaps derived from its Agent Card).
90 |
91 | However, the primary strength of A2A lies in its support for more flexible, stateful, and collaborative interactions that go beyond typical tool invocation. A2A is about agents _partnering_ on tasks, while MCP is more about agents _using_ capabilities.
92 |
93 | By leveraging both A2A for inter-agent collaboration and MCP for tool integration, developers can build more powerful, flexible, and interoperable AI systems.
94 |
--------------------------------------------------------------------------------
/docs/topics/agent-discovery.md:
--------------------------------------------------------------------------------
1 | # Agent Discovery in A2A
2 |
3 | For AI agents to collaborate using the Agent2Agent (A2A) protocol, they first need to find each other and understand what capabilities the other agents offer. A2A standardizes the format of an agent's self-description through the **[Agent Card](../specification.md#5-agent-discovery-the-agent-card)**. However, the methods for discovering these Agent Cards can vary depending on the environment and requirements.
4 |
5 | ## The Role of the Agent Card
6 |
7 | The Agent Card is a JSON document that serves as a digital "business card" for an A2A Server (the remote agent). It is crucial for discovery and initiating interaction. Key information typically included in an Agent Card:
8 |
9 | - **Identity:** `name`, `description`, `provider` information.
10 | - **Service Endpoint:** The `url` where the A2A service can be reached.
11 | - **A2A Capabilities:** Supported protocol features like `streaming` or `pushNotifications`.
12 | - **Authentication:** Required authentication `schemes` (e.g., "Bearer", "OAuth2") to interact with the agent.
13 | - **Skills:** A list of specific tasks or functions the agent can perform (`AgentSkill` objects), including their `id`, `name`, `description`, `inputModes`, `outputModes`, and `examples`.
14 |
15 | Client agents parse the Agent Card to determine if a remote agent is suitable for a given task, how to structure requests for its skills, and how to communicate with it securely.
16 |
17 | ## Discovery Strategies
18 |
19 | Here are common strategies for how a client agent might discover the Agent Card of a remote agent:
20 |
21 | ### 1. Well-Known URI
22 |
23 | This is a recommended approach for public agents or agents intended for broad discoverability within a specific domain.
24 |
25 | - **Mechanism:** A2A Servers host their Agent Card at a standardized, "well-known" path on their domain.
26 | - **Standard Path:** `https://{agent-server-domain}/.well-known/agent.json` (following the principles of [RFC 8615](https://www.ietf.org/rfc/rfc8615.txt) for well-known URIs).
27 | - **Process:**
28 | 1. A client agent knows or programmatically discovers the domain of a potential A2A Server (e.g., `smart-thermostat.example.com`).
29 | 2. The client performs an HTTP `GET` request to `https://smart-thermostat.example.com/.well-known/agent.json`.
30 | 3. If the Agent Card exists and is accessible, the server returns it as a JSON response.
31 | - **Advantages:** Simple, standardized, and enables automated discovery by crawlers or systems that can resolve domains. Effectively reduces the discovery problem to "find the agent's domain."
32 | - **Considerations:** Best suited for agents intended for open discovery or discovery within an organization that controls the domain. The endpoint serving the Agent Card may itself require authentication if the card contains sensitive information.
33 |
34 | ### 2. Curated Registries (Catalog-Based Discovery)
35 |
36 | For enterprise environments, marketplaces, or specialized ecosystems, Agent Cards can be published to and discovered via a central registry or catalog.
37 |
38 | - **Mechanism:** An intermediary service (the registry) maintains a collection of Agent Cards. Clients query this registry to find agents based on various criteria (e.g., skills offered, tags, provider name, desired capabilities).
39 | - **Process:**
40 | 1. A2A Servers (or their administrators) register their Agent Cards with the registry service. The mechanism for this registration is outside the scope of the A2A protocol itself.
41 | 2. Client agents query the registry's API (e.g., "find agents with 'image-generation' skill that support streaming").
42 | 3. The registry returns a list of matching Agent Cards or references to them.
43 | - **Advantages:**
44 | - Centralized management, curation, and governance of available agents.
45 | - Facilitates discovery based on functional capabilities rather than just domain names.
46 | - Can implement access controls, policies, and trust mechanisms at the registry level.
47 | - Enables scenarios like company-specific or team-specific agent catalogs, or public marketplaces of A2A-compliant agents.
48 | - **Considerations:** Requires an additional registry service. The A2A protocol does not currently define a standard API for such registries, though this is an area of potential future exploration and community standardization.
49 |
50 | ### 3. Direct Configuration / Private Discovery
51 |
52 | In many scenarios, especially within tightly coupled systems, for private agents, or during development and testing, clients might be directly configured with Agent Card information or a URL to fetch it.
53 |
54 | - **Mechanism:** The client application has hardcoded Agent Card details, reads them from a local configuration file, receives them through an environment variable, or fetches them from a private, proprietary API endpoint known to the client.
55 | - **Process:** This is highly specific to the application's deployment and configuration strategy.
56 | - **Advantages:** Simple and effective for known, static relationships between agents or when dynamic discovery is not a requirement.
57 | - **Considerations:** Less flexible for discovering new or updated agents dynamically. Changes to the remote agent's card might require re-configuration of the client. Proprietary API-based discovery is not standardized by A2A.
58 |
59 | ## Securing Agent Cards
60 |
61 | Agent Cards themselves can sometimes contain information that should be protected, such as:
62 |
63 | - The `url` of an internal-only or restricted-access agent.
64 | - Details in the `authentication.credentials` field if it's used for scheme-specific, non-secret information (e.g., an OAuth token URL). Storing actual plaintext secrets in an Agent Card is **strongly discouraged**.
65 | - Descriptions of sensitive or internal skills.
66 |
67 | **Protection Mechanisms:**
68 |
69 | - **Access Control on the Endpoint:** The HTTP endpoint serving the Agent Card (whether it's the `/.well-known/agent.json` path, a registry API, or a custom URL) should be secured using standard web practices if the card is not intended for public, unauthenticated access.
70 | - **mTLS:** Require mutual TLS for client authentication if appropriate for the trust model.
71 | - **Network Restrictions:** Limit access to specific IP ranges, VPCs, or private networks.
72 | - **Authentication:** Require standard HTTP authentication (e.g., OAuth 2.0 Bearer token, API Key) to access the Agent Card itself.
73 | - **Selective Disclosure by Registries:** Agent registries can implement logic to return different Agent Cards or varying levels of detail based on the authenticated client's identity and permissions. For example, a public query might return a limited card, while an authenticated partner query might receive a card with more details.
74 |
75 | It's crucial to remember that if an Agent Card were to contain sensitive data (again, **not recommended** for secrets), the card itself **must never** be available without strong authentication and authorization. The A2A protocol encourages authentication schemes where the client obtains dynamic credentials out-of-band, rather than relying on static secrets embedded in the Agent Card.
76 |
77 | ## Future Considerations
78 |
79 | The A2A community may explore standardizing aspects of registry interactions or more advanced, semantic discovery protocols in the future. Feedback and contributions in this area are welcome to enhance the discoverability and interoperability of A2A agents.
80 |
--------------------------------------------------------------------------------
/docs/topics/enterprise-ready.md:
--------------------------------------------------------------------------------
1 | # Enterprise-Ready Features for A2A Agents
2 |
3 | The Agent2Agent (A2A) protocol is designed with enterprise requirements at its core. Instead of inventing new, proprietary standards for security and operations, A2A aims to integrate seamlessly with existing enterprise infrastructure and widely adopted best practices. A2A treats remote agents as standard, HTTP-based enterprise applications. This approach allows organizations to leverage their existing investments and expertise in security, monitoring, governance, and identity management.
4 |
5 | A key principle of A2A is that agents are typically "opaque" – they do not share internal memory, tools, or direct resource access with each other. This opacity naturally aligns with standard client/server security paradigms.
6 |
7 | ## 1. Transport Level Security (TLS)
8 |
9 | Ensuring the confidentiality and integrity of data in transit is fundamental.
10 |
11 | - **HTTPS Mandate:** All A2A communication in production environments **MUST** occur over HTTPS.
12 | - **Modern TLS Standards:** Implementations **SHOULD** use modern TLS versions (TLS 1.2 or higher is recommended) with strong, industry-standard cipher suites to protect data from eavesdropping and tampering.
13 | - **Server Identity Verification:** A2A Clients **SHOULD** verify the A2A Server's identity by validating its TLS certificate against trusted certificate authorities (CAs) during the TLS handshake. This prevents man-in-the-middle attacks.
14 |
15 | ## 2. Authentication
16 |
17 | A2A delegates authentication to standard web mechanisms, primarily relying on HTTP headers. Authentication requirements are advertised by the A2A Server in its [Agent Card](../specification.md#5-agent-discovery-the-agent-card).
18 |
19 | - **No In-Payload Identity:** A2A protocol payloads (JSON-RPC messages) do **not** carry user or client identity information. Identity is established at the transport/HTTP layer.
20 | - **Agent Card Declaration:** The A2A Server's `AgentCard` specifies the required authentication `schemes` (e.g., "Bearer", "OAuth2", "ApiKey", "Basic") in its `authentication` object. These scheme names often align with those defined in the [OpenAPI Specification for authentication](https://swagger.io/docs/specification/authentication/).
21 | - **Out-of-Band Credential Acquisition:** The A2A Client is responsible for obtaining the necessary credential materials (e.g., OAuth 2.0 tokens, API keys, JWTs) through processes external to the A2A protocol itself. This could involve OAuth flows (authorization code, client credentials), secure key distribution, etc.
22 | - **HTTP Header Transmission:** Credentials **MUST** be transmitted in standard HTTP headers as per the requirements of the chosen authentication scheme (e.g., `Authorization: Bearer `, `X-API-Key: `).
23 | - **Server-Side Validation:** The A2A Server **MUST** authenticate **every** incoming request based on the credentials provided in the HTTP headers and its declared requirements.
24 | - If authentication fails or is missing, the server **SHOULD** respond with standard HTTP status codes such as `401 Unauthorized` or `403 Forbidden`.
25 | - A `401 Unauthorized` response **SHOULD** include a `WWW-Authenticate` header indicating the required scheme(s), guiding the client on how to authenticate correctly.
26 | - **In-Task Authentication (Secondary Credentials):** If an agent, during a task, requires additional credentials for a _different_ system (e.g., to access a specific tool on behalf of the user), A2A recommends:
27 | 1. The A2A Server transitions the A2A task to the `input-required` state.
28 | 2. The `TaskStatus.message` (often using a `DataPart`) should provide details about the required authentication for the secondary system, potentially using an `AuthenticationInfo`-like structure.
29 | 3. The A2A Client then obtains these new credentials out-of-band for the secondary system. These credentials might be provided back to the A2A Server (if it's proxying the request) or used by the client to interact directly with the secondary system.
30 |
31 | ## 3. Authorization
32 |
33 | Once a client is authenticated, the A2A Server is responsible for authorizing the request. Authorization logic is specific to the agent's implementation, the data it handles, and applicable enterprise policies.
34 |
35 | - **Granular Control:** Authorization **SHOULD** be applied based on the authenticated identity (which could represent an end user, a client application, or both).
36 | - **Skill-Based Authorization:** Access can be controlled on a per-skill basis, as advertised in the Agent Card. For example, specific OAuth scopes might grant an authenticated client access to invoke certain skills but not others.
37 | - **Data and Action-Level Authorization:** Agents that interact with backend systems, databases, or tools **MUST** enforce appropriate authorization before performing sensitive actions or accessing sensitive data through those underlying resources. The agent acts as a gatekeeper.
38 | - **Principle of Least Privilege:** Grant only the necessary permissions required for a client or user to perform their intended operations via the A2A interface.
39 |
40 | ## 4. Data Privacy and Confidentiality
41 |
42 | - **Sensitivity Awareness:** Implementers must be acutely aware of the sensitivity of data exchanged in `Message` and `Artifact` parts of A2A interactions.
43 | - **Compliance:** Ensure compliance with relevant data privacy regulations (e.g., GDPR, CCPA, HIPAA, depending on the domain and data).
44 | - **Data Minimization:** Avoid including or requesting unnecessarily sensitive information in A2A exchanges.
45 | - **Secure Handling:** Protect data both in transit (via TLS, as mandated) and at rest (if persisted by agents) according to enterprise data security policies and regulatory requirements.
46 |
47 | ## 5. Tracing, Observability, and Monitoring
48 |
49 | A2A's reliance on HTTP allows for straightforward integration with standard enterprise tracing, logging, and monitoring tools.
50 |
51 | - **Distributed Tracing:**
52 | - A2A Clients and Servers **SHOULD** participate in distributed tracing systems (e.g., OpenTelemetry, Jaeger, Zipkin).
53 | - Trace context (trace IDs, span IDs) **SHOULD** be propagated via standard HTTP headers (e.g., W3C Trace Context headers like `traceparent` and `tracestate`).
54 | - This enables end-to-end visibility of requests as they flow across multiple agents and underlying services, which is invaluable for debugging and performance analysis.
55 | - **Comprehensive Logging:** Implement detailed logging on both client and server sides. Logs should include relevant identifiers such as `taskId`, `sessionId`, correlation IDs, and trace context to facilitate troubleshooting and auditing.
56 | - **Metrics:** A2A Servers should expose key operational metrics (e.g., request rates, error rates, task processing latency, resource utilization) to enable performance monitoring, alerting, and capacity planning. These can be integrated with systems like Prometheus or Google Cloud Monitoring.
57 | - **Auditing:** Maintain audit trails for significant events, such as task creation, critical state changes, and actions performed by agents, especially those involving sensitive data access, modifications, or high-impact operations.
58 |
59 | ## 6. API Management and Governance
60 |
61 | For A2A Servers exposed externally, across organizational boundaries, or even within large enterprises, integration with API Management solutions is highly recommended. This can provide:
62 |
63 | - **Centralized Policy Enforcement:** Consistent application of security policies (authentication, authorization), rate limiting, and quotas.
64 | - **Traffic Management:** Load balancing, routing, and mediation.
65 | - **Analytics and Reporting:** Insights into agent usage, performance, and trends.
66 | - **Developer Portals:** Facilitate discovery of A2A-enabled agents, provide documentation (including Agent Cards), and streamline onboarding for client developers.
67 |
68 | By adhering to these enterprise-grade practices, A2A implementations can be deployed securely, reliably, and manageably within complex organizational environments, fostering trust and enabling scalable inter-agent collaboration.
69 |
--------------------------------------------------------------------------------
/docs/topics/key-concepts.md:
--------------------------------------------------------------------------------
1 | # Key Concepts in A2A
2 |
3 | The Agent2Agent (A2A) protocol is built around a set of core concepts that define how agents interact. Understanding these concepts is crucial for developing or integrating with A2A-compliant systems.
4 |
5 | { width="70%" style="margin:20px auto;display:block;" }
6 |
7 | ## Core Actors
8 |
9 | - **User:** The end user (human or automated service) who initiates a request or goal that requires agent assistance.
10 | - **A2A Client (Client Agent):** An application, service, or another AI agent that acts on behalf of the user to request actions or information from a remote agent. The client initiates communication using the A2A protocol.
11 | - **A2A Server (Remote Agent):** An AI agent or agentic system that exposes an HTTP endpoint implementing the A2A protocol. It receives requests from clients, processes tasks, and returns results or status updates. The remote agent operates as an "opaque" system from the client's perspective, meaning the client doesn't need to know its internal workings, memory, or tools.
12 |
13 | ## Fundamental Communication Elements
14 |
15 | - **Agent Card:**
16 |
17 | - A JSON metadata document, typically discoverable at a well-known URL (e.g., `/.well-known/agent.json`), that describes an A2A Server.
18 | - It details the agent's identity (name, description), service endpoint URL, version, supported A2A capabilities (like streaming or push notifications), specific skills it offers, default input/output modalities, and authentication requirements.
19 | - Clients use the Agent Card to discover agents and understand how to interact with them securely and effectively.
20 | - See details in the [Protocol Specification: Agent Card](../specification.md#5-agent-discovery-the-agent-card).
21 |
22 | - **Task:**
23 |
24 | - When a client sends a message to an agent, the agent might determine that fulfilling the request requires a stateful task to be completed (e.g., "generate a report," "book a flight," "answer a question").
25 | - Each task has a unique ID defined by the agent and progresses through a defined lifecycle (e.g., `submitted`, `working`, `input-required`, `completed`, `failed`).
26 | - Tasks are stateful and can involve multiple exchanges (messages) between the client and the server.
27 | - See details in the [Protocol Specification: Task Object](../specification.md#61-task-object).
28 |
29 | - **Message:**
30 |
31 | - Represents a single turn or unit of communication between a client and an agent.
32 | - Messages have a `role` (either `"user"` for client-sent messages or `"agent"` for server-sent messages) and contain one or more `Part` objects that carry the actual content. `messageId` part of the Message object is a unique identifier for each message set by the sender of the message.
33 | - Used for conveying instructions, context, questions, answers, or status updates that are not necessarily formal `Artifacts`.
34 | - See details in the [Protocol Specification: Message Object](../specification.md#64-message-object).
35 |
36 | - **Part:**
37 |
38 | - The fundamental unit of content within a `Message` or an `Artifact`. Each part has a specific `type` and can carry different kinds of data:
39 | - `TextPart`: Contains plain textual content.
40 | - `FilePart`: Represents a file, which can be transmitted as inline base64-encoded bytes or referenced via a URI. Includes metadata like filename and Media Type.
41 | - `DataPart`: Carries structured JSON data, useful for forms, parameters, or any machine-readable information.
42 | - See details in the [Protocol Specification: Part Union Type](../specification.md#65-part-union-type).
43 |
44 | - **Artifact:**
45 | - Represents a tangible output or result generated by the remote agent during the processing of a task.
46 | - Examples include generated documents, images, spreadsheets, structured data results, or any other self-contained piece of information that is a direct result of the task.
47 | - Artifacts are composed of one or more `Part` objects and can be streamed incrementally.
48 | - See details in the [Protocol Specification: Artifact Object](../specification.md#67-artifact-object).
49 |
50 | ## Interaction Mechanisms
51 |
52 | - **Request/Response (Polling):**
53 |
54 | - The client sends a request (e.g., using the `message/send` RPC method) and receives a response from the server.
55 | - If the interaction requires a stateful long-running task, the server might initially respond with a `working` status. The client would then periodically call `tasks/get` to poll for updates until the task reaches a terminal state (e.g., `completed`, `failed`).
56 |
57 | - **Streaming (Server-Sent Events - SSE):**
58 |
59 | - For tasks that produce results incrementally or provide real-time progress updates.
60 | - The client initiates an interaction with the server using `message/stream`.
61 | - The server responds with an HTTP connection that remains open, over which it sends a stream of Server-Sent Events (SSE).
62 | - These events can be `Task`, `Message`, or ``TaskStatusUpdateEvent` (for status changes) or `TaskArtifactUpdateEvent` (for new or updated artifact chunks).
63 | - This requires the server to advertise the `streaming` capability in its Agent Card.
64 | - Learn more about [Streaming & Asynchronous Operations](./streaming-and-async.md).
65 |
66 | - **Push Notifications:**
67 | - For very long-running tasks or scenarios where maintaining a persistent connection (like SSE) is impractical.
68 | - The client can provide a webhook URL when initiating a task (or by calling `tasks/pushNotificationConfig/set`).
69 | - When the task status changes significantly (e.g., completes, fails, or requires input), the server can send an asynchronous notification (an HTTP POST request) to this client-provided webhook.
70 | - This requires the server to advertise the `pushNotifications` capability in its Agent Card.
71 | - Learn more about [Streaming & Asynchronous Operations](./streaming-and-async.md).
72 |
73 | ## Other Important Concepts
74 |
75 | - **Context (`contextId`):** A server-generated identifier that can be used to logically group multiple related `Task` objects, providing context across a series of interactions.
76 | - **Transport and Format:** A2A communication occurs over HTTP(S). JSON-RPC 2.0 is used as the payload format for all requests and responses.
77 | - **Authentication & Authorization:** A2A relies on standard web security practices. Authentication requirements are declared in the Agent Card, and credentials (e.g., OAuth tokens, API keys) are typically passed via HTTP headers, separate from the A2A protocol messages themselves.
78 | - Learn more about [Enterprise-Ready Features](./enterprise-ready.md).
79 | - **Agent Discovery:** The process by which clients find Agent Cards to learn about available A2A Servers and their capabilities.
80 | - Learn more about [Agent Discovery](./agent-discovery.md).
81 |
82 | By understanding these core components and mechanisms, developers can effectively design, implement, and utilize A2A for building interoperable and collaborative AI agent systems.
83 |
--------------------------------------------------------------------------------
/docs/topics/streaming-and-async.md:
--------------------------------------------------------------------------------
1 | # Streaming & Asynchronous Operations in A2A
2 |
3 | The Agent2Agent (A2A) protocol is designed to handle tasks that may not complete immediately. Many AI-driven operations can be long-running, involve multiple steps, produce incremental results, or require human intervention. A2A provides robust mechanisms for managing such asynchronous interactions, ensuring that clients can receive updates effectively, whether they remain continuously connected or operate in a more disconnected fashion.
4 |
5 | ## 1. Streaming with Server-Sent Events (SSE)
6 |
7 | For tasks that produce incremental results (like generating a long document or streaming media) or provide ongoing status updates, A2A supports real-time communication using Server-Sent Events (SSE). This is ideal when the client can maintain an active HTTP connection with the A2A Server.
8 |
9 | **Key Characteristics:**
10 |
11 | - **Initiation:** The client uses the `message/stream` RPC method to send an initial message (e.g., a prompt or command) and simultaneously subscribe to updates for that task.
12 | - **Server Capability:** The A2A Server must indicate its support for streaming by setting `capabilities.streaming: true` in its [Agent Card](../specification.md#552-agentcapabilities-object).
13 | - **Server Response (Connection):** If the subscription is successful, the server responds with an HTTP `200 OK` status and a `Content-Type: text/event-stream`. This HTTP connection remains open for the server to push events.
14 | - **Event Structure:** The server sends events over this stream. Each event's `data` field contains a JSON-RPC 2.0 Response object, specifically a [`SendStreamingMessageResponse`](../specification.md#721-sendstreamingmessageresponse-object). The `id` in this JSON-RPC response matches the `id` from the client's original `message/stream` request.
15 | - **Event Types (within `SendStreamingMessageResponse.result`):**
16 | - [`Task`](../specification.md#61-task-object): Represents the stateful unit of work being processed by the A2A Server for an A2A Client.
17 | - [`TaskStatusUpdateEvent`](../specification.md#722-taskstatusupdateevent-object): Communicates changes in the task's lifecycle state (e.g., from `working` to `input-required` or `completed`). It can also provide intermediate messages from the agent (e.g., "I'm currently analyzing the data...").
18 | - [`TaskArtifactUpdateEvent`](../specification.md#723-taskartifactupdateevent-object): Delivers new or updated [Artifacts](../specification.md#67-artifact-object) generated by the task. This is used to stream large files or data structures in chunks. This object itself contains fields like `append`, and `lastChunk` to help the client reassemble the complete artifact.
19 | - **Stream Termination:** The server signals the end of updates for a particular interaction cycle (i.e., for the current `message/stream` request) by setting `final: true` in a `TaskStatusUpdateEvent`. This typically occurs when the task reaches a terminal state (`completed`, `failed`, `canceled`) or an `input-required` state (where the server expects further input from the client). After sending a `final: true` event, the server usually closes the SSE connection for that specific request.
20 | - **Resubscription:** If a client's SSE connection breaks prematurely while a task is still active (and the server hasn't sent a `final: true` event for that phase), the client can attempt to reconnect to the stream using the `tasks/resubscribe` RPC method. The server's behavior regarding missed events during the disconnection period (e.g., whether it backfills or only sends new updates) is implementation-dependent.
21 |
22 | **When to Use Streaming:**
23 |
24 | - Real-time progress monitoring of long-running tasks.
25 | - Receiving large results (artifacts) incrementally, allowing processing to begin before the entire result is available.
26 | - Interactive, conversational exchanges where immediate feedback or partial responses are beneficial.
27 | - Applications requiring low-latency updates from the agent.
28 |
29 | Refer to the Protocol Specification for detailed structures:
30 |
31 | - [`message/stream`](../specification.md#72-messagestream)
32 | - [`tasks/resubscribe`](../specification.md#77-tasksresubscribe)
33 |
34 | ## 2. Push Notifications for Disconnected Scenarios
35 |
36 | For very long-running tasks (e.g., lasting minutes, hours, or even days) or when clients cannot or prefer not to maintain persistent connections (like mobile clients or serverless functions), A2A supports asynchronous updates via push notifications. This mechanism allows the A2A Server to actively notify a client-provided webhook when a significant task update occurs.
37 |
38 | **Key Characteristics:**
39 |
40 | - **Server Capability:** The A2A Server must indicate its support for this feature by setting `capabilities.pushNotifications: true` in its [Agent Card](../specification.md#552-agentcapabilities-object).
41 | - **Configuration:** The client provides a [`PushNotificationConfig`](../specification.md#68-pushnotificationconfig-object) to the server.
42 | - This configuration can be supplied:
43 | - Within the initial `message/send` or `message/stream` request (via the optional `pushNotification` parameter in `TaskSendParams`).
44 | - Separately, using the `tasks/pushNotificationConfig/set` RPC method for an existing task.
45 |
46 | - The `PushNotificationConfig` includes:
47 | - `url`: The absolute HTTPS webhook URL where the A2A Server should send (POST) task update notifications.
48 | - `token` (optional): A client-generated opaque string (e.g., a secret or task-specific identifier). The server SHOULD include this token in the notification request (e.g., in a custom header like `X-A2A-Notification-Token`) for validation by the client's webhook receiver.
49 | - `authentication` (optional): An [`AuthenticationInfo`](../specification.md#69-pushnotificationauthenticationinfo-object) object specifying how the A2A Server should authenticate itself _to the client's webhook URL_. The client (receiver of the webhook) defines these authentication requirements.
50 |
51 | - **Notification Trigger:** The A2A Server decides when to send a push notification. Typically, this happens when a task reaches a significant state change, such as transitioning to a terminal state (`completed`, `failed`, `canceled`, `rejected`) or an `input-required` or `auth-required` state, particularly after its associated message and artifacts are fully generated and stable.
52 | - **Notification Payload:** The A2A protocol itself does **not** strictly define the HTTP body payload of the push notification sent by the server to the client's webhook. However, the notification **SHOULD** contain sufficient information for the client to identify the `Task ID` and understand the general nature of the update (e.g., the new `TaskState`). Servers might send a minimal payload (just `Task ID` and new state) or a more comprehensive one (e.g., a summary or even the full [`Task`](../specification.md#61-task-object) object).
53 | - **Client Action:** Upon receiving a push notification (and successfully verifying its authenticity and relevance), the client typically uses the `tasks/get` RPC method with the `task ID` from the notification to retrieve the complete, updated `Task` object, including any new artifacts or detailed messages.
54 |
55 | **The Push Notification Service (Client-Side Webhook Infrastructure):**
56 |
57 | - The target `url` specified in `PushNotificationConfig.url` points to a **Push Notification Service**. This service is a component on the client's side (or a service the client subscribes to) responsible for receiving the HTTP POST notification from the A2A Server.
58 | - Its responsibilities include:
59 | - Authenticating the incoming notification (i.e., verifying it's from the legitimate A2A Server).
60 | - Validating the notification's relevance (e.g., checking the `token`).
61 | - Relaying the notification or its content to the appropriate client application logic or system.
62 | - In simple scenarios (e.g., local development), the client application itself might directly expose the webhook endpoint.
63 | - In enterprise or production settings, this is often a robust, secure service that handles incoming webhooks, authenticates callers, and routes messages (e.g., to a message queue, an internal API, a mobile push notification gateway, or another event-driven system).
64 |
65 | ### Security Considerations for Push Notifications
66 |
67 | Security is paramount for push notifications due to their asynchronous and server-initiated outbound nature. Both the A2A Server (sending the notification) and the client's webhook receiver have responsibilities.
68 |
69 | #### A2A Server Security (When Sending Notifications to Client Webhook)
70 |
71 | 1. **Webhook URL Validation:**
72 |
73 | - Servers **SHOULD NOT** blindly trust and send POST requests to any `url` provided by a client in `PushNotificationConfig`. Malicious clients could provide URLs pointing to internal services or unrelated third-party systems to cause harm (Server-Side Request Forgery - SSRF attacks) or act as Distributed Denial of Service (DDoS) amplifiers.
74 | - **Mitigation Strategies:**
75 | - **Allowlisting:** Maintain an allowlist of trusted domains or IP ranges for webhook URLs, if feasible.
76 | - **Ownership Verification / Challenge-Response:** Before sending actual notifications, the server can (and SHOULD ideally) perform a verification step. For example, it could issue an HTTP `GET` or `OPTIONS` request to the proposed webhook URL with a unique `validationToken` (as a query parameter or header). The webhook service must respond appropriately (e.g., echo back the token or confirm readiness) to prove ownership and reachability. The [A2A Python samples](https://github.com/google-a2a/A2A/blob/main/samples/python/agents/langgraph/task_manager.py) demonstrate a simple validation token check mechanism.
77 | - **Network Controls:** Use egress firewalls or network policies to restrict where the A2A Server can send outbound HTTP requests.
78 |
79 | 2. **Authenticating to the Client's Webhook:**
80 | - The A2A Server **MUST** authenticate itself to the client's webhook URL according to the scheme(s) specified in `PushNotificationConfig.authentication`.
81 | - Common authentication schemes for server-to-server webhooks include:
82 | - **Bearer Tokens (OAuth 2.0):** The A2A Server obtains an access token (e.g., using the OAuth 2.0 client credentials grant flow if the webhook provider supports it) for an audience/scope representing the client's webhook, and includes it in the `Authorization: Bearer ` header of the notification POST request.
83 | - **API Keys:** A pre-shared API key that the A2A Server includes in a specific HTTP header (e.g., `X-Api-Key`).
84 | - **HMAC Signatures:** The A2A Server signs the request payload (or parts of the request) with a shared secret key using HMAC, and includes the signature in a header (e.g., `X-Hub-Signature`). The webhook receiver then verifies this signature.
85 | - **Mutual TLS (mTLS):** If supported by the client's webhook infrastructure, the A2A Server can present a client TLS certificate.
86 |
87 | #### Client Webhook Receiver Security (When Receiving Notifications from A2A Server)
88 |
89 | 1. **Authenticating the A2A Server:**
90 |
91 | - The webhook endpoint **MUST** rigorously verify the authenticity of incoming notification requests to ensure they originate from the legitimate A2A Server and not an imposter.
92 | - **Verify Signatures/Tokens:**
93 | - If using JWTs (e.g., as Bearer tokens), validate the JWT's signature against the A2A Server's trusted public keys (e.g., fetched from a JWKS endpoint provided by the A2A Server, if applicable). Also, validate claims like `iss` (issuer), `aud` (audience - should identify your webhook), `iat` (issued at), and `exp` (expiration time).
94 | - If using HMAC signatures, recalculate the signature on the received payload using the shared secret and compare it to the signature in the request header.
95 | - If using API keys, ensure the key is valid and known.
96 | - **Validate `PushNotificationConfig.token`:** If the client provided an opaque `token` in its `PushNotificationConfig` when setting up notifications for the task, the webhook should check that the incoming notification includes this exact token (e.g., in a custom header like `X-A2A-Notification-Token`). This helps ensure the notification is intended for this specific client context and task, adding a layer of authorization.
97 |
98 | 2. **Preventing Replay Attacks:**
99 |
100 | - **Timestamps:** Notifications should ideally include a timestamp (e.g., `iat` - issued at - claim in a JWT, or a custom timestamp header). The webhook should reject notifications that are too old (e.g., older than a few minutes) to prevent attackers from replaying old, captured notifications. The timestamp should be part of the signed payload (if using signatures) to ensure its integrity.
101 | - **Nonces/Unique IDs:** For critical notifications, consider using unique, single-use identifiers (nonces or event IDs) for each notification. The webhook should track received IDs (for a reasonable window) to prevent processing duplicate notifications. A JWT's `jti` (JWT ID) claim can serve this purpose.
102 |
103 | 3. **Secure Key Management and Rotation:**
104 | - If using cryptographic keys (symmetric secrets for HMAC, or asymmetric key pairs for JWT signing/mTLS), implement secure key management practices, including regular key rotation.
105 | - For asymmetric keys where the A2A Server signs and the client webhook verifies, protocols like JWKS (JSON Web Key Set) allow the server to publish its public keys (including new ones during rotation) at a well-known endpoint. Client webhooks can then dynamically fetch the correct public key for signature verification, facilitating smoother key rotation.
106 |
107 | ##### Example Asymmetric Key Flow (JWT + JWKS)
108 |
109 | 1. Client sets `PushNotificationConfig` specifying `authentication.schemes: ["Bearer"]` and possibly an expected `issuer` or `audience` for the JWT.
110 | 2. A2A Server, when sending a notification:
111 | - Generates a JWT, signing it with its private key. The JWT includes claims like `iss` (issuer), `aud` (audience - the webhook), `iat` (issued at), `exp` (expires), `jti` (JWT ID), and `taskId`.
112 | - The JWT header (`alg` and `kid`) indicates the signing algorithm and key ID.
113 | - The A2A Server makes its public keys available via a JWKS endpoint (URL for this endpoint might be known to the webhook provider or discovered).
114 | 3. Client Webhook, upon receiving the notification:
115 | - Extracts the JWT from the `Authorization` header.
116 | - Inspects the `kid` in the JWT header.
117 | - Fetches the corresponding public key from the A2A Server's JWKS endpoint (caching keys is recommended).
118 | - Verifies the JWT signature using the public key.
119 | - Validates claims (`iss`, `aud`, `iat`, `exp`, `jti`).
120 | - Checks the `PushNotificationConfig.token` if provided.
121 |
122 | This comprehensive, layered approach to security for push notifications ensures that messages are authentic, integral, and timely, protecting both the sending A2A Server and the receiving client webhook infrastructure.
123 |
--------------------------------------------------------------------------------
/docs/topics/what-is-a2a.md:
--------------------------------------------------------------------------------
1 | # What is A2A?
2 |
3 | The Agent2Agent (A2A) Protocol is an open standard designed to solve a fundamental challenge in the rapidly evolving landscape of artificial intelligence: **how do AI agents, built by different teams, using different technologies, and owned by different organizations, communicate and collaborate effectively?**
4 |
5 | As AI agents become more specialized and capable, the need for them to work together on complex tasks increases. Imagine a user asking their primary AI assistant to plan an international trip. This single request might involve coordinating the capabilities of several specialized agents:
6 |
7 | 1. An agent for flight bookings.
8 | 2. Another agent for hotel reservations.
9 | 3. A third for local tour recommendations and bookings.
10 | 4. A fourth to handle currency conversion and travel advisories.
11 |
12 | Without a common communication protocol, integrating these diverse agents into a cohesive user experience is a significant engineering hurdle. Each integration would likely be a custom, point-to-point solution, making the system difficult to scale, maintain, and extend.
13 |
14 | ## The A2A Solution
15 |
16 | A2A provides a standardized way for these independent, often "opaque" (black-box) agentic systems to interact. It defines:
17 |
18 | - **A common transport and format:** JSON-RPC 2.0 over HTTP(S) for how messages are structured and transmitted.
19 | - **Discovery mechanisms (Agent Cards):** How agents can advertise their capabilities and be found by other agents.
20 | - **Task management workflows:** How collaborative tasks are initiated, progressed, and completed. This includes support for tasks that may be long-running or require multiple turns of interaction.
21 | - **Support for various data modalities:** How agents exchange not just text, but also files, structured data (like forms), and potentially other rich media.
22 | - **Core principles for security and asynchronicity:** Guidelines for secure communication and handling tasks that might take significant time or involve human-in-the-loop processes.
23 |
24 | ## Key Design Principles of A2A
25 |
26 | The development of A2A is guided by several core principles:
27 |
28 | - **Simplicity:** Leverage existing, well-understood standards like HTTP, JSON-RPC, and Server-Sent Events (SSE) where possible, rather than reinventing the wheel.
29 | - **Enterprise Readiness:** Address critical enterprise needs such as authentication, authorization, security, privacy, tracing, and monitoring from the outset by aligning with standard web practices.
30 | - **Asynchronous First:** Natively support long-running tasks and scenarios where agents or users might not be continuously connected, through mechanisms like streaming and push notifications.
31 | - **Modality Agnostic:** Allow agents to communicate using a variety of content types, enabling rich and flexible interactions beyond plain text.
32 | - **Opaque Execution:** Enable collaboration without requiring agents to expose their internal logic, memory, or proprietary tools. Agents interact based on declared capabilities and exchanged context, preserving intellectual property and enhancing security.
33 |
34 | ## Benefits of Using A2A
35 |
36 | Adopting A2A can lead to significant advantages:
37 |
38 | - **Increased Interoperability:** Break down silos between different AI agent ecosystems, allowing agents from various vendors and frameworks to work together.
39 | - **Enhanced Agent Capabilities:** Allow developers to create more sophisticated applications by composing the strengths of multiple specialized agents.
40 | - **Reduced Integration Complexity:** Standardize the "how" of agent communication, allowing teams to focus on the "what" – the value their agents provide.
41 | - **Fostering Innovation:** Encourage the development of a richer ecosystem of specialized agents that can readily plug into larger collaborative workflows.
42 | - **Future-Proofing:** Provide a flexible framework that can adapt as agent technologies continue to evolve.
43 |
44 | By establishing common ground for agent-to-agent communication, A2A aims to accelerate the adoption and utility of AI agents across diverse industries and applications, paving the way for more powerful and collaborative AI systems.
45 |
46 | [Watch the A2A Demo Video](https://storage.googleapis.com/gweb-developer-goog-blog-assets/original_videos/A2A_demo_v4.mp4)
47 |
48 | Next, learn about the [Key Concepts](./key-concepts.md) that form the foundation of the A2A protocol.
49 |
--------------------------------------------------------------------------------
/docs/tutorials/python/1-introduction.md:
--------------------------------------------------------------------------------
1 | # Python Quickstart Tutorial: Building an A2A Agent
2 |
3 | Welcome to the Agent2Agent (A2A) Python Quickstart Tutorial!
4 |
5 | In this tutorial, you will explore a simple "echo" A2A server using the Python SDK. This will introduce you to the fundamental concepts and components of an A2A server. You will then look at a more advanced example that integrates a Large Language Model (LLM).
6 |
7 | This hands-on guide will help you understand:
8 |
9 | - The basic concepts behind the A2A protocol.
10 | - How to set up a Python environment for A2A development using the SDK.
11 | - How Agent Skills and Agent Cards describe an agent.
12 | - How an A2A server handles tasks.
13 | - How to interact with an A2A server using a client.
14 | - How streaming capabilities and multi-turn interactions work.
15 | - How an LLM can be integrated into an A2A agent.
16 |
17 | By the end of this tutorial, you will have a functional understanding of A2A agents and a solid foundation for building or integrating A2A-compliant applications.
18 |
19 | ## Tutorial Sections
20 |
21 | The tutorial is broken down into the following steps:
22 |
23 | 1. **[Introduction (This Page)](./1-introduction.md)**
24 | 2. **[Setup](./2-setup.md)**: Prepare your Python environment and the A2A SDK.
25 | 3. **[Agent Skills & Agent Card](./3-agent-skills-and-card.md)**: Define what your agent can do and how it describes itself.
26 | 4. **[The Agent Executor](./4-agent-executor.md)**: Understand how the agent logic is implemented.
27 | 5. **[Starting the Server](./5-start-server.md)**: Run the Helloworld A2A server.
28 | 6. **[Interacting with the Server](./6-interact-with-server.md)**: Send requests to your agent.
29 | 7. **[Streaming & Multi-Turn Interactions](./7-streaming-and-multiturn.md)**: Explore advanced capabilities with the LangGraph example.
30 | 8. **[Next Steps](./8-next-steps.md)**: Explore further possibilities with A2A.
31 |
32 | Let's get started!
33 |
--------------------------------------------------------------------------------
/docs/tutorials/python/2-setup.md:
--------------------------------------------------------------------------------
1 | # 2. Setup Your Environment
2 |
3 | ## Prerequisites
4 |
5 | - Python 3.13 or higher.
6 | - Access to a terminal or command prompt.
7 | - Git, for cloning the repository.
8 | - A code editor (e.g., Visual Studio Code) is recommended.
9 |
10 | ## Clone the Repository
11 |
12 | If you haven't already, clone the A2A Samples repository:
13 |
14 | ```bash
15 | git clone https://github.com/google-a2a/a2a-samples.git -b main --depth 1
16 | cd a2a-samples
17 | ```
18 |
19 | ## Python Environment & SDK Installation
20 |
21 | We recommend using a virtual environment for Python projects. The A2A Python SDK uses `uv` for dependency management, but you can use `pip` with `venv` as well.
22 |
23 | 1. **Create and activate a virtual environment:**
24 |
25 | Using `venv` (standard library):
26 |
27 | === "Mac/Linux"
28 |
29 | ```sh
30 | python -m venv .venv
31 | source .venv/bin/activate
32 | ```
33 |
34 | === "Windows"
35 |
36 | ```powershell
37 | python -m venv .venv
38 | .venv\Scripts\activate
39 | ```
40 |
41 | 2. **Install needed Python dependencies along with the A2A SDK and its dependencies:**
42 |
43 | ```bash
44 | pip install -r samples/python/requirements.txt
45 | ```
46 |
47 | ## Verify Installation
48 |
49 | After installation, you should be able to import the `a2a` package in a Python interpreter:
50 |
51 | ```bash
52 | python -c "import a2a; print('A2A SDK imported successfully')"
53 | ```
54 |
55 | If this command runs without error and prints the success message, your environment is set up correctly.
56 |
--------------------------------------------------------------------------------
/docs/tutorials/python/3-agent-skills-and-card.md:
--------------------------------------------------------------------------------
1 | # 3. Agent Skills & Agent Card
2 |
3 | Before an A2A agent can do anything, it needs to define what it _can_ do (its skills) and how other agents or clients can find out about these capabilities (its Agent Card).
4 |
5 | We'll use the `helloworld` example located in [`a2a-samples/samples/python/agents/helloworld/`](https://github.com/google-a2a/a2a-samples/tree/main/samples/python/agents/helloworld).
6 |
7 | ## Agent Skills
8 |
9 | An **Agent Skill** describes a specific capability or function the agent can perform. It's a building block that tells clients what kinds of tasks the agent is good for.
10 |
11 | Key attributes of an `AgentSkill` (defined in `a2a.types`):
12 |
13 | - `id`: A unique identifier for the skill.
14 | - `name`: A human-readable name.
15 | - `description`: A more detailed explanation of what the skill does.
16 | - `tags`: Keywords for categorization and discovery.
17 | - `examples`: Sample prompts or use cases.
18 | - `inputModes` / `outputModes`: Supported Media Types for input and output (e.g., "text/plain", "application/json").
19 |
20 | In `__main__.py`, you can see how a skill for the Helloworld agent is defined:
21 |
22 | ```python { .no-copy }
23 | --8<-- "https://raw.githubusercontent.com/google-a2a/a2a-samples/refs/heads/main/samples/python/agents/helloworld/__main__.py:AgentSkill"
24 | ```
25 |
26 | This skill is very simple: it's named "Returns hello world" and primarily deals with text.
27 |
28 | ## Agent Card
29 |
30 | The **Agent Card** is a JSON document that an A2A Server makes available, typically at a `.well-known/agent.json` endpoint. It's like a digital business card for the agent.
31 |
32 | Key attributes of an `AgentCard` (defined in `a2a.types`):
33 |
34 | - `name`, `description`, `version`: Basic identity information.
35 | - `url`: The endpoint where the A2A service can be reached.
36 | - `capabilities`: Specifies supported A2A features like `streaming` or `pushNotifications`.
37 | - `defaultInputModes` / `defaultOutputModes`: Default Media Types for the agent.
38 | - `skills`: A list of `AgentSkill` objects that the agent offers.
39 |
40 | The `helloworld` example defines its Agent Card like this:
41 |
42 | ```python { .no-copy }
43 | --8<-- "https://raw.githubusercontent.com/google-a2a/a2a-samples/refs/heads/main/samples/python/agents/helloworld/__main__.py:AgentCard"
44 | ```
45 |
46 | This card tells us the agent is named "Hello World Agent", runs at `http://localhost:9999/`, supports text interactions, and has the `hello_world` skill. It also indicates public authentication, meaning no specific credentials are required.
47 |
48 | Understanding the Agent Card is crucial because it's how a client discovers an agent and learns how to interact with it.
49 |
--------------------------------------------------------------------------------
/docs/tutorials/python/4-agent-executor.md:
--------------------------------------------------------------------------------
1 | # 4. The Agent Executor
2 |
3 | The core logic of how an A2A agent processes requests and generates responses/events is handled by an **Agent Executor**. The A2A Python SDK provides an abstract base class `a2a.server.agent_execution.AgentExecutor` that you implement.
4 |
5 | ## `AgentExecutor` Interface
6 |
7 | The `AgentExecutor` class defines two primary methods:
8 |
9 | - `async def execute(self, context: RequestContext, event_queue: EventQueue)`: Handles incoming requests that expect a response or a stream of events. It processes the user's input (available via `context`) and uses the `event_queue` to send back `Message`, `Task`, `TaskStatusUpdateEvent`, or `TaskArtifactUpdateEvent` objects.
10 | - `async def cancel(self, context: RequestContext, event_queue: EventQueue)`: Handles requests to cancel an ongoing task.
11 |
12 | The `RequestContext` provides information about the incoming request, such as the user's message and any existing task details. The `EventQueue` is used by the executor to send events back to the client.
13 |
14 | ## Helloworld Agent Executor
15 |
16 | Let's look at `agent_executor.py`. It defines `HelloWorldAgentExecutor`.
17 |
18 | 1. **The Agent (`HelloWorldAgent`)**:
19 | This is a simple helper class that encapsulates the actual "business logic".
20 |
21 | ```python { .no-copy }
22 | --8<-- "https://raw.githubusercontent.com/google-a2a/a2a-samples/refs/heads/main/samples/python/agents/helloworld/agent_executor.py:HelloWorldAgent"
23 | ```
24 |
25 | It has a simple `invoke` method that returns the string "Hello World".
26 |
27 | 2. **The Executor (`HelloWorldAgentExecutor`)**:
28 | This class implements the `AgentExecutor` interface.
29 |
30 | - **`__init__`**:
31 |
32 | ```python { .no-copy }
33 | --8<-- "https://raw.githubusercontent.com/google-a2a/a2a-samples/refs/heads/main/samples/python/agents/helloworld/agent_executor.py:HelloWorldAgentExecutor_init"
34 | ```
35 |
36 | It instantiates the `HelloWorldAgent`.
37 |
38 | - **`execute`**:
39 |
40 | ```python { .no-copy }
41 | --8<-- "https://raw.githubusercontent.com/google-a2a/a2a-samples/refs/heads/main/samples/python/agents/helloworld/agent_executor.py:HelloWorldAgentExecutor_execute"
42 | ```
43 |
44 | When a `message/send` or `message/stream` request comes in (both are handled by `execute` in this simplified executor):
45 |
46 | 1. It calls `self.agent.invoke()` to get the "Hello World" string.
47 | 2. It creates an A2A `Message` object using the `new_agent_text_message` utility function.
48 | 3. It enqueues this message onto the `event_queue`. The underlying `DefaultRequestHandler` will then process this queue to send the response(s) to the client. For a single message like this, it will result in a single response for `message/send` or a single event for `message/stream` before the stream closes.
49 |
50 | - **`cancel`**:
51 | The Helloworld example's `cancel` method simply raises an exception, indicating that cancellation is not supported for this basic agent.
52 |
53 | ```python { .no-copy }
54 | --8<-- "https://raw.githubusercontent.com/google-a2a/a2a-samples/refs/heads/main/samples/python/agents/helloworld/agent_executor.py:HelloWorldAgentExecutor_cancel"
55 | ```
56 |
57 | The `AgentExecutor` acts as the bridge between the A2A protocol (managed by the request handler and server application) and your agent's specific logic. It receives context about the request and uses an event queue to communicate results or updates back.
58 |
--------------------------------------------------------------------------------
/docs/tutorials/python/5-start-server.md:
--------------------------------------------------------------------------------
1 | # 5. Starting the Server
2 |
3 | Now that we have an Agent Card and an Agent Executor, we can set up and start the A2A server.
4 |
5 | The A2A Python SDK provides an `A2AStarletteApplication` class that simplifies running an A2A-compliant HTTP server. It uses [Starlette](https://www.starlette.io/) for the web framework and is typically run with an ASGI server like [Uvicorn](https://www.uvicorn.org/).
6 |
7 | ## Server Setup in Helloworld
8 |
9 | Let's look at `__main__.py` again to see how the server is initialized and started.
10 |
11 | ```python { .no-copy }
12 | --8<-- "https://raw.githubusercontent.com/google-a2a/a2a-samples/refs/heads/main/samples/python/agents/helloworld/__main__.py"
13 | ```
14 |
15 | Let's break this down:
16 |
17 | 1. **`DefaultRequestHandler`**:
18 |
19 | - The SDK provides `DefaultRequestHandler`. This handler takes your `AgentExecutor` implementation (here, `HelloWorldAgentExecutor`) and a `TaskStore` (here, `InMemoryTaskStore`).
20 | - It routes incoming A2A RPC calls to the appropriate methods on your executor (like `execute` or `cancel`).
21 | - The `TaskStore` is used by the `DefaultRequestHandler` to manage the lifecycle of tasks, especially for stateful interactions, streaming, and resubscription. Even if your agent executor is simple, the handler needs a task store.
22 |
23 | 2. **`A2AStarletteApplication`**:
24 |
25 | - The `A2AStarletteApplication` class is instantiated with the `agent_card` and the `request_handler` (referred to as `http_handler` in its constructor).
26 | - The `agent_card` is crucial because the server will expose it at the `/.well-known/agent.json` endpoint (by default).
27 | - The `request_handler` is responsible for processing all incoming A2A method calls by interacting with your `AgentExecutor`.
28 |
29 | 3. **`uvicorn.run(server_app_builder.build(), ...)`**:
30 | - The `A2AStarletteApplication` has a `build()` method that constructs the actual Starlette application.
31 | - This application is then run using `uvicorn.run()`, making your agent accessible over HTTP.
32 | - `host='0.0.0.0'` makes the server accessible on all network interfaces on your machine.
33 | - `port=9999` specifies the port to listen on. This matches the `url` in the `AgentCard`.
34 |
35 | ## Running the Helloworld Server
36 |
37 | Navigate to the `a2a-samples` directory in your terminal (if you're not already there) and ensure your virtual environment is activated.
38 |
39 | To run the Helloworld server:
40 |
41 | ```bash
42 | # from the a2a-samples directory
43 | python samples/python/agents/helloworld/__main__.py
44 | ```
45 |
46 | You should see output similar to this, indicating the server is running:
47 |
48 | ```console { .no-copy }
49 | INFO: Started server process [xxxxx]
50 | INFO: Waiting for application startup.
51 | INFO: Application startup complete.
52 | INFO: Uvicorn running on http://0.0.0.0:9999 (Press CTRL+C to quit)
53 | ```
54 |
55 | Your A2A Helloworld agent is now live and listening for requests! In the next step, we'll interact with it.
56 |
--------------------------------------------------------------------------------
/docs/tutorials/python/6-interact-with-server.md:
--------------------------------------------------------------------------------
1 | # 6. Interacting with the Server
2 |
3 | With the Helloworld A2A server running, let's send some requests to it. The SDK includes a client (`A2AClient`) that simplifies these interactions.
4 |
5 | ## The Helloworld Test Client
6 |
7 | The `test_client.py` script demonstrates how to:
8 |
9 | 1. Fetch the Agent Card from the server.
10 | 2. Create an `A2AClient` instance.
11 | 3. Send both non-streaming (`message/send`) and streaming (`message/stream`) requests.
12 |
13 | Open a **new terminal window**, activate your virtual environment, and navigate to the `a2a-samples` directory.
14 |
15 | Activate virtual environment (Be sure to do this in the same directory where you created the virtual environment):
16 |
17 | === "Mac/Linux"
18 |
19 | ```sh
20 | source .venv/bin/activate
21 | ```
22 |
23 | === "Windows"
24 |
25 | ```powershell
26 | .venv\Scripts\activate
27 | ```
28 |
29 | Run the test client:
30 |
31 | ```bash
32 | # from the a2a-samples directory
33 | python samples/python/agents/helloworld/test_client.py
34 | ```
35 |
36 | ## Understanding the Client Code
37 |
38 | Let's look at key parts of `test_client.py`:
39 |
40 | 1. **Fetching the Agent Card & Initializing the Client**:
41 |
42 | ```python { .no-copy }
43 | --8<-- "https://raw.githubusercontent.com/google-a2a/a2a-samples/refs/heads/main/samples/python/agents/helloworld/test_client.py:A2ACardResolver"
44 | ```
45 |
46 | The `A2ACardResolver` class is a convenience. It first fetches the `AgentCard` from the server's `/.well-known/agent.json` endpoint (based on the provided base URL) and then initializes the client with it.
47 |
48 | 2. **Sending a Non-Streaming Message (`send_message`)**:
49 |
50 | ```python { .no-copy }
51 | --8<-- "https://raw.githubusercontent.com/google-a2a/a2a-samples/refs/heads/main/samples/python/agents/helloworld/test_client.py:send_message"
52 | ```
53 |
54 | - The `send_message_payload` constructs the data for `MessageSendParams`.
55 | - This is wrapped in a `SendMessageRequest`.
56 | - It includes a `message` object with the `role` set to "user" and the content in `parts`.
57 | - The Helloworld agent's `execute` method will enqueue a single "Hello World" message. The `DefaultRequestHandler` will retrieve this and send it as the response.
58 | - The `response` will be a `SendMessageResponse` object, which contains either a `SendMessageSuccessResponse` (with the agent's `Message` as the result) or a `JSONRPCErrorResponse`.
59 |
60 | 3. **Handling Task IDs (Illustrative Note for Helloworld)**:
61 |
62 | The Helloworld client (`test_client.py`) doesn't attempt `get_task` or `cancel_task` directly because the simple Helloworld agent's `execute` method, when called via `message/send`, results in the `DefaultRequestHandler` returning a direct `Message` response rather than a `Task` object. More complex agents that explicitly manage tasks (like the LangGraph example) would return a `Task` object from `message/send`, and its `id` could then be used for `get_task` or `cancel_task`.
63 |
64 | 4. **Sending a Streaming Message (`send_message_streaming`)**:
65 |
66 | ```python { .no-copy }
67 | --8<-- "https://raw.githubusercontent.com/google-a2a/a2a-samples/refs/heads/main/samples/python/agents/helloworld/test_client.py:send_message_streaming"
68 | ```
69 |
70 | - This method calls the agent's `message/stream` endpoint. The `DefaultRequestHandler` will invoke the `HelloWorldAgentExecutor.execute` method.
71 | - The `execute` method enqueues one "Hello World" message, and then the event queue is closed.
72 | - The client will receive this single message as one `SendStreamingMessageResponse` event, and then the stream will terminate.
73 | - The `stream_response` is an `AsyncGenerator`.
74 |
75 | ## Expected Output
76 |
77 | When you run `test_client.py`, you'll see JSON outputs for:
78 |
79 | - The non-streaming response (a single "Hello World" message).
80 | - The streaming response (a single "Hello World" message as one chunk, after which the stream ends).
81 |
82 | The `id` fields in the output will vary with each run.
83 |
84 | ```console { .no-copy }
85 | // Non-streaming response
86 | {"jsonrpc":"2.0","id":"xxxxxxxx","result":{"type":"message","role":"agent","parts":[{"type":"text","text":"Hello World"}],"messageId":"yyyyyyyy"}}
87 | // Streaming response (one chunk)
88 | {"jsonrpc":"2.0","id":"zzzzzzzz","result":{"type":"message","role":"agent","parts":[{"type":"text","text":"Hello World"}],"messageId":"wwwwwwww","final":true}}
89 | ```
90 |
91 | _(Actual IDs like `xxxxxxxx`, `yyyyyyyy`, `zzzzzzzz`, `wwwwwwww` will be different UUIDs/request IDs)_
92 |
93 | This confirms your server is correctly handling basic A2A interactions with the updated SDK structure!
94 |
95 | Now you can shut down the server by typing Ctrl+C in the terminal window where `__main__.py` is running.
96 |
--------------------------------------------------------------------------------
/docs/tutorials/python/7-streaming-and-multiturn.md:
--------------------------------------------------------------------------------
1 | # 7. Streaming & Multi-Turn Interactions (LangGraph Example)
2 |
3 | The Helloworld example demonstrates the basic mechanics of A2A. For more advanced features like robust streaming, task state management, and multi-turn conversations powered by an LLM, we'll turn to the LangGraph example located in [`a2a-samples/samples/python/agents/langgraph/`](https://github.com/google-a2a/a2a-samples/tree/main/samples/python/agents/langgraph).
4 |
5 | This example features a "Currency Agent" that uses the Gemini model via LangChain and LangGraph to answer currency conversion questions.
6 |
7 | ## Setting up the LangGraph Example
8 |
9 | 1. Create a [Gemini API Key](https://ai.google.dev/gemini-api/docs/api-key), if you don't already have one.
10 |
11 | 2. **Environment Variable:**
12 |
13 | Create a `.env` file in the `a2a-samples/samples/python/agents/langgraph/` directory:
14 |
15 | ```bash
16 | echo "GOOGLE_API_KEY=YOUR_API_KEY_HERE" > .env
17 | ```
18 |
19 | Replace `YOUR_API_KEY_HERE` with your actual Gemini API key.
20 |
21 | 3. **Install Dependencies (if not already covered):**
22 |
23 | The `langgraph` example has its own `pyproject.toml` which includes dependencies like `langchain-google-genai` and `langgraph`. When you installed the SDK from the `a2a-samples` root using `pip install -e .[dev]`, this should have also installed the dependencies for the workspace examples, including `langgraph-example`. If you encounter import errors, ensure your primary SDK installation from the root directory was successful.
24 |
25 | ## Running the LangGraph Server
26 |
27 | Navigate to the `a2a-samples/samples/python/agents/langgraph/app` directory in your terminal and ensure your virtual environment (from the SDK root) is activated.
28 |
29 | Start the LangGraph agent server:
30 |
31 | ```bash
32 | python __main__.py
33 | ```
34 |
35 | This will start the server, usually on `http://localhost:10000`.
36 |
37 | ## Interacting with the LangGraph Agent
38 |
39 | Open a **new terminal window**, activate your virtual environment, and navigate to `a2a-samples/samples/python/agents/langgraph/app`.
40 |
41 | Run its test client:
42 |
43 | ```bash
44 | python test_client.py
45 | ```
46 |
47 | Now, you can shut down the server by typing Ctrl+C in the terminal window where `__main__.py` is running.
48 |
49 | ## Key Features Demonstrated
50 |
51 | The `langgraph` example showcases several important A2A concepts:
52 |
53 | 1. **LLM Integration**:
54 |
55 | - `agent.py` defines `CurrencyAgent`. It uses `ChatGoogleGenerativeAI` and LangGraph's `create_react_agent` to process user queries.
56 | - This demonstrates how a real LLM can power the agent's logic.
57 |
58 | 2. **Task State Management**:
59 |
60 | - `samples/langgraph/__main__.py` initializes a `DefaultRequestHandler` with an `InMemoryTaskStore`.
61 |
62 | ```python { .no-copy }
63 | --8<-- "https://raw.githubusercontent.com/google-a2a/a2a-samples/refs/heads/main/samples/python/agents/langgraph/app/__main__.py:DefaultRequestHandler"
64 | ```
65 |
66 | - The `CurrencyAgentExecutor` (in `samples/langgraph/agent_executor.py`), when its `execute` method is called by the `DefaultRequestHandler`, interacts with the `RequestContext` which contains the current task (if any).
67 | - For `message/send`, the `DefaultRequestHandler` uses the `TaskStore` to persist and retrieve task state across interactions. The response to `message/send` will be a full `Task` object if the agent's execution flow involves multiple steps or results in a persistent task.
68 | - The `test_client.py`'s `run_single_turn_test` demonstrates getting a `Task` object back and then querying it using `get_task`.
69 |
70 | 3. **Streaming with `TaskStatusUpdateEvent` and `TaskArtifactUpdateEvent`**:
71 |
72 | - The `execute` method in `CurrencyAgentExecutor` is responsible for handling both non-streaming and streaming requests, orchestrated by the `DefaultRequestHandler`.
73 | - As the LangGraph agent processes the request (which might involve calling tools like `get_exchange_rate`), the `CurrencyAgentExecutor` enqueues different types of events onto the `EventQueue`:
74 | - `TaskStatusUpdateEvent`: For intermediate updates (e.g., "Looking up exchange rates...", "Processing the exchange rates.."). The `final` flag on these events is `False`.
75 | - `TaskArtifactUpdateEvent`: When the final answer is ready, it's enqueued as an artifact. The `lastChunk` flag is `True`.
76 | - A final `TaskStatusUpdateEvent` with `state=TaskState.completed` and `final=True` is sent to signify the end of the task for streaming.
77 | - The `test_client.py`'s `run_streaming_test` function will print these individual event chunks as they are received from the server.
78 |
79 | 4. **Multi-Turn Conversation (`TaskState.input_required`)**:
80 |
81 | - The `CurrencyAgent` can ask for clarification if a query is ambiguous (e.g., user asks "how much is 100 USD?").
82 | - When this happens, the `CurrencyAgentExecutor` will enqueue a `TaskStatusUpdateEvent` where `status.state` is `TaskState.input_required` and `status.message` contains the agent's question (e.g., "To which currency would you like to convert?"). This event will have `final=True` for the current interaction stream.
83 | - The `test_client.py`'s `run_multi_turn_test` function demonstrates this:
84 | - It sends an initial ambiguous query.
85 | - The agent responds (via the `DefaultRequestHandler` processing the enqueued events) with a `Task` whose status is `input_required`.
86 | - The client then sends a second message, including the `taskId` and `contextId` from the first turn's `Task` response, to provide the missing information ("in GBP"). This continues the same task.
87 |
88 | ## Exploring the Code
89 |
90 | Take some time to look through these files:
91 |
92 | - `__main__.py`: Server setup using `A2AStarletteApplication` and `DefaultRequestHandler`. Note the `AgentCard` definition includes `capabilities.streaming=True`.
93 | - `agent.py`: The `CurrencyAgent` with LangGraph, LLM model, and tool definitions.
94 | - `agent_executor.py`: The `CurrencyAgentExecutor` implementing the `execute` (and `cancel`) method. It uses the `RequestContext` to understand the ongoing task and the `EventQueue` to send back various events (`TaskStatusUpdateEvent`, `TaskArtifactUpdateEvent`, new `Task` object implicitly via the first event if no task exists).
95 | - `test_client.py`: Demonstrates various interaction patterns, including retrieving task IDs and using them for multi-turn conversations.
96 |
97 | This example provides a much richer illustration of how A2A facilitates complex, stateful, and asynchronous interactions between agents.
98 |
--------------------------------------------------------------------------------
/docs/tutorials/python/8-next-steps.md:
--------------------------------------------------------------------------------
1 | # Next Steps
2 |
3 | Congratulations on completing the A2A Python SDK Tutorial! You've learned how to:
4 |
5 | - Set up your environment for A2A development.
6 | - Define Agent Skills and Agent Cards using the SDK's types.
7 | - Implement a basic HelloWorld A2A server and client.
8 | - Understand and implement streaming capabilities.
9 | - Integrate a more complex agent using LangGraph, demonstrating task state management and tool use.
10 |
11 | You now have a solid foundation for building and integrating your own A2A-compliant agents.
12 |
13 | ## Where to Go From Here?
14 |
15 | Here are some ideas and resources to continue your A2A journey:
16 |
17 | - **Explore Other Examples:**
18 | - Check out the other examples in the `a2a-samples/samples/` directory in the [A2A GitHub repository](https://github.com/google-a2a/a2a-samples/tree/main/examples) for more complex agent integrations and features.
19 | - The main A2A repository also has [samples for other languages and frameworks](https://github.com/google-a2a/A2A/tree/main/samples).
20 | - **Deepen Your Protocol Understanding:**
21 | - 📚 Read the complete [A2A Protocol Documentation site](https://google.github.io/A2A/) for a comprehensive overview.
22 | - 📝 Review the detailed [A2A Protocol Specification](../../specification.md) to understand the nuances of all data structures and RPC methods.
23 | - **Review Key A2A Topics:**
24 | - [A2A and MCP](../../topics/a2a-and-mcp.md): Understand how A2A complements the Model Context Protocol for tool usage.
25 | - [Enterprise-Ready Features](../../topics/enterprise-ready.md): Learn about security, observability, and other enterprise considerations.
26 | - [Streaming & Asynchronous Operations](../../topics/streaming-and-async.md): Get more details on SSE and push notifications.
27 | - [Agent Discovery](../../topics/agent-discovery.md): Explore different ways agents can find each other.
28 | - **Build Your Own Agent:**
29 | - Try creating a new A2A agent using your favorite Python agent framework (like LangChain, CrewAI, AutoGen, Semantic Kernel, or a custom solution).
30 | - Implement the `a2a.server.AgentExecutor` interface to bridge your agent's logic with the A2A protocol.
31 | - Think about what unique skills your agent could offer and how its Agent Card would represent them.
32 | - **Experiment with Advanced Features:**
33 | - Implement robust task management with a persistent `TaskStore` if your agent handles long-running or multi-session tasks.
34 | - Explore implementing push notifications if your agent's tasks are very long-lived.
35 | - Consider more complex input and output modalities (e.g., handling file uploads/downloads, or structured data via `DataPart`).
36 | - **Contribute to the A2A Community:**
37 | - Join the discussions on the [A2A GitHub Discussions page](https://github.com/google-a2a/A2A/discussions).
38 | - Report issues or suggest improvements via [GitHub Issues](https://github.com/google-a2a/A2A/issues).
39 | - Consider contributing code, examples, or documentation. See the [CONTRIBUTING.md](https://github.com/google-a2a/A2A/blob/main/CONTRIBUTING.md) guide.
40 |
41 | The A2A protocol aims to foster an ecosystem of interoperable AI agents. By building and sharing A2A-compliant agents, you can be a part of this exciting development!
42 |
--------------------------------------------------------------------------------
/lychee.toml:
--------------------------------------------------------------------------------
1 | exclude = [
2 | 'https://fonts.gstatic.com/',
3 | 'https://fonts.googleapis.com/',
4 | 'http://go/github',
5 | 'http://go/github-googlecloudplatform',
6 | 'https://medium.com/',
7 | 'https://x.com/',
8 | 'http://localhost:12000/',
9 | 'http://localhost:10020/',
10 | 'https://www.askmarvin.ai/',
11 | 'https://www.bcg.com/',
12 | 'https://www.oracle.com/netsuite',
13 | 'https://www.spglobal.com/',
14 | 'https://www.epam.com/',
15 | 'https://www.servicenow.com/',
16 | ]
17 | exclude_path = [
18 | ".github/actions/spelling",
19 | ]
20 |
21 | max_retries = 0
22 |
--------------------------------------------------------------------------------
/mkdocs.yml:
--------------------------------------------------------------------------------
1 | # Project information
2 | site_name: Agent2Agent Protocol (A2A)
3 | site_url: https://google.github.io/A2A/
4 | site_description: >-
5 | An open protocol enabling communication and interoperability between opaque agentic applications.
6 | site_dir: site
7 |
8 | # Navigation
9 | nav:
10 | - Home: index.md
11 | - Topics:
12 | - What is A2A?: topics/what-is-a2a.md
13 | - Key Concepts: topics/key-concepts.md
14 | - A2A and MCP: topics/a2a-and-mcp.md
15 | - Agent Discovery: topics/agent-discovery.md
16 | - Enterprise-Ready Features: topics/enterprise-ready.md
17 | - Streaming & Asynchronous Operations: topics/streaming-and-async.md
18 | - Specification: specification.md
19 | - Community: community.md
20 | - Partners: partners.md
21 | - SDK Reference:
22 | - Python: sdk/python/index.md
23 | - Tutorial (Python):
24 | - Introduction: tutorials/python/1-introduction.md
25 | - Setup: tutorials/python/2-setup.md
26 | - Agent Skills & Agent Card: tutorials/python/3-agent-skills-and-card.md
27 | - Agent Executor: tutorials/python/4-agent-executor.md
28 | - Start Server: tutorials/python/5-start-server.md
29 | - Interact with Server: tutorials/python/6-interact-with-server.md
30 | - Streaming & Multiturn: tutorials/python/7-streaming-and-multiturn.md
31 | - Next Steps: tutorials/python/8-next-steps.md
32 |
33 | # Repository
34 | repo_name: google-a2a/A2A
35 | repo_url: https://github.com/google-a2a/A2A
36 |
37 | # Copyright
38 | copyright: Copyright Google 2025
39 |
40 | # Custom CSS
41 | extra_css:
42 | - stylesheets/custom.css
43 |
44 | # Configuration
45 | theme:
46 | name: material
47 | font:
48 | text: Google Sans
49 | code: Roboto Mono
50 | logo: assets/a2a-logo-white.svg
51 | favicon: assets/a2a-logo-black.svg
52 | icon:
53 | repo: fontawesome/brands/github
54 | palette:
55 | - scheme: default
56 | primary: indigo
57 | accent: white
58 | toggle:
59 | icon: material/brightness-7
60 | name: Switch to dark mode
61 | - scheme: slate
62 | primary: indigo
63 | accent: white
64 | toggle:
65 | icon: material/brightness-4
66 | name: Switch to light mode
67 | features:
68 | - content.code.annotate
69 | - content.code.copy
70 | - content.code.select
71 | - content.tabs.link
72 | - navigation.expand
73 | - navigation.footer
74 | - navigation.indexes
75 | - navigation.instant
76 | - navigation.instant.progress
77 | - navigation.path
78 | - navigation.tabs
79 | - navigation.top
80 | - navigation.tracking
81 | - toc.follow
82 |
83 | # Extensions
84 | markdown_extensions:
85 | - admonition
86 | - attr_list
87 | - md_in_html
88 | - pymdownx.details
89 | - pymdownx.emoji:
90 | emoji_index: !!python/name:material.extensions.emoji.twemoji
91 | emoji_generator: !!python/name:material.extensions.emoji.to_svg
92 | - pymdownx.highlight:
93 | anchor_linenums: true
94 | line_spans: __span
95 | pygments_lang_class: true
96 | - pymdownx.inlinehilite
97 | - pymdownx.snippets:
98 | url_download: true
99 | dedent_subsections: true
100 | - pymdownx.superfences:
101 | custom_fences:
102 | - name: mermaid
103 | class: mermaid
104 | format: !!python/name:pymdownx.superfences.fence_code_format
105 | - pymdownx.tabbed:
106 | alternate_style: true
107 | slugify: !!python/object/apply:pymdownx.slugs.slugify
108 | kwds:
109 | case: lower
110 | - toc:
111 | permalink: true
112 |
113 | # Plugins
114 | plugins:
115 | - search
116 | - redirects:
117 | redirect_maps:
118 | "spec-json.md": https://raw.githubusercontent.com/google-a2a/A2A/refs/heads/main/specification/json/a2a.json
119 | "specification/overview.md": "specification.md"
120 | "specification/agent-card.md": "specification.md#5-agent-discovery-the-agent-card"
121 | "specification/agent-to-agent-communication.md": "specification.md#6-protocol-data-objects"
122 | "specification/sample-messages.md": "specification.md#9-common-workflows-examples"
123 | "specification/details.md": "specification.md"
124 | "documentation.md": "topics/key-concepts.md"
125 | "resources.md": "index.md"
126 | "topics/push-notifications.md": "topics/streaming-and-async.md"
127 | "specification/topics/a2a_and_mcp.md": "topics/a2a-and-mcp.md"
128 | "specification/topics/agent_discovery.md": "topics/agent-discovery.md"
129 | "specification/topics/enterprise_ready.md": "topics/enterprise-ready.md"
130 | "specification/topics/push_notification.md": "topics/streaming-and-async.md"
131 | "specification/topics/push_notifications.md": "topics/streaming-and-async.md"
132 | "topics/index.md": "topics/what-is-a2a.md"
133 | # Tutorial
134 | "tutorials/index.md": "tutorials/python/1-introduction.md"
135 | "tutorials/python/index.md": "tutorials/python/1-introduction.md"
136 | "tutorials/python/1_introduction.md": "tutorials/python/1-introduction.md"
137 | "tutorials/python/3-create-project.md": "tutorials/python/2-setup.md"
138 | "tutorials/python/4-agent-skills.md": "tutorials/python/3-agent-skills-and-card.md"
139 | "tutorials/python/5-add-agent-card.md": "tutorials/python/3-agent-skills-and-card.md"
140 | "tutorials/python/6-start-server.md": "tutorials/python/5-start-server.md"
141 | "tutorials/python/7-interact-with-server.md": "tutorials/python/6-interact-with-server.md"
142 | "tutorials/python/8-agent-capabilities.md": "tutorials/python/7-streaming-and-multiturn.md"
143 | "tutorials/python/9-ollama-agent.md": "tutorials/python/7-streaming-and-multiturn.md"
144 | "tutorials/python/10-next-steps.md": "tutorials/python/8-next-steps.md"
145 | - mkdocstrings:
146 | handlers:
147 | python:
148 | options:
149 | show_root_heading: false
150 | show_object_full_path: false
151 | show_value: true
152 | show_if_no_docstring: true
153 | filters: ["!^_"]
154 | show_qualifiers: false
155 |
--------------------------------------------------------------------------------
/noxfile.py:
--------------------------------------------------------------------------------
1 | # pylint: skip-file
2 | # type: ignore
3 | # -*- coding: utf-8 -*-
4 | #
5 | # Copyright 2025 Google LLC
6 | #
7 | # Licensed under the Apache License, Version 2.0 (the "License");
8 | # you may not use this file except in compliance with the License.
9 | # You may obtain a copy of the License at
10 | #
11 | # https://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing, software
14 | # distributed under the License is distributed on an "AS IS" BASIS,
15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | # See the License for the specific language governing permissions and
17 | # limitations under the License.
18 |
19 | import os
20 | import pathlib
21 | import subprocess
22 |
23 | import nox
24 |
25 |
26 | DEFAULT_PYTHON_VERSION = '3.11'
27 |
28 | CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute()
29 |
30 | nox.options.sessions = [
31 | 'format',
32 | ]
33 |
34 | # Error if a python version is missing
35 | nox.options.error_on_missing_interpreters = True
36 |
37 |
38 | @nox.session(python=DEFAULT_PYTHON_VERSION)
39 | def format(session):
40 | """Format Python code using autoflake, pyupgrade, and ruff."""
41 | # Sort Spelling Allowlist
42 | spelling_allow_file = '.github/actions/spelling/allow.txt'
43 |
44 | with open(spelling_allow_file, encoding='utf-8') as file:
45 | unique_words = sorted(set(file))
46 |
47 | with open(spelling_allow_file, 'w', encoding='utf-8') as file:
48 | file.writelines(unique_words)
49 |
50 | format_all = False
51 |
52 | if format_all:
53 | lint_paths_py = ['.']
54 | else:
55 | target_branch = 'origin/main'
56 |
57 | unstaged_files = subprocess.run(
58 | [
59 | 'git',
60 | 'diff',
61 | '--name-only',
62 | '--diff-filter=ACMRTUXB',
63 | target_branch,
64 | ],
65 | stdout=subprocess.PIPE,
66 | text=True,
67 | check=False,
68 | ).stdout.splitlines()
69 |
70 | staged_files = subprocess.run(
71 | [
72 | 'git',
73 | 'diff',
74 | '--cached',
75 | '--name-only',
76 | '--diff-filter=ACMRTUXB',
77 | target_branch,
78 | ],
79 | stdout=subprocess.PIPE,
80 | text=True,
81 | check=False,
82 | ).stdout.splitlines()
83 |
84 | committed_files = subprocess.run(
85 | [
86 | 'git',
87 | 'diff',
88 | 'HEAD',
89 | target_branch,
90 | '--name-only',
91 | '--diff-filter=ACMRTUXB',
92 | ],
93 | stdout=subprocess.PIPE,
94 | text=True,
95 | check=False,
96 | ).stdout.splitlines()
97 |
98 | changed_files = sorted(
99 | {
100 | file
101 | for file in (unstaged_files + staged_files + committed_files)
102 | if os.path.isfile(file)
103 | }
104 | )
105 |
106 | lint_paths_py = [f for f in changed_files if f.endswith('.py')]
107 |
108 | if not lint_paths_py:
109 | session.log('No changed Python files to lint.')
110 | return
111 |
112 | session.install(
113 | 'types-requests',
114 | 'pyupgrade',
115 | 'autoflake',
116 | 'ruff',
117 | )
118 |
119 | if lint_paths_py:
120 | if not format_all:
121 | session.run(
122 | 'pyupgrade',
123 | '--exit-zero-even-if-changed',
124 | '--py311-plus',
125 | *lint_paths_py,
126 | )
127 | session.run(
128 | 'autoflake',
129 | '-i',
130 | '-r',
131 | '--remove-all-unused-imports',
132 | *lint_paths_py,
133 | )
134 | session.run(
135 | 'ruff',
136 | 'check',
137 | '--fix-only',
138 | *lint_paths_py,
139 | )
140 | session.run(
141 | 'ruff',
142 | 'format',
143 | *lint_paths_py,
144 | )
145 |
--------------------------------------------------------------------------------
/requirements-docs.txt:
--------------------------------------------------------------------------------
1 | mkdocs-material==9.6.12
2 | mkdocs-redirects==1.2.2
3 | mkdocstrings[python]
4 |
--------------------------------------------------------------------------------
/specification/json/README.md:
--------------------------------------------------------------------------------
1 | # A2A Specification JSON
2 |
3 | DO NOT EDIT `a2a.json` directly.
4 |
5 | Make all edits in [`types/src/types.ts`](https://github.com/google-a2a/A2A/blob/main/types/src/types.ts) and follow the directions in [`types/README.md`](https://github.com/google-a2a/A2A/blob/main/types/README.md)
6 |
--------------------------------------------------------------------------------
/types/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 |
--------------------------------------------------------------------------------
/types/README.md:
--------------------------------------------------------------------------------
1 | # A2A Types
2 |
3 | Core objects and method types for A2A Protocol
4 |
5 | ## Steps to update
6 |
7 | 1. Clone this repository.
8 | 2. Run `npm install`
9 | 3. Update `types.ts` with required changes
10 | 4. Run `npm run generate`, this will update `a2a.json`.
11 | 5. Verify the updates and push to the repository.
12 |
13 | **DO NOT DIRECTLY CHANGE `a2a.json` file. THIS MUST BE GENERATED USING `npm run generate`**
14 |
--------------------------------------------------------------------------------
/types/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "types",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "generate": "./node_modules/.bin/typescript-json-schema tsconfig.json \"*\" --defaultNumberType integer --required > ../specification/json/a2a.json"
7 | },
8 | "author": "",
9 | "description": "A2A Types",
10 | "dependencies": {
11 | "typescript-json-schema": "^0.65.1"
12 | },
13 | "devDependencies": {
14 | "typescript": "^5.3.3"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/types/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "noEmit": true,
4 | "emitDecoratorMetadata": true,
5 | "experimentalDecorators": true,
6 | "target": "ES5",
7 | "module": "CommonJS",
8 | "strictNullChecks": false,
9 | "skipLibCheck": true
10 | },
11 | "include": ["**/*.ts"],
12 | "exclude": ["node_modules"]
13 | }
14 |
--------------------------------------------------------------------------------