@kb-labs/agent-entry 2.93.0 → 2.96.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/dist/cli/commands/diff.js +4 -4
- package/dist/cli/commands/diff.js.map +1 -1
- package/dist/cli/commands/history.js +6 -6
- package/dist/cli/commands/history.js.map +1 -1
- package/dist/cli/commands/quality-report.js +3 -3
- package/dist/cli/commands/quality-report.js.map +1 -1
- package/dist/cli/commands/rollback.js +1 -1
- package/dist/cli/commands/rollback.js.map +1 -1
- package/dist/cli/commands/run.js +24 -7
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/trace-context.js +3 -3
- package/dist/cli/commands/trace-context.js.map +1 -1
- package/dist/cli/commands/trace-diagnose.js +3 -3
- package/dist/cli/commands/trace-diagnose.js.map +1 -1
- package/dist/cli/commands/trace-stats.js +3 -3
- package/dist/cli/commands/trace-stats.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +40 -35
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +62 -7
- package/dist/manifest.js +40 -35
- package/dist/manifest.js.map +1 -1
- package/dist/rest/handlers/approve-handler.js +51 -47
- package/dist/rest/handlers/approve-handler.js.map +1 -1
- package/dist/rest/handlers/approve-session-plan-handler.js +38 -34
- package/dist/rest/handlers/approve-session-plan-handler.js.map +1 -1
- package/dist/rest/handlers/correct-handler.js +49 -45
- package/dist/rest/handlers/correct-handler.js.map +1 -1
- package/dist/rest/handlers/create-session-handler.js +17 -13
- package/dist/rest/handlers/create-session-handler.js.map +1 -1
- package/dist/rest/handlers/execute-session-plan-handler.js +216 -208
- package/dist/rest/handlers/execute-session-plan-handler.js.map +1 -1
- package/dist/rest/handlers/generate-spec-handler.js +103 -98
- package/dist/rest/handlers/generate-spec-handler.js.map +1 -1
- package/dist/rest/handlers/get-file-diff-handler.js +35 -31
- package/dist/rest/handlers/get-file-diff-handler.js.map +1 -1
- package/dist/rest/handlers/get-session-handler.js +15 -11
- package/dist/rest/handlers/get-session-handler.js.map +1 -1
- package/dist/rest/handlers/get-session-plan-handler.js +28 -24
- package/dist/rest/handlers/get-session-plan-handler.js.map +1 -1
- package/dist/rest/handlers/get-session-turns-handler.js +27 -23
- package/dist/rest/handlers/get-session-turns-handler.js.map +1 -1
- package/dist/rest/handlers/get-spec-handler.js +22 -18
- package/dist/rest/handlers/get-spec-handler.js.map +1 -1
- package/dist/rest/handlers/list-file-changes-handler.js +25 -21
- package/dist/rest/handlers/list-file-changes-handler.js.map +1 -1
- package/dist/rest/handlers/list-sessions-handler.js +16 -12
- package/dist/rest/handlers/list-sessions-handler.js.map +1 -1
- package/dist/rest/handlers/rollback-handler.js +73 -69
- package/dist/rest/handlers/rollback-handler.js.map +1 -1
- package/dist/rest/handlers/run-handler.js +151 -147
- package/dist/rest/handlers/run-handler.js.map +1 -1
- package/dist/rest/handlers/sessions-handler.js +47 -35
- package/dist/rest/handlers/sessions-handler.js.map +1 -1
- package/dist/rest/handlers/status-handler.js +33 -29
- package/dist/rest/handlers/status-handler.js.map +1 -1
- package/dist/rest/handlers/stop-handler.js +37 -33
- package/dist/rest/handlers/stop-handler.js.map +1 -1
- package/dist/widgets/117.js +24 -1
- package/dist/widgets/{300.js → 215.js} +1 -1
- package/dist/widgets/370.js +1 -1
- package/dist/widgets/{805.js → 46.js} +92 -92
- package/dist/widgets/50.js +1 -1
- package/dist/widgets/62.js +96 -0
- package/dist/widgets/648.js +1 -0
- package/dist/widgets/669.js +1 -1
- package/dist/widgets/775.js +1 -1
- package/dist/widgets/78.js +1 -0
- package/dist/widgets/968.js +2 -2
- package/dist/widgets/__federation_expose_AgentsPage.js +1 -1
- package/dist/widgets/mf-manifest.json +31 -31
- package/dist/widgets/mf-stats.json +39 -39
- package/dist/widgets/remoteEntry.js +2 -2
- package/dist/ws/session-stream-handler.js +17 -6
- package/dist/ws/session-stream-handler.js.map +1 -1
- package/package.json +16 -15
- package/dist/widgets/418.js +0 -38
- package/dist/widgets/451.js +0 -1
- package/dist/widgets/694.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineHandler, useAnalytics, useCache, useConfig, usePlatform } from '@kb-labs/sdk';
|
|
1
|
+
import { defineHandler, useAnalytics, useCache, useConfig, rethrowForRest, usePlatform } from '@kb-labs/sdk';
|
|
2
2
|
import { bootstrapAgentSDK, SessionManager, createSessionMemoryBridge, createCoreToolPack, PlanDocumentService } from '@kb-labs/agent-core';
|
|
3
3
|
import fs, { promises } from 'fs';
|
|
4
4
|
import { createDefaultResponseRequirementsSelector } from '@kb-labs/agent-runtime';
|
|
@@ -353,161 +353,165 @@ async function inferFollowUpWorkingDir(sessionManager, sessionId, baseWorkingDir
|
|
|
353
353
|
}
|
|
354
354
|
var run_handler_default = defineHandler({
|
|
355
355
|
async execute(ctx, input) {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
const analytics = useAnalytics();
|
|
361
|
-
const runId = RunManager.generateRunId();
|
|
362
|
-
const startTime = Date.now();
|
|
363
|
-
let sessionId = body.sessionId;
|
|
364
|
-
let workingDir = body.workingDir || ctx.cwd;
|
|
365
|
-
let sessionManager = new SessionManager(workingDir);
|
|
366
|
-
if (!sessionId) {
|
|
367
|
-
const session = await sessionManager.createSession({
|
|
368
|
-
mode: "execute",
|
|
369
|
-
task: body.task,
|
|
370
|
-
agentId: body.agentId ?? "orchestrator"
|
|
371
|
-
});
|
|
372
|
-
sessionId = session.id;
|
|
373
|
-
ctx.platform.logger.info(`[run-handler] Created new session ${sessionId}`);
|
|
374
|
-
} else {
|
|
375
|
-
const existingSession = await sessionManager.loadSession(sessionId);
|
|
376
|
-
let resolvedSession = existingSession;
|
|
377
|
-
if (!resolvedSession && pathExists(ctx.cwd)) {
|
|
378
|
-
const fallbackManager = new SessionManager(ctx.cwd);
|
|
379
|
-
const fallbackSession = await fallbackManager.loadSession(sessionId);
|
|
380
|
-
if (fallbackSession) {
|
|
381
|
-
sessionManager = fallbackManager;
|
|
382
|
-
resolvedSession = fallbackSession;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
if (!resolvedSession) {
|
|
386
|
-
throw new Error(`Session not found: ${sessionId} (cwd=${ctx.cwd})`);
|
|
356
|
+
try {
|
|
357
|
+
const body = input.body;
|
|
358
|
+
if (!body?.task) {
|
|
359
|
+
throw new Error("Task is required");
|
|
387
360
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
361
|
+
const analytics = useAnalytics();
|
|
362
|
+
const runId = RunManager.generateRunId();
|
|
363
|
+
const startTime = Date.now();
|
|
364
|
+
let sessionId = body.sessionId;
|
|
365
|
+
let workingDir = body.workingDir || ctx.cwd;
|
|
366
|
+
let sessionManager = new SessionManager(workingDir);
|
|
367
|
+
if (!sessionId) {
|
|
368
|
+
const session = await sessionManager.createSession({
|
|
369
|
+
mode: "execute",
|
|
370
|
+
task: body.task,
|
|
371
|
+
agentId: body.agentId ?? "orchestrator"
|
|
372
|
+
});
|
|
373
|
+
sessionId = session.id;
|
|
374
|
+
ctx.platform.logger.info(`[run-handler] Created new session ${sessionId}`);
|
|
375
|
+
} else {
|
|
376
|
+
const existingSession = await sessionManager.loadSession(sessionId);
|
|
377
|
+
let resolvedSession = existingSession;
|
|
378
|
+
if (!resolvedSession && pathExists(ctx.cwd)) {
|
|
379
|
+
const fallbackManager = new SessionManager(ctx.cwd);
|
|
380
|
+
const fallbackSession = await fallbackManager.loadSession(sessionId);
|
|
381
|
+
if (fallbackSession) {
|
|
382
|
+
sessionManager = fallbackManager;
|
|
383
|
+
resolvedSession = fallbackSession;
|
|
384
|
+
}
|
|
394
385
|
}
|
|
386
|
+
if (!resolvedSession) {
|
|
387
|
+
throw new Error(`Session not found: ${sessionId} (cwd=${ctx.cwd})`);
|
|
388
|
+
}
|
|
389
|
+
workingDir = body.workingDir || resolvedSession.workingDir || workingDir;
|
|
390
|
+
if (!body.workingDir && isLikelyFollowUpScopeTask(body.task)) {
|
|
391
|
+
const inferred = await inferFollowUpWorkingDir(sessionManager, sessionId, resolvedSession.workingDir || ctx.cwd);
|
|
392
|
+
if (inferred && inferred !== workingDir) {
|
|
393
|
+
ctx.platform.logger.info(`[run-handler] Follow-up scope inferred: ${workingDir} -> ${inferred}`);
|
|
394
|
+
workingDir = inferred;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
sessionManager = new SessionManager(workingDir);
|
|
398
|
+
ctx.platform.logger.info(`[run-handler] Continuing session ${sessionId} (workingDir=${workingDir})`);
|
|
395
399
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
const seqEvent = RunManager.broadcast(runId, event);
|
|
438
|
-
void sessionManager.addEvent(finalSessionId, {
|
|
439
|
-
...seqEvent,
|
|
440
|
-
sessionId: finalSessionId,
|
|
441
|
-
runId,
|
|
442
|
-
metadata: {
|
|
443
|
-
...seqEvent.metadata,
|
|
400
|
+
ctx.platform.logger.info(`[run-handler] Starting run ${runId} for task: ${body.task}`);
|
|
401
|
+
await sessionManager.createUserTurn(sessionId, body.task, runId);
|
|
402
|
+
await analytics?.track(AGENT_ANALYTICS_EVENTS.RUN_STARTED, {
|
|
403
|
+
runId,
|
|
404
|
+
sessionId,
|
|
405
|
+
taskLength: body.task.length,
|
|
406
|
+
tier: body.tier ?? "medium",
|
|
407
|
+
enableEscalation: body.enableEscalation ?? true,
|
|
408
|
+
responseMode: body.responseMode ?? "auto",
|
|
409
|
+
verbose: body.verbose ?? false
|
|
410
|
+
});
|
|
411
|
+
const sessionMemory = createSessionMemoryBridge(workingDir, sessionId);
|
|
412
|
+
const responseRequirementsSelector = createDefaultResponseRequirementsSelector();
|
|
413
|
+
const toolRegistry = createToolRegistry({
|
|
414
|
+
workingDir,
|
|
415
|
+
currentTask: body.task,
|
|
416
|
+
sessionId,
|
|
417
|
+
verbose: body.verbose,
|
|
418
|
+
cache: useCache(),
|
|
419
|
+
sessionMemory,
|
|
420
|
+
responseRequirementsResolver: async ({ task, kernel }) => responseRequirementsSelector.select({
|
|
421
|
+
state: kernel,
|
|
422
|
+
messages: [],
|
|
423
|
+
task: task ?? body.task
|
|
424
|
+
})
|
|
425
|
+
});
|
|
426
|
+
const agentsConfig = await useConfig();
|
|
427
|
+
const finalSessionId = sessionId;
|
|
428
|
+
const traceDir = path.join(workingDir, ".kb", "traces", "incremental");
|
|
429
|
+
const traceWriter = new IncrementalTraceWriter(runId, {}, traceDir);
|
|
430
|
+
const agent = new AgentSDK().register(createCoreToolPack(toolRegistry)).createRunner({
|
|
431
|
+
sessionId: finalSessionId,
|
|
432
|
+
workingDir,
|
|
433
|
+
maxIterations: 50,
|
|
434
|
+
temperature: 0.1,
|
|
435
|
+
tier: body.tier ?? "medium",
|
|
436
|
+
tokenBudget: agentsConfig?.tokenBudget,
|
|
437
|
+
onEvent: (event) => {
|
|
438
|
+
const seqEvent = RunManager.broadcast(runId, event);
|
|
439
|
+
void sessionManager.addEvent(finalSessionId, {
|
|
440
|
+
...seqEvent,
|
|
444
441
|
sessionId: finalSessionId,
|
|
445
442
|
runId,
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
void (async () => {
|
|
454
|
-
try {
|
|
455
|
-
const result = await agent.execute(body.task);
|
|
456
|
-
const durationMs = Date.now() - startTime;
|
|
457
|
-
const detailedTrace = traceWriter.getEntries();
|
|
458
|
-
await traceWriter.finalize?.();
|
|
459
|
-
if (detailedTrace.length > 0) {
|
|
460
|
-
await sessionManager.storeTraceArtifacts(finalSessionId, runId, detailedTrace);
|
|
461
|
-
}
|
|
462
|
-
if (result.fileChanges && result.fileChanges.length > 0) {
|
|
463
|
-
await sessionManager.attachFileChangesToTurn(finalSessionId, runId, result.fileChanges);
|
|
443
|
+
metadata: {
|
|
444
|
+
...seqEvent.metadata,
|
|
445
|
+
sessionId: finalSessionId,
|
|
446
|
+
runId,
|
|
447
|
+
workingDir
|
|
448
|
+
}
|
|
449
|
+
});
|
|
464
450
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
451
|
+
});
|
|
452
|
+
const run = await RunManager.register(runId, body.task, agent, sessionManager, finalSessionId);
|
|
453
|
+
await RunManager.updateStatus(runId, "running");
|
|
454
|
+
void (async () => {
|
|
455
|
+
try {
|
|
456
|
+
const result = await agent.execute(body.task);
|
|
457
|
+
const durationMs = Date.now() - startTime;
|
|
458
|
+
const detailedTrace = traceWriter.getEntries();
|
|
459
|
+
await traceWriter.finalize?.();
|
|
460
|
+
if (detailedTrace.length > 0) {
|
|
461
|
+
await sessionManager.storeTraceArtifacts(finalSessionId, runId, detailedTrace);
|
|
462
|
+
}
|
|
463
|
+
if (result.fileChanges && result.fileChanges.length > 0) {
|
|
464
|
+
await sessionManager.attachFileChangesToTurn(finalSessionId, runId, result.fileChanges);
|
|
465
|
+
}
|
|
466
|
+
await RunManager.updateStatus(runId, result.success ? "completed" : "failed", {
|
|
467
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
475
468
|
durationMs,
|
|
476
|
-
|
|
477
|
-
|
|
469
|
+
summary: result.summary,
|
|
470
|
+
error: result.error
|
|
471
|
+
});
|
|
472
|
+
await analytics?.track(
|
|
473
|
+
result.success ? AGENT_ANALYTICS_EVENTS.RUN_COMPLETED : AGENT_ANALYTICS_EVENTS.RUN_FAILED,
|
|
474
|
+
{
|
|
475
|
+
runId,
|
|
476
|
+
durationMs,
|
|
477
|
+
success: result.success,
|
|
478
|
+
summary: result.summary?.slice(0, 200)
|
|
479
|
+
}
|
|
480
|
+
);
|
|
481
|
+
ctx.platform.logger.info(`[run-handler] Run ${runId} completed: ${result.success}`);
|
|
482
|
+
} catch (error) {
|
|
483
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
484
|
+
const durationMs = Date.now() - startTime;
|
|
485
|
+
const detailedTrace = traceWriter.getEntries();
|
|
486
|
+
await traceWriter.finalize?.();
|
|
487
|
+
if (detailedTrace.length > 0) {
|
|
488
|
+
await sessionManager.storeTraceArtifacts(finalSessionId, runId, detailedTrace);
|
|
478
489
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
490
|
+
await RunManager.updateStatus(runId, "failed", {
|
|
491
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
492
|
+
durationMs,
|
|
493
|
+
error: errorMsg
|
|
494
|
+
});
|
|
495
|
+
await analytics?.track(AGENT_ANALYTICS_EVENTS.RUN_FAILED, {
|
|
496
|
+
runId,
|
|
497
|
+
durationMs,
|
|
498
|
+
error: errorMsg.slice(0, 200)
|
|
499
|
+
});
|
|
500
|
+
ctx.platform.logger.error(`[run-handler] Run ${runId} failed: ${errorMsg}`);
|
|
488
501
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
}
|
|
502
|
-
const wsPath = AGENTS_WS_CHANNELS.SESSION_STREAM.replace(":sessionId", finalSessionId);
|
|
503
|
-
const eventsPath = `${AGENTS_WS_BASE_PATH}${wsPath}`;
|
|
504
|
-
return {
|
|
505
|
-
runId,
|
|
506
|
-
sessionId: finalSessionId,
|
|
507
|
-
eventsPath,
|
|
508
|
-
status: "started",
|
|
509
|
-
startedAt: run.startedAt
|
|
510
|
-
};
|
|
502
|
+
})();
|
|
503
|
+
const wsPath = AGENTS_WS_CHANNELS.SESSION_STREAM.replace(":sessionId", finalSessionId);
|
|
504
|
+
const eventsPath = `${AGENTS_WS_BASE_PATH}${wsPath}`;
|
|
505
|
+
return {
|
|
506
|
+
runId,
|
|
507
|
+
sessionId: finalSessionId,
|
|
508
|
+
eventsPath,
|
|
509
|
+
status: "started",
|
|
510
|
+
startedAt: run.startedAt
|
|
511
|
+
};
|
|
512
|
+
} catch (err) {
|
|
513
|
+
rethrowForRest(err);
|
|
514
|
+
}
|
|
511
515
|
}
|
|
512
516
|
});
|
|
513
517
|
|
|
@@ -564,69 +568,73 @@ function buildExecutionTaskWithSpec(plan, spec) {
|
|
|
564
568
|
}
|
|
565
569
|
var execute_session_plan_handler_default = defineHandler({
|
|
566
570
|
async execute(ctx, input) {
|
|
567
|
-
const params = input.params;
|
|
568
|
-
const sessionId = params?.sessionId;
|
|
569
|
-
const body = input.body ?? {};
|
|
570
|
-
if (!sessionId) {
|
|
571
|
-
throw new Error("Session ID is required");
|
|
572
|
-
}
|
|
573
|
-
const baseManager = new SessionManager(ctx.cwd);
|
|
574
|
-
const session = await baseManager.loadSession(sessionId);
|
|
575
|
-
if (!session) {
|
|
576
|
-
throw new Error(`Session not found: ${sessionId}`);
|
|
577
|
-
}
|
|
578
|
-
const workingDir = session.workingDir || ctx.cwd;
|
|
579
|
-
const sessionManager = new SessionManager(workingDir);
|
|
580
|
-
const planPath = sessionManager.getSessionPlanPath(sessionId);
|
|
581
|
-
let plan;
|
|
582
|
-
try {
|
|
583
|
-
plan = await loadPlan(planPath);
|
|
584
|
-
} catch {
|
|
585
|
-
throw new Error(`Plan not found for session ${sessionId}`);
|
|
586
|
-
}
|
|
587
|
-
if (plan.status !== "approved" && plan.status !== "spec_ready") {
|
|
588
|
-
throw new Error(`Plan must be approved before execution (current status: ${plan.status})`);
|
|
589
|
-
}
|
|
590
|
-
let spec = null;
|
|
591
571
|
try {
|
|
592
|
-
const
|
|
593
|
-
const
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
const executionTask = spec?.markdown ? buildExecutionTaskWithSpec(plan, spec) : buildExecutionTask(plan);
|
|
598
|
-
const runInput = {
|
|
599
|
-
body: {
|
|
600
|
-
task: executionTask,
|
|
601
|
-
sessionId,
|
|
602
|
-
workingDir,
|
|
603
|
-
tier: body.tier,
|
|
604
|
-
responseMode: body.responseMode,
|
|
605
|
-
verbose: body.verbose,
|
|
606
|
-
enableEscalation: body.enableEscalation
|
|
572
|
+
const params = input.params;
|
|
573
|
+
const sessionId = params?.sessionId;
|
|
574
|
+
const body = input.body ?? {};
|
|
575
|
+
if (!sessionId) {
|
|
576
|
+
throw new Error("Session ID is required");
|
|
607
577
|
}
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
578
|
+
const baseManager = new SessionManager(ctx.cwd);
|
|
579
|
+
const session = await baseManager.loadSession(sessionId);
|
|
580
|
+
if (!session) {
|
|
581
|
+
throw new Error(`Session not found: ${sessionId}`);
|
|
582
|
+
}
|
|
583
|
+
const workingDir = session.workingDir || ctx.cwd;
|
|
584
|
+
const sessionManager = new SessionManager(workingDir);
|
|
585
|
+
const planPath = sessionManager.getSessionPlanPath(sessionId);
|
|
586
|
+
let plan;
|
|
587
|
+
try {
|
|
588
|
+
plan = await loadPlan(planPath);
|
|
589
|
+
} catch {
|
|
590
|
+
throw new Error(`Plan not found for session ${sessionId}`);
|
|
591
|
+
}
|
|
592
|
+
if (plan.status !== "approved" && plan.status !== "spec_ready") {
|
|
593
|
+
throw new Error(`Plan must be approved before execution (current status: ${plan.status})`);
|
|
594
|
+
}
|
|
595
|
+
let spec = null;
|
|
596
|
+
try {
|
|
597
|
+
const specPath = sessionManager.getSessionSpecPath(sessionId);
|
|
598
|
+
const specContent = await promises.readFile(specPath, "utf-8");
|
|
599
|
+
spec = JSON.parse(specContent);
|
|
600
|
+
} catch {
|
|
601
|
+
}
|
|
602
|
+
const executionTask = spec?.markdown ? buildExecutionTaskWithSpec(plan, spec) : buildExecutionTask(plan);
|
|
603
|
+
const runInput = {
|
|
604
|
+
body: {
|
|
605
|
+
task: executionTask,
|
|
606
|
+
sessionId,
|
|
607
|
+
workingDir,
|
|
608
|
+
tier: body.tier,
|
|
609
|
+
responseMode: body.responseMode,
|
|
610
|
+
verbose: body.verbose,
|
|
611
|
+
enableEscalation: body.enableEscalation
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
const runResponse = await run_handler_default.execute(ctx, runInput);
|
|
615
|
+
const inProgressPlan = {
|
|
616
|
+
...plan,
|
|
617
|
+
status: "in_progress",
|
|
618
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
619
|
+
};
|
|
620
|
+
await promises.writeFile(planPath, JSON.stringify(inProgressPlan, null, 2), "utf-8");
|
|
621
|
+
const documentService = new PlanDocumentService(workingDir);
|
|
622
|
+
const markdownPath = documentService.getPlanPath(plan);
|
|
623
|
+
await documentService.appendExecutionLog(
|
|
624
|
+
markdownPath,
|
|
625
|
+
`- ${(/* @__PURE__ */ new Date()).toISOString()}: Execution started (runId: ${runResponse.runId}).`
|
|
626
|
+
);
|
|
627
|
+
return {
|
|
628
|
+
sessionId,
|
|
629
|
+
planId: plan.id,
|
|
630
|
+
runId: runResponse.runId,
|
|
631
|
+
eventsPath: runResponse.eventsPath,
|
|
632
|
+
status: runResponse.status,
|
|
633
|
+
startedAt: runResponse.startedAt
|
|
634
|
+
};
|
|
635
|
+
} catch (err) {
|
|
636
|
+
rethrowForRest(err);
|
|
637
|
+
}
|
|
630
638
|
}
|
|
631
639
|
});
|
|
632
640
|
|