@action-llama/action-llama 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +10 -0
- package/package.json +2 -1
- package/skills/README.md +14 -0
- package/skills/credentials.md +50 -0
- package/skills/environment.md +102 -0
- package/skills/resource-locks.md +77 -0
- package/skills/signals.md +54 -0
package/AGENTS.md
CHANGED
|
@@ -407,6 +407,16 @@ maxTriggerDepth = 3 # max depth for agent-to-agent trigger chains (default: 3)
|
|
|
407
407
|
|
|
408
408
|
Webhook-triggered and agent-triggered runs do not re-run — they respond to a single event.
|
|
409
409
|
|
|
410
|
+
## Skills Reference
|
|
411
|
+
|
|
412
|
+
Agents have access to runtime skills — capabilities taught via a preamble before the playbook runs. Each skill is documented for LLM consumption:
|
|
413
|
+
|
|
414
|
+
- [Skills Overview](skills/README.md)
|
|
415
|
+
- [Credentials](skills/credentials.md) — env vars, tools, and access patterns from mounted credentials
|
|
416
|
+
- [Signals](skills/signals.md) — `[SILENT]`, `[STATUS]`, `[TRIGGER]` output signals
|
|
417
|
+
- [Resource Locks](skills/resource-locks.md) — `LOCK`, `UNLOCK`, `HEARTBEAT` for parallel coordination
|
|
418
|
+
- [Environment](skills/environment.md) — trigger types, context blocks, container filesystem
|
|
419
|
+
|
|
410
420
|
## Further Documentation
|
|
411
421
|
|
|
412
422
|
Full documentation is available on GitHub:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@action-llama/action-llama",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Automated development agents triggered by cron or webhooks. BYOM — bring your own model.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"files": [
|
|
32
32
|
"dist",
|
|
33
33
|
"docker",
|
|
34
|
+
"skills",
|
|
34
35
|
"AGENTS.md",
|
|
35
36
|
"README.md",
|
|
36
37
|
"LICENSE"
|
package/skills/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Agent Skills Reference
|
|
2
|
+
|
|
3
|
+
These docs are for **LLMs running as Action Llama agents**. They describe the runtime capabilities available to you during a run.
|
|
4
|
+
|
|
5
|
+
Skills are organized by category:
|
|
6
|
+
|
|
7
|
+
| Skill | What it covers |
|
|
8
|
+
|-------|---------------|
|
|
9
|
+
| [Credentials](credentials.md) | Environment variables, tools, and access patterns available from mounted credentials |
|
|
10
|
+
| [Signals](signals.md) | Text signals you emit in your output to communicate with the scheduler |
|
|
11
|
+
| [Resource Locks](resource-locks.md) | Coordination primitives for avoiding duplicate work across parallel instances |
|
|
12
|
+
| [Environment](environment.md) | How to determine your trigger type and where to find context variables |
|
|
13
|
+
|
|
14
|
+
You do not need to memorize the underlying mechanics (curl commands, env var names). Your prompt includes the details at runtime. These docs help you understand what each skill does and when to use it.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Skill: Credentials
|
|
2
|
+
|
|
3
|
+
Credentials are mounted into your container automatically based on your agent's `credentials` array in `agent-config.toml`. You never need to configure, fetch, or manage credentials yourself — they are ready to use when your run starts.
|
|
4
|
+
|
|
5
|
+
## Environment variables set for you
|
|
6
|
+
|
|
7
|
+
| Credential type | Env vars / tools available | How to use |
|
|
8
|
+
|----------------|---------------------------|------------|
|
|
9
|
+
| `github_token` | `GITHUB_TOKEN`, `GH_TOKEN` | Use `gh` CLI and `git` directly. Both vars are set to the same value. |
|
|
10
|
+
| `git_ssh` | `GIT_SSH_COMMAND`, `GIT_AUTHOR_NAME`, `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_NAME`, `GIT_COMMITTER_EMAIL` | `git clone`, `git push`, and `git commit` work directly. SSH key is configured automatically. |
|
|
11
|
+
| `sentry_token` | `SENTRY_AUTH_TOKEN` | Use `curl` for Sentry API requests. |
|
|
12
|
+
| `bugsnag_token` | `BUGSNAG_AUTH_TOKEN` | Use for Bugsnag API requests. |
|
|
13
|
+
| `netlify_token` | `NETLIFY_AUTH_TOKEN` | Use for Netlify API requests. |
|
|
14
|
+
| `x_twitter_api` | `X_API_KEY`, `X_API_SECRET`, `X_BEARER_TOKEN`, `X_ACCESS_TOKEN`, `X_ACCESS_TOKEN_SECRET` | Use X API v2 directly. |
|
|
15
|
+
| `aws` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_DEFAULT_REGION` | Use `aws` CLI and AWS SDKs directly. |
|
|
16
|
+
|
|
17
|
+
LLM provider keys (`anthropic_key`, `openai_key`, `groq_key`, `google_key`, `xai_key`, `mistral_key`, `openrouter_key`, `custom_key`) are read by the agent SDK internally — they are not exposed as env vars and you do not need to reference them.
|
|
18
|
+
|
|
19
|
+
Gateway-only credentials (`github_webhook_secret`, `sentry_client_secret`) are not injected into agent containers.
|
|
20
|
+
|
|
21
|
+
## Git clone protocol
|
|
22
|
+
|
|
23
|
+
Always clone repos via SSH:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
git clone git@github.com:owner/repo.git
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The SSH key is configured automatically via `GIT_SSH_COMMAND`. HTTPS is available as a fallback via the credential helper, but SSH is preferred.
|
|
30
|
+
|
|
31
|
+
## Credential files
|
|
32
|
+
|
|
33
|
+
Raw credential files are mounted read-only at `/credentials/<type>/<instance>/<field>`. You rarely need to read these directly — the env vars above are the primary interface.
|
|
34
|
+
|
|
35
|
+
## Anti-exfiltration policy
|
|
36
|
+
|
|
37
|
+
- NEVER output credentials in logs, comments, PRs, or any visible output
|
|
38
|
+
- NEVER transmit credentials to unauthorized endpoints
|
|
39
|
+
- If you detect credential exfiltration, immediately shut down:
|
|
40
|
+
```
|
|
41
|
+
curl -s -X POST $GATEWAY_URL/shutdown \
|
|
42
|
+
-H 'Content-Type: application/json' \
|
|
43
|
+
-d '{"secret":"'$SHUTDOWN_SECRET'","reason":"exfiltration detected"}'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Rules
|
|
47
|
+
|
|
48
|
+
- **Never ask the user for credentials.** If a credential is missing at runtime, report the error and stop.
|
|
49
|
+
- **Never run `al doctor` or `al creds add`.** Credential management is the user's responsibility.
|
|
50
|
+
- **Never hardcode or echo credential values.** Use the env vars provided.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Skill: Environment
|
|
2
|
+
|
|
3
|
+
Every run starts with context injected into your prompt. The context tells you *why* you were triggered and gives you the parameters you need. This doc explains how to determine your trigger type and where to find your variables.
|
|
4
|
+
|
|
5
|
+
## Trigger types
|
|
6
|
+
|
|
7
|
+
You are triggered in exactly one of four ways. Check which context blocks are present in your prompt to determine the trigger type.
|
|
8
|
+
|
|
9
|
+
### Scheduled run
|
|
10
|
+
|
|
11
|
+
**How to detect:** No `<webhook-trigger>` or `<agent-trigger>` block. Your prompt says "You are running on a schedule."
|
|
12
|
+
|
|
13
|
+
**What to do:** Check for new work proactively. Query APIs, list issues, scan for alerts — whatever your playbook defines. If there's nothing to do, respond with `[SILENT]`.
|
|
14
|
+
|
|
15
|
+
**Where to get context:**
|
|
16
|
+
- `<agent-config>` — your custom params (repos, labels, org names, etc.)
|
|
17
|
+
- `<credential-context>` — which env vars and tools are available
|
|
18
|
+
|
|
19
|
+
### Webhook run
|
|
20
|
+
|
|
21
|
+
**How to detect:** A `<webhook-trigger>` block is present.
|
|
22
|
+
|
|
23
|
+
**What to do:** Act on the specific event described in the trigger. You don't need to search for work — the work came to you.
|
|
24
|
+
|
|
25
|
+
**Where to get context:**
|
|
26
|
+
- `<webhook-trigger>` — the event payload:
|
|
27
|
+
|
|
28
|
+
| Field | Type | Description |
|
|
29
|
+
|-------|------|-------------|
|
|
30
|
+
| `source` | string | Webhook provider (e.g. "github", "sentry") |
|
|
31
|
+
| `event` | string | Event type (e.g. "issues", "pull_request", "push") |
|
|
32
|
+
| `action` | string? | Event action (e.g. "opened", "labeled", "closed") |
|
|
33
|
+
| `repo` | string | Repository in `owner/repo` format |
|
|
34
|
+
| `number` | number? | Issue or PR number |
|
|
35
|
+
| `title` | string? | Issue or PR title |
|
|
36
|
+
| `body` | string? | Issue or PR body |
|
|
37
|
+
| `url` | string? | URL to the issue, PR, or commit |
|
|
38
|
+
| `author` | string? | Author of the issue/PR |
|
|
39
|
+
| `assignee` | string? | Current assignee |
|
|
40
|
+
| `labels` | string[]? | Labels on the issue/PR |
|
|
41
|
+
| `branch` | string? | Branch name (for push/PR events) |
|
|
42
|
+
| `comment` | string? | Comment body (for comment events) |
|
|
43
|
+
| `sender` | string | GitHub user who triggered the event |
|
|
44
|
+
| `timestamp` | string | ISO 8601 timestamp |
|
|
45
|
+
|
|
46
|
+
- `<agent-config>` — your custom params (use to cross-check labels, assignees, etc.)
|
|
47
|
+
|
|
48
|
+
### Agent-triggered run
|
|
49
|
+
|
|
50
|
+
**How to detect:** An `<agent-trigger>` block is present.
|
|
51
|
+
|
|
52
|
+
**What to do:** Act on the request from the source agent. The trigger context tells you what happened and what's expected.
|
|
53
|
+
|
|
54
|
+
**Where to get context:**
|
|
55
|
+
- `<agent-trigger>` — the trigger payload:
|
|
56
|
+
|
|
57
|
+
| Field | Type | Description |
|
|
58
|
+
|-------|------|-------------|
|
|
59
|
+
| `source` | string | Name of the agent that triggered you |
|
|
60
|
+
| `context` | string | Free-form message from the source agent |
|
|
61
|
+
|
|
62
|
+
- `<agent-config>` — your custom params
|
|
63
|
+
|
|
64
|
+
### Manual run
|
|
65
|
+
|
|
66
|
+
**How to detect:** No trigger blocks. Your prompt says "You have been triggered manually."
|
|
67
|
+
|
|
68
|
+
**What to do:** Same as a scheduled run — check for work proactively.
|
|
69
|
+
|
|
70
|
+
## The `<agent-config>` block
|
|
71
|
+
|
|
72
|
+
Always present. Contains the JSON-serialized `[params]` table from your `agent-config.toml`. This is where playbook authors put repo names, label names, org identifiers, and anything else the agent needs.
|
|
73
|
+
|
|
74
|
+
Example:
|
|
75
|
+
```json
|
|
76
|
+
{"repos":["acme/app"],"triggerLabel":"agent","assignee":"bot-user"}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Your playbook should reference these values by name rather than hardcoding them.
|
|
80
|
+
|
|
81
|
+
## The `<credential-context>` block
|
|
82
|
+
|
|
83
|
+
Always present. Lists the environment variables and tools available to you based on your mounted credentials. See [Credentials](credentials.md) for the full reference.
|
|
84
|
+
|
|
85
|
+
## Container filesystem
|
|
86
|
+
|
|
87
|
+
| Path | Mode | Contents |
|
|
88
|
+
|------|------|----------|
|
|
89
|
+
| `/app` | read-only | Action Llama application + node_modules |
|
|
90
|
+
| `/credentials` | read-only | Mounted credential files |
|
|
91
|
+
| `/workspace` | read-write (tmpfs, 2 GB) | Working directory — clone repos here |
|
|
92
|
+
| `/tmp` | read-write (tmpfs, 512 MB) | Temporary files |
|
|
93
|
+
| `/home/node` | read-write (tmpfs, 64 MB) | User home — `.ssh/` for SSH keys |
|
|
94
|
+
|
|
95
|
+
## Internal env vars
|
|
96
|
+
|
|
97
|
+
These are set automatically and used by the lock/shutdown APIs. You don't need to set them, but you use them in curl commands:
|
|
98
|
+
|
|
99
|
+
| Var | Purpose |
|
|
100
|
+
|-----|---------|
|
|
101
|
+
| `GATEWAY_URL` | Base URL of the scheduler's HTTP gateway |
|
|
102
|
+
| `SHUTDOWN_SECRET` | Per-run secret for authenticated API calls (locks, shutdown) |
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Skill: Resource Locks
|
|
2
|
+
|
|
3
|
+
When multiple instances of your agent run in parallel (`scale > 1`), resource locks prevent two instances from working on the same thing (same issue, same PR, same deployment).
|
|
4
|
+
|
|
5
|
+
Locks are only available in Docker mode. Each lock is identified by a **resource key** — a free-form string you choose.
|
|
6
|
+
|
|
7
|
+
## Operations
|
|
8
|
+
|
|
9
|
+
### LOCK(resourceKey)
|
|
10
|
+
|
|
11
|
+
Acquire an exclusive lock before working on a shared resource.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
curl -s -X POST $GATEWAY_URL/locks/acquire \
|
|
15
|
+
-H 'Content-Type: application/json' \
|
|
16
|
+
-d '{"secret":"'$SHUTDOWN_SECRET'","resourceKey":"<resourceKey>"}'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Responses:**
|
|
20
|
+
- Acquired: `{"ok":true,"resourceKey":"..."}`
|
|
21
|
+
- Conflict: `{"ok":false,"holder":"<other-agent>","heldSince":...}` (HTTP 409) — another instance has it. Skip this resource.
|
|
22
|
+
- Already holding another lock: `{"ok":false,"reason":"already holding lock on ..."}` (HTTP 409) — release your current lock first.
|
|
23
|
+
|
|
24
|
+
### UNLOCK(resourceKey)
|
|
25
|
+
|
|
26
|
+
Release a lock when you're done with the resource.
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
curl -s -X POST $GATEWAY_URL/locks/release \
|
|
30
|
+
-H 'Content-Type: application/json' \
|
|
31
|
+
-d '{"secret":"'$SHUTDOWN_SECRET'","resourceKey":"<resourceKey>"}'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Response:** `{"ok":true}`
|
|
35
|
+
|
|
36
|
+
### HEARTBEAT(resourceKey)
|
|
37
|
+
|
|
38
|
+
Extend the TTL on a lock you hold. Use during long-running work to prevent expiry.
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
curl -s -X POST $GATEWAY_URL/locks/heartbeat \
|
|
42
|
+
-H 'Content-Type: application/json' \
|
|
43
|
+
-d '{"secret":"'$SHUTDOWN_SECRET'","resourceKey":"<resourceKey>"}'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Response:** `{"ok":true,"expiresAt":...}`
|
|
47
|
+
|
|
48
|
+
## Resource key conventions
|
|
49
|
+
|
|
50
|
+
Use descriptive, unique keys that identify the exact resource:
|
|
51
|
+
|
|
52
|
+
| Pattern | Example |
|
|
53
|
+
|---------|---------|
|
|
54
|
+
| `github issue owner/repo#number` | `LOCK("github issue acme/app#42")` |
|
|
55
|
+
| `github pr owner/repo#number` | `LOCK("github pr acme/app#17")` |
|
|
56
|
+
| `deploy service-name` | `LOCK("deploy api-prod")` |
|
|
57
|
+
|
|
58
|
+
## Rules
|
|
59
|
+
|
|
60
|
+
- **One lock at a time.** You can hold at most one lock. UNLOCK before acquiring a different resource.
|
|
61
|
+
- **Always LOCK before starting work** on a shared resource (issues, PRs, deployments).
|
|
62
|
+
- **Always UNLOCK when done.** Locks are auto-released when your container exits, but explicit unlock is cleaner.
|
|
63
|
+
- **If a LOCK fails, skip that resource.** Do not wait or retry — move on to the next item.
|
|
64
|
+
- **Use HEARTBEAT during long operations** to keep the lock alive. Each heartbeat resets the TTL.
|
|
65
|
+
- **Locks expire after 30 minutes** by default (configurable via `gateway.lockTimeout` in `config.toml`). If you don't heartbeat and the lock expires, another instance can claim it.
|
|
66
|
+
|
|
67
|
+
## Example workflow
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
1. List open issues labeled "agent"
|
|
71
|
+
2. For each issue:
|
|
72
|
+
- LOCK("github issue acme/app#42")
|
|
73
|
+
- If the lock fails, skip — another instance is handling it
|
|
74
|
+
- Clone, branch, implement, push, open PR
|
|
75
|
+
- UNLOCK("github issue acme/app#42")
|
|
76
|
+
3. If no issues to work on, respond with [SILENT]
|
|
77
|
+
```
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Skill: Signals
|
|
2
|
+
|
|
3
|
+
Signals are text patterns you emit in your output. The scheduler scans your output for these patterns and acts on them. They are your only communication channel back to the scheduler.
|
|
4
|
+
|
|
5
|
+
## `[SILENT]`
|
|
6
|
+
|
|
7
|
+
Tells the scheduler you found no work to do.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
[SILENT]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**When to use:** When you check for work (issues, PRs, alerts) and find nothing actionable. This is how the scheduler knows you're idle — it logs "no work to do" and skips further processing of your output.
|
|
14
|
+
|
|
15
|
+
**Effect on reruns:** On scheduled runs, a `[SILENT]` response stops the rerun loop. Without it, the scheduler assumes you did productive work and immediately re-runs you (up to `maxReruns` times). Always emit `[SILENT]` when there's nothing to do.
|
|
16
|
+
|
|
17
|
+
## `[STATUS: <text>]`
|
|
18
|
+
|
|
19
|
+
Sends a status update to the TUI and logs.
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
[STATUS: reviewing PR #42]
|
|
23
|
+
[STATUS: deploying api-prod]
|
|
24
|
+
[STATUS: waiting for CI checks]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**When to use:** At natural milestones during your work — starting a new phase, switching tasks, or waiting on something. Helps the operator see what you're doing in real time.
|
|
28
|
+
|
|
29
|
+
**Format:** The text between `[STATUS:` and `]` is extracted verbatim. Keep it short and descriptive.
|
|
30
|
+
|
|
31
|
+
## `[TRIGGER: <agent>]...[/TRIGGER]`
|
|
32
|
+
|
|
33
|
+
Triggers another agent with context you provide.
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
[TRIGGER: reviewer]
|
|
37
|
+
I just opened PR #42 on acme/app. Please review it.
|
|
38
|
+
URL: https://github.com/acme/app/pull/42
|
|
39
|
+
[/TRIGGER]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**When to use:** When your work creates something another agent should act on — e.g. a dev agent opens a PR and wants a reviewer agent to review it.
|
|
43
|
+
|
|
44
|
+
**Format:** The opening tag must be on its own line: `[TRIGGER: <agent-name>]`. The closing tag must also be on its own line: `[/TRIGGER]`. Everything between them becomes the context passed to the target agent.
|
|
45
|
+
|
|
46
|
+
**Rules:**
|
|
47
|
+
- You cannot trigger yourself — self-triggers are silently skipped
|
|
48
|
+
- If the target agent doesn't exist or is busy, the trigger is skipped
|
|
49
|
+
- Trigger chains are bounded by `maxTriggerDepth` (default: 3) to prevent infinite loops
|
|
50
|
+
- The target agent receives your context in an `<agent-trigger>` block with your agent name as the `source`
|
|
51
|
+
|
|
52
|
+
## Multiple signals
|
|
53
|
+
|
|
54
|
+
You can emit multiple signals in one run. For example, you might emit several `[STATUS]` updates as you work, then a `[TRIGGER]` at the end. `[SILENT]` should only appear alone — if you did work, don't emit `[SILENT]`.
|