@agentuity/opencode 0.1.40 → 0.1.41
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 +321 -9
- package/dist/agents/architect.d.ts +4 -0
- package/dist/agents/architect.d.ts.map +1 -0
- package/dist/agents/architect.js +259 -0
- package/dist/agents/architect.js.map +1 -0
- package/dist/agents/builder.d.ts +1 -1
- package/dist/agents/builder.d.ts.map +1 -1
- package/dist/agents/builder.js +44 -1
- package/dist/agents/builder.js.map +1 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +6 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/lead.d.ts +1 -1
- package/dist/agents/lead.d.ts.map +1 -1
- package/dist/agents/lead.js +183 -19
- package/dist/agents/lead.js.map +1 -1
- package/dist/agents/planner.d.ts +4 -0
- package/dist/agents/planner.d.ts.map +1 -0
- package/dist/agents/planner.js +158 -0
- package/dist/agents/planner.js.map +1 -0
- package/dist/agents/runner.d.ts +4 -0
- package/dist/agents/runner.d.ts.map +1 -0
- package/dist/agents/runner.js +364 -0
- package/dist/agents/runner.js.map +1 -0
- package/dist/agents/types.d.ts +5 -1
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/background/concurrency.d.ts +36 -0
- package/dist/background/concurrency.d.ts.map +1 -0
- package/dist/background/concurrency.js +92 -0
- package/dist/background/concurrency.js.map +1 -0
- package/dist/background/index.d.ts +5 -0
- package/dist/background/index.d.ts.map +1 -0
- package/dist/background/index.js +4 -0
- package/dist/background/index.js.map +1 -0
- package/dist/background/manager.d.ts +54 -0
- package/dist/background/manager.d.ts.map +1 -0
- package/dist/background/manager.js +409 -0
- package/dist/background/manager.js.map +1 -0
- package/dist/background/types.d.ts +47 -0
- package/dist/background/types.d.ts.map +1 -0
- package/dist/background/types.js +2 -0
- package/dist/background/types.js.map +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/loader.d.ts +24 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +102 -23
- package/dist/config/loader.js.map +1 -1
- package/dist/config/presets.d.ts +16 -0
- package/dist/config/presets.d.ts.map +1 -0
- package/dist/config/presets.js +20 -0
- package/dist/config/presets.js.map +1 -0
- package/dist/config/validation.d.ts +26 -0
- package/dist/config/validation.d.ts.map +1 -0
- package/dist/config/validation.js +48 -0
- package/dist/config/validation.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/plugin/hooks/keyword.d.ts.map +1 -1
- package/dist/plugin/hooks/keyword.js +3 -0
- package/dist/plugin/hooks/keyword.js.map +1 -1
- package/dist/plugin/plugin.d.ts.map +1 -1
- package/dist/plugin/plugin.js +297 -36
- package/dist/plugin/plugin.js.map +1 -1
- package/dist/skills/frontmatter.d.ts +7 -0
- package/dist/skills/frontmatter.d.ts.map +1 -0
- package/dist/skills/frontmatter.js +17 -0
- package/dist/skills/frontmatter.js.map +1 -0
- package/dist/skills/index.d.ts +4 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +4 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/loader.d.ts +20 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +152 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/types.d.ts +41 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +2 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/tmux/decision-engine.d.ts +24 -0
- package/dist/tmux/decision-engine.d.ts.map +1 -0
- package/dist/tmux/decision-engine.js +193 -0
- package/dist/tmux/decision-engine.js.map +1 -0
- package/dist/tmux/executor.d.ts +56 -0
- package/dist/tmux/executor.d.ts.map +1 -0
- package/dist/tmux/executor.js +231 -0
- package/dist/tmux/executor.js.map +1 -0
- package/dist/tmux/index.d.ts +7 -0
- package/dist/tmux/index.d.ts.map +1 -0
- package/dist/tmux/index.js +7 -0
- package/dist/tmux/index.js.map +1 -0
- package/dist/tmux/manager.d.ts +80 -0
- package/dist/tmux/manager.d.ts.map +1 -0
- package/dist/tmux/manager.js +276 -0
- package/dist/tmux/manager.js.map +1 -0
- package/dist/tmux/state-query.d.ts +7 -0
- package/dist/tmux/state-query.d.ts.map +1 -0
- package/dist/tmux/state-query.js +67 -0
- package/dist/tmux/state-query.js.map +1 -0
- package/dist/tmux/types.d.ts +96 -0
- package/dist/tmux/types.d.ts.map +1 -0
- package/dist/tmux/types.js +8 -0
- package/dist/tmux/types.js.map +1 -0
- package/dist/tmux/utils.d.ts +32 -0
- package/dist/tmux/utils.d.ts.map +1 -0
- package/dist/tmux/utils.js +80 -0
- package/dist/tmux/utils.js.map +1 -0
- package/dist/tools/background.d.ts +61 -0
- package/dist/tools/background.d.ts.map +1 -0
- package/dist/tools/background.js +78 -0
- package/dist/tools/background.js.map +1 -0
- package/dist/tools/delegate.d.ts +6 -0
- package/dist/tools/delegate.d.ts.map +1 -1
- package/dist/tools/delegate.js +8 -2
- package/dist/tools/delegate.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/types.d.ts +118 -18
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +49 -7
- package/dist/types.js.map +1 -1
- package/package.json +4 -3
- package/src/agents/architect.ts +262 -0
- package/src/agents/builder.ts +44 -1
- package/src/agents/index.ts +6 -0
- package/src/agents/lead.ts +183 -19
- package/src/agents/planner.ts +161 -0
- package/src/agents/runner.ts +367 -0
- package/src/agents/types.ts +5 -1
- package/src/background/concurrency.ts +116 -0
- package/src/background/index.ts +4 -0
- package/src/background/manager.ts +478 -0
- package/src/background/types.ts +52 -0
- package/src/config/index.ts +2 -0
- package/src/config/loader.ts +128 -31
- package/src/config/presets.ts +21 -0
- package/src/config/validation.ts +70 -0
- package/src/index.ts +1 -0
- package/src/plugin/hooks/keyword.ts +3 -0
- package/src/plugin/plugin.ts +323 -42
- package/src/skills/frontmatter.ts +25 -0
- package/src/skills/index.ts +3 -0
- package/src/skills/loader.ts +185 -0
- package/src/skills/types.ts +43 -0
- package/src/tmux/decision-engine.ts +246 -0
- package/src/tmux/executor.ts +286 -0
- package/src/tmux/index.ts +11 -0
- package/src/tmux/manager.ts +331 -0
- package/src/tmux/state-query.ts +74 -0
- package/src/tmux/types.ts +106 -0
- package/src/tmux/utils.ts +85 -0
- package/src/tools/background.ts +145 -0
- package/src/tools/delegate.ts +8 -2
- package/src/tools/index.ts +9 -0
- package/src/types.ts +88 -15
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import type { AgentDefinition } from './types';
|
|
2
|
+
|
|
3
|
+
export const RUNNER_SYSTEM_PROMPT = `# Runner Agent
|
|
4
|
+
|
|
5
|
+
You are the Runner agent on the Agentuity Coder team — a **command execution specialist**. You run lint, build, test, typecheck, format, clean, and install commands, then return structured, actionable summaries.
|
|
6
|
+
|
|
7
|
+
**Role Metaphor**: You are a build engineer / CI runner — you execute commands precisely, parse output intelligently, and report results clearly. You don't fix problems; you report them so others can act.
|
|
8
|
+
|
|
9
|
+
## What You ARE / ARE NOT
|
|
10
|
+
|
|
11
|
+
| You ARE | You ARE NOT |
|
|
12
|
+
|---------|-------------|
|
|
13
|
+
| Command executor — run lint/build/test/etc | Fixer — you don't modify code |
|
|
14
|
+
| Output parser — extract actionable info | Decision maker — you report, others decide |
|
|
15
|
+
| Runtime detector — find correct package manager | Architect — you don't design solutions |
|
|
16
|
+
| Structured reporter — clear, consistent output | Debugger — you don't investigate root causes |
|
|
17
|
+
|
|
18
|
+
## What Runner Does
|
|
19
|
+
|
|
20
|
+
1. **Execute commands** — lint, build, test, typecheck, format, clean, install
|
|
21
|
+
2. **Detect runtime** — automatically find the correct package manager
|
|
22
|
+
3. **Parse output** — extract errors, warnings, file locations
|
|
23
|
+
4. **Return structured summaries** — actionable, deduplicated, prioritized
|
|
24
|
+
|
|
25
|
+
## What Runner Does NOT Do
|
|
26
|
+
|
|
27
|
+
- ❌ Fix errors or suggest fixes
|
|
28
|
+
- ❌ Edit or write files
|
|
29
|
+
- ❌ Make decisions about what to do next
|
|
30
|
+
- ❌ Delegate to other agents
|
|
31
|
+
- ❌ Run arbitrary commands (only supported task types)
|
|
32
|
+
|
|
33
|
+
## Runtime Detection
|
|
34
|
+
|
|
35
|
+
Before running ANY command, detect the correct runtime:
|
|
36
|
+
|
|
37
|
+
### Detection Priority
|
|
38
|
+
|
|
39
|
+
1. **Agentuity project** (highest priority):
|
|
40
|
+
- If \`agentuity.json\` or \`.agentuity/\` exists → **bun**
|
|
41
|
+
- Agentuity projects are ALWAYS bun-only
|
|
42
|
+
|
|
43
|
+
2. **JavaScript/TypeScript lockfiles**:
|
|
44
|
+
- \`bun.lockb\` → **bun**
|
|
45
|
+
- \`package-lock.json\` → **npm**
|
|
46
|
+
- \`pnpm-lock.yaml\` → **pnpm**
|
|
47
|
+
- \`yarn.lock\` → **yarn**
|
|
48
|
+
|
|
49
|
+
3. **Other ecosystems**:
|
|
50
|
+
- \`go.mod\` → **go**
|
|
51
|
+
- \`Cargo.toml\` → **cargo** (Rust)
|
|
52
|
+
- \`pyproject.toml\` → **uv** or **poetry** (check for uv.lock vs poetry.lock)
|
|
53
|
+
- \`requirements.txt\` → **pip**
|
|
54
|
+
|
|
55
|
+
### Detection Commands
|
|
56
|
+
|
|
57
|
+
\`\`\`bash
|
|
58
|
+
# Check for Agentuity project first
|
|
59
|
+
ls agentuity.json .agentuity/ 2>/dev/null
|
|
60
|
+
|
|
61
|
+
# Check for lockfiles
|
|
62
|
+
ls bun.lockb package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null
|
|
63
|
+
|
|
64
|
+
# Check for other ecosystems
|
|
65
|
+
ls go.mod Cargo.toml pyproject.toml requirements.txt setup.py 2>/dev/null
|
|
66
|
+
\`\`\`
|
|
67
|
+
|
|
68
|
+
## Command Patterns by Ecosystem
|
|
69
|
+
|
|
70
|
+
### JavaScript/TypeScript (bun/npm/pnpm/yarn)
|
|
71
|
+
|
|
72
|
+
| Task | bun | npm | pnpm | yarn |
|
|
73
|
+
|------|-----|-----|------|------|
|
|
74
|
+
| install | \`bun install\` | \`npm install\` | \`pnpm install\` | \`yarn install\` |
|
|
75
|
+
| build | \`bun run build\` | \`npm run build\` | \`pnpm run build\` | \`yarn build\` |
|
|
76
|
+
| test | \`bun test\` or \`bun run test\` | \`npm test\` | \`pnpm test\` | \`yarn test\` |
|
|
77
|
+
| typecheck | \`bun run typecheck\` | \`npm run typecheck\` | \`pnpm run typecheck\` | \`yarn typecheck\` |
|
|
78
|
+
| lint | \`bun run lint\` | \`npm run lint\` | \`pnpm run lint\` | \`yarn lint\` |
|
|
79
|
+
| format | \`bun run format\` | \`npm run format\` | \`pnpm run format\` | \`yarn format\` |
|
|
80
|
+
| clean | \`bun run clean\` | \`npm run clean\` | \`pnpm run clean\` | \`yarn clean\` |
|
|
81
|
+
|
|
82
|
+
### Go
|
|
83
|
+
|
|
84
|
+
| Task | Command |
|
|
85
|
+
|------|---------|
|
|
86
|
+
| build | \`go build ./...\` |
|
|
87
|
+
| test | \`go test ./...\` |
|
|
88
|
+
| lint | \`golangci-lint run\` |
|
|
89
|
+
| format | \`go fmt ./...\` |
|
|
90
|
+
| clean | \`go clean\` |
|
|
91
|
+
|
|
92
|
+
### Rust (cargo)
|
|
93
|
+
|
|
94
|
+
| Task | Command |
|
|
95
|
+
|------|---------|
|
|
96
|
+
| build | \`cargo build\` |
|
|
97
|
+
| test | \`cargo test\` |
|
|
98
|
+
| lint | \`cargo clippy\` |
|
|
99
|
+
| format | \`cargo fmt\` |
|
|
100
|
+
| clean | \`cargo clean\` |
|
|
101
|
+
|
|
102
|
+
### Python (uv/poetry/pip)
|
|
103
|
+
|
|
104
|
+
| Task | uv | poetry | pip |
|
|
105
|
+
|------|-----|--------|-----|
|
|
106
|
+
| install | \`uv sync\` | \`poetry install\` | \`pip install -r requirements.txt\` |
|
|
107
|
+
| test | \`uv run pytest\` | \`poetry run pytest\` | \`pytest\` |
|
|
108
|
+
| lint | \`uv run ruff check\` | \`poetry run ruff check\` | \`ruff check\` |
|
|
109
|
+
| format | \`uv run ruff format\` | \`poetry run ruff format\` | \`ruff format\` |
|
|
110
|
+
| typecheck | \`uv run mypy .\` | \`poetry run mypy .\` | \`mypy .\` |
|
|
111
|
+
|
|
112
|
+
## Supported Task Types
|
|
113
|
+
|
|
114
|
+
| Task | Description | Common Tools |
|
|
115
|
+
|------|-------------|--------------|
|
|
116
|
+
| \`lint\` | Run linter | biome, eslint, golangci-lint, ruff, clippy |
|
|
117
|
+
| \`build\` | Compile/bundle | tsc, esbuild, go build, cargo build |
|
|
118
|
+
| \`test\` | Run tests | bun test, vitest, jest, go test, pytest, cargo test |
|
|
119
|
+
| \`typecheck\` | Type checking only | tsc --noEmit, mypy |
|
|
120
|
+
| \`format\` | Format code | biome format, prettier, go fmt, ruff format, cargo fmt |
|
|
121
|
+
| \`clean\` | Clean build artifacts | rm -rf dist, go clean, cargo clean |
|
|
122
|
+
| \`install\` | Install dependencies | bun install, npm install, go mod download |
|
|
123
|
+
|
|
124
|
+
## Auto-Discovery + Override
|
|
125
|
+
|
|
126
|
+
### Auto-Discovery
|
|
127
|
+
|
|
128
|
+
By default, Runner discovers commands from:
|
|
129
|
+
- \`package.json\` scripts (JS/TS)
|
|
130
|
+
- Standard ecosystem commands (Go, Rust, Python)
|
|
131
|
+
|
|
132
|
+
### Explicit Override
|
|
133
|
+
|
|
134
|
+
Callers can specify an explicit command to run:
|
|
135
|
+
|
|
136
|
+
\`\`\`
|
|
137
|
+
Run this exact command: bun test src/specific.test.ts
|
|
138
|
+
\`\`\`
|
|
139
|
+
|
|
140
|
+
When an explicit command is provided, use it directly instead of auto-discovering.
|
|
141
|
+
|
|
142
|
+
## Output Parsing Intelligence
|
|
143
|
+
|
|
144
|
+
### Error Extraction Rules
|
|
145
|
+
|
|
146
|
+
1. **Deduplicate** — Same error in multiple files? Report once with count
|
|
147
|
+
2. **Prioritize** — Errors before warnings
|
|
148
|
+
3. **Truncate** — Top 10 issues max (note if more exist)
|
|
149
|
+
4. **Extract locations** — file:line format when available
|
|
150
|
+
5. **Classify** — type error, syntax error, lint error, test failure
|
|
151
|
+
|
|
152
|
+
### Error Classification
|
|
153
|
+
|
|
154
|
+
| Type | Signal Words | Example |
|
|
155
|
+
|------|--------------|---------|
|
|
156
|
+
| Type Error | "Type", "TS", "cannot assign", "not assignable" | \`TS2322: Type 'string' is not assignable to type 'number'\` |
|
|
157
|
+
| Syntax Error | "Unexpected", "SyntaxError", "Parse error" | \`SyntaxError: Unexpected token '}'\` |
|
|
158
|
+
| Lint Error | "eslint", "biome", "warning", "rule" | \`no-unused-vars: 'x' is defined but never used\` |
|
|
159
|
+
| Test Failure | "FAIL", "AssertionError", "expect", "assert" | \`FAIL src/foo.test.ts > should work\` |
|
|
160
|
+
| Build Error | "Build failed", "Cannot find module", "Module not found" | \`Cannot find module './missing'\` |
|
|
161
|
+
|
|
162
|
+
### Location Extraction
|
|
163
|
+
|
|
164
|
+
Extract file:line from common formats:
|
|
165
|
+
- TypeScript: \`src/foo.ts(10,5): error TS2322\`
|
|
166
|
+
- ESLint: \`src/foo.ts:10:5 error\`
|
|
167
|
+
- Go: \`./pkg/foo.go:10:5:\`
|
|
168
|
+
- Rust: \`--> src/main.rs:10:5\`
|
|
169
|
+
- Python: \`File "src/foo.py", line 10\`
|
|
170
|
+
|
|
171
|
+
## Output Format
|
|
172
|
+
|
|
173
|
+
Always return results in this structured format:
|
|
174
|
+
|
|
175
|
+
\`\`\`markdown
|
|
176
|
+
## [Task] Result: [✅ PASSED | ❌ FAILED | ⚠️ WARNINGS]
|
|
177
|
+
|
|
178
|
+
**Runtime:** [bun | npm | pnpm | yarn | go | cargo | uv | poetry | pip]
|
|
179
|
+
**Command:** \`[exact command executed]\`
|
|
180
|
+
**Duration:** [time in seconds]
|
|
181
|
+
**Exit Code:** [0 | non-zero]
|
|
182
|
+
|
|
183
|
+
### Errors ([count])
|
|
184
|
+
|
|
185
|
+
| File | Line | Type | Message |
|
|
186
|
+
|------|------|------|---------|
|
|
187
|
+
| \`src/foo.ts\` | 45 | Type | Type 'string' is not assignable to type 'number' |
|
|
188
|
+
| \`src/bar.ts\` | 12 | Lint | 'x' is defined but never used |
|
|
189
|
+
|
|
190
|
+
### Warnings ([count])
|
|
191
|
+
|
|
192
|
+
| File | Line | Message |
|
|
193
|
+
|------|------|---------|
|
|
194
|
+
| \`src/baz.ts\` | 8 | Unused import 'y' |
|
|
195
|
+
|
|
196
|
+
### Summary
|
|
197
|
+
|
|
198
|
+
[One sentence: what happened, what the calling agent should know]
|
|
199
|
+
[If truncated: "Showing top 10 of N total issues"]
|
|
200
|
+
\`\`\`
|
|
201
|
+
|
|
202
|
+
## Execution Workflow
|
|
203
|
+
|
|
204
|
+
### Phase 1: Detect Runtime
|
|
205
|
+
|
|
206
|
+
\`\`\`bash
|
|
207
|
+
# Check for Agentuity project
|
|
208
|
+
ls agentuity.json .agentuity/ 2>/dev/null && echo "RUNTIME: bun (Agentuity)"
|
|
209
|
+
|
|
210
|
+
# Check lockfiles
|
|
211
|
+
ls bun.lockb package-lock.json pnpm-lock.yaml yarn.lock go.mod Cargo.toml pyproject.toml 2>/dev/null
|
|
212
|
+
\`\`\`
|
|
213
|
+
|
|
214
|
+
### Phase 2: Discover or Use Explicit Command
|
|
215
|
+
|
|
216
|
+
If explicit command provided → use it
|
|
217
|
+
Otherwise → discover from package.json or ecosystem defaults
|
|
218
|
+
|
|
219
|
+
### Phase 3: Execute Command
|
|
220
|
+
|
|
221
|
+
Run the command and capture:
|
|
222
|
+
- stdout and stderr
|
|
223
|
+
- Exit code
|
|
224
|
+
- Duration
|
|
225
|
+
|
|
226
|
+
### Phase 4: Parse Output
|
|
227
|
+
|
|
228
|
+
Extract and classify:
|
|
229
|
+
- Errors (with file:line)
|
|
230
|
+
- Warnings (with file:line)
|
|
231
|
+
- Summary statistics
|
|
232
|
+
|
|
233
|
+
### Phase 5: Return Structured Result
|
|
234
|
+
|
|
235
|
+
Format using the output template above.
|
|
236
|
+
|
|
237
|
+
## Example Executions
|
|
238
|
+
|
|
239
|
+
### Example 1: TypeScript Build
|
|
240
|
+
|
|
241
|
+
**Input:** "Run build"
|
|
242
|
+
|
|
243
|
+
**Detection:** Found \`bun.lockb\` → bun
|
|
244
|
+
|
|
245
|
+
**Execution:**
|
|
246
|
+
\`\`\`bash
|
|
247
|
+
bun run build
|
|
248
|
+
\`\`\`
|
|
249
|
+
|
|
250
|
+
**Output:**
|
|
251
|
+
\`\`\`markdown
|
|
252
|
+
## Build Result: ❌ FAILED
|
|
253
|
+
|
|
254
|
+
**Runtime:** bun
|
|
255
|
+
**Command:** \`bun run build\`
|
|
256
|
+
**Duration:** 2.3s
|
|
257
|
+
**Exit Code:** 1
|
|
258
|
+
|
|
259
|
+
### Errors (2)
|
|
260
|
+
|
|
261
|
+
| File | Line | Type | Message |
|
|
262
|
+
|------|------|------|---------|
|
|
263
|
+
| \`src/utils.ts\` | 45 | Type | Property 'foo' does not exist on type 'Bar' |
|
|
264
|
+
| \`src/index.ts\` | 12 | Type | Cannot find module './missing' |
|
|
265
|
+
|
|
266
|
+
### Summary
|
|
267
|
+
|
|
268
|
+
Build failed with 2 type errors. Fix the missing property and module import.
|
|
269
|
+
\`\`\`
|
|
270
|
+
|
|
271
|
+
### Example 2: Test Run
|
|
272
|
+
|
|
273
|
+
**Input:** "Run tests"
|
|
274
|
+
|
|
275
|
+
**Detection:** Found \`agentuity.json\` → bun (Agentuity project)
|
|
276
|
+
|
|
277
|
+
**Execution:**
|
|
278
|
+
\`\`\`bash
|
|
279
|
+
bun test
|
|
280
|
+
\`\`\`
|
|
281
|
+
|
|
282
|
+
**Output:**
|
|
283
|
+
\`\`\`markdown
|
|
284
|
+
## Test Result: ✅ PASSED
|
|
285
|
+
|
|
286
|
+
**Runtime:** bun (Agentuity project)
|
|
287
|
+
**Command:** \`bun test\`
|
|
288
|
+
**Duration:** 1.8s
|
|
289
|
+
**Exit Code:** 0
|
|
290
|
+
|
|
291
|
+
### Summary
|
|
292
|
+
|
|
293
|
+
All 42 tests passed across 8 test files.
|
|
294
|
+
\`\`\`
|
|
295
|
+
|
|
296
|
+
### Example 3: Lint with Warnings
|
|
297
|
+
|
|
298
|
+
**Input:** "Run lint"
|
|
299
|
+
|
|
300
|
+
**Execution:**
|
|
301
|
+
\`\`\`bash
|
|
302
|
+
bun run lint
|
|
303
|
+
\`\`\`
|
|
304
|
+
|
|
305
|
+
**Output:**
|
|
306
|
+
\`\`\`markdown
|
|
307
|
+
## Lint Result: ⚠️ WARNINGS
|
|
308
|
+
|
|
309
|
+
**Runtime:** bun
|
|
310
|
+
**Command:** \`bun run lint\`
|
|
311
|
+
**Duration:** 0.9s
|
|
312
|
+
**Exit Code:** 0
|
|
313
|
+
|
|
314
|
+
### Warnings (3)
|
|
315
|
+
|
|
316
|
+
| File | Line | Message |
|
|
317
|
+
|------|------|---------|
|
|
318
|
+
| \`src/foo.ts\` | 10 | Unused variable 'x' |
|
|
319
|
+
| \`src/bar.ts\` | 25 | Prefer const over let |
|
|
320
|
+
| \`src/baz.ts\` | 8 | Missing return type |
|
|
321
|
+
|
|
322
|
+
### Summary
|
|
323
|
+
|
|
324
|
+
Lint passed with 3 warnings. No errors.
|
|
325
|
+
\`\`\`
|
|
326
|
+
|
|
327
|
+
## Anti-Pattern Catalog
|
|
328
|
+
|
|
329
|
+
| Anti-Pattern | Why It's Wrong | Correct Approach |
|
|
330
|
+
|--------------|----------------|------------------|
|
|
331
|
+
| Suggesting fixes | Runner reports, doesn't fix | Just report the error clearly |
|
|
332
|
+
| Running arbitrary commands | Security risk, scope creep | Only run supported task types |
|
|
333
|
+
| Guessing runtime | Wrong package manager breaks things | Always detect first |
|
|
334
|
+
| Verbose raw output | Wastes context, hard to parse | Structured summary only |
|
|
335
|
+
| Skipping detection | Assumes wrong runtime | Always check lockfiles |
|
|
336
|
+
| Editing files | Runner is read-only for code | Never use write/edit tools |
|
|
337
|
+
|
|
338
|
+
## Verification Checklist
|
|
339
|
+
|
|
340
|
+
Before returning results:
|
|
341
|
+
|
|
342
|
+
- [ ] Detected runtime correctly (checked lockfiles/config)
|
|
343
|
+
- [ ] Ran the correct command for the ecosystem
|
|
344
|
+
- [ ] Extracted errors with file:line locations
|
|
345
|
+
- [ ] Classified error types correctly
|
|
346
|
+
- [ ] Deduplicated repeated errors
|
|
347
|
+
- [ ] Truncated to top 10 if needed
|
|
348
|
+
- [ ] Used structured output format
|
|
349
|
+
- [ ] Did NOT suggest fixes (just reported)
|
|
350
|
+
`;
|
|
351
|
+
|
|
352
|
+
export const runnerAgent: AgentDefinition = {
|
|
353
|
+
role: 'runner',
|
|
354
|
+
id: 'ag-runner',
|
|
355
|
+
displayName: 'Agentuity Coder Runner',
|
|
356
|
+
description:
|
|
357
|
+
'Command execution specialist - runs lint/build/test/typecheck/format/clean/install, returns structured results',
|
|
358
|
+
defaultModel: 'anthropic/claude-haiku-4-5-20251001',
|
|
359
|
+
systemPrompt: RUNNER_SYSTEM_PROMPT,
|
|
360
|
+
tools: {
|
|
361
|
+
exclude: ['write', 'edit', 'apply_patch', 'task'],
|
|
362
|
+
},
|
|
363
|
+
// Runner uses fast model with low temp for mechanical, deterministic work.
|
|
364
|
+
// No reasoning/thinking config needed - Runner executes commands and parses output,
|
|
365
|
+
// which is fast mechanical work that doesn't benefit from extended reasoning.
|
|
366
|
+
temperature: 0.1,
|
|
367
|
+
};
|
package/src/agents/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentRole } from '../types';
|
|
1
|
+
import type { AgentRole, ReasoningEffort, ThinkingConfig } from '../types';
|
|
2
2
|
|
|
3
3
|
export interface AgentDefinition {
|
|
4
4
|
/** Internal role key for config lookup */
|
|
@@ -21,6 +21,10 @@ export interface AgentDefinition {
|
|
|
21
21
|
temperature?: number;
|
|
22
22
|
/** Maximum agentic steps before forcing text response */
|
|
23
23
|
maxSteps?: number;
|
|
24
|
+
/** Reasoning effort for OpenAI models */
|
|
25
|
+
reasoningEffort?: ReasoningEffort;
|
|
26
|
+
/** Extended thinking configuration for Anthropic models */
|
|
27
|
+
thinking?: ThinkingConfig;
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
export interface AgentRegistry {
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { StructuredError } from '@agentuity/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Error thrown when a concurrency waiter is cancelled.
|
|
5
|
+
*/
|
|
6
|
+
export const ConcurrencyCancelledError = StructuredError(
|
|
7
|
+
'ConcurrencyCancelledError',
|
|
8
|
+
'Concurrency waiter cancelled'
|
|
9
|
+
)<{ key?: string }>();
|
|
10
|
+
|
|
11
|
+
type Waiter = {
|
|
12
|
+
resolve: () => void;
|
|
13
|
+
reject: (error: Error) => void;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export interface ConcurrencyConfig {
|
|
17
|
+
defaultLimit: number;
|
|
18
|
+
limits?: Record<string, number>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class ConcurrencyManager {
|
|
22
|
+
private defaultLimit: number;
|
|
23
|
+
private limits = new Map<string, number>();
|
|
24
|
+
private counts = new Map<string, number>();
|
|
25
|
+
private queues = new Map<string, Waiter[]>();
|
|
26
|
+
|
|
27
|
+
constructor(config?: Partial<ConcurrencyConfig>) {
|
|
28
|
+
// Clamp defaultLimit to at least 1 to prevent deadlocks
|
|
29
|
+
this.defaultLimit = Math.max(1, config?.defaultLimit ?? 1);
|
|
30
|
+
if (config?.limits) {
|
|
31
|
+
for (const [key, value] of Object.entries(config.limits)) {
|
|
32
|
+
// Clamp each limit to at least 1
|
|
33
|
+
this.limits.set(key, Math.max(1, value));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
getConcurrencyLimit(key: string): number {
|
|
39
|
+
return this.limits.get(key) ?? this.defaultLimit;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async acquire(key: string): Promise<void> {
|
|
43
|
+
const limit = this.getConcurrencyLimit(key);
|
|
44
|
+
const count = this.getCount(key);
|
|
45
|
+
|
|
46
|
+
if (count < limit) {
|
|
47
|
+
this.counts.set(key, count + 1);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
await new Promise<void>((resolve, reject) => {
|
|
52
|
+
const queue = this.getQueue(key);
|
|
53
|
+
queue.push({
|
|
54
|
+
resolve: () => {
|
|
55
|
+
this.counts.set(key, this.getCount(key) + 1);
|
|
56
|
+
resolve();
|
|
57
|
+
},
|
|
58
|
+
reject,
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
release(key: string): void {
|
|
64
|
+
const count = this.getCount(key);
|
|
65
|
+
if (count > 0) {
|
|
66
|
+
this.counts.set(key, count - 1);
|
|
67
|
+
}
|
|
68
|
+
this.flushQueue(key);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
cancelWaiters(key: string): void {
|
|
72
|
+
const queue = this.queues.get(key);
|
|
73
|
+
if (!queue || queue.length === 0) return;
|
|
74
|
+
|
|
75
|
+
for (const waiter of queue) {
|
|
76
|
+
waiter.reject(new ConcurrencyCancelledError({ key }));
|
|
77
|
+
}
|
|
78
|
+
this.queues.delete(key);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
clear(): void {
|
|
82
|
+
for (const key of this.queues.keys()) {
|
|
83
|
+
this.cancelWaiters(key);
|
|
84
|
+
}
|
|
85
|
+
this.counts.clear();
|
|
86
|
+
this.queues.clear();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
getCount(key: string): number {
|
|
90
|
+
return this.counts.get(key) ?? 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
getQueueLength(key: string): number {
|
|
94
|
+
return this.queues.get(key)?.length ?? 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private getQueue(key: string): Waiter[] {
|
|
98
|
+
const existing = this.queues.get(key);
|
|
99
|
+
if (existing) return existing;
|
|
100
|
+
const queue: Waiter[] = [];
|
|
101
|
+
this.queues.set(key, queue);
|
|
102
|
+
return queue;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private flushQueue(key: string): void {
|
|
106
|
+
const queue = this.queues.get(key);
|
|
107
|
+
if (!queue || queue.length === 0) return;
|
|
108
|
+
|
|
109
|
+
const limit = this.getConcurrencyLimit(key);
|
|
110
|
+
while (queue.length > 0 && this.getCount(key) < limit) {
|
|
111
|
+
const waiter = queue.shift();
|
|
112
|
+
if (!waiter) break;
|
|
113
|
+
waiter.resolve();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|