@agent-link/agent 0.1.89 → 0.1.91
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/dist/claude.d.ts +11 -0
- package/dist/claude.js +69 -20
- package/dist/claude.js.map +1 -1
- package/dist/connection.js +136 -1
- package/dist/connection.js.map +1 -1
- package/dist/history.d.ts +2 -0
- package/dist/history.js +1 -1
- package/dist/history.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/memory.d.ts +18 -0
- package/dist/memory.js +71 -0
- package/dist/memory.js.map +1 -0
- package/dist/scheduler.d.ts +84 -0
- package/dist/scheduler.js +559 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/team-types.d.ts +10 -2
- package/dist/team.d.ts +13 -5
- package/dist/team.js +18 -18
- package/dist/team.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loop (Scheduled Tasks) scheduler module.
|
|
3
|
+
*
|
|
4
|
+
* Manages Loop CRUD, cron scheduling, execution lifecycle, and output capture.
|
|
5
|
+
* Each Loop is a scheduled prompt sent to Claude on a cron schedule.
|
|
6
|
+
* Executions are persisted as JSONL files for later replay.
|
|
7
|
+
*/
|
|
8
|
+
import { randomUUID } from 'crypto';
|
|
9
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, appendFileSync, renameSync, } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
import cron from 'node-cron';
|
|
12
|
+
import { CONFIG_DIR } from './config.js';
|
|
13
|
+
// ── Constants ─────────────────────────────────────────────────────────────
|
|
14
|
+
const LOOPS_FILE = join(CONFIG_DIR, 'loops.json');
|
|
15
|
+
const EXECUTIONS_DIR = join(CONFIG_DIR, 'loop-executions');
|
|
16
|
+
const MAX_CONCURRENT_LOOPS = 3;
|
|
17
|
+
// ── Module state ──────────────────────────────────────────────────────────
|
|
18
|
+
let loops = [];
|
|
19
|
+
const cronJobs = new Map();
|
|
20
|
+
const runningExecutions = new Map();
|
|
21
|
+
let sendFn = null;
|
|
22
|
+
let handleChatFn = null;
|
|
23
|
+
let cancelExecutionFn = null;
|
|
24
|
+
let addOutputObserverFn = null;
|
|
25
|
+
let removeOutputObserverFn = null;
|
|
26
|
+
let addCloseObserverFn = null;
|
|
27
|
+
let removeCloseObserverFn = null;
|
|
28
|
+
// ── Public API ────────────────────────────────────────────────────────────
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the scheduler. Loads loops from disk, reconciles orphaned
|
|
31
|
+
* executions, and starts cron jobs for all enabled loops.
|
|
32
|
+
*/
|
|
33
|
+
export function initScheduler(deps) {
|
|
34
|
+
sendFn = deps.send;
|
|
35
|
+
handleChatFn = deps.handleChat;
|
|
36
|
+
cancelExecutionFn = deps.cancelExecution;
|
|
37
|
+
addOutputObserverFn = deps.addOutputObserver;
|
|
38
|
+
removeOutputObserverFn = deps.removeOutputObserver;
|
|
39
|
+
addCloseObserverFn = deps.addCloseObserver;
|
|
40
|
+
removeCloseObserverFn = deps.removeCloseObserver;
|
|
41
|
+
loops = loadLoopsFromDisk();
|
|
42
|
+
reconcileOrphanedExecutions();
|
|
43
|
+
// Register output and close observers
|
|
44
|
+
addOutputObserverFn(onLoopOutput);
|
|
45
|
+
addCloseObserverFn(onLoopClose);
|
|
46
|
+
for (const loop of loops) {
|
|
47
|
+
if (loop.enabled && loop.scheduleType !== 'manual') {
|
|
48
|
+
scheduleLoop(loop);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
console.log(`[Scheduler] Initialized with ${loops.length} loops (${cronJobs.size} scheduled)`);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Shutdown the scheduler. Stops all cron jobs.
|
|
55
|
+
* Running executions are NOT cancelled; they complete naturally.
|
|
56
|
+
*/
|
|
57
|
+
export function shutdownScheduler() {
|
|
58
|
+
for (const [, job] of cronJobs) {
|
|
59
|
+
job.stop();
|
|
60
|
+
}
|
|
61
|
+
cronJobs.clear();
|
|
62
|
+
// Remove observers
|
|
63
|
+
if (removeOutputObserverFn)
|
|
64
|
+
removeOutputObserverFn(onLoopOutput);
|
|
65
|
+
if (removeCloseObserverFn)
|
|
66
|
+
removeCloseObserverFn(onLoopClose);
|
|
67
|
+
console.log('[Scheduler] Shutdown complete');
|
|
68
|
+
}
|
|
69
|
+
// ── CRUD Operations ───────────────────────────────────────────────────────
|
|
70
|
+
export function createLoop(config) {
|
|
71
|
+
// Validate cron expression (skip for manual loops)
|
|
72
|
+
if (config.scheduleType !== 'manual' && !cron.validate(config.schedule)) {
|
|
73
|
+
throw new Error(`Invalid cron expression: ${config.schedule}`);
|
|
74
|
+
}
|
|
75
|
+
const loop = {
|
|
76
|
+
id: randomUUID(),
|
|
77
|
+
name: config.name,
|
|
78
|
+
prompt: config.prompt,
|
|
79
|
+
schedule: config.schedule,
|
|
80
|
+
scheduleType: config.scheduleType,
|
|
81
|
+
scheduleConfig: config.scheduleConfig,
|
|
82
|
+
workDir: config.workDir,
|
|
83
|
+
enabled: true,
|
|
84
|
+
createdAt: new Date().toISOString(),
|
|
85
|
+
updatedAt: new Date().toISOString(),
|
|
86
|
+
};
|
|
87
|
+
loops.push(loop);
|
|
88
|
+
saveLoopsToDisk();
|
|
89
|
+
if (config.scheduleType !== 'manual')
|
|
90
|
+
scheduleLoop(loop);
|
|
91
|
+
console.log(`[Scheduler] Created loop "${loop.name}" (${loop.id.slice(0, 8)}) schedule: ${loop.schedule}`);
|
|
92
|
+
return loop;
|
|
93
|
+
}
|
|
94
|
+
export function updateLoop(loopId, updates) {
|
|
95
|
+
const loop = loops.find(l => l.id === loopId);
|
|
96
|
+
if (!loop)
|
|
97
|
+
return null;
|
|
98
|
+
// Validate new cron expression if provided (skip for manual loops)
|
|
99
|
+
const effectiveType = updates.scheduleType ?? loop.scheduleType;
|
|
100
|
+
if (effectiveType !== 'manual' && updates.schedule && !cron.validate(updates.schedule)) {
|
|
101
|
+
throw new Error(`Invalid cron expression: ${updates.schedule}`);
|
|
102
|
+
}
|
|
103
|
+
const scheduleChanged = updates.schedule && updates.schedule !== loop.schedule;
|
|
104
|
+
const enabledChanged = updates.enabled !== undefined && updates.enabled !== loop.enabled;
|
|
105
|
+
const typeChanged = updates.scheduleType !== undefined && updates.scheduleType !== loop.scheduleType;
|
|
106
|
+
Object.assign(loop, updates, { updatedAt: new Date().toISOString() });
|
|
107
|
+
saveLoopsToDisk();
|
|
108
|
+
if (scheduleChanged || enabledChanged || typeChanged) {
|
|
109
|
+
unscheduleLoop(loopId);
|
|
110
|
+
if (loop.enabled && loop.scheduleType !== 'manual')
|
|
111
|
+
scheduleLoop(loop);
|
|
112
|
+
}
|
|
113
|
+
console.log(`[Scheduler] Updated loop "${loop.name}" (${loop.id.slice(0, 8)})`);
|
|
114
|
+
return loop;
|
|
115
|
+
}
|
|
116
|
+
export function deleteLoop(loopId) {
|
|
117
|
+
const idx = loops.findIndex(l => l.id === loopId);
|
|
118
|
+
if (idx < 0)
|
|
119
|
+
return false;
|
|
120
|
+
// Cancel if running
|
|
121
|
+
cancelLoopExecution(loopId);
|
|
122
|
+
unscheduleLoop(loopId);
|
|
123
|
+
loops.splice(idx, 1);
|
|
124
|
+
saveLoopsToDisk();
|
|
125
|
+
console.log(`[Scheduler] Deleted loop ${loopId.slice(0, 8)}`);
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
export function listLoops(workDir) {
|
|
129
|
+
const filtered = workDir ? loops.filter(l => l.workDir === workDir) : loops;
|
|
130
|
+
return filtered.map(l => ({ ...l }));
|
|
131
|
+
}
|
|
132
|
+
export function getLoop(loopId) {
|
|
133
|
+
const loop = loops.find(l => l.id === loopId);
|
|
134
|
+
return loop ? { ...loop } : null;
|
|
135
|
+
}
|
|
136
|
+
export function listLoopExecutions(loopId, limit = 50) {
|
|
137
|
+
return readExecutionIndex(loopId, limit);
|
|
138
|
+
}
|
|
139
|
+
export function getLoopExecutionMessages(loopId, executionId) {
|
|
140
|
+
return readExecutionLog(loopId, executionId);
|
|
141
|
+
}
|
|
142
|
+
export function runLoopNow(loopId) {
|
|
143
|
+
executeLoop(loopId, 'manual');
|
|
144
|
+
}
|
|
145
|
+
export function cancelLoopExecution(loopId) {
|
|
146
|
+
for (const [execId, exec] of runningExecutions) {
|
|
147
|
+
if (exec.loopId === loopId && exec.conversationId) {
|
|
148
|
+
if (cancelExecutionFn) {
|
|
149
|
+
cancelExecutionFn(exec.conversationId);
|
|
150
|
+
}
|
|
151
|
+
completeExecution(execId, 'cancelled');
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** Get currently running executions (for status queries). */
|
|
157
|
+
export function getRunningExecutions() {
|
|
158
|
+
return runningExecutions;
|
|
159
|
+
}
|
|
160
|
+
// ── Scheduling ────────────────────────────────────────────────────────────
|
|
161
|
+
function scheduleLoop(loop) {
|
|
162
|
+
if (cronJobs.has(loop.id)) {
|
|
163
|
+
cronJobs.get(loop.id).stop();
|
|
164
|
+
}
|
|
165
|
+
const job = cron.schedule(loop.schedule, () => {
|
|
166
|
+
console.log(`[Scheduler] Cron fired for loop "${loop.name}" (${loop.id.slice(0, 8)})`);
|
|
167
|
+
executeLoop(loop.id, 'scheduled');
|
|
168
|
+
});
|
|
169
|
+
cronJobs.set(loop.id, job);
|
|
170
|
+
console.log(`[Scheduler] Scheduled loop "${loop.name}" with cron: ${loop.schedule}`);
|
|
171
|
+
}
|
|
172
|
+
function unscheduleLoop(loopId) {
|
|
173
|
+
const job = cronJobs.get(loopId);
|
|
174
|
+
if (job) {
|
|
175
|
+
job.stop();
|
|
176
|
+
cronJobs.delete(loopId);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// ── Execution ─────────────────────────────────────────────────────────────
|
|
180
|
+
function executeLoop(loopId, trigger) {
|
|
181
|
+
const loop = loops.find(l => l.id === loopId);
|
|
182
|
+
if (!loop) {
|
|
183
|
+
console.warn(`[Scheduler] Cannot execute: loop ${loopId.slice(0, 8)} not found`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// For scheduled triggers, the loop must be enabled
|
|
187
|
+
if (trigger === 'scheduled' && !loop.enabled) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// Check concurrent Loop quota
|
|
191
|
+
if (runningExecutions.size >= MAX_CONCURRENT_LOOPS) {
|
|
192
|
+
console.warn(`[Scheduler] Skipping execution for "${loop.name}": concurrent limit reached (${MAX_CONCURRENT_LOOPS})`);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
// Prevent overlap: skip if this specific Loop already has a running execution
|
|
196
|
+
for (const exec of runningExecutions.values()) {
|
|
197
|
+
if (exec.loopId === loopId) {
|
|
198
|
+
console.warn(`[Scheduler] Skipping execution for "${loop.name}": already running`);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (!handleChatFn) {
|
|
203
|
+
console.error('[Scheduler] Cannot execute: handleChat not initialized');
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const executionId = randomUUID();
|
|
207
|
+
const conversationId = `loop-${executionId.slice(0, 8)}`;
|
|
208
|
+
const execution = {
|
|
209
|
+
id: executionId,
|
|
210
|
+
loopId,
|
|
211
|
+
status: 'running',
|
|
212
|
+
trigger,
|
|
213
|
+
startedAt: new Date().toISOString(),
|
|
214
|
+
conversationId,
|
|
215
|
+
};
|
|
216
|
+
runningExecutions.set(executionId, execution);
|
|
217
|
+
// Ensure execution directory exists
|
|
218
|
+
ensureExecutionDir(loopId);
|
|
219
|
+
// Persist execution metadata
|
|
220
|
+
appendExecutionIndex(loopId, execution);
|
|
221
|
+
// Notify web UI
|
|
222
|
+
sendFn?.({
|
|
223
|
+
type: 'loop_execution_started',
|
|
224
|
+
loopId,
|
|
225
|
+
execution: { ...execution },
|
|
226
|
+
});
|
|
227
|
+
console.log(`[Scheduler] Starting execution ${executionId.slice(0, 8)} for "${loop.name}" (trigger: ${trigger})`);
|
|
228
|
+
// Execute via existing claude.ts handleChat
|
|
229
|
+
try {
|
|
230
|
+
handleChatFn(conversationId, loop.prompt, loop.workDir, {});
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
console.error(`[Scheduler] Failed to start execution: ${err.message}`);
|
|
234
|
+
completeExecution(executionId, 'error', err.message);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// ── Output Observer ───────────────────────────────────────────────────────
|
|
238
|
+
/**
|
|
239
|
+
* Output observer callback registered with claude.ts.
|
|
240
|
+
* Captures messages from Loop conversations and persists them.
|
|
241
|
+
*/
|
|
242
|
+
function onLoopOutput(conversationId, msg) {
|
|
243
|
+
// Only handle loop conversations
|
|
244
|
+
if (!conversationId.startsWith('loop-'))
|
|
245
|
+
return false;
|
|
246
|
+
const execution = findExecutionByConversationId(conversationId);
|
|
247
|
+
if (!execution)
|
|
248
|
+
return false;
|
|
249
|
+
// 1. Append raw message to execution JSONL file
|
|
250
|
+
appendToExecutionLog(execution.loopId, execution.id, msg);
|
|
251
|
+
// 2. Forward to web UI with loop context
|
|
252
|
+
sendFn?.({
|
|
253
|
+
type: 'loop_execution_output',
|
|
254
|
+
loopId: execution.loopId,
|
|
255
|
+
executionId: execution.id,
|
|
256
|
+
data: msg,
|
|
257
|
+
});
|
|
258
|
+
// 3. Capture session ID
|
|
259
|
+
if (msg.type === 'system' && msg.session_id) {
|
|
260
|
+
execution.claudeSessionId = msg.session_id;
|
|
261
|
+
}
|
|
262
|
+
// 4. Detect completion
|
|
263
|
+
if (msg.type === 'result') {
|
|
264
|
+
const summary = extractSummary(msg);
|
|
265
|
+
const isError = !!msg.is_error || msg.subtype === 'error_response';
|
|
266
|
+
completeExecution(execution.id, isError ? 'error' : 'success', undefined, summary);
|
|
267
|
+
}
|
|
268
|
+
// Don't suppress: let normal forwarding happen too so the web client
|
|
269
|
+
// gets the standard claude_output/turn_completed messages if needed.
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Close observer callback. Detects Loop processes that exit without a result.
|
|
274
|
+
*/
|
|
275
|
+
function onLoopClose(conversationId, _exitCode, resultReceived) {
|
|
276
|
+
if (!conversationId.startsWith('loop-'))
|
|
277
|
+
return;
|
|
278
|
+
if (resultReceived)
|
|
279
|
+
return;
|
|
280
|
+
const execution = findExecutionByConversationId(conversationId);
|
|
281
|
+
if (!execution)
|
|
282
|
+
return;
|
|
283
|
+
console.log(`[Scheduler] Loop process exited without result for execution ${execution.id.slice(0, 8)}`);
|
|
284
|
+
completeExecution(execution.id, 'error', 'Process exited without completing');
|
|
285
|
+
}
|
|
286
|
+
// ── Execution Completion ──────────────────────────────────────────────────
|
|
287
|
+
function completeExecution(executionId, status, error, summary) {
|
|
288
|
+
const execution = runningExecutions.get(executionId);
|
|
289
|
+
if (!execution)
|
|
290
|
+
return;
|
|
291
|
+
execution.status = status;
|
|
292
|
+
execution.completedAt = new Date().toISOString();
|
|
293
|
+
execution.durationMs = Date.now() - new Date(execution.startedAt).getTime();
|
|
294
|
+
if (summary)
|
|
295
|
+
execution.summary = summary;
|
|
296
|
+
if (error)
|
|
297
|
+
execution.error = error;
|
|
298
|
+
runningExecutions.delete(executionId);
|
|
299
|
+
// Update execution index on disk
|
|
300
|
+
updateExecutionIndex(execution.loopId, execution);
|
|
301
|
+
// Update Loop's lastExecution
|
|
302
|
+
const loop = loops.find(l => l.id === execution.loopId);
|
|
303
|
+
if (loop) {
|
|
304
|
+
loop.lastExecution = {
|
|
305
|
+
id: execution.id,
|
|
306
|
+
status: execution.status,
|
|
307
|
+
startedAt: execution.startedAt,
|
|
308
|
+
durationMs: execution.durationMs,
|
|
309
|
+
trigger: execution.trigger,
|
|
310
|
+
};
|
|
311
|
+
saveLoopsToDisk();
|
|
312
|
+
}
|
|
313
|
+
console.log(`[Scheduler] Execution ${executionId.slice(0, 8)} completed: ${status}${error ? ` (${error})` : ''}`);
|
|
314
|
+
// Notify web UI
|
|
315
|
+
sendFn?.({
|
|
316
|
+
type: 'loop_execution_completed',
|
|
317
|
+
loopId: execution.loopId,
|
|
318
|
+
execution: { ...execution },
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
// ── Helpers ───────────────────────────────────────────────────────────────
|
|
322
|
+
function findExecutionByConversationId(conversationId) {
|
|
323
|
+
for (const exec of runningExecutions.values()) {
|
|
324
|
+
if (exec.conversationId === conversationId)
|
|
325
|
+
return exec;
|
|
326
|
+
}
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
function extractSummary(msg) {
|
|
330
|
+
if (typeof msg.result === 'string' && msg.result.length > 0) {
|
|
331
|
+
// Truncate summary to first 500 chars
|
|
332
|
+
return msg.result.length > 500
|
|
333
|
+
? msg.result.slice(0, 497) + '...'
|
|
334
|
+
: msg.result;
|
|
335
|
+
}
|
|
336
|
+
return undefined;
|
|
337
|
+
}
|
|
338
|
+
// ── Persistence: Loops ────────────────────────────────────────────────────
|
|
339
|
+
function loadLoopsFromDisk() {
|
|
340
|
+
try {
|
|
341
|
+
if (!existsSync(LOOPS_FILE))
|
|
342
|
+
return [];
|
|
343
|
+
const raw = readFileSync(LOOPS_FILE, 'utf-8');
|
|
344
|
+
const parsed = JSON.parse(raw);
|
|
345
|
+
if (!Array.isArray(parsed))
|
|
346
|
+
return [];
|
|
347
|
+
return parsed;
|
|
348
|
+
}
|
|
349
|
+
catch (err) {
|
|
350
|
+
console.error(`[Scheduler] Failed to load loops.json: ${err.message}`);
|
|
351
|
+
return [];
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
function saveLoopsToDisk() {
|
|
355
|
+
try {
|
|
356
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
357
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
358
|
+
}
|
|
359
|
+
const tmpFile = LOOPS_FILE + '.tmp';
|
|
360
|
+
writeFileSync(tmpFile, JSON.stringify(loops, null, 2) + '\n', 'utf-8');
|
|
361
|
+
renameSync(tmpFile, LOOPS_FILE);
|
|
362
|
+
}
|
|
363
|
+
catch (err) {
|
|
364
|
+
console.error(`[Scheduler] Failed to save loops.json: ${err.message}`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
// ── Persistence: Executions ───────────────────────────────────────────────
|
|
368
|
+
function ensureExecutionDir(loopId) {
|
|
369
|
+
const dir = join(EXECUTIONS_DIR, loopId);
|
|
370
|
+
if (!existsSync(dir)) {
|
|
371
|
+
mkdirSync(dir, { recursive: true });
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function getExecutionIndexPath(loopId) {
|
|
375
|
+
return join(EXECUTIONS_DIR, loopId, 'index.jsonl');
|
|
376
|
+
}
|
|
377
|
+
function getExecutionLogPath(loopId, executionId) {
|
|
378
|
+
return join(EXECUTIONS_DIR, loopId, `${executionId}.jsonl`);
|
|
379
|
+
}
|
|
380
|
+
function appendExecutionIndex(loopId, execution) {
|
|
381
|
+
try {
|
|
382
|
+
ensureExecutionDir(loopId);
|
|
383
|
+
const line = JSON.stringify(execution) + '\n';
|
|
384
|
+
appendFileSync(getExecutionIndexPath(loopId), line, 'utf-8');
|
|
385
|
+
}
|
|
386
|
+
catch (err) {
|
|
387
|
+
console.error(`[Scheduler] Failed to append execution index: ${err.message}`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
function updateExecutionIndex(loopId, execution) {
|
|
391
|
+
try {
|
|
392
|
+
const indexPath = getExecutionIndexPath(loopId);
|
|
393
|
+
if (!existsSync(indexPath)) {
|
|
394
|
+
appendExecutionIndex(loopId, execution);
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
const raw = readFileSync(indexPath, 'utf-8');
|
|
398
|
+
const lines = raw.trim().split('\n').filter(l => l.trim());
|
|
399
|
+
const updated = [];
|
|
400
|
+
let found = false;
|
|
401
|
+
for (const line of lines) {
|
|
402
|
+
try {
|
|
403
|
+
const entry = JSON.parse(line);
|
|
404
|
+
if (entry.id === execution.id) {
|
|
405
|
+
updated.push(JSON.stringify(execution));
|
|
406
|
+
found = true;
|
|
407
|
+
}
|
|
408
|
+
else {
|
|
409
|
+
updated.push(line);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
catch {
|
|
413
|
+
updated.push(line); // preserve unparseable lines
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (!found) {
|
|
417
|
+
updated.push(JSON.stringify(execution));
|
|
418
|
+
}
|
|
419
|
+
writeFileSync(indexPath, updated.join('\n') + '\n', 'utf-8');
|
|
420
|
+
}
|
|
421
|
+
catch (err) {
|
|
422
|
+
console.error(`[Scheduler] Failed to update execution index: ${err.message}`);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
function readExecutionIndex(loopId, limit) {
|
|
426
|
+
try {
|
|
427
|
+
const indexPath = getExecutionIndexPath(loopId);
|
|
428
|
+
if (!existsSync(indexPath))
|
|
429
|
+
return [];
|
|
430
|
+
const raw = readFileSync(indexPath, 'utf-8');
|
|
431
|
+
const lines = raw.trim().split('\n').filter(l => l.trim());
|
|
432
|
+
const executions = [];
|
|
433
|
+
for (const line of lines) {
|
|
434
|
+
try {
|
|
435
|
+
executions.push(JSON.parse(line));
|
|
436
|
+
}
|
|
437
|
+
catch {
|
|
438
|
+
// skip unparseable lines
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
// Sort by startedAt descending (most recent first) and limit
|
|
442
|
+
executions.sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime());
|
|
443
|
+
// Merge running status from in-memory state
|
|
444
|
+
for (const exec of executions) {
|
|
445
|
+
const running = runningExecutions.get(exec.id);
|
|
446
|
+
if (running) {
|
|
447
|
+
exec.status = running.status;
|
|
448
|
+
exec.claudeSessionId = running.claudeSessionId;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
return executions.slice(0, limit);
|
|
452
|
+
}
|
|
453
|
+
catch (err) {
|
|
454
|
+
console.error(`[Scheduler] Failed to read execution index: ${err.message}`);
|
|
455
|
+
return [];
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
function appendToExecutionLog(loopId, executionId, msg) {
|
|
459
|
+
try {
|
|
460
|
+
ensureExecutionDir(loopId);
|
|
461
|
+
const line = JSON.stringify(msg) + '\n';
|
|
462
|
+
appendFileSync(getExecutionLogPath(loopId, executionId), line, 'utf-8');
|
|
463
|
+
}
|
|
464
|
+
catch (err) {
|
|
465
|
+
console.error(`[Scheduler] Failed to append execution log: ${err.message}`);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
function readExecutionLog(loopId, executionId) {
|
|
469
|
+
try {
|
|
470
|
+
const logPath = getExecutionLogPath(loopId, executionId);
|
|
471
|
+
if (!existsSync(logPath))
|
|
472
|
+
return [];
|
|
473
|
+
const raw = readFileSync(logPath, 'utf-8');
|
|
474
|
+
const lines = raw.trim().split('\n').filter(l => l.trim());
|
|
475
|
+
const result = [];
|
|
476
|
+
for (const line of lines) {
|
|
477
|
+
try {
|
|
478
|
+
const data = JSON.parse(line);
|
|
479
|
+
const ts = data.timestamp || undefined;
|
|
480
|
+
if (data.type === 'user' && data.message?.content) {
|
|
481
|
+
// Extract tool results for tool_result content blocks
|
|
482
|
+
const content = data.message.content;
|
|
483
|
+
if (Array.isArray(content)) {
|
|
484
|
+
for (const block of content) {
|
|
485
|
+
if (block.type === 'tool_result' && block.content) {
|
|
486
|
+
const text = typeof block.content === 'string'
|
|
487
|
+
? block.content
|
|
488
|
+
: JSON.stringify(block.content);
|
|
489
|
+
// Find the matching tool message and add output
|
|
490
|
+
for (let i = result.length - 1; i >= 0; i--) {
|
|
491
|
+
if (result[i].role === 'tool' && result[i].toolId === block.tool_use_id) {
|
|
492
|
+
result[i].toolOutput = text;
|
|
493
|
+
break;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
else if (typeof content === 'string' && content.trim()) {
|
|
500
|
+
result.push({ role: 'user', content, timestamp: ts });
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
if (data.type === 'assistant' && data.message?.content && Array.isArray(data.message.content)) {
|
|
504
|
+
const textParts = [];
|
|
505
|
+
const toolBlocks = [];
|
|
506
|
+
for (const block of data.message.content) {
|
|
507
|
+
if (block.type === 'text' && block.text) {
|
|
508
|
+
textParts.push(block.text);
|
|
509
|
+
}
|
|
510
|
+
else if (block.type === 'tool_use') {
|
|
511
|
+
toolBlocks.push(block);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (textParts.length > 0) {
|
|
515
|
+
result.push({ role: 'assistant', content: textParts.join('\n\n'), timestamp: ts });
|
|
516
|
+
}
|
|
517
|
+
for (const tool of toolBlocks) {
|
|
518
|
+
result.push({
|
|
519
|
+
role: 'tool',
|
|
520
|
+
content: '',
|
|
521
|
+
toolName: tool.name,
|
|
522
|
+
toolInput: JSON.stringify(tool.input || {}),
|
|
523
|
+
toolId: tool.id,
|
|
524
|
+
timestamp: ts,
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
catch {
|
|
530
|
+
// skip unparseable lines
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return result;
|
|
534
|
+
}
|
|
535
|
+
catch (err) {
|
|
536
|
+
console.error(`[Scheduler] Failed to read execution log: ${err.message}`);
|
|
537
|
+
return [];
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
// ── Orphaned Execution Recovery ───────────────────────────────────────────
|
|
541
|
+
function reconcileOrphanedExecutions() {
|
|
542
|
+
let orphanCount = 0;
|
|
543
|
+
for (const loop of loops) {
|
|
544
|
+
const executions = readExecutionIndex(loop.id, 100);
|
|
545
|
+
for (const exec of executions) {
|
|
546
|
+
if (exec.status === 'running') {
|
|
547
|
+
exec.status = 'error';
|
|
548
|
+
exec.error = 'Agent restarted during execution';
|
|
549
|
+
exec.completedAt = new Date().toISOString();
|
|
550
|
+
updateExecutionIndex(loop.id, exec);
|
|
551
|
+
orphanCount++;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
if (orphanCount > 0) {
|
|
556
|
+
console.log(`[Scheduler] Reconciled ${orphanCount} orphaned execution(s)`);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}
|
package/dist/team-types.d.ts
CHANGED
|
@@ -108,9 +108,17 @@ export type HandleChatFn = (conversationId: string | undefined, prompt: string,
|
|
|
108
108
|
extraArgs?: string[];
|
|
109
109
|
}) => void;
|
|
110
110
|
export type CancelExecutionFn = (conversationId?: string) => void;
|
|
111
|
-
export type
|
|
111
|
+
export type AddOutputObserverFn = (fn: (conversationId: string, msg: Record<string, unknown>) => boolean | void) => void;
|
|
112
|
+
export type RemoveOutputObserverFn = (fn: (conversationId: string, msg: Record<string, unknown>) => boolean | void) => void;
|
|
113
|
+
export type AddCloseObserverFn = (fn: (conversationId: string, exitCode: number | null, resultReceived: boolean) => void) => void;
|
|
114
|
+
export type RemoveCloseObserverFn = (fn: (conversationId: string, exitCode: number | null, resultReceived: boolean) => void) => void;
|
|
115
|
+
/** @deprecated Use AddOutputObserverFn instead. */
|
|
116
|
+
export type SetOutputObserverFn = AddOutputObserverFn;
|
|
117
|
+
/** @deprecated Use RemoveOutputObserverFn instead. */
|
|
112
118
|
export type ClearOutputObserverFn = () => void;
|
|
113
|
-
|
|
119
|
+
/** @deprecated Use AddCloseObserverFn instead. */
|
|
120
|
+
export type SetCloseObserverFn = AddCloseObserverFn;
|
|
121
|
+
/** @deprecated Use RemoveCloseObserverFn instead. */
|
|
114
122
|
export type ClearCloseObserverFn = () => void;
|
|
115
123
|
export interface AgentDef {
|
|
116
124
|
description: string;
|
package/dist/team.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type { TeamConfig, AgentRole, TaskItem, TeamState, AgentTeammate, TeamAge
|
|
|
10
10
|
export { buildAgentsDef, buildLeadPrompt } from './team-templates.js';
|
|
11
11
|
export { getNextAgentColor, classifyRole, pickCharacter, deriveAgentDisplayName, deriveTaskTitle } from './team-naming.js';
|
|
12
12
|
export { serializeTeam, deserializeTeam, persistTeam, persistTeamDebounced, loadTeam, listTeams, deleteTeam, renameTeam, } from './team-persistence.js';
|
|
13
|
-
import type { TeamConfig, TeamState, AgentTeammate, TeamAgentMessage, TeamFeedEntry, SendFn, HandleChatFn, CancelExecutionFn,
|
|
13
|
+
import type { TeamConfig, TeamState, AgentTeammate, TeamAgentMessage, TeamFeedEntry, SendFn, HandleChatFn, CancelExecutionFn, AddOutputObserverFn, RemoveOutputObserverFn, AddCloseObserverFn, RemoveCloseObserverFn } from './team-types.js';
|
|
14
14
|
export declare function setTeamSendFn(fn: SendFn): void;
|
|
15
15
|
/**
|
|
16
16
|
* Inject claude.ts dependencies to avoid circular imports.
|
|
@@ -19,10 +19,18 @@ export declare function setTeamSendFn(fn: SendFn): void;
|
|
|
19
19
|
export declare function setTeamClaudeFns(fns: {
|
|
20
20
|
handleChat: HandleChatFn;
|
|
21
21
|
cancelExecution: CancelExecutionFn;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
addOutputObserver: AddOutputObserverFn;
|
|
23
|
+
removeOutputObserver: RemoveOutputObserverFn;
|
|
24
|
+
addCloseObserver: AddCloseObserverFn;
|
|
25
|
+
removeCloseObserver: RemoveCloseObserverFn;
|
|
26
|
+
/** @deprecated Alias for addOutputObserver */
|
|
27
|
+
setOutputObserver?: AddOutputObserverFn;
|
|
28
|
+
/** @deprecated Alias for removeOutputObserver */
|
|
29
|
+
clearOutputObserver?: () => void;
|
|
30
|
+
/** @deprecated Alias for addCloseObserver */
|
|
31
|
+
setCloseObserver?: AddCloseObserverFn;
|
|
32
|
+
/** @deprecated Alias for removeCloseObserver */
|
|
33
|
+
clearCloseObserver?: () => void;
|
|
26
34
|
}): void;
|
|
27
35
|
export declare function getActiveTeam(): TeamState | null;
|
|
28
36
|
/**
|