@ebowwa/glm-daemon 0.3.2 → 0.4.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/package.json +5 -5
- package/src/agent.js +166 -0
- package/src/builtin-tools.js +349 -0
- package/src/channels/base.js +509 -0
- package/src/channels/discord.js +374 -0
- package/src/channels/index.js +186 -0
- package/src/channels/telegram.js +395 -0
- package/src/daemon.js +593 -0
- package/src/daemon.ts +188 -1
- package/src/hooks.js +145 -0
- package/src/hooks.ts +3 -0
- package/src/index.js +123 -0
- package/src/memory.js +323 -0
- package/src/state.js +168 -0
- package/src/tools.js +192 -0
- package/src/types.js +21 -0
- package/src/types.ts +62 -0
- package/src/worktree.js +195 -0
package/src/types.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* GLM Daemon - Core Types
|
|
4
|
+
*
|
|
5
|
+
* Autonomous AI daemon powered by GLM 4.7 with hooks, tools, and teammates.
|
|
6
|
+
* Based on Ralph Iterative's SLAM pattern (State → Loop → Action → Memory).
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.GLM_PHASES = void 0;
|
|
10
|
+
/**
|
|
11
|
+
* GLM Daemon state phases (SLAM pattern)
|
|
12
|
+
*/
|
|
13
|
+
exports.GLM_PHASES = {
|
|
14
|
+
planning: "planning",
|
|
15
|
+
executing: "executing",
|
|
16
|
+
paranoid: "paranoid",
|
|
17
|
+
reviewing: "reviewing",
|
|
18
|
+
fixing: "fixing",
|
|
19
|
+
committing: "committing",
|
|
20
|
+
complete: "complete",
|
|
21
|
+
};
|
package/src/types.ts
CHANGED
|
@@ -13,6 +13,7 @@ import type { Team } from "@ebowwa/teammates";
|
|
|
13
13
|
export const GLM_PHASES = {
|
|
14
14
|
planning: "planning",
|
|
15
15
|
executing: "executing",
|
|
16
|
+
reflecting: "reflecting", // Checkpoint after N tools
|
|
16
17
|
paranoid: "paranoid",
|
|
17
18
|
reviewing: "reviewing",
|
|
18
19
|
fixing: "fixing",
|
|
@@ -58,6 +59,9 @@ export interface GLMDaemonConfig {
|
|
|
58
59
|
|
|
59
60
|
/** Tools configuration */
|
|
60
61
|
tools?: GLMToolsConfig;
|
|
62
|
+
|
|
63
|
+
/** Reflection checkpoint configuration */
|
|
64
|
+
reflection?: GLMReflectionConfig;
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
/**
|
|
@@ -106,6 +110,8 @@ export interface GLMDaemonState {
|
|
|
106
110
|
slam: {
|
|
107
111
|
enabled: boolean;
|
|
108
112
|
phase: GLMPhase;
|
|
113
|
+
/** Previous phase (used to return after reflection) */
|
|
114
|
+
previousPhase?: GLMPhase;
|
|
109
115
|
state: {
|
|
110
116
|
currentTask: string;
|
|
111
117
|
beliefs: Record<string, unknown>;
|
|
@@ -133,6 +139,20 @@ export interface GLMDaemonState {
|
|
|
133
139
|
currentCommit: string;
|
|
134
140
|
};
|
|
135
141
|
|
|
142
|
+
/** Reflection checkpoint state */
|
|
143
|
+
reflection: {
|
|
144
|
+
/** Current tool call count in this chunk */
|
|
145
|
+
toolCount: number;
|
|
146
|
+
/** Total tool calls across all chunks */
|
|
147
|
+
totalToolCount: number;
|
|
148
|
+
/** Number of reflection checkpoints completed */
|
|
149
|
+
checkpointCount: number;
|
|
150
|
+
/** Timestamp of last reflection */
|
|
151
|
+
lastReflection: string | null;
|
|
152
|
+
/** Accumulated TL;DR summaries */
|
|
153
|
+
summaries: GLMReflectionSummary[];
|
|
154
|
+
};
|
|
155
|
+
|
|
136
156
|
/** Machine info */
|
|
137
157
|
machine?: {
|
|
138
158
|
cpu: { count: number; model: string; tier: string };
|
|
@@ -169,6 +189,8 @@ export interface GLMHooksConfig {
|
|
|
169
189
|
onSubagentStop?: (subagentId: string, result: unknown) => Promise<void>;
|
|
170
190
|
onIterationStart?: (iteration: number) => Promise<void>;
|
|
171
191
|
onIterationEnd?: (iteration: number, result: unknown) => Promise<void>;
|
|
192
|
+
/** Called at each reflection checkpoint */
|
|
193
|
+
onReflection?: (state: GLMDaemonState, summary: GLMReflectionSummary) => Promise<void>;
|
|
172
194
|
}
|
|
173
195
|
|
|
174
196
|
/**
|
|
@@ -191,6 +213,24 @@ export interface GLMToolsConfig {
|
|
|
191
213
|
maxRetries?: number;
|
|
192
214
|
}
|
|
193
215
|
|
|
216
|
+
/**
|
|
217
|
+
* Reflection checkpoint configuration
|
|
218
|
+
* Triggers TL;DR summary after N tool calls
|
|
219
|
+
*/
|
|
220
|
+
export interface GLMReflectionConfig {
|
|
221
|
+
/** Enable reflection checkpoints */
|
|
222
|
+
enabled: boolean;
|
|
223
|
+
|
|
224
|
+
/** Number of tools before reflection (default: 50) */
|
|
225
|
+
toolLimit: number;
|
|
226
|
+
|
|
227
|
+
/** Auto-continue after reflection (default: true) */
|
|
228
|
+
autoContinue: boolean;
|
|
229
|
+
|
|
230
|
+
/** Save reflection summaries to file */
|
|
231
|
+
saveToFile?: string;
|
|
232
|
+
}
|
|
233
|
+
|
|
194
234
|
/**
|
|
195
235
|
* GLM Agent (individual GLM-powered agent)
|
|
196
236
|
*/
|
|
@@ -230,6 +270,28 @@ export interface GLMToolResult {
|
|
|
230
270
|
duration: number;
|
|
231
271
|
}
|
|
232
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Reflection summary generated at checkpoint
|
|
275
|
+
*/
|
|
276
|
+
export interface GLMReflectionSummary {
|
|
277
|
+
/** Checkpoint number */
|
|
278
|
+
checkpoint: number;
|
|
279
|
+
/** Timestamp */
|
|
280
|
+
timestamp: string;
|
|
281
|
+
/** Tools used in this chunk */
|
|
282
|
+
toolsUsed: number;
|
|
283
|
+
/** Phase when reflection occurred */
|
|
284
|
+
phase: GLMPhase;
|
|
285
|
+
/** TL;DR summary */
|
|
286
|
+
summary: string;
|
|
287
|
+
/** Key accomplishments */
|
|
288
|
+
accomplishments: string[];
|
|
289
|
+
/** Next steps identified */
|
|
290
|
+
nextSteps: string[];
|
|
291
|
+
/** Issues/blockers found */
|
|
292
|
+
issues: string[];
|
|
293
|
+
}
|
|
294
|
+
|
|
233
295
|
/**
|
|
234
296
|
* GLM Daemon status
|
|
235
297
|
*/
|
package/src/worktree.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* GLM Daemon - Worktree Manager
|
|
4
|
+
*
|
|
5
|
+
* Handles git worktree isolation for parallel task execution.
|
|
6
|
+
*/
|
|
7
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
8
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
9
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
10
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
11
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
12
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
13
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
17
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
18
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
19
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
20
|
+
function step(op) {
|
|
21
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
22
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
23
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
24
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
25
|
+
switch (op[0]) {
|
|
26
|
+
case 0: case 1: t = op; break;
|
|
27
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
28
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
29
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
30
|
+
default:
|
|
31
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
32
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
33
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
34
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
35
|
+
if (t[2]) _.ops.pop();
|
|
36
|
+
_.trys.pop(); continue;
|
|
37
|
+
}
|
|
38
|
+
op = body.call(thisArg, _);
|
|
39
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
40
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.WorktreeManager = void 0;
|
|
45
|
+
var child_process_1 = require("child_process");
|
|
46
|
+
var util_1 = require("util");
|
|
47
|
+
var path_1 = require("path");
|
|
48
|
+
var execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
49
|
+
var WorktreeManager = /** @class */ (function () {
|
|
50
|
+
function WorktreeManager(config) {
|
|
51
|
+
this.worktreePath = null;
|
|
52
|
+
this.config = config;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Create a new worktree for isolation
|
|
56
|
+
*/
|
|
57
|
+
WorktreeManager.prototype.createWorktree = function () {
|
|
58
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
59
|
+
var timestamp, worktreeName;
|
|
60
|
+
return __generator(this, function (_a) {
|
|
61
|
+
switch (_a.label) {
|
|
62
|
+
case 0:
|
|
63
|
+
if (!this.config.enableWorktree) {
|
|
64
|
+
return [2 /*return*/, this.config.cwd];
|
|
65
|
+
}
|
|
66
|
+
timestamp = Date.now();
|
|
67
|
+
worktreeName = "glm-".concat(timestamp);
|
|
68
|
+
this.worktreePath = (0, path_1.join)(this.config.cwd, "worktrees", worktreeName);
|
|
69
|
+
// Create worktrees directory
|
|
70
|
+
return [4 /*yield*/, execAsync("mkdir -p ".concat((0, path_1.join)(this.config.cwd, "worktrees")))];
|
|
71
|
+
case 1:
|
|
72
|
+
// Create worktrees directory
|
|
73
|
+
_a.sent();
|
|
74
|
+
// Create worktree
|
|
75
|
+
return [4 /*yield*/, execAsync("git worktree add -b ".concat(worktreeName, " ").concat(this.worktreePath))];
|
|
76
|
+
case 2:
|
|
77
|
+
// Create worktree
|
|
78
|
+
_a.sent();
|
|
79
|
+
return [2 /*return*/, this.worktreePath];
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Create a feature branch in the worktree
|
|
86
|
+
*/
|
|
87
|
+
WorktreeManager.prototype.createBranch = function () {
|
|
88
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
89
|
+
var branchName;
|
|
90
|
+
return __generator(this, function (_a) {
|
|
91
|
+
switch (_a.label) {
|
|
92
|
+
case 0:
|
|
93
|
+
if (!this.worktreePath) {
|
|
94
|
+
throw new Error("No worktree created");
|
|
95
|
+
}
|
|
96
|
+
branchName = "feat/glm-".concat(Date.now());
|
|
97
|
+
return [4 /*yield*/, execAsync("cd ".concat(this.worktreePath, " && git checkout -b ").concat(branchName))];
|
|
98
|
+
case 1:
|
|
99
|
+
_a.sent();
|
|
100
|
+
return [2 /*return*/, branchName];
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Commit changes in the worktree
|
|
107
|
+
*/
|
|
108
|
+
WorktreeManager.prototype.commitChanges = function (options) {
|
|
109
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
110
|
+
var cwd, _i, _a, file, stdout;
|
|
111
|
+
return __generator(this, function (_b) {
|
|
112
|
+
switch (_b.label) {
|
|
113
|
+
case 0:
|
|
114
|
+
cwd = this.worktreePath || this.config.cwd;
|
|
115
|
+
_i = 0, _a = options.files;
|
|
116
|
+
_b.label = 1;
|
|
117
|
+
case 1:
|
|
118
|
+
if (!(_i < _a.length)) return [3 /*break*/, 4];
|
|
119
|
+
file = _a[_i];
|
|
120
|
+
return [4 /*yield*/, execAsync("cd ".concat(cwd, " && git add ").concat(file))];
|
|
121
|
+
case 2:
|
|
122
|
+
_b.sent();
|
|
123
|
+
_b.label = 3;
|
|
124
|
+
case 3:
|
|
125
|
+
_i++;
|
|
126
|
+
return [3 /*break*/, 1];
|
|
127
|
+
case 4: return [4 /*yield*/, execAsync("cd ".concat(cwd, " && git commit -m \"").concat(options.message, "\""))];
|
|
128
|
+
case 5:
|
|
129
|
+
stdout = (_b.sent()).stdout;
|
|
130
|
+
return [2 /*return*/, stdout.trim()];
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Create a pull request
|
|
137
|
+
*/
|
|
138
|
+
WorktreeManager.prototype.createPullRequest = function (options) {
|
|
139
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
140
|
+
var cwd;
|
|
141
|
+
return __generator(this, function (_a) {
|
|
142
|
+
switch (_a.label) {
|
|
143
|
+
case 0:
|
|
144
|
+
cwd = this.worktreePath || this.config.cwd;
|
|
145
|
+
// Push branch
|
|
146
|
+
return [4 /*yield*/, execAsync("cd ".concat(cwd, " && git push -u origin HEAD"))];
|
|
147
|
+
case 1:
|
|
148
|
+
// Push branch
|
|
149
|
+
_a.sent();
|
|
150
|
+
// Create PR using gh CLI
|
|
151
|
+
return [4 /*yield*/, execAsync("cd ".concat(cwd, " && gh pr create --title \"").concat(options.title, "\" --body \"").concat(options.body, "\""))];
|
|
152
|
+
case 2:
|
|
153
|
+
// Create PR using gh CLI
|
|
154
|
+
_a.sent();
|
|
155
|
+
return [2 /*return*/];
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* Clean up worktree
|
|
162
|
+
*/
|
|
163
|
+
WorktreeManager.prototype.cleanup = function () {
|
|
164
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
165
|
+
return __generator(this, function (_a) {
|
|
166
|
+
switch (_a.label) {
|
|
167
|
+
case 0:
|
|
168
|
+
if (!this.worktreePath) {
|
|
169
|
+
return [2 /*return*/];
|
|
170
|
+
}
|
|
171
|
+
// Remove worktree
|
|
172
|
+
return [4 /*yield*/, execAsync("git worktree remove ".concat(this.worktreePath))];
|
|
173
|
+
case 1:
|
|
174
|
+
// Remove worktree
|
|
175
|
+
_a.sent();
|
|
176
|
+
// Delete directory
|
|
177
|
+
return [4 /*yield*/, execAsync("rm -rf ".concat(this.worktreePath))];
|
|
178
|
+
case 2:
|
|
179
|
+
// Delete directory
|
|
180
|
+
_a.sent();
|
|
181
|
+
this.worktreePath = null;
|
|
182
|
+
return [2 /*return*/];
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Get worktree path
|
|
189
|
+
*/
|
|
190
|
+
WorktreeManager.prototype.getPath = function () {
|
|
191
|
+
return this.worktreePath;
|
|
192
|
+
};
|
|
193
|
+
return WorktreeManager;
|
|
194
|
+
}());
|
|
195
|
+
exports.WorktreeManager = WorktreeManager;
|