Merge pull request #5 from living-ip/leo-disposable-test-agent

Add disposable Leo Telegram test agent
This commit is contained in:
twentyOne2x 2026-06-20 01:48:53 +02:00 committed by GitHub
commit 4cc6a5d06e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 126 additions and 0 deletions

View file

@ -0,0 +1,60 @@
# Leo Disposable Test Agent
## Working Target
Run a second Leo Telegram transport against `https://leo.livingip.xyz/api/agents/leo/chat` without touching the production `@TeleoHumanBot` token or `teleo-agent@leo` service.
## Why
Production Leo is currently blocked by a Telegram `getUpdates` conflict from an unseen consumer. A disposable bot avoids that conflict by using a separate Telegram bot token and service instance.
## Secret Boundary
Do not commit the bot token. Store it only on the VPS as:
```text
/opt/teleo-eval/secrets/leo-test-telegram-bot-token
```
The file should be readable by the `teleo` runtime user and should not be printed in logs.
## Boot
After syncing this branch or PR to the VPS:
```sh
sudo -u teleo /opt/teleo-eval/pipeline/.venv/bin/python3 \
/opt/teleo-eval/telegram/agent_runner.py --agent leo-test --validate
sudo systemctl start teleo-agent@leo-test
sudo systemctl is-active teleo-agent@leo-test
```
Then DM the disposable Telegram bot from a user account. Do not post into public groups for this canary.
## Evidence
Collect sanitized logs only:
```sh
journalctl -u teleo-agent@leo-test --since "10 minutes ago" --no-pager
```
Retained proof should say:
- bot token value was not printed;
- production `teleo-agent@leo` was not stopped;
- disposable service name was `teleo-agent@leo-test`;
- public HTTP Leo route responded through the Telegram transport;
- no paid x402 spend was attempted unless separately authorized.
## Tear Down
```sh
sudo systemctl stop teleo-agent@leo-test
sudo systemctl is-active teleo-agent@leo-test || true
```
## Slack Note
Slack is the preferred long-term internal transport, but this repository does not yet include a Slack bot transport. A Slack canary should be a separate PR with a Socket Mode or Events API adapter and separate `leo-slack-*` secret files.

View file

@ -0,0 +1,59 @@
# Leo Test — disposable Living IP x402 research agent
# Uses a separate Telegram bot token so test polling cannot collide with Leo prod.
# ─── Identity ────────────────────────────────────────────────────────────
name: Leo Test
handle: "@LivingIPLeoTestBot"
x_handle: "@teLEOhuman"
mention_aliases:
- "@leo-test"
- "@LivingIPLeoTestBot"
bot_token_file: leo-test-telegram-bot-token
pentagon_agent_id: livingip-leo-test
domain: collective-intelligence
domain_expertise: >
collective intelligence, Living IP strategy, agent markets, paid research,
x402 service rails, and transport canary validation
# ─── Hosted Leo Runtime ──────────────────────────────────────────────────
http_chat_proxy_url: "https://leo.livingip.xyz/api/agents/leo/chat"
respond_to_private_chats: true
# ─── KB Scope ────────────────────────────────────────────────────────────
kb_scope:
primary:
- domains/collective-intelligence
- domains/ai-alignment
- domains/space-development
- foundations
- core
# ─── Voice ───────────────────────────────────────────────────────────────
voice_summary: "Disposable Leo transport canary. Direct, proof-aware, concise."
voice_definition: |
## Register
You are Leo Test, a disposable transport canary for Living IP's Leo agent.
Be direct, proof-aware, and concise. Prefer current route/readback evidence
over broad claims.
## x402 / Paid Research
When a user asks about paid services, research spend, or x402 capability,
answer from retained Living IP runtime evidence and current route state.
Do not claim payment execution unless the HTTP route returns retained
payment/readback evidence.
## Test Boundary
Make clear that this Telegram bot is a disposable test transport. Do not
claim it is the production Leo bot.
# ─── Learnings ───────────────────────────────────────────────────────────
learnings_file: agents/leo/learnings.md
# ─── Model ───────────────────────────────────────────────────────────────
response_model: anthropic/claude-opus-4-6
triage_model: anthropic/claude-haiku-4.5
max_tokens: 500
# ─── Rate Limits ─────────────────────────────────────────────────────────
max_response_per_user_per_hour: 10

View file

@ -15,12 +15,19 @@ from http_chat_proxy import build_chat_proxy_payload, extract_chat_proxy_reply
def test_leo_config_opts_into_http_chat_proxy_without_changing_default_agents():
leo = load_agent_config(str(TELEGRAM_DIR / "agents" / "leo.yaml"))
leo_test = load_agent_config(str(TELEGRAM_DIR / "agents" / "leo-test.yaml"))
rio = load_agent_config(str(TELEGRAM_DIR / "agents" / "rio.yaml"))
assert leo.name == "Leo"
assert leo.http_chat_proxy_url == "https://leo.livingip.xyz/api/agents/leo/chat"
assert leo.respond_to_private_chats is True
assert "@teLEOhuman" in leo.mention_aliases
assert leo_test.name == "Leo Test"
assert leo_test.http_chat_proxy_url == leo.http_chat_proxy_url
assert leo_test.respond_to_private_chats is True
assert leo_test.bot_token_file == "leo-test-telegram-bot-token"
assert leo_test.bot_token_file != leo.bot_token_file
assert leo_test.handle != leo.handle
assert rio.http_chat_proxy_url is None
assert rio.respond_to_private_chats is False