diff --git a/examples/01-exec-demo/README.md b/examples/01-exec-demo/README.md new file mode 100644 index 0000000..b6f1fbc --- /dev/null +++ b/examples/01-exec-demo/README.md @@ -0,0 +1,102 @@ +# Lesson 1 — build an A2A server from a script + +The first step in learning the `a2a` CLI is to stand up a server you can send messages to and get replies from. The CLI gives you two ready-made server modes, no A2A-specific code required. + +The simplest is `--echo`, which sends your message straight back. It is a "ping" for A2A: perfect for a first connection test. The more advanced is `--exec`: point it at any script that reads input and prints output, and it becomes a working A2A server. `--exec` is where the fun is — it turns any program into an agent for demos, testing, and small jobs. + +> `--echo` and `--exec` are built for learning, demos, and testing, not for production use. + +## What you'll learn + +- How to start the simplest server with `--echo` +- How `--exec` wraps an ordinary script as an A2A server +- How to send a one-shot message and read the reply +- How to stream a reply piece by piece + +## How `--exec` works + +The CLI hands your script the message on **stdin** and turns whatever the script prints on **stdout** into the response. The exit code sets the result: `0` succeeds, non-zero fails. Anything on **stderr** is logged and shown in the failure message. + +This example ships two small scripts: + +| File | What it does | +|---|---| +| `content-generator.sh` | Uppercases the message and adds a word count. Returns one response. | +| `a2a_unaware_agent.py` | Prints one numbered line per word, with a short delay — handy for streaming. | + +## Prerequisites + +Install the CLI (see the [repo README](../../README.md)): + +```bash +go install github.com/a2aproject/a2a-cli@latest +``` + +## Step 1 — warm up with the echo server + +Start the simplest possible server in **terminal A**: + +```bash +a2a server --echo --port 8080 +``` + +Send it a message from **terminal B** and get the same text back: + +```bash +a2a send -a http://localhost:8080 "hello world from A2A" +``` + +That is a full A2A round trip. Stop the echo server (Ctrl-C) and move on to `--exec` for something more useful. + +## Step 2 — run the scripts on their own + +Before the CLI is involved, confirm each script works on a plain pipe: + +```bash +echo "1 2 3 4 5 helloworld" | bash content-generator.sh +echo "5 4 3 2 1 helloworld" | python3 a2a_unaware_agent.py +``` + +## Step 3 — start a server from a script (terminal A) + +Wrap one of the scripts in a server: + +```bash +# Bash script — returns the whole output as one response +a2a server --exec "bash content-generator.sh" --port 8080 + +# Python script — streams one piece per line. +# -u keeps output unbuffered so pieces arrive promptly; --chunk splits on newline. +a2a server --exec "python3 -u a2a_unaware_agent.py" --chunk=$'\n' --port 8080 +``` + +Leave the server running. + +## Step 4 — send a message (terminal B) + +```bash +# Fetch the agent card to confirm the server is up +a2a card get -a http://localhost:8080 -o json + +# One-shot response +a2a send -a http://localhost:8080 "hello world from A2A" + +# Watch pieces arrive live (pair with the --chunk server above) +a2a send -a http://localhost:8080 --stream "one two three four" +``` + +## Test + +`test.sh` checks both scripts on a plain pipe — no server needed. Because `--exec` only pipes the message to stdin and reads stdout, this exercises the same path the server runs: + +```bash +bash test.sh +``` + +## Next + +You have a running agent. In [lesson 2](../02-card-and-send/) you learn the client side properly: reading the agent card, saving it, and setting it once through config so you can drop the `-a` flag from every command. + +## Learn more + +These scripts scratch the surface. The `a2a` CLI also does agent-card discovery, multi-part messages, async and streaming sends, task management, and echo and proxy server modes. Read the [a2a-cli specification](../../specification/SPEC.md) to explore everything the tool offers. diff --git a/examples/01-exec-demo/a2a_unaware_agent.py b/examples/01-exec-demo/a2a_unaware_agent.py new file mode 100755 index 0000000..575a029 --- /dev/null +++ b/examples/01-exec-demo/a2a_unaware_agent.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +"""An A2A-unaware agent. + +`a2a server --exec` pipes the incoming message text to stdin and turns +stdout into the response artifact. Exit 0 => completed, non-zero => failed. +stderr is logged by the CLI (and attached to the failure status on error). + +Run streaming chunks with: a2a server --exec "python3 -u a2a_unaware_agent.py" --chunk=$'\n' +Use `python3 -u` so stdout is unbuffered and chunks stream promptly. +""" + +import sys +import time + + +def main() -> int: + message = sys.stdin.read().strip() + if not message: + print("error: empty message", file=sys.stderr) + return 1 + + # Do the "work". Here: stream one line per word so --chunk can split on \n. + for i, word in enumerate(message.split(), start=1): + print(f"{i}. {word}") + sys.stdout.flush() + time.sleep(0.3) # visible streaming when run with --chunk=$'\n' + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/examples/01-exec-demo/content-generator.sh b/examples/01-exec-demo/content-generator.sh new file mode 100755 index 0000000..db74536 --- /dev/null +++ b/examples/01-exec-demo/content-generator.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# An A2A-unaware agent. The a2a CLI (server --exec) feeds the incoming +# message text on stdin and turns whatever we print on stdout into the +# response artifact. Exit 0 => completed, non-zero => failed. +set -euo pipefail + +# Read the whole message from stdin. +message="$(cat)" + +if [[ -z "${message// }" ]]; then + echo "error: empty message" >&2 # stderr is logged; shows up in the failure status + exit 1 +fi + +# Do the "work". Here: shout it back with a word count. +words=$(echo "$message" | wc -w | tr -d ' ') +echo "You said (${words} words): ${message^^}" diff --git a/examples/01-exec-demo/test.sh b/examples/01-exec-demo/test.sh new file mode 100755 index 0000000..5a48d0f --- /dev/null +++ b/examples/01-exec-demo/test.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Smoke-test the demo scripts without starting a server. +# --exec just pipes stdin -> stdout and checks the exit code, so testing the +# scripts on a plain pipe tests exactly what the server would run. +set -uo pipefail +cd "$(dirname "$0")" + +fails=0 +check() { # check -- output actual-exit + local name=$1 want_code=$2 want_text=$3 got_code=$5 out=$4 + if [[ "$got_code" != "$want_code" ]]; then + echo "FAIL: $name — exit $got_code, want $want_code"; ((fails++)); return + fi + if [[ -n "$want_text" && "$out" != *"$want_text"* ]]; then + echo "FAIL: $name — output missing '$want_text'"; ((fails++)); return + fi + echo "ok: $name" +} + +# content-generator.sh: uppercases and counts words, exit 0. +out=$(echo "hello world" | bash content-generator.sh); code=$? +check "bash: happy path" 0 "HELLO WORLD" "$out" "$code" + +# content-generator.sh: empty input fails with exit 1. +out=$(echo "" | bash content-generator.sh 2>/dev/null); code=$? +check "bash: empty input fails" 1 "" "$out" "$code" + +# a2a_unaware_agent.py: one numbered line per word, exit 0. +out=$(echo "one two" | python3 a2a_unaware_agent.py); code=$? +check "python: happy path" 0 "1. one" "$out" "$code" + +# a2a_unaware_agent.py: empty input fails with exit 1. +out=$(echo "" | python3 a2a_unaware_agent.py 2>/dev/null); code=$? +check "python: empty input fails" 1 "" "$out" "$code" + +echo +if ((fails)); then echo "$fails test(s) failed"; exit 1; fi +echo "all tests passed" diff --git a/examples/02-card-and-send/.env.example b/examples/02-card-and-send/.env.example new file mode 100644 index 0000000..2a4ebb0 --- /dev/null +++ b/examples/02-card-and-send/.env.example @@ -0,0 +1,3 @@ +# Copy to .env so the a2a CLI picks it up automatically. +# With the agent card set here, you can drop the -a flag on every command. +A2ACLI_AGENT_CARD=http://localhost:8090 diff --git a/examples/02-card-and-send/README.md b/examples/02-card-and-send/README.md new file mode 100644 index 0000000..d9f4115 --- /dev/null +++ b/examples/02-card-and-send/README.md @@ -0,0 +1,115 @@ +# Lesson 2 — discover and talk to an agent + +In lesson 1 you started a server. Now learn the client side: read an agent's card, save it, set it once through config, and send a message. + +## What you'll learn + +- What an **agent card** is and how to fetch it, plain and as JSON +- How to export a card to a file +- How to set the agent through a `.env` file so you can drop the `-a` flag +- How to send a simple text message + +## Prerequisites + +The `a2a` CLI installed (see the [repo README](../../README.md)). This lesson uses the built-in **echo** server, so there is nothing to write and you do not need to have finished lesson 1 first. + +## Start the agent (terminal A) + +The echo server sends your message straight back — a simple partner for learning the client: + +```bash +a2a server --echo --port 8090 --name "Echo Agent" +``` + +Leave it running. Do everything below in **terminal B**. + +## Step 1 — get the agent card + +Every A2A agent publishes an **agent card** that describes who it is and how to reach it. Fetch it: + +```bash +a2a card get http://localhost:8090 +``` + +```text +Echo Agent + URL: http://localhost:8090 + Version: 1.0.0 +``` + +Add `-o json` for the raw card — useful for scripts and for saving it: + +```bash +a2a card get http://localhost:8090 -o json +``` + +## Step 2 — export the card + +Save the card to a file so you can inspect it or serve it later: + +```bash +a2a card get http://localhost:8090 -o json > agent-card.json +``` + +## Step 3 — set the card through config + +Typing `-a http://localhost:8090` on every command gets old. Put it in a `.env` file instead: + +```bash +cp .env.example .env +``` + +This `.env` contains the following: + +```dotenv +A2ACLI_AGENT_CARD=http://localhost:8090 +``` + +The CLI reads `.env` from the working directory automatically, so you can now drop `-a`: + +```bash +a2a card get # uses A2ACLI_AGENT_CARD from .env +a2a config show # confirm the value and where it resolved from +``` + +```text +SETTING VALUE SOURCE +agent-card http://localhost:8090 local-file +... +``` + +The `local-file` source means the value came from a `.env` file in the working directory. + +## Step 4 — send a message + +The echo agent sends your text right back. Every `send` runs as a task, so the CLI prints the task, its status, and the reply in the artifacts: + +```bash +a2a send "hello world from A2A" +``` + +```text +Task: 01a08152-ae99-73ae-98a3-58b82e14bde0 +Context: 01a08152-ae99-74bc-bfc7-d6ce8b2c74d2 +Status: completed (2026-09-08T14:01:14Z) +Artifacts: + [01a08152-ae99-75cd-891b-cceb14223d58] hello world from A2A +History: + [user] hello world from A2A +``` + +## Run the whole lesson + +`run.sh` does every step above — start the agent, read and export the card, set config, and send a message — then stops the agent: + +```bash +bash run.sh +``` + +## Next + +Lesson 3 shows the three ways to [configure the CLI](../03-config/) and lists every setting you can change. + +## Learn more + +Read the [a2a-cli specification](../../specification/SPEC.md) for the full set of commands and flags. diff --git a/examples/02-card-and-send/run.sh b/examples/02-card-and-send/run.sh new file mode 100755 index 0000000..89fc61b --- /dev/null +++ b/examples/02-card-and-send/run.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# Lesson 2, end to end: start the agent, read its card, set config, send a message. +# Requires the `a2a` CLI on your PATH (go install github.com/a2aproject/a2a-cli@latest). +set -uo pipefail +cd "$(dirname "$0")" + +# Use the a2a CLI; if it is installed as a2a-cli, alias it. +shopt -s expand_aliases +type a2a >/dev/null 2>&1 || alias a2a=a2a-cli + +PORT=8090 +URL="http://localhost:$PORT" + +# Start the built-in echo server in the background; stop it on exit. +a2a server --echo --name "Echo Agent" --port "$PORT" --quiet & +SERVER_PID=$! +trap 'kill "$SERVER_PID" 2>/dev/null' EXIT + +# Wait for it to accept requests. +for _ in $(seq 1 20); do + a2a card get "$URL" >/dev/null 2>&1 && break + sleep 0.25 +done + +echo "== card get ==" +a2a card get "$URL" + +echo; echo "== card get -o json ==" +a2a card get "$URL" -o json + +echo; echo "== export the card to agent-card.json ==" +a2a card get "$URL" -o json > agent-card.json +echo "wrote agent-card.json" + +echo; echo "== set the card via .env, then drop -a ==" +echo "A2ACLI_AGENT_CARD=$URL" > .env +a2a config show + +echo; echo "== send a text message ==" +a2a send "hello world from A2A" diff --git a/examples/03-config/.env.example b/examples/03-config/.env.example new file mode 100644 index 0000000..dd54672 --- /dev/null +++ b/examples/03-config/.env.example @@ -0,0 +1,8 @@ +# Copy to .env so the a2a CLI picks it up automatically from this folder. +# Every A2ACLI_* variable maps to a flag; see the README for the full list. +A2ACLI_AGENT_CARD=http://localhost:8090 + +# A few more you might set: +# A2ACLI_OUTPUT=json +# A2ACLI_TIMEOUT=60s +# A2ACLI_TRANSPORT=rest,jsonrpc diff --git a/examples/03-config/README.md b/examples/03-config/README.md new file mode 100644 index 0000000..7cb7990 --- /dev/null +++ b/examples/03-config/README.md @@ -0,0 +1,124 @@ +# Lesson 3 — configure the CLI + +In lesson 2 you set the agent card in a `.env` file. That is one of three ways to give the `a2a` CLI a setting. This lesson covers all three. It also shows how `a2a config show` reveals which one won, and lists every setting you can configure. + +## What you'll learn + +- The three ways to pass a setting: a CLI flag, a session environment variable, and a `.env` file +- Which one to reach for, and why flags are best for agentic tools +- How `a2a config show` reports the effective value and where it came from +- Every setting you can configure, with its environment variable and default + +## Prerequisites + +The `a2a` CLI installed (see the [repo README](../../README.md)). For the `send` step, start a throwaway echo server in **terminal A**: + +```bash +a2a server --echo --port 8090 +``` + +An echo server sends your message straight back, so you can see requests land. Do everything below in **terminal B**. + +## The three ways to set a value + +### (a) Pass it on the command line + +Set the value right where you run the command: + +```bash +a2a card get -a http://localhost:8090 +a2a send -a http://localhost:8090 -o json "hello" +``` + +**Recommended for agentic tools and scripts.** The command carries its own settings, so anyone reading it sees exactly which agent the request goes to. Nothing is hidden in the environment or a file. + +### (b) Set a session environment variable + +Export a setting once and every command in that shell session picks it up. It lasts until you close the session: + +```bash +export A2ACLI_AGENT_CARD=http://localhost:8090 + +a2a card get # no -a needed +a2a send "hello" # runs as a task; the reply is in the artifacts +``` + +Good for a focused session against one agent, without editing any file. + +### (c) Put it in a `.env` file + +For a setting you want every time you work in a folder, write it to `.env`: + +```bash +echo "A2ACLI_AGENT_CARD=http://localhost:8090" > .env + +a2a card get # reads .env from the working directory +``` + +The CLI reads `.env` from the working directory automatically. Point at a different file with `--config ./other.env`. + +## See what won: `a2a config show` + +Settings can come from several places at once. `config show` prints the effective value and the source it resolved from: + +```bash +a2a config show +``` + +```text +SETTING VALUE SOURCE +agent-card http://localhost:8090 env +output text default +timeout 30s default +... +``` + +Add `-o json` for a machine-readable version. Credential settings such as `auth` are shown as ``. + +## Precedence + +When the same setting is given in more than one place, the CLI uses the first match in this order: + +1. a command-line flag +2. a session environment variable +3. the local `.env` (the file named by `--config`, or the nearest `.env` above the working directory) +4. the global `.env` at `~/.config/a2a-cli/.env` +5. the built-in default + +## All settings you can configure + +Set any of these as a flag, an environment variable, or a `.env` entry. The table lists each one with its variable name and default. The variable name is always the flag name in capitals, with a `A2ACLI_` prefix. + +| Setting | Short | Environment variable | Default | Purpose | +|---|---|---|---|---| +| `--agent-card` | `-a` | `A2ACLI_AGENT_CARD` | (unset) | Agent Card reference: host, card URL, or file path | +| `--endpoint` | `-e` | `A2ACLI_ENDPOINT` | (unset) | Direct interface URL; skips card resolution | +| `--transport` | | `A2ACLI_TRANSPORT` | (card order) | Transport preference: `rest`, `jsonrpc`, `grpc` | +| `--a2a-version` | | `A2ACLI_A2A_VERSION` | (unset) | A2A protocol version to advertise to the server | +| `--output` | `-o` | `A2ACLI_OUTPUT` | `text` | Output format: `text`, `json`, or `jsonl` | +| `--svc-param` | | `A2ACLI_SVC_PARAM` | (unset) | Service parameter, `key=value` | +| `--auth` | | `A2ACLI_AUTH` | (unset) | Authorization credentials (redacted in `config show`) | +| `--tenant` | | `A2ACLI_TENANT` | (unset) | Tenant identifier, sent on every request | +| `--timeout` | | `A2ACLI_TIMEOUT` | `30s` | Request timeout | +| `--verbose` | `-v` | `A2ACLI_VERBOSE` | `false` | Verbose output to stderr | +| `--insecure` | | `A2ACLI_INSECURE` | `false` | Use plaintext gRPC credentials | + +`--stream`, `--config`, `--help`, and `--version` must be passed as flags; they are never read from the environment or a `.env` file. + +> Store secrets such as `--auth` only in files you keep private. + +## Run the whole lesson + +`run.sh` starts an echo server, then walks through the three methods and `config show`: + +```bash +bash run.sh +``` + +## Next + +Lesson 4 goes deeper into [messages and tasks](../04-messages-and-tasks/). You will build multi-part messages, stream replies, and send async. + +## Learn more + +Read the [a2a-cli specification](../../specification/SPEC.md) for the full set of commands and flags. diff --git a/examples/03-config/run.sh b/examples/03-config/run.sh new file mode 100755 index 0000000..0f46bc5 --- /dev/null +++ b/examples/03-config/run.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Lesson 3, end to end: the three ways to set a value, and `config show`. +# Requires the `a2a` CLI on your PATH (go install github.com/a2aproject/a2a-cli@latest). +set -uo pipefail +cd "$(dirname "$0")" + +# Use the a2a CLI; if it is installed as a2a-cli, alias it. +shopt -s expand_aliases +type a2a >/dev/null 2>&1 || alias a2a=a2a-cli + +PORT=8090 +URL="http://localhost:$PORT" + +# Start a throwaway echo server in the background; stop it on exit. +a2a server --echo --port "$PORT" --quiet & +SERVER_PID=$! +trap 'kill "$SERVER_PID" 2>/dev/null; rm -f .env' EXIT + +# Wait for it to accept requests. +for _ in $(seq 1 20); do + a2a card get "$URL" >/dev/null 2>&1 && break + sleep 0.25 +done + +echo "== (a) pass it on the command line ==" +a2a send -a "$URL" "hello from a flag" + +echo; echo "== (b) session environment variable ==" +export A2ACLI_AGENT_CARD="$URL" +a2a send "hello from an env var" + +echo; echo "== (c) .env file (unset the env var first so the file is used) ==" +unset A2ACLI_AGENT_CARD +echo "A2ACLI_AGENT_CARD=$URL" > .env +a2a send "hello from .env" + +echo; echo "== config show: effective values and their sources ==" +a2a config show diff --git a/examples/04-messages-and-tasks/README.md b/examples/04-messages-and-tasks/README.md new file mode 100644 index 0000000..75a4f28 --- /dev/null +++ b/examples/04-messages-and-tasks/README.md @@ -0,0 +1,95 @@ +# Lesson 4 — messages and tasks + +You can already talk to an agent. This lesson explores two richer areas. First, building a message from several **parts**. Second, the **task** every send creates. + +## What you'll learn + +- The three kinds of message part: text, file, and data +- How to combine parts in one message +- How to stream a reply and how to send async +- How a send maps to a task, and the `task` commands for servers that keep tasks + +## Prerequisites + +The `a2a` CLI installed (see the [repo README](../../README.md)). This lesson reuses the Python script from [lesson 1](../01-exec-demo/), whose short per-word delay makes streaming easy to watch. You do not need to have finished the earlier lessons first. + +## Start the agent + +Run the agent in **terminal A**: + +```bash +a2a server --exec "python3 -u ../01-exec-demo/a2a_unaware_agent.py" --name "Word Numberer" --port 8080 +``` + +Set the card once in **terminal B** so the commands below stay short: + +```bash +echo "A2ACLI_AGENT_CARD=http://localhost:8080" > .env +``` + +## Messages + +A message is one or more **parts**, sent in the order you list them. There are three kinds: + +```bash +# Text part (a trailing string is shorthand for a single text part) +a2a send --text-part "number these words" + +# File part — a local path is inlined; a URL is sent by reference +a2a send --file-part note.txt --media-type text/plain + +# Data part — structured JSON, from a file or inline +a2a send --data-part priority.json +a2a send --data-part '{"priority":"high"}' + +# Combine parts in order +a2a send --text-part "with an attachment" --file-part note.txt --media-type text/plain +``` + +> The CLI flattens every part into text on the script's stdin, so this demo agent numbers all of them — including the file's name and metadata. Add `-o json` or `--verbose` to see the full message the CLI builds. + +### Streaming and async + +```bash +# Stream the response as it is produced +a2a send --stream "one two three four five" + +# Fire-and-forget — returns a task id immediately +a2a send --async "one two three four five" +``` + +## Tasks + +Every `send` creates a **task**. The `--async` send prints its id and state right away: + +```text +Task: 01a08153-324e-7683-8551-320a70453e60 +Context: 01a08153-324e-7729-9632-7ecc52f71689 +Status: submitted +History: + [user] one two three four five +``` + +Once you have a task id, the `task` commands inspect and manage it: + +```bash +a2a task get # inspect one task +a2a task get --history 10 -o json +a2a task list --status completed --limit 20 # list recent tasks +a2a task subscribe # follow it until it finishes +a2a task cancel # cancel it +``` + +> These commands need a server that **keeps** its tasks. The demo `--exec` server runs each request synchronously and does not store them, so against it the send commands above work but `task get`/`list`/`subscribe`/`cancel` return an error. Point them at a task-backed A2A server to see them in action. + +## Run the whole lesson + +`run.sh` starts the agent and walks through the message, streaming, and async commands, then stops the agent: + +```bash +bash run.sh +``` + +## Learn more + +Read the [a2a-cli specification](../../specification/SPEC.md) for the full set of commands and flags. diff --git a/examples/04-messages-and-tasks/note.txt b/examples/04-messages-and-tasks/note.txt new file mode 100644 index 0000000..c496f52 --- /dev/null +++ b/examples/04-messages-and-tasks/note.txt @@ -0,0 +1 @@ +A small local file to attach as a file part. diff --git a/examples/04-messages-and-tasks/priority.json b/examples/04-messages-and-tasks/priority.json new file mode 100644 index 0000000..3ab1c5e --- /dev/null +++ b/examples/04-messages-and-tasks/priority.json @@ -0,0 +1 @@ +{"priority": "high", "topic": "demo"} diff --git a/examples/04-messages-and-tasks/run.sh b/examples/04-messages-and-tasks/run.sh new file mode 100755 index 0000000..78f1dfb --- /dev/null +++ b/examples/04-messages-and-tasks/run.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# Lesson 4, end to end: multi-part messages, streaming, and async. +# Requires the `a2a` CLI on your PATH (go install github.com/a2aproject/a2a-cli@latest). +set -uo pipefail +cd "$(dirname "$0")" + +# Use the a2a CLI; if it is installed as a2a-cli, alias it. +shopt -s expand_aliases +type a2a >/dev/null 2>&1 || alias a2a=a2a-cli + +PORT=8080 +URL="http://localhost:$PORT" +export A2ACLI_AGENT_CARD="$URL" # so the client commands can skip -a + +# Start the lesson 1 script as a server in the background; stop it on exit. +a2a server --exec "python3 -u ../01-exec-demo/a2a_unaware_agent.py" --name "Word Numberer" --port "$PORT" --quiet & +SERVER_PID=$! +trap 'kill "$SERVER_PID" 2>/dev/null' EXIT + +for _ in $(seq 1 20); do + a2a card get >/dev/null 2>&1 && break + sleep 0.25 +done + +echo "== text part (shorthand) ==" +a2a send "number these words" + +echo; echo "== file part ==" +a2a send --file-part note.txt --media-type text/plain "with an attachment" + +echo; echo "== data part (inline) ==" +a2a send --data-part '{"priority":"high"}' "with data" + +echo; echo "== streaming ==" +a2a send --stream "one two three four five" + +echo; echo "== async: returns a task id ==" +a2a send --async "one two three four five" + +# The `task get`/`list`/`subscribe`/`cancel` commands need a server that keeps +# its tasks. This demo `--exec` server runs synchronously and does not store +# them, so those commands are covered in the README rather than run here. diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..61e0606 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,35 @@ +# Cookbook: Learn the a2a CLI by example + +> New to the `a2a` CLI? Start with the [repo README](../README.md), then keep the [command reference](../internal/) handy. + +👋 Welcome to the A2A CLI Cookbook. + +This is a short, hands-on course. Each lesson is a small folder you can run on its own, and each one builds on the last. As you progress you will see how capable the `a2a` CLI is and get to know its richer features. + +To get started you need only the `a2a` CLI installed. Every lesson starts its own example agent, so you can jump straight to any one of them. + +## Lessons + +### 1. Build a quick A2A server — [`01-exec-demo/`](01-exec-demo/) + +The `a2a` CLI is a client for A2A servers. It sends messages, tracks task progress, and fetches results. So first you need a server to talk to. + +Learn how to stand up a simple demo server. You will turn an ordinary script into a working A2A server with `--exec`, then send it a message and read the reply. No A2A-specific code required. + +### 2. Discover and talk to an agent — [`02-card-and-send/`](02-card-and-send/) + +Before you can use an agent, you need to know what it can do. Every A2A agent answers that with an **agent card**. + +Learn the client side: read an agent's card, save it, set it once through config, and send a text message. + +### 3. Configure the CLI — [`03-config/`](03-config/) + +Learn the three ways to pass a setting: a CLI flag, a session environment variable, and a `.env` file. See how `a2a config show` tells you which one won, plus a table of every setting you can configure. + +### 4. Messages and tasks — [`04-messages-and-tasks/`](04-messages-and-tasks/) + +Go deeper: build messages from text, file, and data parts; stream a reply; and send async to get back a task id and watch its lifecycle. Includes a reference for the `task` commands. + +## Learn more + +Read the [a2a-cli specification](../specification/SPEC.md) for everything the tool offers.