@ebowwa/daemons 0.5.0
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 +264 -0
- package/dist/bin/discord-cli.js +124118 -0
- package/dist/bin/manager.js +143 -0
- package/dist/bin/telegram-cli.js +124114 -0
- package/dist/index.js +125340 -0
- package/package.json +94 -0
- package/src/agent.ts +111 -0
- package/src/channels/base.ts +573 -0
- package/src/channels/discord.ts +306 -0
- package/src/channels/index.ts +169 -0
- package/src/channels/telegram.ts +315 -0
- package/src/daemon.ts +534 -0
- package/src/hooks.ts +97 -0
- package/src/index.ts +111 -0
- package/src/memory.ts +369 -0
- package/src/skills/coding/commit.ts +202 -0
- package/src/skills/coding/execute-subtask.ts +136 -0
- package/src/skills/coding/fix-issues.ts +126 -0
- package/src/skills/coding/index.ts +26 -0
- package/src/skills/coding/plan-task.ts +158 -0
- package/src/skills/coding/quality-check.ts +155 -0
- package/src/skills/index.ts +65 -0
- package/src/skills/registry.ts +380 -0
- package/src/skills/shared/index.ts +21 -0
- package/src/skills/shared/reflect.ts +156 -0
- package/src/skills/shared/review.ts +201 -0
- package/src/skills/shared/trajectory.ts +319 -0
- package/src/skills/trading/analyze-market.ts +144 -0
- package/src/skills/trading/check-risk.ts +176 -0
- package/src/skills/trading/execute-trade.ts +185 -0
- package/src/skills/trading/generate-signal.ts +160 -0
- package/src/skills/trading/index.ts +26 -0
- package/src/skills/trading/monitor-position.ts +179 -0
- package/src/skills/types.ts +235 -0
- package/src/skills/workflows.ts +340 -0
- package/src/state.ts +77 -0
- package/src/tools.ts +134 -0
- package/src/types.ts +314 -0
- package/src/workflow.ts +341 -0
- package/src/workflows/coding.ts +580 -0
- package/src/workflows/index.ts +61 -0
- package/src/workflows/trading.ts +608 -0
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GLM Daemon - Coding Workflow
|
|
3
|
+
*
|
|
4
|
+
* Default coding workflow extracted from hardcoded daemon phases.
|
|
5
|
+
* Phases: planning → executing → reflecting → paranoid → reviewing → fixing → committing → complete
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
BaseWorkflow,
|
|
10
|
+
type GLMWorkflowConfig,
|
|
11
|
+
type GLMWorkflowContext,
|
|
12
|
+
type GLMWorkflowPhaseResult,
|
|
13
|
+
type GLMWorkflowPhase,
|
|
14
|
+
type GLMWorkflowTransition,
|
|
15
|
+
} from "../workflow.js";
|
|
16
|
+
import type { GLMReflectionSummary } from "../types.js";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Coding workflow phases
|
|
20
|
+
*/
|
|
21
|
+
export type CodingPhase =
|
|
22
|
+
| "planning"
|
|
23
|
+
| "executing"
|
|
24
|
+
| "reflecting"
|
|
25
|
+
| "paranoid"
|
|
26
|
+
| "reviewing"
|
|
27
|
+
| "fixing"
|
|
28
|
+
| "committing"
|
|
29
|
+
| "complete";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Coding workflow phases definition
|
|
33
|
+
*/
|
|
34
|
+
export const CODING_PHASES: GLMWorkflowPhase<CodingPhase>[] = [
|
|
35
|
+
{
|
|
36
|
+
name: "planning",
|
|
37
|
+
label: "Planning",
|
|
38
|
+
description: "Break down the task into subtasks",
|
|
39
|
+
skippable: false,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: "executing",
|
|
43
|
+
label: "Executing",
|
|
44
|
+
description: "Work on the current subtask",
|
|
45
|
+
skippable: false,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: "reflecting",
|
|
49
|
+
label: "Reflecting",
|
|
50
|
+
description: "Checkpoint after N tools - summarize progress",
|
|
51
|
+
skippable: true,
|
|
52
|
+
timeout: 60000,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "paranoid",
|
|
56
|
+
label: "Paranoid",
|
|
57
|
+
description: "Quality check after every edit",
|
|
58
|
+
skippable: false,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "reviewing",
|
|
62
|
+
label: "Reviewing",
|
|
63
|
+
description: "Final quality review",
|
|
64
|
+
skippable: false,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "fixing",
|
|
68
|
+
label: "Fixing",
|
|
69
|
+
description: "Fix issues found in review",
|
|
70
|
+
skippable: true,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "committing",
|
|
74
|
+
label: "Committing",
|
|
75
|
+
description: "Commit changes",
|
|
76
|
+
skippable: true,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "complete",
|
|
80
|
+
label: "Complete",
|
|
81
|
+
description: "Task is finished",
|
|
82
|
+
skippable: false,
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Coding workflow transition rules
|
|
88
|
+
*/
|
|
89
|
+
export const CODING_TRANSITIONS: GLMWorkflowTransition<CodingPhase>[] = [
|
|
90
|
+
// Planning -> Executing (always)
|
|
91
|
+
{
|
|
92
|
+
from: "planning",
|
|
93
|
+
to: "executing",
|
|
94
|
+
priority: 100,
|
|
95
|
+
},
|
|
96
|
+
// Executing -> Paranoid (when all subtasks complete)
|
|
97
|
+
{
|
|
98
|
+
from: "executing",
|
|
99
|
+
to: "paranoid",
|
|
100
|
+
priority: 90,
|
|
101
|
+
condition: (ctx) => {
|
|
102
|
+
const subtasks = ctx.state.slam.subtasks;
|
|
103
|
+
const completed = ctx.state.slam.completedSubtasks;
|
|
104
|
+
return subtasks.length > 0 && subtasks.every((s) => completed.includes(s.id));
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
// Executing -> Executing (continue with next subtask)
|
|
108
|
+
{
|
|
109
|
+
from: "executing",
|
|
110
|
+
to: "executing",
|
|
111
|
+
priority: 80,
|
|
112
|
+
},
|
|
113
|
+
// Paranoid -> Fixing (if issues found)
|
|
114
|
+
{
|
|
115
|
+
from: "paranoid",
|
|
116
|
+
to: "fixing",
|
|
117
|
+
priority: 90,
|
|
118
|
+
condition: async (ctx) => {
|
|
119
|
+
// This will be set by the phase execution
|
|
120
|
+
return ctx.custom.hasIssues === true;
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
// Paranoid -> Reviewing (if no issues)
|
|
124
|
+
{
|
|
125
|
+
from: "paranoid",
|
|
126
|
+
to: "reviewing",
|
|
127
|
+
priority: 80,
|
|
128
|
+
},
|
|
129
|
+
// Reviewing -> Fixing (if not approved)
|
|
130
|
+
{
|
|
131
|
+
from: "reviewing",
|
|
132
|
+
to: "fixing",
|
|
133
|
+
priority: 90,
|
|
134
|
+
condition: async (ctx) => {
|
|
135
|
+
return ctx.custom.approved !== true;
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
// Reviewing -> Committing (if approved)
|
|
139
|
+
{
|
|
140
|
+
from: "reviewing",
|
|
141
|
+
to: "committing",
|
|
142
|
+
priority: 80,
|
|
143
|
+
},
|
|
144
|
+
// Fixing -> Paranoid (re-check after fixes)
|
|
145
|
+
{
|
|
146
|
+
from: "fixing",
|
|
147
|
+
to: "paranoid",
|
|
148
|
+
priority: 100,
|
|
149
|
+
},
|
|
150
|
+
// Committing -> Complete
|
|
151
|
+
{
|
|
152
|
+
from: "committing",
|
|
153
|
+
to: "complete",
|
|
154
|
+
priority: 100,
|
|
155
|
+
},
|
|
156
|
+
// Reflecting -> previous phase (handled specially)
|
|
157
|
+
{
|
|
158
|
+
from: "reflecting",
|
|
159
|
+
to: "executing", // Default, will be overridden
|
|
160
|
+
priority: 100,
|
|
161
|
+
condition: async (ctx) => {
|
|
162
|
+
// Return to previous phase
|
|
163
|
+
const prev = ctx.state.slam.previousPhase;
|
|
164
|
+
if (prev) {
|
|
165
|
+
ctx.custom.nextPhase = prev;
|
|
166
|
+
}
|
|
167
|
+
return true;
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Coding workflow configuration
|
|
174
|
+
*/
|
|
175
|
+
export const CODING_WORKFLOW_CONFIG: GLMWorkflowConfig<CodingPhase> = {
|
|
176
|
+
id: "coding",
|
|
177
|
+
name: "Coding Workflow",
|
|
178
|
+
description: "Default coding workflow for software development tasks",
|
|
179
|
+
phases: CODING_PHASES,
|
|
180
|
+
initialPhase: "planning",
|
|
181
|
+
terminalPhases: ["complete"],
|
|
182
|
+
transitions: CODING_TRANSITIONS,
|
|
183
|
+
defaultOrder: ["planning", "executing", "paranoid", "reviewing", "fixing", "committing", "complete"],
|
|
184
|
+
reflectionPhase: "reflecting",
|
|
185
|
+
systemPromptExtensions: `Use tools when available. Be thorough but efficient.
|
|
186
|
+
Focus on code changes, testing, and verification.`,
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Coding Workflow implementation
|
|
191
|
+
*/
|
|
192
|
+
export class CodingWorkflow extends BaseWorkflow<CodingPhase> {
|
|
193
|
+
constructor() {
|
|
194
|
+
super(CODING_WORKFLOW_CONFIG);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Execute a coding phase
|
|
199
|
+
*/
|
|
200
|
+
async executePhase(phase: string, context: GLMWorkflowContext): Promise<GLMWorkflowPhaseResult> {
|
|
201
|
+
switch (phase as CodingPhase) {
|
|
202
|
+
case "planning":
|
|
203
|
+
return this.phasePlanning(context);
|
|
204
|
+
case "executing":
|
|
205
|
+
return this.phaseExecuting(context);
|
|
206
|
+
case "reflecting":
|
|
207
|
+
return this.phaseReflecting(context);
|
|
208
|
+
case "paranoid":
|
|
209
|
+
return this.phaseParanoid(context);
|
|
210
|
+
case "reviewing":
|
|
211
|
+
return this.phaseReviewing(context);
|
|
212
|
+
case "fixing":
|
|
213
|
+
return this.phaseFixing(context);
|
|
214
|
+
case "committing":
|
|
215
|
+
return this.phaseCommitting(context);
|
|
216
|
+
case "complete":
|
|
217
|
+
return this.phaseComplete(context);
|
|
218
|
+
default:
|
|
219
|
+
throw new Error(`Unknown phase: ${phase}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Planning phase - break down task into subtasks
|
|
225
|
+
*/
|
|
226
|
+
private async phasePlanning(context: GLMWorkflowContext): Promise<GLMWorkflowPhaseResult> {
|
|
227
|
+
console.log("[CodingWorkflow] Phase: Planning");
|
|
228
|
+
|
|
229
|
+
const prompt = `${context.state.prompt}
|
|
230
|
+
|
|
231
|
+
Break this task down into 3-7 concrete subtasks.
|
|
232
|
+
For each subtask, specify:
|
|
233
|
+
- Title (short description)
|
|
234
|
+
- Description (what needs to be done)
|
|
235
|
+
- Dependencies (which subtasks must come first)
|
|
236
|
+
|
|
237
|
+
Respond with a JSON array of subtasks.
|
|
238
|
+
`;
|
|
239
|
+
|
|
240
|
+
const response = await context.agent.execute(prompt);
|
|
241
|
+
const subtasks = this.parseSubtasks(response, context);
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
nextPhase: "executing",
|
|
245
|
+
continue: true,
|
|
246
|
+
stateUpdates: {
|
|
247
|
+
slam: {
|
|
248
|
+
...context.state.slam,
|
|
249
|
+
subtasks,
|
|
250
|
+
currentSubtask: subtasks[0]?.id || null,
|
|
251
|
+
phase: "executing",
|
|
252
|
+
},
|
|
253
|
+
} as any,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Executing phase - work on current subtask
|
|
259
|
+
*/
|
|
260
|
+
private async phaseExecuting(context: GLMWorkflowContext): Promise<GLMWorkflowPhaseResult> {
|
|
261
|
+
const currentSubtaskId = context.state.slam.currentSubtask;
|
|
262
|
+
|
|
263
|
+
if (!currentSubtaskId) {
|
|
264
|
+
return {
|
|
265
|
+
nextPhase: "reviewing",
|
|
266
|
+
continue: true,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const subtask = context.state.slam.subtasks.find((st) => st.id === currentSubtaskId);
|
|
271
|
+
if (!subtask) {
|
|
272
|
+
return {
|
|
273
|
+
nextPhase: "reviewing",
|
|
274
|
+
continue: true,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
console.log(`[CodingWorkflow] Executing subtask: ${subtask.title}`);
|
|
279
|
+
|
|
280
|
+
const prompt = `Work on this subtask: ${subtask.title}
|
|
281
|
+
|
|
282
|
+
${subtask.description}
|
|
283
|
+
|
|
284
|
+
Use available tools to complete the work.
|
|
285
|
+
Focus on code changes, testing, and verification.
|
|
286
|
+
`;
|
|
287
|
+
|
|
288
|
+
const response = await context.agent.execute(prompt);
|
|
289
|
+
|
|
290
|
+
// Find next subtask
|
|
291
|
+
const completedSubtasks = [...context.state.slam.completedSubtasks, currentSubtaskId];
|
|
292
|
+
const nextSubtask = context.state.slam.subtasks.find(
|
|
293
|
+
(st) => !completedSubtasks.includes(st.id)
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
// Update subtask status
|
|
297
|
+
const updatedSubtasks = context.state.slam.subtasks.map((st) =>
|
|
298
|
+
st.id === currentSubtaskId
|
|
299
|
+
? { ...st, status: "completed" as const, result: response }
|
|
300
|
+
: st
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
// Determine next phase
|
|
304
|
+
const nextPhase = nextSubtask ? "executing" : "paranoid";
|
|
305
|
+
|
|
306
|
+
return {
|
|
307
|
+
nextPhase,
|
|
308
|
+
continue: true,
|
|
309
|
+
stateUpdates: {
|
|
310
|
+
slam: {
|
|
311
|
+
...context.state.slam,
|
|
312
|
+
subtasks: updatedSubtasks,
|
|
313
|
+
completedSubtasks,
|
|
314
|
+
currentSubtask: nextSubtask?.id || null,
|
|
315
|
+
phase: nextPhase,
|
|
316
|
+
},
|
|
317
|
+
} as any,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Reflecting phase - TL;DR checkpoint after N tools
|
|
323
|
+
*/
|
|
324
|
+
private async phaseReflecting(context: GLMWorkflowContext): Promise<GLMWorkflowPhaseResult> {
|
|
325
|
+
console.log(`[CodingWorkflow] Phase: Reflecting (checkpoint #${context.state.reflection.checkpointCount + 1})`);
|
|
326
|
+
console.log(`[CodingWorkflow] Tools used this chunk: ${context.state.reflection.toolCount}`);
|
|
327
|
+
|
|
328
|
+
const previousPhase = context.state.slam.previousPhase || "executing";
|
|
329
|
+
|
|
330
|
+
const prompt = `REFLECTION CHECKPOINT #${context.state.reflection.checkpointCount + 1}
|
|
331
|
+
|
|
332
|
+
You have used ${context.state.reflection.toolCount} tools. Pause and reflect.
|
|
333
|
+
|
|
334
|
+
Task: ${context.state.prompt}
|
|
335
|
+
Current Phase (before reflection): ${previousPhase}
|
|
336
|
+
Iteration: ${context.state.iteration}
|
|
337
|
+
Subtasks: ${context.state.slam.completedSubtasks.length}/${context.state.slam.subtasks.length} complete
|
|
338
|
+
|
|
339
|
+
Files changed: ${context.state.filesChanged.length > 0 ? context.state.filesChanged.join(", ") : "none"}
|
|
340
|
+
|
|
341
|
+
Generate a TL;DR summary in this JSON format:
|
|
342
|
+
{
|
|
343
|
+
"summary": "1-2 sentence summary of progress",
|
|
344
|
+
"accomplishments": ["what was done"],
|
|
345
|
+
"nextSteps": ["what needs to be done next"],
|
|
346
|
+
"issues": ["any blockers or problems"]
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
Be concise. Focus on what matters for continuing the task.
|
|
350
|
+
`;
|
|
351
|
+
|
|
352
|
+
const response = await context.agent.execute(prompt);
|
|
353
|
+
const summary = this.parseReflectionSummary(response, previousPhase, context);
|
|
354
|
+
|
|
355
|
+
// Run reflection hook
|
|
356
|
+
await context.executeHook("onReflection", context.state, summary);
|
|
357
|
+
|
|
358
|
+
// Log the reflection
|
|
359
|
+
console.log(`[CodingWorkflow] TL;DR: ${summary.summary}`);
|
|
360
|
+
console.log(`[CodingWorkflow] Accomplishments: ${summary.accomplishments.join(", ")}`);
|
|
361
|
+
console.log(`[CodingWorkflow] Next: ${summary.nextSteps.join(", ")}`);
|
|
362
|
+
|
|
363
|
+
return {
|
|
364
|
+
nextPhase: previousPhase,
|
|
365
|
+
continue: true,
|
|
366
|
+
data: { summary },
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Paranoid phase - quality check after every edit
|
|
372
|
+
*/
|
|
373
|
+
private async phaseParanoid(context: GLMWorkflowContext): Promise<GLMWorkflowPhaseResult> {
|
|
374
|
+
console.log("[CodingWorkflow] Phase: Paranoid (quality check)");
|
|
375
|
+
|
|
376
|
+
const prompt = `Review the changes made in this session for:
|
|
377
|
+
- Bugs or errors
|
|
378
|
+
- Edge cases not handled
|
|
379
|
+
- Security vulnerabilities
|
|
380
|
+
- Performance issues
|
|
381
|
+
- Breaking changes
|
|
382
|
+
|
|
383
|
+
Task: ${context.state.prompt}
|
|
384
|
+
|
|
385
|
+
Changes made:
|
|
386
|
+
${context.state.filesChanged.map((f) => `- ${f}`).join("\n")}
|
|
387
|
+
|
|
388
|
+
Be thorough. If issues found, we'll fix them. If clean, we proceed to review.
|
|
389
|
+
`;
|
|
390
|
+
|
|
391
|
+
const response = await context.agent.execute(prompt);
|
|
392
|
+
const hasIssues = this.detectIssues(response);
|
|
393
|
+
|
|
394
|
+
// Store result in context for transition condition
|
|
395
|
+
context.custom.hasIssues = hasIssues;
|
|
396
|
+
|
|
397
|
+
return {
|
|
398
|
+
nextPhase: hasIssues ? "fixing" : "reviewing",
|
|
399
|
+
continue: true,
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Reviewing phase - final quality review
|
|
405
|
+
*/
|
|
406
|
+
private async phaseReviewing(context: GLMWorkflowContext): Promise<GLMWorkflowPhaseResult> {
|
|
407
|
+
console.log("[CodingWorkflow] Phase: Reviewing");
|
|
408
|
+
|
|
409
|
+
const prompt = `Final review of the completed work.
|
|
410
|
+
|
|
411
|
+
Task: ${context.state.prompt}
|
|
412
|
+
Completion promise: ${context.state.promise}
|
|
413
|
+
|
|
414
|
+
Does the implementation fully satisfy the completion promise?
|
|
415
|
+
Are there any remaining issues or TODOs?
|
|
416
|
+
|
|
417
|
+
If complete and clean, respond with "APPROVED".
|
|
418
|
+
Otherwise, list remaining issues.
|
|
419
|
+
`;
|
|
420
|
+
|
|
421
|
+
const response = await context.agent.execute(prompt);
|
|
422
|
+
const approved = response.includes("APPROVED");
|
|
423
|
+
|
|
424
|
+
// Store result in context for transition condition
|
|
425
|
+
context.custom.approved = approved;
|
|
426
|
+
|
|
427
|
+
return {
|
|
428
|
+
nextPhase: approved ? "committing" : "fixing",
|
|
429
|
+
continue: true,
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Fixing phase - fix issues found
|
|
435
|
+
*/
|
|
436
|
+
private async phaseFixing(context: GLMWorkflowContext): Promise<GLMWorkflowPhaseResult> {
|
|
437
|
+
console.log("[CodingWorkflow] Phase: Fixing");
|
|
438
|
+
|
|
439
|
+
const prompt = `Fix the issues identified in the review.
|
|
440
|
+
|
|
441
|
+
Use tools to make necessary changes.
|
|
442
|
+
Test your fixes thoroughly.
|
|
443
|
+
`;
|
|
444
|
+
|
|
445
|
+
await context.agent.execute(prompt);
|
|
446
|
+
|
|
447
|
+
// Reset approval state
|
|
448
|
+
context.custom.approved = false;
|
|
449
|
+
context.custom.hasIssues = false;
|
|
450
|
+
|
|
451
|
+
return {
|
|
452
|
+
nextPhase: "paranoid", // Re-check after fixes
|
|
453
|
+
continue: true,
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Committing phase - commit changes
|
|
459
|
+
*/
|
|
460
|
+
private async phaseCommitting(context: GLMWorkflowContext): Promise<GLMWorkflowPhaseResult> {
|
|
461
|
+
console.log("[CodingWorkflow] Phase: Committing");
|
|
462
|
+
|
|
463
|
+
if (context.state.git.autoCommit) {
|
|
464
|
+
// TODO: Use MCP git tools for commits
|
|
465
|
+
console.log("[CodingWorkflow] Auto-commit would happen here via MCP git tools");
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return {
|
|
469
|
+
nextPhase: "complete",
|
|
470
|
+
continue: true,
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Complete phase - task is finished
|
|
476
|
+
*/
|
|
477
|
+
private async phaseComplete(context: GLMWorkflowContext): Promise<GLMWorkflowPhaseResult> {
|
|
478
|
+
console.log("[CodingWorkflow] Task complete!");
|
|
479
|
+
|
|
480
|
+
await context.executeHook("onSessionEnd", context.state);
|
|
481
|
+
|
|
482
|
+
return {
|
|
483
|
+
nextPhase: "complete",
|
|
484
|
+
continue: false, // Stop the loop
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Parse subtasks from agent response
|
|
490
|
+
*/
|
|
491
|
+
private parseSubtasks(
|
|
492
|
+
response: string,
|
|
493
|
+
context: GLMWorkflowContext
|
|
494
|
+
): Array<{
|
|
495
|
+
id: string;
|
|
496
|
+
title: string;
|
|
497
|
+
description: string;
|
|
498
|
+
status: "pending" | "in_progress" | "completed" | "blocked" | "failed";
|
|
499
|
+
dependencies?: string[];
|
|
500
|
+
}> {
|
|
501
|
+
try {
|
|
502
|
+
const jsonMatch = response.match(/\[[\s\S]*\]/);
|
|
503
|
+
if (jsonMatch) {
|
|
504
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
505
|
+
return parsed.map((st: any, idx: number) => ({
|
|
506
|
+
id: st.id || `subtask-${idx}`,
|
|
507
|
+
title: st.title || st.task || `Subtask ${idx + 1}`,
|
|
508
|
+
description: st.description || "",
|
|
509
|
+
status: "pending" as const,
|
|
510
|
+
dependencies: st.dependencies || [],
|
|
511
|
+
}));
|
|
512
|
+
}
|
|
513
|
+
} catch {
|
|
514
|
+
// Fallback: create single subtask from prompt
|
|
515
|
+
return [{
|
|
516
|
+
id: "subtask-0",
|
|
517
|
+
title: context.state.prompt.substring(0, 50),
|
|
518
|
+
description: context.state.prompt,
|
|
519
|
+
status: "pending",
|
|
520
|
+
}];
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
return [];
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Parse reflection summary from agent response
|
|
528
|
+
*/
|
|
529
|
+
private parseReflectionSummary(
|
|
530
|
+
response: string,
|
|
531
|
+
phase: string,
|
|
532
|
+
context: GLMWorkflowContext
|
|
533
|
+
): GLMReflectionSummary {
|
|
534
|
+
try {
|
|
535
|
+
const jsonMatch = response.match(/\{[\s\S]*\}/);
|
|
536
|
+
if (jsonMatch) {
|
|
537
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
538
|
+
return {
|
|
539
|
+
checkpoint: context.state.reflection.checkpointCount + 1,
|
|
540
|
+
timestamp: new Date().toISOString(),
|
|
541
|
+
toolsUsed: context.state.reflection.toolCount,
|
|
542
|
+
phase: phase as any,
|
|
543
|
+
summary: parsed.summary || "Progress made",
|
|
544
|
+
accomplishments: parsed.accomplishments || [],
|
|
545
|
+
nextSteps: parsed.nextSteps || [],
|
|
546
|
+
issues: parsed.issues || [],
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
} catch {
|
|
550
|
+
// Fallback
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
return {
|
|
554
|
+
checkpoint: context.state.reflection.checkpointCount + 1,
|
|
555
|
+
timestamp: new Date().toISOString(),
|
|
556
|
+
toolsUsed: context.state.reflection.toolCount,
|
|
557
|
+
phase: phase as any,
|
|
558
|
+
summary: response.substring(0, 200),
|
|
559
|
+
accomplishments: [],
|
|
560
|
+
nextSteps: [],
|
|
561
|
+
issues: [],
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Detect issues in paranoid check response
|
|
567
|
+
*/
|
|
568
|
+
private detectIssues(response: string): boolean {
|
|
569
|
+
const issueKeywords = [
|
|
570
|
+
"bug", "error", "issue", "problem", "vulnerability",
|
|
571
|
+
"fix", "improve", "missing", "incomplete", "broken"
|
|
572
|
+
];
|
|
573
|
+
|
|
574
|
+
const lower = response.toLowerCase();
|
|
575
|
+
return issueKeywords.some((kw) => lower.includes(kw));
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// Export singleton instance
|
|
580
|
+
export const codingWorkflow = new CodingWorkflow();
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GLM Daemon - Workflows Index
|
|
3
|
+
*
|
|
4
|
+
* Export all available workflows and register them with the registry.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { workflowRegistry } from "../workflow.js";
|
|
8
|
+
import { CodingWorkflow, codingWorkflow } from "./coding.js";
|
|
9
|
+
import { TradingWorkflow, tradingWorkflow } from "./trading.js";
|
|
10
|
+
|
|
11
|
+
// Re-export workflow types
|
|
12
|
+
export type {
|
|
13
|
+
GLMWorkflowPhase,
|
|
14
|
+
GLMWorkflowContext,
|
|
15
|
+
GLMWorkflowPhaseResult,
|
|
16
|
+
GLMWorkflowTransition,
|
|
17
|
+
GLMWorkflowConfig,
|
|
18
|
+
GLMWorkflowExecutor,
|
|
19
|
+
} from "../workflow.js";
|
|
20
|
+
|
|
21
|
+
export { BaseWorkflow, WorkflowRegistry, workflowRegistry } from "../workflow.js";
|
|
22
|
+
|
|
23
|
+
// Re-export coding workflow
|
|
24
|
+
export { CodingWorkflow, CODING_PHASES, CODING_TRANSITIONS, CODING_WORKFLOW_CONFIG, codingWorkflow } from "./coding.js";
|
|
25
|
+
|
|
26
|
+
// Re-export trading workflow
|
|
27
|
+
export { TradingWorkflow, TRADING_PHASES, TRADING_TRANSITIONS, TRADING_WORKFLOW_CONFIG, tradingWorkflow } from "./trading.js";
|
|
28
|
+
|
|
29
|
+
// Export phase types
|
|
30
|
+
export type { CodingPhase } from "./coding.js";
|
|
31
|
+
export type { TradingPhase } from "./trading.js";
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Initialize all built-in workflows
|
|
35
|
+
*/
|
|
36
|
+
export function initializeWorkflows(): void {
|
|
37
|
+
// Register coding workflow as default
|
|
38
|
+
workflowRegistry.register(codingWorkflow, true);
|
|
39
|
+
|
|
40
|
+
// Register trading workflow
|
|
41
|
+
workflowRegistry.register(tradingWorkflow);
|
|
42
|
+
|
|
43
|
+
console.log("[Workflows] Initialized workflows:", workflowRegistry.list().map(w => w.id).join(", "));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get a workflow by ID
|
|
48
|
+
*/
|
|
49
|
+
export function getWorkflow(id: string) {
|
|
50
|
+
return workflowRegistry.get(id);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Get the default workflow
|
|
55
|
+
*/
|
|
56
|
+
export function getDefaultWorkflow() {
|
|
57
|
+
return workflowRegistry.getDefault();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Auto-initialize on import
|
|
61
|
+
initializeWorkflows();
|