Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions examples/exec-demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# `--exec` demo — turn a script into an A2A server

Two simple, runnable scripts for demonstration. Each builds a working A2A server from an ordinary program. You write no A2A-specific code; the `a2a` CLI does the work through its `--exec` mode.

With `--exec`, 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, and anything on **stderr** is logged (and shown in the failure message).

| 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. |

## Try the scripts on their own

Run either script directly and pipe in a message:

```bash
echo "1 2 3 4 5 helloworld" | bash content-generator.sh
echo "5 4 3 2 1 helloworld" | python3 a2a_unaware_agent.py
```

## Run them as an A2A server

Install the CLI (see the [repo README](../../README.md)):

```bash
go install github.com/a2aproject/a2a-cli@latest
```

### Server Instance

Start a server that wraps one of the scripts (**terminal A**):

```bash
# Bash script — returns the whole output as one response
a2a server --exec "bash content-generator.sh" --port 8080

# Python script — stream 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
```

### Client Instance

Send a message with the client (**terminal B**):

```bash
# Know your agent
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"
```

## Learn more

These scripts scratch the surface. The `a2a` CLI does much more: agent-card discovery, direct-endpoint connections, and multi-part messages with text, file, and data parts. It also handles 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.
31 changes: 31 additions & 0 deletions examples/exec-demo/a2a_unaware_agent.py
Original file line number Diff line number Diff line change
@@ -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())
17 changes: 17 additions & 0 deletions examples/exec-demo/content-generator.sh
Original file line number Diff line number Diff line change
@@ -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^^}"