Skip to content
Open
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
176 changes: 176 additions & 0 deletions docs/usage/integrations/external-task-trigger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# External Task Trigger Integration

This document describes how an external backend system (CRM, ticket system, workflow engine, monitoring alert, etc.) can submit structured jobs into AgentTeams through the existing Manager-centered Matrix workflow.

## Why

AgentTeams currently routes all tasks through Matrix conversation — either from a human admin typing in Element Web or from the `scripts/replay-task.sh` CLI bridge. Enterprise systems produce structured jobs, not free-form chat messages. To bridge this gap, an integration needs to:

1. Accept a structured task envelope
2. Generate traceable task and correlation IDs
3. Convert the envelope into a Manager-understandable message
4. Submit through the existing Matrix task submission path
5. Return a traceable result

## What This Example Demonstrates

```
External system (CRM, ticket, workflow engine)
Structured JSON task
{team, skill, params, metadata}
Task envelope generator
(task_id + trace_id)
Manager message builder
(deterministic, parseable)
replay-task.sh (Matrix bridge)
AgentTeams Manager
(existing collaboration mechanism)
Structured result
{task_id, trace_id, status, result}
```

## How to Run

### Dry-run mode (no Matrix or LLM required)

```bash
python3 scripts/external-task-trigger.py --task scripts/example-task.json --dry-run
```

This validates the JSON input, generates task_id and trace_id, builds the Manager message, and returns a simulated result without calling Matrix.

### Live mode (requires running AgentTeams environment)

```bash
python3 scripts/external-task-trigger.py --task scripts/example-task.json
```

This uses `scripts/replay-task.sh` to authenticate via Matrix, find or create the DM room with the Manager, send the task, and wait for the Manager's reply.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Live mode relies on scripts/replay-task.sh, which hardcodes an openclaw gateway health readiness check (see replay-task.sh line ~328), so it only works when the Manager runs the OpenClaw runtime. Since other Manager runtimes (qwenpaw/copaw) are common, the documented live mode may fail out of the box. Suggest adding a note about this limitation or making the readiness check runtime-aware.


### Pipe mode

```bash
cat scripts/example-task.json | python3 scripts/external-task-trigger.py --stdin --dry-run
```

## Input Schema

Minimum required fields:

| Field | Type | Description |
|-------|------|-------------|
| `team` | string | Target team name |
| `skill` | string | Skill or capability name |
| `params` | object | Skill parameters (JSON object) |

Optional fields:

| Field | Type | Description |
|-------|------|-------------|
| `metadata.external_job_id` | string | External system's job ID for correlation |
| `metadata.context` | string | Additional context for the Manager |

Example:

```json
{
"team": "demo-team",
"skill": "analyze_request",
"params": {
"request": "Analyze this customer request and return a recommendation",
"priority": "medium"
},
"metadata": {
"external_job_id": "crm-2026-001",
"context": "Customer CRM ticket #4821"
}
}
```

## Output Schema

```json
{
"task_id": "task-da6a32f06eec",
"trace_id": "trace-530278c30bf9",
"status": "completed",
"result": "Manager's response text...",
"external_job_id": "crm-2026-001",
"submitted_at": "2026-08-11T20:49:58.568769+00:00"
}
```

| Field | Description |
|-------|-------------|
| `task_id` | Generated by the script; unique per submission |
| `trace_id` | Generated by the script; unique per submission |
| `status` | `submitted` (fire-and-forget), `completed`, or `error` |
| `result` | Manager's reply text (null for fire-and-forget) |
| `external_job_id` | Passed through from metadata for client-side correlation |
| `submitted_at` | ISO 8601 UTC timestamp |

## How It Bridges to AgentTeams

The adapter script converts the structured task into a deterministic, parseable message for the Manager:

```
[EXTERNAL_TASK]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The [EXTERNAL_TASK] envelope could be read as a Manager-understandable protocol, but the Manager has no special parser for this tag — it is a plain Matrix text message (as line 143 notes). Worth clarifying explicitly that this is a suggested human/LLM-readable convention, not a core AgentTeams protocol.

task_id: task-da6a32f06eec
trace_id: trace-530278c30bf9
external_job_id: crm-2026-001
team: demo-team
skill: analyze_request
---
params: {
"request": "Analyze this customer request and return a recommendation",
"priority": "medium"
}
context: Customer CRM ticket #4821
```

This message is sent through `scripts/replay-task.sh`, which authenticates as the admin user, finds or creates the DM room with the Manager, sends the message, and waits for the Manager's reply. The Manager receives this as a normal Matrix message and processes it through its existing task coordination workflow.

## Testing

```bash
# Run deterministic tests (no Matrix or LLM needed)
python3 -m pytest tests/test_external_task_trigger.py -v

# Or with unittest
python3 -m unittest tests.test_external_task_trigger -v
```

Tests cover:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs claim the tests cover 'Shell syntax and Python compilation checks', but no such tests exist in tests/test_external_task_trigger.py. The suite also does not exercise the subprocess invocation of replay-task.sh or the --no-wait code path, leaving the integration boundary untested. Suggest updating the claims and/or adding coverage for those paths.

- Valid JSON task creates task_id + trace_id
- external_job_id preserved through the pipeline
- Missing required fields return useful errors
- Dry-run mode does not require Matrix or LLM
- Generated Manager message contains trace_id and task_id for log correlation
- Shell syntax and Python compilation checks pass

## Limitations

**This example is not a production task API.** It demonstrates an integration pattern. Production deployments need:

- **Authentication** — API keys, OAuth, or service-to-service auth between the external system and AgentTeams
- **Authorization / RBAC** — Control which external systems can submit to which teams
- **Persistent task state** — Database or state store for task lifecycle tracking
- **Idempotency** — Prevent duplicate task submissions for the same external_job_id
- **Retry** — Handle transient Matrix or Manager failures
- **Timeouts** — Enforce maximum task execution time
- **Audit retention** — Long-term storage of task submissions and results
- **Rate limiting** — Protect the Manager from excessive submissions

For production use, consider wrapping this pattern in a service with the above controls, or contributing a formal `POST /tasks` API design to AgentTeams core.
12 changes: 12 additions & 0 deletions scripts/example-task.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"team": "demo-team",
"skill": "analyze_request",
"params": {
"request": "Analyze this customer request and return a recommendation",
"priority": "medium"
},
"metadata": {
"external_job_id": "crm-2026-001",
"context": "Customer CRM ticket #4821: Request for quarterly report analysis"
}
}
Loading
Loading