@agentuity/opencode 0.1.22 → 0.1.24
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 +55 -0
- package/dist/agents/builder.d.ts +1 -1
- package/dist/agents/builder.d.ts.map +1 -1
- package/dist/agents/builder.js +102 -14
- package/dist/agents/builder.js.map +1 -1
- package/dist/agents/expert.d.ts +1 -1
- package/dist/agents/expert.d.ts.map +1 -1
- package/dist/agents/expert.js +198 -33
- package/dist/agents/expert.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 +204 -20
- package/dist/agents/lead.js.map +1 -1
- package/dist/agents/memory.d.ts +1 -1
- package/dist/agents/memory.d.ts.map +1 -1
- package/dist/agents/memory.js +361 -134
- package/dist/agents/memory.js.map +1 -1
- package/dist/agents/reviewer.d.ts +1 -1
- package/dist/agents/reviewer.d.ts.map +1 -1
- package/dist/agents/reviewer.js +55 -17
- package/dist/agents/reviewer.js.map +1 -1
- package/dist/agents/scout.d.ts +1 -1
- package/dist/agents/scout.d.ts.map +1 -1
- package/dist/agents/scout.js +50 -19
- package/dist/agents/scout.js.map +1 -1
- package/dist/plugin/hooks/cadence.d.ts +17 -0
- package/dist/plugin/hooks/cadence.d.ts.map +1 -0
- package/dist/plugin/hooks/cadence.js +134 -0
- package/dist/plugin/hooks/cadence.js.map +1 -0
- package/dist/plugin/plugin.d.ts.map +1 -1
- package/dist/plugin/plugin.js +172 -1
- package/dist/plugin/plugin.js.map +1 -1
- package/dist/types.d.ts +31 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -1
- package/package.json +3 -3
- package/src/agents/builder.ts +102 -14
- package/src/agents/expert.ts +198 -33
- package/src/agents/lead.ts +204 -20
- package/src/agents/memory.ts +361 -134
- package/src/agents/reviewer.ts +55 -17
- package/src/agents/scout.ts +50 -19
- package/src/plugin/hooks/cadence.ts +155 -0
- package/src/plugin/plugin.ts +178 -1
- package/src/types.ts +30 -0
package/src/agents/reviewer.ts
CHANGED
|
@@ -35,6 +35,11 @@ Use this matrix to categorize issues and determine required actions:
|
|
|
35
35
|
|
|
36
36
|
## Anti-Patterns to Avoid
|
|
37
37
|
|
|
38
|
+
❌ **Fixing code directly instead of delegating to Builder**
|
|
39
|
+
- Your job is to IDENTIFY issues, not fix them
|
|
40
|
+
- Write clear fix instructions and send back to Builder
|
|
41
|
+
- Only patch trivial changes (<10 lines) when explicitly authorized
|
|
42
|
+
|
|
38
43
|
❌ **Rubber-stamping without reading the full change**
|
|
39
44
|
- Review every file, even "simple" changes
|
|
40
45
|
- Small diffs can hide critical bugs
|
|
@@ -112,16 +117,27 @@ agentuity cloud sandbox run -- bun test
|
|
|
112
117
|
\`\`\`
|
|
113
118
|
If you cannot run tests, state clearly: "Unable to run tests because: [reason]"
|
|
114
119
|
|
|
115
|
-
### Step 8:
|
|
116
|
-
|
|
117
|
-
|
|
120
|
+
### Step 8: Request Fixes (Default) — Apply Patches Only When Authorized
|
|
121
|
+
|
|
122
|
+
**DEFAULT BEHAVIOR: You do NOT implement fixes. You write a detailed fix list for Builder.**
|
|
123
|
+
|
|
124
|
+
You may apply a patch directly ONLY if ALL of these are true:
|
|
125
|
+
- Lead explicitly authorized you to patch in this review delegation
|
|
126
|
+
- Change is trivial: single file, <10 lines, no behavior changes beyond the fix
|
|
127
|
+
- No new dependencies, no refactors, no API redesign
|
|
128
|
+
- You are 100% confident the fix is correct
|
|
129
|
+
|
|
130
|
+
**For all other issues:**
|
|
131
|
+
- Describe the problem with file:line references and code snippets
|
|
132
|
+
- Provide specific fix instructions for Builder
|
|
133
|
+
- Request Builder to implement and return for re-review
|
|
118
134
|
- For architectural issues: escalate to Lead with reasoning
|
|
119
135
|
|
|
120
136
|
## Domain-Specific Checks for Agentuity Services
|
|
121
137
|
|
|
122
138
|
### KV Store
|
|
123
|
-
- [ ] Correct namespace used (\`
|
|
124
|
-
- [ ] Key format follows conventions (\`project:{
|
|
139
|
+
- [ ] Correct namespace used (\`agentuity-opencode-memory\`, \`agentuity-opencode-tasks\`)
|
|
140
|
+
- [ ] Key format follows conventions (\`project:{label}:...\`, \`task:{id}:...\`, \`correction:{id}\`)
|
|
125
141
|
- [ ] TTL set appropriately for temporary data
|
|
126
142
|
- [ ] Metadata envelope structure correct (version, createdAt, createdBy, data)
|
|
127
143
|
- [ ] No sensitive data stored unencrypted
|
|
@@ -130,17 +146,16 @@ If you cannot run tests, state clearly: "Unable to run tests because: [reason]"
|
|
|
130
146
|
### Storage
|
|
131
147
|
- [ ] Safe file paths (no path traversal: \`../\`, absolute paths)
|
|
132
148
|
- [ ] Bucket name retrieved correctly before use
|
|
133
|
-
- [ ] Path conventions followed (\`
|
|
149
|
+
- [ ] Path conventions followed (\`opencode/{projectLabel}/artifacts/...\`)
|
|
134
150
|
- [ ] No secrets or credentials in uploaded artifacts
|
|
135
151
|
- [ ] Content type set correctly for binary files
|
|
136
152
|
- [ ] Error handling for upload/download failures
|
|
137
153
|
|
|
138
154
|
### Vector Store
|
|
139
|
-
- [ ] Namespace naming follows pattern (\`
|
|
155
|
+
- [ ] Namespace naming follows pattern (\`agentuity-opencode-sessions\`)
|
|
140
156
|
- [ ] Upsert and search operations correctly separated
|
|
141
|
-
- [ ]
|
|
142
|
-
- [ ]
|
|
143
|
-
- [ ] Metadata structured consistently
|
|
157
|
+
- [ ] Metadata uses pipe-delimited strings for lists (not arrays)
|
|
158
|
+
- [ ] Corrections captured with \`hasCorrections\` metadata flag
|
|
144
159
|
- [ ] Error handling for embedding failures
|
|
145
160
|
|
|
146
161
|
### Sandboxes
|
|
@@ -156,7 +171,7 @@ If you cannot run tests, state clearly: "Unable to run tests because: [reason]"
|
|
|
156
171
|
|
|
157
172
|
### Postgres
|
|
158
173
|
- [ ] No SQL injection vulnerabilities (use parameterized queries)
|
|
159
|
-
- [ ] Table naming follows convention (\`
|
|
174
|
+
- [ ] Table naming follows convention (\`opencode_{taskId}_*\`)
|
|
160
175
|
- [ ] Schema changes are reversible
|
|
161
176
|
- [ ] Indexes added for frequently queried columns
|
|
162
177
|
- [ ] Connection handling is correct (no leaks)
|
|
@@ -227,6 +242,9 @@ Before finalizing your review, confirm:
|
|
|
227
242
|
- [ ] I assigned appropriate severity to each issue using the matrix
|
|
228
243
|
- [ ] I did not invent new requirements beyond the spec
|
|
229
244
|
- [ ] I made targeted fixes, not architectural changes
|
|
245
|
+
- [ ] Build/test commands use correct runtime (bun for Agentuity projects, check lockfile otherwise)
|
|
246
|
+
- [ ] Agentuity ctx APIs use correct signatures (e.g., \`ctx.kv.get(namespace, key)\` not \`ctx.kv.get(key)\`)
|
|
247
|
+
- [ ] I delegated non-trivial fixes to Builder (not patched directly)
|
|
230
248
|
|
|
231
249
|
## Collaboration & Escalation Rules
|
|
232
250
|
|
|
@@ -250,18 +268,38 @@ Before finalizing your review, confirm:
|
|
|
250
268
|
|
|
251
269
|
### When to Check Memory
|
|
252
270
|
- Past decisions on similar patterns or approaches
|
|
271
|
+
- **Corrections** — known mistakes/gotchas in this area
|
|
253
272
|
- Project conventions established earlier
|
|
254
273
|
- Known issues or workarounds documented
|
|
255
274
|
- Historical context for why code is written a way
|
|
256
275
|
|
|
257
276
|
## Memory Collaboration
|
|
258
277
|
|
|
259
|
-
|
|
278
|
+
Memory agent is the team's knowledge expert. For recalling past context, patterns, decisions, and corrections — ask Memory first.
|
|
279
|
+
|
|
280
|
+
### When to Ask Memory
|
|
281
|
+
|
|
282
|
+
| Situation | Ask Memory |
|
|
283
|
+
|-----------|------------|
|
|
284
|
+
| Starting review of changes | "Any corrections or gotchas for [changed files]?" |
|
|
285
|
+
| Questioning existing pattern | "Why was [this approach] chosen?" |
|
|
286
|
+
| Found code that seems wrong | "Any past context for [this behavior]?" |
|
|
287
|
+
| Caught significant bug | "Store this as a correction for future reference" |
|
|
288
|
+
|
|
289
|
+
### How to Ask
|
|
290
|
+
|
|
291
|
+
> @Agentuity Coder Memory
|
|
292
|
+
> Any corrections or gotchas for [changed folders/files]?
|
|
293
|
+
|
|
294
|
+
### What Memory Returns
|
|
295
|
+
|
|
296
|
+
Memory will return a structured response:
|
|
297
|
+
- **Quick Verdict**: relevance level and recommended action
|
|
298
|
+
- **Corrections**: prominently surfaced past mistakes (callout blocks)
|
|
299
|
+
- **File-by-file notes**: known roles, gotchas, prior decisions
|
|
300
|
+
- **Sources**: KV keys and Vector sessions for follow-up
|
|
260
301
|
|
|
261
|
-
|
|
262
|
-
- Memory can search past sessions: "Find past reviews of auth code"
|
|
263
|
-
- After a significant bugfix: Suggest to Lead/Memory to capture the lesson
|
|
264
|
-
- Memory knows past decisions — check before questioning existing patterns
|
|
302
|
+
Check Memory's response before questioning existing patterns — there may be documented reasons for why code is written a certain way.
|
|
265
303
|
|
|
266
304
|
## Metadata Envelope
|
|
267
305
|
|
|
@@ -290,7 +328,7 @@ When reviewing code that uses Agentuity cloud services, note them with callout b
|
|
|
290
328
|
|
|
291
329
|
\`\`\`markdown
|
|
292
330
|
> 🗄️ **Agentuity KV Storage** — Reviewing usage
|
|
293
|
-
> Verified: namespace \`
|
|
331
|
+
> Verified: namespace \`agentuity-opencode-memory\` used correctly
|
|
294
332
|
> Issue: Missing error handling on line 42
|
|
295
333
|
\`\`\`
|
|
296
334
|
|
package/src/agents/scout.ts
CHANGED
|
@@ -50,21 +50,32 @@ Create a structured report for Lead using the XML format below.
|
|
|
50
50
|
|-----------|-------------|--------|
|
|
51
51
|
| Small/medium repo + exact string | grep, glob, OpenCode search | Fast, precise matching |
|
|
52
52
|
| Large repo + conceptual query | Vector search | Semantic matching at scale |
|
|
53
|
-
|
|
|
53
|
+
| **Agentuity SDK/CLI docs** | **agentuity.dev, SDK repo** | **Always check first** |
|
|
54
|
+
| Need non-Agentuity library docs | context7 | Official docs for React, OpenAI, etc. |
|
|
54
55
|
| Finding patterns across OSS | grep.app | GitHub-wide code search |
|
|
55
56
|
| Finding symbol definitions/refs | lsp_* tools | Language-aware, precise |
|
|
56
57
|
| External API docs | web fetch | Official sources |
|
|
57
58
|
| Understanding file contents | Read | Full context |
|
|
58
59
|
|
|
60
|
+
### Documentation Source Priority
|
|
61
|
+
|
|
62
|
+
**For Agentuity-specific questions, follow this order:**
|
|
63
|
+
1. **agentuity.dev** — Official documentation
|
|
64
|
+
2. **SDK repo** — https://github.com/agentuity/sdk
|
|
65
|
+
3. **CLI help** — \`agentuity <cmd> --help\`
|
|
66
|
+
|
|
67
|
+
**For non-Agentuity libraries (React, OpenAI, etc.):**
|
|
68
|
+
- Use context7 or web fetch
|
|
69
|
+
|
|
59
70
|
### grep.app Usage
|
|
60
71
|
Search GitHub for code patterns and examples (free, no auth):
|
|
61
72
|
- Great for: "How do others implement X pattern?"
|
|
62
73
|
- Returns: Code snippets from public repos
|
|
63
74
|
|
|
64
75
|
### context7 Usage
|
|
65
|
-
Look up library documentation (free):
|
|
66
|
-
- Great for:
|
|
67
|
-
-
|
|
76
|
+
Look up **non-Agentuity** library documentation (free):
|
|
77
|
+
- Great for: React, OpenAI SDK, Hono, Zod, etc.
|
|
78
|
+
- **NOT for**: Agentuity SDK, CLI, or platform questions (use agentuity.dev instead)
|
|
68
79
|
|
|
69
80
|
### lsp_* Tools
|
|
70
81
|
Language Server Protocol tools for precise code intelligence:
|
|
@@ -88,15 +99,16 @@ Language Server Protocol tools for precise code intelligence:
|
|
|
88
99
|
|
|
89
100
|
### Vector Search Commands
|
|
90
101
|
\`\`\`bash
|
|
91
|
-
# Search
|
|
92
|
-
agentuity cloud vector search
|
|
102
|
+
# Search session history for similar past work
|
|
103
|
+
agentuity cloud vector search agentuity-opencode-sessions "authentication middleware" --limit 5 --json
|
|
93
104
|
|
|
94
|
-
# Search with
|
|
95
|
-
agentuity cloud vector search
|
|
105
|
+
# Search with project filter
|
|
106
|
+
agentuity cloud vector search agentuity-opencode-sessions "error handling" \\
|
|
107
|
+
--metadata "projectLabel=github.com/org/repo" --limit 5 --json
|
|
96
108
|
\`\`\`
|
|
97
109
|
|
|
98
110
|
### Prerequisites
|
|
99
|
-
|
|
111
|
+
Ask Memory agent first — Memory has better judgment about when to use Vector vs KV for recall.
|
|
100
112
|
|
|
101
113
|
## Report Format
|
|
102
114
|
|
|
@@ -197,12 +209,31 @@ Ask Expert for help with vector index creation or storage bucket setup. Don't at
|
|
|
197
209
|
|
|
198
210
|
## Memory Collaboration
|
|
199
211
|
|
|
200
|
-
|
|
212
|
+
Memory agent is the team's knowledge expert. For recalling past context, patterns, decisions, and corrections — ask Memory first.
|
|
213
|
+
|
|
214
|
+
### When to Ask Memory
|
|
215
|
+
|
|
216
|
+
| Situation | Ask Memory |
|
|
217
|
+
|-----------|------------|
|
|
218
|
+
| Before broad exploration (grep/lsp sweeps) | "Any context for [these folders/files]?" |
|
|
219
|
+
| Exploring unfamiliar module or area | "Any patterns or past work in [this area]?" |
|
|
220
|
+
| Found something that contradicts expectations | "What do we know about [this behavior]?" |
|
|
221
|
+
| Discovered valuable pattern | "Store this pattern for future reference" |
|
|
222
|
+
|
|
223
|
+
### How to Ask
|
|
224
|
+
|
|
225
|
+
> @Agentuity Coder Memory
|
|
226
|
+
> Any relevant context for [these folders/files] before I explore?
|
|
227
|
+
|
|
228
|
+
### What Memory Returns
|
|
229
|
+
|
|
230
|
+
Memory will return a structured response:
|
|
231
|
+
- **Quick Verdict**: relevance level and recommended action
|
|
232
|
+
- **Corrections**: prominently surfaced past mistakes (callout blocks)
|
|
233
|
+
- **File-by-file notes**: known roles, gotchas, prior decisions
|
|
234
|
+
- **Sources**: KV keys and Vector sessions for follow-up
|
|
201
235
|
|
|
202
|
-
|
|
203
|
-
- Memory can semantically search past sessions: "Find sessions about auth bugs"
|
|
204
|
-
- When you discover valuable patterns: Suggest that Lead/Memory store them
|
|
205
|
-
- Memory's Vector search complements your grep/lsp searches with semantic matching
|
|
236
|
+
Include Memory's findings in your Scout Report.
|
|
206
237
|
|
|
207
238
|
## Storing Large Findings
|
|
208
239
|
|
|
@@ -211,23 +242,23 @@ For large downloaded docs or analysis results that exceed message size:
|
|
|
211
242
|
### Save to Storage
|
|
212
243
|
Get bucket from KV first, or ask Expert to set one up.
|
|
213
244
|
\`\`\`bash
|
|
214
|
-
agentuity cloud storage upload ag-abc123 ./api-docs.md --key
|
|
245
|
+
agentuity cloud storage upload ag-abc123 ./api-docs.md --key opencode/{projectLabel}/docs/{source}/{docId}.md --json
|
|
215
246
|
\`\`\`
|
|
216
247
|
|
|
217
248
|
### Record Pointer in KV
|
|
218
249
|
\`\`\`bash
|
|
219
|
-
agentuity cloud kv set
|
|
250
|
+
agentuity cloud kv set agentuity-opencode-memory task:{taskId}:notes '{
|
|
220
251
|
"version": "v1",
|
|
221
252
|
"createdAt": "...",
|
|
222
|
-
"
|
|
253
|
+
"projectLabel": "...",
|
|
223
254
|
"taskId": "...",
|
|
224
255
|
"createdBy": "scout",
|
|
225
256
|
"data": {
|
|
226
257
|
"type": "observation",
|
|
227
258
|
"scope": "api-docs",
|
|
228
259
|
"content": "Downloaded OpenAPI spec for external service",
|
|
229
|
-
"storage_path": "
|
|
230
|
-
"tags":
|
|
260
|
+
"storage_path": "opencode/{projectLabel}/docs/openapi/external-api.json",
|
|
261
|
+
"tags": "api|external|openapi"
|
|
231
262
|
}
|
|
232
263
|
}'
|
|
233
264
|
\`\`\`
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import type { PluginContext, CoderConfig } from '../../types';
|
|
2
|
+
|
|
3
|
+
export interface CadenceHooks {
|
|
4
|
+
onMessage: (input: unknown, output: unknown) => Promise<void>;
|
|
5
|
+
onEvent: (input: unknown) => Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const COMPLETION_PATTERN = /<promise>\s*DONE\s*<\/promise>/i;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Cadence hooks track which sessions are in long-running Cadence mode.
|
|
12
|
+
*
|
|
13
|
+
* The actual continuation logic is agentic - Lead manages its own state and
|
|
14
|
+
* continuation via KV storage and the Cadence mode instructions in its prompt.
|
|
15
|
+
* These hooks primarily:
|
|
16
|
+
* 1. Detect when Cadence mode starts (via command or [CADENCE MODE] tag)
|
|
17
|
+
* 2. Detect when Cadence completes (via <promise>DONE</promise>)
|
|
18
|
+
* 3. Clean up on session abort/error
|
|
19
|
+
*/
|
|
20
|
+
export function createCadenceHooks(ctx: PluginContext, _config: CoderConfig): CadenceHooks {
|
|
21
|
+
const activeCadenceSessions = new Set<string>();
|
|
22
|
+
|
|
23
|
+
const log = (msg: string) => {
|
|
24
|
+
ctx.client.app.log({
|
|
25
|
+
body: {
|
|
26
|
+
service: 'coder-cadence',
|
|
27
|
+
level: 'debug',
|
|
28
|
+
message: msg,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
async onMessage(input: unknown, output: unknown): Promise<void> {
|
|
35
|
+
const sessionId = extractSessionId(input);
|
|
36
|
+
if (!sessionId) return;
|
|
37
|
+
|
|
38
|
+
const messageText = extractMessageText(output);
|
|
39
|
+
if (!messageText) return;
|
|
40
|
+
|
|
41
|
+
// Check if this is a Cadence start command
|
|
42
|
+
if (isCadenceStart(messageText)) {
|
|
43
|
+
log(`Cadence started for session ${sessionId}`);
|
|
44
|
+
activeCadenceSessions.add(sessionId);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Check if this session is in Cadence mode
|
|
49
|
+
if (!activeCadenceSessions.has(sessionId)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Check for completion signal
|
|
54
|
+
if (COMPLETION_PATTERN.test(messageText)) {
|
|
55
|
+
log(`Cadence completed for session ${sessionId}`);
|
|
56
|
+
activeCadenceSessions.delete(sessionId);
|
|
57
|
+
showToast(ctx, '✅ Cadence loop completed!');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Check for explicit stop/cancel
|
|
62
|
+
if (isCadenceStop(messageText)) {
|
|
63
|
+
log(`Cadence stopped for session ${sessionId}`);
|
|
64
|
+
activeCadenceSessions.delete(sessionId);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
async onEvent(input: unknown): Promise<void> {
|
|
70
|
+
const event = extractEvent(input);
|
|
71
|
+
if (!event) return;
|
|
72
|
+
|
|
73
|
+
log(`Event received: ${event.type}`);
|
|
74
|
+
|
|
75
|
+
// Handle session.idle - log for debugging/monitoring
|
|
76
|
+
// Actual continuation is agentic: Lead manages its own state via KV
|
|
77
|
+
if (event.type === 'session.idle') {
|
|
78
|
+
const sessionId = event.sessionId;
|
|
79
|
+
if (!sessionId) return;
|
|
80
|
+
|
|
81
|
+
if (activeCadenceSessions.has(sessionId)) {
|
|
82
|
+
log(`Session ${sessionId} idle while in Cadence mode`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Handle session abort
|
|
87
|
+
if (event.type === 'session.abort' || event.type === 'session.error') {
|
|
88
|
+
const sessionId = event.sessionId;
|
|
89
|
+
if (sessionId && activeCadenceSessions.has(sessionId)) {
|
|
90
|
+
log(`Cadence aborted for session ${sessionId}`);
|
|
91
|
+
activeCadenceSessions.delete(sessionId);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function extractSessionId(input: unknown): string | undefined {
|
|
99
|
+
if (typeof input !== 'object' || input === null) return undefined;
|
|
100
|
+
const inp = input as Record<string, unknown>;
|
|
101
|
+
if (typeof inp.sessionID === 'string') return inp.sessionID;
|
|
102
|
+
if (typeof inp.sessionId === 'string') return inp.sessionId;
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function extractMessageText(output: unknown): string | undefined {
|
|
107
|
+
if (typeof output !== 'object' || output === null) return undefined;
|
|
108
|
+
|
|
109
|
+
// Try parts array (Open Code format)
|
|
110
|
+
const out = output as { parts?: Array<{ type?: string; text?: string }>; text?: string };
|
|
111
|
+
if (out.parts && Array.isArray(out.parts)) {
|
|
112
|
+
for (const part of out.parts) {
|
|
113
|
+
if (part.type === 'text' && part.text) {
|
|
114
|
+
return part.text;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Try direct text property
|
|
120
|
+
if (typeof out.text === 'string') {
|
|
121
|
+
return out.text;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function extractEvent(input: unknown): { type: string; sessionId?: string } | undefined {
|
|
128
|
+
if (typeof input !== 'object' || input === null) return undefined;
|
|
129
|
+
|
|
130
|
+
const inp = input as { event?: { type?: string; properties?: Record<string, unknown> } };
|
|
131
|
+
if (!inp.event || typeof inp.event.type !== 'string') return undefined;
|
|
132
|
+
|
|
133
|
+
const sessionId = inp.event.properties?.sessionId as string | undefined;
|
|
134
|
+
return { type: inp.event.type, sessionId };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function isCadenceStart(text: string): boolean {
|
|
138
|
+
return text.includes('[CADENCE MODE]') || text.includes('agentuity-cadence');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function isCadenceStop(text: string): boolean {
|
|
142
|
+
return (
|
|
143
|
+
text.includes('status: "cancelled"') ||
|
|
144
|
+
text.includes("status: 'cancelled'") ||
|
|
145
|
+
text.includes('status":"cancelled')
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function showToast(ctx: PluginContext, message: string): void {
|
|
150
|
+
try {
|
|
151
|
+
ctx.client.tui?.showToast?.({ body: { message } });
|
|
152
|
+
} catch {
|
|
153
|
+
// Toast may not be available
|
|
154
|
+
}
|
|
155
|
+
}
|
package/src/plugin/plugin.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { createSessionHooks } from './hooks/session';
|
|
|
5
5
|
import { createToolHooks } from './hooks/tools';
|
|
6
6
|
import { createKeywordHooks } from './hooks/keyword';
|
|
7
7
|
import { createParamsHooks } from './hooks/params';
|
|
8
|
+
import { createCadenceHooks } from './hooks/cadence';
|
|
8
9
|
import { z } from 'zod';
|
|
9
10
|
import type { AgentRole } from '../types';
|
|
10
11
|
|
|
@@ -34,6 +35,7 @@ export async function createCoderPlugin(ctx: PluginContext): Promise<PluginHooks
|
|
|
34
35
|
const toolHooks = createToolHooks(ctx, coderConfig);
|
|
35
36
|
const keywordHooks = createKeywordHooks(ctx, coderConfig);
|
|
36
37
|
const paramsHooks = createParamsHooks(ctx, coderConfig);
|
|
38
|
+
const cadenceHooks = createCadenceHooks(ctx, coderConfig);
|
|
37
39
|
|
|
38
40
|
const configHandler = createConfigHandler(coderConfig);
|
|
39
41
|
|
|
@@ -57,10 +59,12 @@ export async function createCoderPlugin(ctx: PluginContext): Promise<PluginHooks
|
|
|
57
59
|
'chat.message': async (input: unknown, output: unknown) => {
|
|
58
60
|
await keywordHooks.onMessage(input, output);
|
|
59
61
|
await sessionHooks.onMessage(input, output);
|
|
62
|
+
await cadenceHooks.onMessage(input, output);
|
|
60
63
|
},
|
|
61
64
|
'chat.params': paramsHooks.onParams,
|
|
62
65
|
'tool.execute.before': toolHooks.before,
|
|
63
66
|
'tool.execute.after': toolHooks.after,
|
|
67
|
+
event: cadenceHooks.onEvent,
|
|
64
68
|
};
|
|
65
69
|
}
|
|
66
70
|
|
|
@@ -151,11 +155,13 @@ $ARGUMENTS
|
|
|
151
155
|
template: `Memorialize this session. Summarize what was accomplished in this conversation:
|
|
152
156
|
- Problem/task that was addressed
|
|
153
157
|
- Key decisions and their rationale
|
|
158
|
+
- Corrections/mistakes (user corrected agent or agent corrected user)
|
|
154
159
|
- Patterns and approaches used
|
|
155
160
|
- Solutions implemented
|
|
161
|
+
- Files and folders referenced
|
|
156
162
|
- Open questions or follow-ups
|
|
157
163
|
|
|
158
|
-
Save to vector storage using the
|
|
164
|
+
Save to vector storage using the agentuity-opencode-sessions namespace. Store any corrections prominently in agentuity-opencode-memory KV.
|
|
159
165
|
|
|
160
166
|
$ARGUMENTS`,
|
|
161
167
|
agent: 'Agentuity Coder Memory',
|
|
@@ -242,6 +248,177 @@ $ARGUMENTS`,
|
|
|
242
248
|
subtask: true,
|
|
243
249
|
argumentHint: '"run bun test" or "create a sandbox with 2Gi memory"',
|
|
244
250
|
},
|
|
251
|
+
|
|
252
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
253
|
+
// Agentuity Cadence Commands (Long-Running Tasks)
|
|
254
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
255
|
+
|
|
256
|
+
'agentuity-cadence': {
|
|
257
|
+
name: 'agentuity-cadence',
|
|
258
|
+
description: '🔄 Start a long-running Cadence loop (autonomous task completion)',
|
|
259
|
+
template: `[CADENCE MODE]
|
|
260
|
+
|
|
261
|
+
You are the Agentuity Coder Lead in **Cadence mode** — a long-running autonomous loop.
|
|
262
|
+
|
|
263
|
+
## Your Team (use @mentions to invoke)
|
|
264
|
+
- **@Agentuity Coder Scout**: Explore codebase, find patterns, research docs (read-only)
|
|
265
|
+
- **@Agentuity Coder Builder**: Implement features, write code, run tests
|
|
266
|
+
- **@Agentuity Coder Reviewer**: Review changes, catch issues, apply fixes
|
|
267
|
+
- **@Agentuity Coder Memory**: Store context, remember decisions, checkpoints
|
|
268
|
+
- **@Agentuity Coder Expert**: Agentuity CLI and cloud services specialist
|
|
269
|
+
|
|
270
|
+
## Task
|
|
271
|
+
$ARGUMENTS
|
|
272
|
+
|
|
273
|
+
## Cadence Workflow
|
|
274
|
+
|
|
275
|
+
1. **Initialize loop state**:
|
|
276
|
+
- Generate loop ID (format: \`lp_short_name_01\`)
|
|
277
|
+
- Store in KV: \`agentuity cloud kv set agentuity-opencode-tasks "loop:{loopId}:state" '{...}'\`
|
|
278
|
+
|
|
279
|
+
2. **Each iteration**:
|
|
280
|
+
- Ask @Agentuity Coder Memory for relevant context
|
|
281
|
+
- Use @Agentuity Coder Scout to understand what's needed
|
|
282
|
+
- Delegate implementation to @Agentuity Coder Builder
|
|
283
|
+
- Have @Agentuity Coder Reviewer verify the work
|
|
284
|
+
- Tell @Agentuity Coder Memory to store checkpoint
|
|
285
|
+
|
|
286
|
+
3. **When truly complete**, output:
|
|
287
|
+
\`\`\`
|
|
288
|
+
<promise>DONE</promise>
|
|
289
|
+
\`\`\`
|
|
290
|
+
|
|
291
|
+
4. **Tell @Agentuity Coder Memory to memorialize** the completed session
|
|
292
|
+
|
|
293
|
+
## Guidelines
|
|
294
|
+
- **Always delegate** — use Scout for research, Builder for code, Reviewer for verification
|
|
295
|
+
- Ask Memory for context at each iteration start
|
|
296
|
+
- Store checkpoints at each iteration end
|
|
297
|
+
- If stuck, ask Scout to re-evaluate before pausing
|
|
298
|
+
- Use @Agentuity Coder Expert for sandbox/cloud operations
|
|
299
|
+
- Respect max iterations (50 default)`,
|
|
300
|
+
agent: 'Agentuity Coder Lead',
|
|
301
|
+
argumentHint: 'build the new auth feature with tests',
|
|
302
|
+
},
|
|
303
|
+
|
|
304
|
+
'agentuity-cadence-status': {
|
|
305
|
+
name: 'agentuity-cadence-status',
|
|
306
|
+
description: '📊 Check status of active Cadence loops',
|
|
307
|
+
template: `Check the status of active Cadence loops.
|
|
308
|
+
|
|
309
|
+
## Instructions
|
|
310
|
+
|
|
311
|
+
1. Search for active loops:
|
|
312
|
+
\`\`\`bash
|
|
313
|
+
agentuity cloud kv search agentuity-opencode-tasks "loop:" --json
|
|
314
|
+
\`\`\`
|
|
315
|
+
|
|
316
|
+
2. For each loop found, get its state:
|
|
317
|
+
\`\`\`bash
|
|
318
|
+
agentuity cloud kv get agentuity-opencode-tasks "loop:{loopId}:state" --json
|
|
319
|
+
\`\`\`
|
|
320
|
+
|
|
321
|
+
3. Report status in a clear format:
|
|
322
|
+
- Loop ID
|
|
323
|
+
- Status (running/paused/completed/failed/cancelled)
|
|
324
|
+
- Current iteration / max iterations
|
|
325
|
+
- Original task (brief)
|
|
326
|
+
- Last update time
|
|
327
|
+
|
|
328
|
+
$ARGUMENTS`,
|
|
329
|
+
agent: 'Agentuity Coder Lead',
|
|
330
|
+
argumentHint: '(optional: specific loop ID)',
|
|
331
|
+
},
|
|
332
|
+
|
|
333
|
+
'agentuity-cadence-pause': {
|
|
334
|
+
name: 'agentuity-cadence-pause',
|
|
335
|
+
description: '⏸️ Pause an active Cadence loop',
|
|
336
|
+
template: `Pause the active Cadence loop.
|
|
337
|
+
|
|
338
|
+
## Instructions
|
|
339
|
+
|
|
340
|
+
1. Find the active loop (or use the provided loop ID):
|
|
341
|
+
\`\`\`bash
|
|
342
|
+
agentuity cloud kv search agentuity-opencode-tasks "loop:" --json
|
|
343
|
+
\`\`\`
|
|
344
|
+
|
|
345
|
+
2. Update the loop status to paused:
|
|
346
|
+
\`\`\`bash
|
|
347
|
+
agentuity cloud kv get agentuity-opencode-tasks "loop:{loopId}:state" --json
|
|
348
|
+
# Then update with status: "paused"
|
|
349
|
+
agentuity cloud kv set agentuity-opencode-tasks "loop:{loopId}:state" '{...updated state with status: "paused"...}'
|
|
350
|
+
\`\`\`
|
|
351
|
+
|
|
352
|
+
3. Confirm the pause to the user.
|
|
353
|
+
|
|
354
|
+
$ARGUMENTS`,
|
|
355
|
+
agent: 'Agentuity Coder Lead',
|
|
356
|
+
argumentHint: '(optional: specific loop ID)',
|
|
357
|
+
},
|
|
358
|
+
|
|
359
|
+
'agentuity-cadence-resume': {
|
|
360
|
+
name: 'agentuity-cadence-resume',
|
|
361
|
+
description: '▶️ Resume a paused Cadence loop',
|
|
362
|
+
template: `[CADENCE MODE]
|
|
363
|
+
|
|
364
|
+
Resume a paused Cadence loop.
|
|
365
|
+
|
|
366
|
+
## Instructions
|
|
367
|
+
|
|
368
|
+
1. Find the paused loop (or use the provided loop ID):
|
|
369
|
+
\`\`\`bash
|
|
370
|
+
agentuity cloud kv search agentuity-opencode-tasks "loop:" --json
|
|
371
|
+
\`\`\`
|
|
372
|
+
|
|
373
|
+
2. Get the loop state and last checkpoint:
|
|
374
|
+
\`\`\`bash
|
|
375
|
+
agentuity cloud kv get agentuity-opencode-tasks "loop:{loopId}:state" --json
|
|
376
|
+
\`\`\`
|
|
377
|
+
|
|
378
|
+
3. Ask Memory for context:
|
|
379
|
+
- Get the last few checkpoints
|
|
380
|
+
- Get any handoff packet if available
|
|
381
|
+
- Get relevant corrections
|
|
382
|
+
|
|
383
|
+
4. Update status to running and continue from where you left off:
|
|
384
|
+
\`\`\`bash
|
|
385
|
+
agentuity cloud kv set agentuity-opencode-tasks "loop:{loopId}:state" '{...updated state with status: "running"...}'
|
|
386
|
+
\`\`\`
|
|
387
|
+
|
|
388
|
+
5. Continue the Cadence loop following the iteration workflow.
|
|
389
|
+
|
|
390
|
+
$ARGUMENTS`,
|
|
391
|
+
agent: 'Agentuity Coder Lead',
|
|
392
|
+
argumentHint: '(optional: specific loop ID)',
|
|
393
|
+
},
|
|
394
|
+
|
|
395
|
+
'agentuity-cadence-stop': {
|
|
396
|
+
name: 'agentuity-cadence-stop',
|
|
397
|
+
description: '⏹️ Stop and cancel a Cadence loop',
|
|
398
|
+
template: `Stop and cancel the Cadence loop.
|
|
399
|
+
|
|
400
|
+
## Instructions
|
|
401
|
+
|
|
402
|
+
1. Find the active loop (or use the provided loop ID):
|
|
403
|
+
\`\`\`bash
|
|
404
|
+
agentuity cloud kv search agentuity-opencode-tasks "loop:" --json
|
|
405
|
+
\`\`\`
|
|
406
|
+
|
|
407
|
+
2. Update the loop status to cancelled:
|
|
408
|
+
\`\`\`bash
|
|
409
|
+
agentuity cloud kv get agentuity-opencode-tasks "loop:{loopId}:state" --json
|
|
410
|
+
# Then update with status: "cancelled"
|
|
411
|
+
agentuity cloud kv set agentuity-opencode-tasks "loop:{loopId}:state" '{...updated state with status: "cancelled"...}'
|
|
412
|
+
\`\`\`
|
|
413
|
+
|
|
414
|
+
3. Ask Memory to store a final checkpoint noting the cancellation reason.
|
|
415
|
+
|
|
416
|
+
4. Confirm the stop to the user.
|
|
417
|
+
|
|
418
|
+
$ARGUMENTS`,
|
|
419
|
+
agent: 'Agentuity Coder Lead',
|
|
420
|
+
argumentHint: '(optional: specific loop ID)',
|
|
421
|
+
},
|
|
245
422
|
};
|
|
246
423
|
}
|
|
247
424
|
|
package/src/types.ts
CHANGED
|
@@ -9,6 +9,36 @@ export type TaskStatus = z.infer<typeof TaskStatusSchema>;
|
|
|
9
9
|
export const OrchestrationPatternSchema = z.enum(['single', 'fanout', 'pipeline']);
|
|
10
10
|
export type OrchestrationPattern = z.infer<typeof OrchestrationPatternSchema>;
|
|
11
11
|
|
|
12
|
+
export const CadenceStatusSchema = z.enum([
|
|
13
|
+
'running',
|
|
14
|
+
'paused',
|
|
15
|
+
'completed',
|
|
16
|
+
'failed',
|
|
17
|
+
'cancelled',
|
|
18
|
+
]);
|
|
19
|
+
export type CadenceStatus = z.infer<typeof CadenceStatusSchema>;
|
|
20
|
+
|
|
21
|
+
export const CadenceSandboxModeSchema = z.enum(['off', 'per_iteration', 'persistent']);
|
|
22
|
+
export type CadenceSandboxMode = z.infer<typeof CadenceSandboxModeSchema>;
|
|
23
|
+
|
|
24
|
+
export interface CadenceLoop {
|
|
25
|
+
loopId: string;
|
|
26
|
+
parentId?: string;
|
|
27
|
+
projectLabel?: string;
|
|
28
|
+
sessionId?: string;
|
|
29
|
+
status: CadenceStatus;
|
|
30
|
+
iteration: number;
|
|
31
|
+
maxIterations: number;
|
|
32
|
+
prompt: string;
|
|
33
|
+
createdAt: string;
|
|
34
|
+
updatedAt: string;
|
|
35
|
+
lastError?: string;
|
|
36
|
+
sandbox?: {
|
|
37
|
+
mode: CadenceSandboxMode;
|
|
38
|
+
sandboxId?: string;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
12
42
|
export interface AgentConfig {
|
|
13
43
|
/** Agent description - explains what it does and when to use it */
|
|
14
44
|
description: string;
|