@action-llama/action-llama 0.1.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/README.md +448 -0
- package/dist/agents/container-entry.d.ts +2 -0
- package/dist/agents/container-entry.d.ts.map +1 -0
- package/dist/agents/container-entry.js +173 -0
- package/dist/agents/container-entry.js.map +1 -0
- package/dist/agents/container-runner.d.ts +20 -0
- package/dist/agents/container-runner.d.ts.map +1 -0
- package/dist/agents/container-runner.js +208 -0
- package/dist/agents/container-runner.js.map +1 -0
- package/dist/agents/definitions/dev/AGENTS.md +44 -0
- package/dist/agents/definitions/dev/config-definition.json +39 -0
- package/dist/agents/definitions/devops/AGENTS.md +33 -0
- package/dist/agents/definitions/devops/config-definition.json +37 -0
- package/dist/agents/definitions/loader.d.ts +18 -0
- package/dist/agents/definitions/loader.d.ts.map +1 -0
- package/dist/agents/definitions/loader.js +59 -0
- package/dist/agents/definitions/loader.js.map +1 -0
- package/dist/agents/definitions/reviewer/AGENTS.md +37 -0
- package/dist/agents/definitions/reviewer/config-definition.json +24 -0
- package/dist/agents/definitions/schema.d.ts +38 -0
- package/dist/agents/definitions/schema.d.ts.map +1 -0
- package/dist/agents/definitions/schema.js +97 -0
- package/dist/agents/definitions/schema.js.map +1 -0
- package/dist/agents/prompt.d.ts +6 -0
- package/dist/agents/prompt.d.ts.map +1 -0
- package/dist/agents/prompt.js +42 -0
- package/dist/agents/prompt.js.map +1 -0
- package/dist/agents/runner.d.ts +14 -0
- package/dist/agents/runner.d.ts.map +1 -0
- package/dist/agents/runner.js +148 -0
- package/dist/agents/runner.js.map +1 -0
- package/dist/broker/index.d.ts +16 -0
- package/dist/broker/index.d.ts.map +1 -0
- package/dist/broker/index.js +53 -0
- package/dist/broker/index.js.map +1 -0
- package/dist/broker/router.d.ts +13 -0
- package/dist/broker/router.d.ts.map +1 -0
- package/dist/broker/router.js +71 -0
- package/dist/broker/router.js.map +1 -0
- package/dist/broker/routes/shutdown.d.ts +4 -0
- package/dist/broker/routes/shutdown.d.ts.map +1 -0
- package/dist/broker/routes/shutdown.js +37 -0
- package/dist/broker/routes/shutdown.js.map +1 -0
- package/dist/broker/routes/webhooks.d.ts +5 -0
- package/dist/broker/routes/webhooks.d.ts.map +1 -0
- package/dist/broker/routes/webhooks.js +50 -0
- package/dist/broker/routes/webhooks.js.map +1 -0
- package/dist/cli/commands/agent/add.d.ts +5 -0
- package/dist/cli/commands/agent/add.d.ts.map +1 -0
- package/dist/cli/commands/agent/add.js +86 -0
- package/dist/cli/commands/agent/add.js.map +1 -0
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +75 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +7 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +121 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/start.d.ts +5 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +44 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +4 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +52 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +75 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/docker/container.d.ts +19 -0
- package/dist/docker/container.d.ts.map +1 -0
- package/dist/docker/container.js +73 -0
- package/dist/docker/container.js.map +1 -0
- package/dist/docker/image.d.ts +4 -0
- package/dist/docker/image.d.ts.map +1 -0
- package/dist/docker/image.js +38 -0
- package/dist/docker/image.js.map +1 -0
- package/dist/docker/network.d.ts +5 -0
- package/dist/docker/network.d.ts.map +1 -0
- package/dist/docker/network.js +23 -0
- package/dist/docker/network.js.map +1 -0
- package/dist/scheduler/event-queue.d.ts +12 -0
- package/dist/scheduler/event-queue.d.ts.map +1 -0
- package/dist/scheduler/event-queue.js +12 -0
- package/dist/scheduler/event-queue.js.map +1 -0
- package/dist/scheduler/index.d.ts +19 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +192 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/types.d.ts +14 -0
- package/dist/scheduler/types.d.ts.map +1 -0
- package/dist/scheduler/types.js +2 -0
- package/dist/scheduler/types.js.map +1 -0
- package/dist/setup/prompts.d.ts +52 -0
- package/dist/setup/prompts.d.ts.map +1 -0
- package/dist/setup/prompts.js +656 -0
- package/dist/setup/prompts.js.map +1 -0
- package/dist/setup/scaffold.d.ts +11 -0
- package/dist/setup/scaffold.d.ts.map +1 -0
- package/dist/setup/scaffold.js +70 -0
- package/dist/setup/scaffold.js.map +1 -0
- package/dist/setup/validators.d.ts +23 -0
- package/dist/setup/validators.d.ts.map +1 -0
- package/dist/setup/validators.js +61 -0
- package/dist/setup/validators.js.map +1 -0
- package/dist/shared/config.d.ts +40 -0
- package/dist/shared/config.d.ts.map +1 -0
- package/dist/shared/config.js +46 -0
- package/dist/shared/config.js.map +1 -0
- package/dist/shared/credentials.d.ts +4 -0
- package/dist/shared/credentials.d.ts.map +1 -0
- package/dist/shared/credentials.js +21 -0
- package/dist/shared/credentials.js.map +1 -0
- package/dist/shared/git.d.ts +3 -0
- package/dist/shared/git.d.ts.map +1 -0
- package/dist/shared/git.js +24 -0
- package/dist/shared/git.js.map +1 -0
- package/dist/shared/logger.d.ts +6 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/logger.js +47 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/paths.d.ts +8 -0
- package/dist/shared/paths.d.ts.map +1 -0
- package/dist/shared/paths.js +20 -0
- package/dist/shared/paths.js.map +1 -0
- package/dist/tui/App.d.ts +5 -0
- package/dist/tui/App.d.ts.map +1 -0
- package/dist/tui/App.js +85 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/render.d.ts +5 -0
- package/dist/tui/render.d.ts.map +1 -0
- package/dist/tui/render.js +9 -0
- package/dist/tui/render.js.map +1 -0
- package/dist/tui/status-tracker.d.ts +39 -0
- package/dist/tui/status-tracker.d.ts.map +1 -0
- package/dist/tui/status-tracker.js +73 -0
- package/dist/tui/status-tracker.js.map +1 -0
- package/dist/webhooks/providers/github.d.ts +9 -0
- package/dist/webhooks/providers/github.d.ts.map +1 -0
- package/dist/webhooks/providers/github.js +169 -0
- package/dist/webhooks/providers/github.js.map +1 -0
- package/dist/webhooks/registry.d.ts +13 -0
- package/dist/webhooks/registry.d.ts.map +1 -0
- package/dist/webhooks/registry.js +82 -0
- package/dist/webhooks/registry.js.map +1 -0
- package/dist/webhooks/types.d.ts +49 -0
- package/dist/webhooks/types.d.ts.map +1 -0
- package/dist/webhooks/types.js +2 -0
- package/dist/webhooks/types.js.map +1 -0
- package/docker/Dockerfile +29 -0
- package/package.json +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="action_llama.jpg" alt="Action Llama" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# Action Llama
|
|
6
|
+
|
|
7
|
+
It's like a Lambda that runs an agent. Triggered either by cron or webhooks. BYOM- bring your own model.
|
|
8
|
+
|
|
9
|
+
It's a very simple wrapper around whatever your favourite flavour of LLM is:
|
|
10
|
+
|
|
11
|
+
1. Either a webhook or cron wakes up the agent
|
|
12
|
+
2. The agent runs according the instructions in AGENTS.md you define
|
|
13
|
+
3. The agent shuts down
|
|
14
|
+
|
|
15
|
+
Allows you to create:
|
|
16
|
+
|
|
17
|
+
- A developer agent that watches for new Github issues and reacts
|
|
18
|
+
- A reviewer agent that watches for new Github Pull Requests and reviews them then merges if all ok
|
|
19
|
+
|
|
20
|
+
Have as many agents as you like. Customize the behaviour as you wish. The system is MIT licensed and fully extensible.
|
|
21
|
+
|
|
22
|
+
Built on [pi.dev](https://github.com/badlogic/pi-mono) as the agent harness.
|
|
23
|
+
|
|
24
|
+
## Built-in Agents
|
|
25
|
+
|
|
26
|
+
The project includes a few default agents to get you started
|
|
27
|
+
|
|
28
|
+
| Agent | Trigger | Action |
|
|
29
|
+
|-------|---------|--------|
|
|
30
|
+
| **Developer** | Webhook: issue labeled; or poll for labeled issues | Checks out a worktree, implements the fix/feature, runs tests, opens a PR |
|
|
31
|
+
| **PR Reviewer** | Webhook: PR opened/updated; or poll for open PRs | Reviews code for correctness, style, security; approves+merges or requests changes |
|
|
32
|
+
| **DevOps** | Poll for CI failures/Sentry errors | Creates Github issues describing problem and potential fix |
|
|
33
|
+
|
|
34
|
+
## Prerequisites
|
|
35
|
+
|
|
36
|
+
- Node.js >= 20
|
|
37
|
+
- Git
|
|
38
|
+
- Docker
|
|
39
|
+
- A GitHub Personal Access Token with `repo` and `workflow` scopes
|
|
40
|
+
- Anthropic auth — one of:
|
|
41
|
+
- Existing pi auth (`pi /login`) or Claude Code auth (`claude setup-token`)
|
|
42
|
+
- An Anthropic API key (`sk-ant-api...`)
|
|
43
|
+
- An OAuth token (`sk-ant-oat...`)
|
|
44
|
+
- (Optional) A Sentry auth token
|
|
45
|
+
- (Optional) A GitHub webhook secret (for webhook-triggered agents)
|
|
46
|
+
|
|
47
|
+
## Install
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npx @action-llama/action-llama init my-project
|
|
51
|
+
cd my-project
|
|
52
|
+
npm install
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
This creates a new project directory with a `package.json` (including `@action-llama/action-llama` as a dependency), agent configs, and credentials.
|
|
56
|
+
|
|
57
|
+
## Quick start
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# 1. Initialize a project (interactive setup)
|
|
61
|
+
npx @action-llama/action-llama init my-project
|
|
62
|
+
cd my-project
|
|
63
|
+
npm install
|
|
64
|
+
|
|
65
|
+
# 2. Start the agents
|
|
66
|
+
npx al start
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Architecture
|
|
70
|
+
|
|
71
|
+
Action Llama separates three concerns:
|
|
72
|
+
|
|
73
|
+
| Directory | Purpose | Created by |
|
|
74
|
+
|-----------|---------|------------|
|
|
75
|
+
| `~/.al-credentials/` | Secrets (shared across projects) | `al init` |
|
|
76
|
+
| `./<project-name>/` | Per-project config, agent instructions, scratch space | `al init` |
|
|
77
|
+
|
|
78
|
+
Agents run with credentials injected directly — `GITHUB_TOKEN`, `SENTRY_AUTH_TOKEN`, etc. are set as environment variables, and credential files are available at `/credentials/` in Docker mode. Agents use standard tools (`gh` CLI, `git`, `curl`) to interact with external services.
|
|
79
|
+
|
|
80
|
+
## Setup walkthrough
|
|
81
|
+
|
|
82
|
+
The setup CLI (`al init <name>`) walks through three steps:
|
|
83
|
+
|
|
84
|
+
### Step 1: Credentials
|
|
85
|
+
- Paste your GitHub PAT
|
|
86
|
+
- (Optional) Paste your Sentry auth token
|
|
87
|
+
- Choose your Anthropic authentication method:
|
|
88
|
+
- **Use existing pi auth** — if you already ran `pi /login` or `claude setup-token`
|
|
89
|
+
- **Enter an API key** — a standard `sk-ant-api...` key, validated against the API
|
|
90
|
+
- **Enter an OAuth token** — a `sk-ant-oat...` token from `claude setup-token`, format-checked
|
|
91
|
+
|
|
92
|
+
### Step 2: LLM defaults
|
|
93
|
+
- Select a model (default: `claude-sonnet-4-20250514`)
|
|
94
|
+
- Select thinking level (default: `medium`)
|
|
95
|
+
|
|
96
|
+
### Step 3: Agents
|
|
97
|
+
- Select which built-in agents to enable (dev, reviewer, devops) and/or add custom agents
|
|
98
|
+
- For each agent, configure:
|
|
99
|
+
- **Name** (allows multiple instances, e.g., `dev-frontend`, `dev-backend`)
|
|
100
|
+
- **Repos** to monitor
|
|
101
|
+
- Type-specific options: trigger label / assignee (dev), Sentry org / projects (devops)
|
|
102
|
+
- **Webhooks** — listen for GitHub events (default webhook filter per agent type)
|
|
103
|
+
- **Schedule** — poll on a cron interval (optional if webhooks are enabled)
|
|
104
|
+
- If any agent uses webhooks, you'll be asked for a **GitHub webhook secret** (used to verify `x-hub-signature-256` on incoming payloads)
|
|
105
|
+
|
|
106
|
+
## Running
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Start all agents (host mode, default)
|
|
110
|
+
npx al start
|
|
111
|
+
|
|
112
|
+
# Check agent status
|
|
113
|
+
npx al status
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The scheduler runs as a single Node.js process. Agents wake on incoming webhooks or their cron schedule (or both), do their work (or log `[SILENT]` if there's nothing to do), then wait for the next trigger. If any agent uses webhooks, a broker server starts automatically to receive `POST /webhooks/github` requests. Press `Ctrl+C` for graceful shutdown.
|
|
117
|
+
|
|
118
|
+
### Docker mode (opt-in)
|
|
119
|
+
|
|
120
|
+
When `docker.enabled` is set in `config.json`, agents run in isolated Docker containers with credentials mounted read-only at `/credentials/`. Containers have internet access and use standard tools (`gh`, `git`, `curl`) directly. A broker server provides a shutdown endpoint for the anti-exfiltration kill switch.
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Requires Docker installed and running
|
|
124
|
+
# Enable in config.json: "docker": { "enabled": true }
|
|
125
|
+
npx al start
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
See the [Docker mode](#docker-mode-1) section below for details.
|
|
129
|
+
|
|
130
|
+
### Logs
|
|
131
|
+
|
|
132
|
+
Structured JSON logs are written to daily files at `<project>/.al/logs/<agent>-<YYYY-MM-DD>.log` and also printed to stdout. In Docker mode, container logs are forwarded through the same pino logger — tool events and errors all appear in the standard log files.
|
|
133
|
+
|
|
134
|
+
## CLI commands
|
|
135
|
+
|
|
136
|
+
| Command | Description |
|
|
137
|
+
|---------|-------------|
|
|
138
|
+
| `npx @action-llama/action-llama init <name>` | Interactive setup, creates project dir + credentials |
|
|
139
|
+
| `al start` | Start scheduler (cron + webhooks) |
|
|
140
|
+
| `al status` | Show agent status |
|
|
141
|
+
| `al logs` | View agent logs |
|
|
142
|
+
| `al agent add` | Add a new agent to an existing project |
|
|
143
|
+
|
|
144
|
+
## Using the developer agent
|
|
145
|
+
|
|
146
|
+
1. Create an issue in one of your monitored repos
|
|
147
|
+
2. Add the trigger label (default: `agent`) and assign it to the configured user
|
|
148
|
+
3. The developer agent wakes (immediately via webhook, or on the next poll) and will:
|
|
149
|
+
- Find the issue via `gh issue list`
|
|
150
|
+
- Clone the repo and create a branch
|
|
151
|
+
- Read `AGENTS.md`/`CLAUDE.md` for project conventions
|
|
152
|
+
- Implement the changes, run tests
|
|
153
|
+
- Push and open a PR via `gh pr create`
|
|
154
|
+
|
|
155
|
+
## Using the PR reviewer agent
|
|
156
|
+
|
|
157
|
+
The reviewer automatically picks up open PRs on each poll. It:
|
|
158
|
+
- Gets the diff via `gh pr diff`, checks CI status
|
|
159
|
+
- Reviews for correctness, style, tests, and security
|
|
160
|
+
- Approves and squash-merges clean PRs with green CI
|
|
161
|
+
- Requests changes with specific feedback on problematic PRs
|
|
162
|
+
- Skips PRs it has already reviewed at the same commit SHA
|
|
163
|
+
|
|
164
|
+
## Using the DevOps agent
|
|
165
|
+
|
|
166
|
+
The DevOps agent monitors for failures:
|
|
167
|
+
- **GitHub Actions**: finds failed workflow runs via `gh run list`
|
|
168
|
+
- **Sentry**: finds new unresolved error groups via `curl` to the Sentry API (if configured)
|
|
169
|
+
|
|
170
|
+
For each new error, it creates a GitHub issue with the error details and a link to the source. Errors are deduplicated by fingerprint so the same failure is never filed twice.
|
|
171
|
+
|
|
172
|
+
## Project structure
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
~/.al-credentials/ # Secrets (shared across projects)
|
|
176
|
+
github-token
|
|
177
|
+
sentry-token # (optional)
|
|
178
|
+
anthropic-key # (optional, if not using pi_auth)
|
|
179
|
+
github-webhook-secret # (optional, for webhook-triggered agents)
|
|
180
|
+
|
|
181
|
+
./<project-name>/ # Per-project (created by npx @action-llama/action-llama init)
|
|
182
|
+
package.json # Includes @action-llama/action-llama as a dependency
|
|
183
|
+
config.json # Global config: docker, broker, webhooks (no secrets)
|
|
184
|
+
dev/ # Agent directory (CWD for agent sessions)
|
|
185
|
+
config.json # Agent config: repos, webhooks, schedule, prompt, etc.
|
|
186
|
+
AGENTS.md # Instructions (written during init, edit to customize)
|
|
187
|
+
dev-backend/ # Multiple instances are supported
|
|
188
|
+
config.json
|
|
189
|
+
AGENTS.md
|
|
190
|
+
reviewer/
|
|
191
|
+
config.json
|
|
192
|
+
AGENTS.md
|
|
193
|
+
devops/
|
|
194
|
+
config.json
|
|
195
|
+
AGENTS.md
|
|
196
|
+
node_modules/ # Dependencies (after npm install)
|
|
197
|
+
.workspace/ # Git clones and worktrees (gitignored)
|
|
198
|
+
.al/
|
|
199
|
+
state/{dev,dev-backend,...}/ # Dedup/tracking state per agent
|
|
200
|
+
logs/ # Structured logs
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Security
|
|
204
|
+
|
|
205
|
+
### Host mode
|
|
206
|
+
|
|
207
|
+
Secrets are isolated from agent context:
|
|
208
|
+
|
|
209
|
+
1. Credential files live in `~/.al-credentials/` (mode 600, directory mode 700)
|
|
210
|
+
2. The runner injects credentials as environment variables (`GITHUB_TOKEN`, etc.) — agents never see raw credential files
|
|
211
|
+
3. Agents use standard tools (`gh` CLI, `git`, `curl`) which read credentials from env vars
|
|
212
|
+
4. Agents have no extensions loaded (`noExtensions: true`) — only bash, read, edit, write tools for working in worktrees
|
|
213
|
+
5. Anti-exfiltration policy is injected into agent prompts — agents are instructed to never output credentials in logs, comments, or PRs
|
|
214
|
+
|
|
215
|
+
### Docker mode
|
|
216
|
+
|
|
217
|
+
Docker mode adds stronger isolation:
|
|
218
|
+
|
|
219
|
+
1. **Credentials mounted read-only** — credential files are symlinked into a temp staging dir and mounted at `/credentials/` (read-only)
|
|
220
|
+
2. **Minimal privileges** — `--read-only` root FS, `--cap-drop ALL`, `--security-opt no-new-privileges`, non-root user, PID/memory/CPU limits
|
|
221
|
+
3. **Kill switch** — each container gets a unique shutdown secret; if exfiltration is detected, the agent calls `POST /shutdown` to immediately kill the container
|
|
222
|
+
4. **Tmpfs workspace** — all writable space is tmpfs (`/workspace`, `/tmp`), nothing persists after container exit
|
|
223
|
+
5. **Standard tooling** — containers include `gh` CLI, `git`, and `curl`; no custom proxy or command routing
|
|
224
|
+
|
|
225
|
+
## Configuration
|
|
226
|
+
|
|
227
|
+
Config is split between a global `config.json` and per-agent `config.json` files.
|
|
228
|
+
|
|
229
|
+
**`<project>/config.json`** — global settings (Docker, broker, webhooks):
|
|
230
|
+
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"docker": { "enabled": false },
|
|
234
|
+
"broker": { "port": 8080 },
|
|
235
|
+
"webhooks": { "githubSecretCredential": "github-webhook-secret" }
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**`<project>/<agent>/config.json`** — per-agent (includes model):
|
|
240
|
+
|
|
241
|
+
```json
|
|
242
|
+
{
|
|
243
|
+
"credentials": ["github-token", "anthropic-key"],
|
|
244
|
+
"model": { "provider": "anthropic", "model": "claude-sonnet-4-20250514", "thinkingLevel": "medium", "authType": "pi_auth" },
|
|
245
|
+
"prompt": "An issue was just assigned to you. Implement the changes described in the issue.",
|
|
246
|
+
"repos": ["acme/frontend"],
|
|
247
|
+
"triggerLabel": "agent",
|
|
248
|
+
"assignee": "bot-user",
|
|
249
|
+
"webhooks": {
|
|
250
|
+
"filters": [{
|
|
251
|
+
"source": "github",
|
|
252
|
+
"repos": ["acme/frontend"],
|
|
253
|
+
"events": ["issues"],
|
|
254
|
+
"actions": ["labeled"],
|
|
255
|
+
"labels": ["agent"],
|
|
256
|
+
"assignee": "bot-user"
|
|
257
|
+
}]
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Agents can use webhooks, a cron schedule, or both. Add a `"schedule"` field (e.g., `"*/5 * * * *"`) for polling. Each agent carries its own model config, so you can run different agents on different models (e.g., Opus for dev, Haiku for devops).
|
|
263
|
+
|
|
264
|
+
Edit these files directly to change triggers, add repos, or switch models. Re-run `al init` for a guided reconfiguration.
|
|
265
|
+
|
|
266
|
+
### Docker config options
|
|
267
|
+
|
|
268
|
+
| Key | Default | Description |
|
|
269
|
+
|-----|---------|-------------|
|
|
270
|
+
| `docker.enabled` | `false` | Enable Docker container mode |
|
|
271
|
+
| `docker.image` | `"al-agent:latest"` | Docker image for agent containers |
|
|
272
|
+
| `docker.memory` | `"4g"` | Memory limit per container |
|
|
273
|
+
| `docker.cpus` | `2` | CPU limit per container |
|
|
274
|
+
| `docker.timeout` | `3600` | Max container runtime in seconds |
|
|
275
|
+
| `broker.port` | `8080` | Broker server listen port |
|
|
276
|
+
| `webhooks.githubSecretCredential` | `"github-webhook-secret"` | Credential name for the GitHub webhook HMAC secret |
|
|
277
|
+
|
|
278
|
+
## Webhooks
|
|
279
|
+
|
|
280
|
+
Agents can be triggered by GitHub webhooks for real-time responses instead of (or in addition to) polling. The setup wizard configures default webhook filters per agent type:
|
|
281
|
+
|
|
282
|
+
| Agent | Default filter |
|
|
283
|
+
|-------|---------------|
|
|
284
|
+
| **Developer** | `issues` event, `labeled` action, matching trigger label + assignee |
|
|
285
|
+
| **PR Reviewer** | `pull_request` event, `opened` / `synchronize` actions |
|
|
286
|
+
| **DevOps** | `workflow_run` event, `completed` action |
|
|
287
|
+
|
|
288
|
+
### Setting up the GitHub webhook
|
|
289
|
+
|
|
290
|
+
1. Run `al init` and enable webhooks for your agents — the wizard will ask for a webhook secret
|
|
291
|
+
2. In your GitHub repo (or org) settings, add a webhook:
|
|
292
|
+
- **Payload URL**: `http://<your-host>:8080/webhooks/github`
|
|
293
|
+
- **Content type**: `application/json`
|
|
294
|
+
- **Secret**: the same secret you entered during `al init`
|
|
295
|
+
- **Events**: select the events your agents listen for (or "Send me everything")
|
|
296
|
+
3. Start AL — the broker server listens for incoming webhooks automatically
|
|
297
|
+
|
|
298
|
+
Webhook payloads are validated using HMAC-SHA256 (`x-hub-signature-256`). If the signature doesn't match, the request is rejected with 401.
|
|
299
|
+
|
|
300
|
+
### Webhook filter options
|
|
301
|
+
|
|
302
|
+
Filters are configured in `<agent>/config.json` under `webhooks.filters`. Each filter can match on:
|
|
303
|
+
|
|
304
|
+
| Field | Type | Description |
|
|
305
|
+
|-------|------|-------------|
|
|
306
|
+
| `source` | `"github"` | Required — the webhook source |
|
|
307
|
+
| `repos` | `string[]` | Only match events from these repos |
|
|
308
|
+
| `events` | `string[]` | GitHub event types (`issues`, `pull_request`, `push`, etc.) |
|
|
309
|
+
| `actions` | `string[]` | Event actions (`opened`, `labeled`, `synchronize`, etc.) |
|
|
310
|
+
| `labels` | `string[]` | Match if the issue/PR has any of these labels |
|
|
311
|
+
| `assignee` | `string` | Match if assigned to this user |
|
|
312
|
+
| `author` | `string` | Match if authored by this user |
|
|
313
|
+
| `branches` | `string[]` | Match if targeting one of these branches |
|
|
314
|
+
|
|
315
|
+
All specified fields must match (AND logic). Omitted fields are not checked.
|
|
316
|
+
|
|
317
|
+
## Customizing agent behavior
|
|
318
|
+
|
|
319
|
+
Each agent has an `AGENTS.md` file written during `al init`. Edit `<project>/<agent>/AGENTS.md` to customize agent behavior — changes take effect on the next run.
|
|
320
|
+
|
|
321
|
+
Agent config values (repos, trigger label, etc.) are automatically injected into the prompt as an `<agent-config>` block, so AGENTS.md can reference them without hardcoding. When triggered by a webhook, a `<webhook-trigger>` block is also injected with event details (issue title, PR number, labels, etc.).
|
|
322
|
+
|
|
323
|
+
## Testing
|
|
324
|
+
|
|
325
|
+
Tests use [Vitest](https://vitest.dev/) with globals enabled and V8 coverage.
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
# Run all tests once
|
|
329
|
+
npm test
|
|
330
|
+
|
|
331
|
+
# Watch mode (re-runs on file changes)
|
|
332
|
+
npm run test:watch
|
|
333
|
+
|
|
334
|
+
# Run with coverage report
|
|
335
|
+
npm run test:coverage
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Test files live in `test/` mirroring the `src/` layout:
|
|
339
|
+
|
|
340
|
+
```
|
|
341
|
+
test/
|
|
342
|
+
helpers.ts # Shared test utilities
|
|
343
|
+
shared/ # Unit tests for shared modules
|
|
344
|
+
agents/ # Agent runner, prompt builder, default agent tests
|
|
345
|
+
setup/ # Setup validators + scaffolding tests
|
|
346
|
+
scheduler/ # Scheduler, webhook integration tests
|
|
347
|
+
webhooks/ # Webhook registry + GitHub provider tests
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Coverage is collected for all `src/**/*.ts` files, excluding entry points (`cli/main.ts`), interactive prompts (`setup/prompts.ts`), and pure type definitions (`scheduler/types.ts`).
|
|
351
|
+
|
|
352
|
+
## Docker mode
|
|
353
|
+
|
|
354
|
+
Docker mode runs each agent session in an isolated container. Credentials are mounted read-only at `/credentials/`, and the container has internet access to use standard tools directly.
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
HOST DOCKER (al-net)
|
|
358
|
+
┌──────────────────────────────────┐ ┌──────────────────────────────┐
|
|
359
|
+
│ Scheduler │ │ Agent Container (per run) │
|
|
360
|
+
│ generates shutdown secret │ │ pi-coding-agent session │
|
|
361
|
+
│ stages credentials │ │ coding tools (bash,r/w) │
|
|
362
|
+
│ launches container │ │ gh, git, curl │
|
|
363
|
+
│ waits for exit │ │ │
|
|
364
|
+
│ │ │ /credentials/ (read-only) │
|
|
365
|
+
│ Broker (in-process) │◄────────│ anthropic-key │
|
|
366
|
+
│ ● Health endpoint │ HTTP │ github-token │
|
|
367
|
+
│ ● Shutdown kill switch │ │ sentry-token (optional) │
|
|
368
|
+
│ ● Webhook receiver │ │ │
|
|
369
|
+
│ │ │ /workspace/ (tmpfs) │
|
|
370
|
+
│ Credentials (~/.al-creds/) │ │ Internet access: yes │
|
|
371
|
+
│ Workspace (project/.workspace/)│ └──────────────────────────────┘
|
|
372
|
+
└──────────────────────────────────┘
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Prerequisites
|
|
376
|
+
|
|
377
|
+
- Docker installed and running
|
|
378
|
+
- Set `"docker": { "enabled": true }` in `config.json`
|
|
379
|
+
|
|
380
|
+
The agent Docker image is built automatically on first run from `docker/Dockerfile`.
|
|
381
|
+
|
|
382
|
+
## Publishing to npm
|
|
383
|
+
|
|
384
|
+
The package is configured for standard npm publishing under the `@action-llama` scope.
|
|
385
|
+
|
|
386
|
+
### Prerequisites
|
|
387
|
+
|
|
388
|
+
1. An [npm account](https://www.npmjs.com/signup) with access to the `@action-llama` org
|
|
389
|
+
2. Login to npm:
|
|
390
|
+
```bash
|
|
391
|
+
npm login
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Version and publish
|
|
395
|
+
|
|
396
|
+
Use `npm version` to bump the version (updates `package.json`, creates a git tag, and pushes):
|
|
397
|
+
|
|
398
|
+
```bash
|
|
399
|
+
# Patch release (0.1.0 → 0.1.1)
|
|
400
|
+
npm version patch
|
|
401
|
+
|
|
402
|
+
# Minor release (0.1.0 → 0.2.0)
|
|
403
|
+
npm version minor
|
|
404
|
+
|
|
405
|
+
# Major release (0.1.0 → 1.0.0)
|
|
406
|
+
npm version major
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
Then publish:
|
|
410
|
+
|
|
411
|
+
```bash
|
|
412
|
+
npm publish --access public
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
The `prepublishOnly` script automatically runs the build and tests before publishing. If either fails, the publish is aborted.
|
|
416
|
+
|
|
417
|
+
### First-time publish
|
|
418
|
+
|
|
419
|
+
For the very first publish of a scoped package:
|
|
420
|
+
|
|
421
|
+
```bash
|
|
422
|
+
npm publish --access public
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
The `--access public` flag is required for scoped packages on the first publish (subsequent publishes remember the setting).
|
|
426
|
+
|
|
427
|
+
### What gets published
|
|
428
|
+
|
|
429
|
+
Only these files are included in the npm tarball (controlled by the `files` field in `package.json`):
|
|
430
|
+
|
|
431
|
+
- `dist/` — compiled JavaScript, source maps, and type declarations
|
|
432
|
+
- `docker/` — Dockerfile for container mode
|
|
433
|
+
- `README.md`
|
|
434
|
+
- `LICENSE`
|
|
435
|
+
- `package.json` (always included by npm)
|
|
436
|
+
|
|
437
|
+
### Build scripts
|
|
438
|
+
|
|
439
|
+
| Script | Description |
|
|
440
|
+
|--------|-------------|
|
|
441
|
+
| `npm run build` | Compile TypeScript to `dist/` and copy agent definition assets |
|
|
442
|
+
| `npm run clean` | Remove the `dist/` directory |
|
|
443
|
+
| `npm test` | Run all tests |
|
|
444
|
+
| `npm version <patch\|minor\|major>` | Bump version, tag, and push |
|
|
445
|
+
|
|
446
|
+
## License
|
|
447
|
+
|
|
448
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container-entry.d.ts","sourceRoot":"","sources":["../../src/agents/container-entry.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from "fs";
|
|
2
|
+
import { getModel } from "@mariozechner/pi-ai";
|
|
3
|
+
import { AuthStorage, createAgentSession, DefaultResourceLoader, SessionManager, SettingsManager, createCodingTools, } from "@mariozechner/pi-coding-agent";
|
|
4
|
+
// Structured log line — written to stdout, parsed by ContainerAgentRunner on the host
|
|
5
|
+
function emitLog(level, msg, data) {
|
|
6
|
+
console.log(JSON.stringify({ _log: true, level, msg, ...data, ts: Date.now() }));
|
|
7
|
+
}
|
|
8
|
+
function readCredential(name) {
|
|
9
|
+
const path = `/credentials/${name}`;
|
|
10
|
+
if (!existsSync(path))
|
|
11
|
+
return undefined;
|
|
12
|
+
return readFileSync(path, "utf-8").trim();
|
|
13
|
+
}
|
|
14
|
+
async function main() {
|
|
15
|
+
// Switch CWD to /workspace so child processes (git, bash, etc.) default to it.
|
|
16
|
+
// Node must resolve from /app (WORKDIR at build time), so we chdir after startup.
|
|
17
|
+
process.chdir("/workspace");
|
|
18
|
+
const brokerUrl = process.env.BROKER_URL;
|
|
19
|
+
const shutdownSecret = process.env.SHUTDOWN_SECRET;
|
|
20
|
+
// Parse agent config from env var
|
|
21
|
+
const agentConfigStr = process.env.AGENT_CONFIG;
|
|
22
|
+
if (!agentConfigStr) {
|
|
23
|
+
emitLog("error", "missing AGENT_CONFIG env var");
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const parsed = JSON.parse(agentConfigStr);
|
|
27
|
+
const agentsMd = parsed._agentsMd;
|
|
28
|
+
delete parsed._agentsMd;
|
|
29
|
+
const agentConfig = parsed;
|
|
30
|
+
const modelId = agentConfig.model.model;
|
|
31
|
+
const modelThinking = agentConfig.model.thinkingLevel;
|
|
32
|
+
emitLog("info", "container starting", { agentName: agentConfig.name, modelId, brokerUrl });
|
|
33
|
+
// Read Anthropic API key from credentials volume
|
|
34
|
+
const anthropicKey = readCredential("anthropic-key");
|
|
35
|
+
if (!anthropicKey) {
|
|
36
|
+
emitLog("error", "missing anthropic-key credential");
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
// Set GitHub and Sentry tokens in environment if available
|
|
40
|
+
const githubToken = readCredential("github-token");
|
|
41
|
+
if (githubToken) {
|
|
42
|
+
process.env.GITHUB_TOKEN = githubToken;
|
|
43
|
+
process.env.GH_TOKEN = githubToken;
|
|
44
|
+
}
|
|
45
|
+
const sentryToken = readCredential("sentry-token");
|
|
46
|
+
if (sentryToken) {
|
|
47
|
+
process.env.SENTRY_AUTH_TOKEN = sentryToken;
|
|
48
|
+
}
|
|
49
|
+
const cwd = "/workspace";
|
|
50
|
+
const model = getModel("anthropic", modelId);
|
|
51
|
+
const authStorage = AuthStorage.create();
|
|
52
|
+
authStorage.setRuntimeApiKey("anthropic", anthropicKey);
|
|
53
|
+
// AGENTS.md content is passed via the serialized config from the host
|
|
54
|
+
const agentsContent = agentsMd || `# ${agentConfig.name} Agent\n\nCustom agent.\n`;
|
|
55
|
+
const agentsFile = "/tmp/AGENTS.md";
|
|
56
|
+
const resourceLoader = new DefaultResourceLoader({
|
|
57
|
+
noExtensions: true,
|
|
58
|
+
agentsFilesOverride: () => ({
|
|
59
|
+
agentsFiles: [
|
|
60
|
+
{ path: agentsFile, content: agentsContent },
|
|
61
|
+
],
|
|
62
|
+
}),
|
|
63
|
+
});
|
|
64
|
+
await resourceLoader.reload();
|
|
65
|
+
const settingsManager = SettingsManager.inMemory({
|
|
66
|
+
compaction: { enabled: true },
|
|
67
|
+
retry: { enabled: true, maxRetries: 2 },
|
|
68
|
+
});
|
|
69
|
+
emitLog("info", "creating agent session", { model: modelId, thinking: modelThinking });
|
|
70
|
+
const { session } = await createAgentSession({
|
|
71
|
+
cwd,
|
|
72
|
+
model,
|
|
73
|
+
thinkingLevel: modelThinking,
|
|
74
|
+
authStorage,
|
|
75
|
+
resourceLoader,
|
|
76
|
+
tools: createCodingTools(cwd),
|
|
77
|
+
sessionManager: SessionManager.inMemory(),
|
|
78
|
+
settingsManager,
|
|
79
|
+
});
|
|
80
|
+
emitLog("info", "session created, sending prompt");
|
|
81
|
+
// Mirror the host-mode AgentRunner's session event logging
|
|
82
|
+
const pendingCmds = new Map();
|
|
83
|
+
let outputText = "";
|
|
84
|
+
let eventCount = 0;
|
|
85
|
+
session.subscribe((event) => {
|
|
86
|
+
eventCount++;
|
|
87
|
+
// Log all event types for debugging
|
|
88
|
+
if (event.type !== "message_update") {
|
|
89
|
+
const extra = { type: event.type, eventCount };
|
|
90
|
+
// Dump message events to see what the SDK is doing
|
|
91
|
+
if (event.type === "message_start" || event.type === "message_end") {
|
|
92
|
+
extra.role = event.role || event.message?.role;
|
|
93
|
+
extra.content = JSON.stringify(event.content || event.message?.content || []).slice(0, 500);
|
|
94
|
+
extra.stopReason = event.stopReason || event.stop_reason;
|
|
95
|
+
}
|
|
96
|
+
if (event.type === "turn_end") {
|
|
97
|
+
extra.turnResult = JSON.stringify(event).slice(0, 500);
|
|
98
|
+
}
|
|
99
|
+
emitLog("debug", "event", extra);
|
|
100
|
+
}
|
|
101
|
+
if (event.type === "error") {
|
|
102
|
+
emitLog("error", "session error", { error: String(event.error || event.message || JSON.stringify(event)) });
|
|
103
|
+
}
|
|
104
|
+
if (event.type === "message_update" && event.assistantMessageEvent?.type === "text_delta") {
|
|
105
|
+
outputText += event.assistantMessageEvent.delta;
|
|
106
|
+
}
|
|
107
|
+
if (event.type === "tool_execution_start") {
|
|
108
|
+
const cmd = String(event.args?.command || "");
|
|
109
|
+
if (event.toolName === "bash") {
|
|
110
|
+
pendingCmds.set(event.toolCallId, cmd);
|
|
111
|
+
emitLog("info", "bash", { cmd: cmd.slice(0, 200) });
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
emitLog("debug", "tool start", { tool: event.toolName });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (event.type === "tool_execution_end") {
|
|
118
|
+
const resultStr = typeof event.result === "string"
|
|
119
|
+
? event.result
|
|
120
|
+
: JSON.stringify(event.result);
|
|
121
|
+
pendingCmds.delete(event.toolCallId);
|
|
122
|
+
if (event.isError) {
|
|
123
|
+
emitLog("error", "tool error", { tool: event.toolName, result: resultStr.slice(0, 1000) });
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
emitLog("debug", "tool done", { tool: event.toolName, resultLength: resultStr.length });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
// Prompt is pre-built by the scheduler and passed via PROMPT env var
|
|
131
|
+
const fullPrompt = process.env.PROMPT;
|
|
132
|
+
if (!fullPrompt) {
|
|
133
|
+
emitLog("error", "missing PROMPT env var");
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
// Retry on rate limit errors with exponential backoff
|
|
137
|
+
const MAX_PROMPT_RETRIES = 5;
|
|
138
|
+
const DEFAULT_BACKOFF_MS = 30_000;
|
|
139
|
+
const MAX_BACKOFF_MS = 300_000;
|
|
140
|
+
let result;
|
|
141
|
+
for (let attempt = 0; attempt <= MAX_PROMPT_RETRIES; attempt++) {
|
|
142
|
+
try {
|
|
143
|
+
result = await session.prompt(fullPrompt);
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
catch (promptErr) {
|
|
147
|
+
const msg = String(promptErr?.message || promptErr || "");
|
|
148
|
+
const isRateLimit = msg.includes("rate_limit") || msg.includes("429") || msg.includes("529") || msg.includes("overloaded");
|
|
149
|
+
if (!isRateLimit || attempt === MAX_PROMPT_RETRIES) {
|
|
150
|
+
throw promptErr;
|
|
151
|
+
}
|
|
152
|
+
const delayMs = Math.min(DEFAULT_BACKOFF_MS * Math.pow(2, attempt), MAX_BACKOFF_MS);
|
|
153
|
+
emitLog("warn", "rate limited, retrying prompt", { attempt: attempt + 1, delayMs });
|
|
154
|
+
await new Promise((r) => setTimeout(r, delayMs));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
emitLog("info", "prompt returned", { eventCount, resultType: typeof result, resultKeys: result ? Object.keys(result) : [] });
|
|
158
|
+
if (outputText.includes("[SILENT]")) {
|
|
159
|
+
emitLog("info", "no work to do");
|
|
160
|
+
console.log("[SILENT]");
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
emitLog("info", "run completed", { outputLength: outputText.length });
|
|
164
|
+
console.log(outputText.slice(0, 2000));
|
|
165
|
+
}
|
|
166
|
+
session.dispose();
|
|
167
|
+
process.exit(0);
|
|
168
|
+
}
|
|
169
|
+
main().catch((err) => {
|
|
170
|
+
emitLog("error", "container entry error", { error: err.message, stack: err.stack?.split("\n").slice(0, 5).join("\n") });
|
|
171
|
+
process.exit(1);
|
|
172
|
+
});
|
|
173
|
+
//# sourceMappingURL=container-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container-entry.js","sourceRoot":"","sources":["../../src/agents/container-entry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { GlobalConfig, AgentConfig } from "../shared/config.js";
|
|
2
|
+
import type { Logger } from "../shared/logger.js";
|
|
3
|
+
import type { StatusTracker } from "../tui/status-tracker.js";
|
|
4
|
+
export declare class ContainerAgentRunner {
|
|
5
|
+
private _running;
|
|
6
|
+
private globalConfig;
|
|
7
|
+
private agentConfig;
|
|
8
|
+
private logger;
|
|
9
|
+
private registerContainer;
|
|
10
|
+
private brokerUrl;
|
|
11
|
+
private projectPath;
|
|
12
|
+
private statusTracker?;
|
|
13
|
+
constructor(globalConfig: GlobalConfig, agentConfig: AgentConfig, logger: Logger, registerContainer: (secret: string, containerName: string) => void, brokerUrl: string, projectPath: string, statusTracker?: StatusTracker);
|
|
14
|
+
get isRunning(): boolean;
|
|
15
|
+
private forwardLogLine;
|
|
16
|
+
private streamContainerLogs;
|
|
17
|
+
private waitForContainer;
|
|
18
|
+
run(prompt: string): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=container-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container-runner.d.ts","sourceRoot":"","sources":["../../src/agents/container-runner.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAMlD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,iBAAiB,CAAkD;IAC3E,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,aAAa,CAAC,CAAgB;gBAGpC,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,KAAK,IAAI,EAClE,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,aAAa;IAW/B,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,OAAO,CAAC,cAAc;IAyCtB,OAAO,CAAC,mBAAmB;IAkC3B,OAAO,CAAC,gBAAgB;IA6BlB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAyFzC"}
|