@kb-labs/agent-entry 2.94.0 → 2.98.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/165.js +1 -1
- package/dist/widgets/370.js +1 -1
- package/dist/widgets/405.js +1 -1
- package/dist/widgets/{805.js → 46.js} +92 -92
- package/dist/widgets/50.js +1 -1
- package/dist/widgets/546.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/733.js +34 -0
- 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 +41 -41
- package/dist/widgets/remoteEntry.js +4 -4
- 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/300.js +0 -34
- package/dist/widgets/418.js +0 -38
- package/dist/widgets/451.js +0 -1
- package/dist/widgets/694.js +0 -1
|
@@ -1,57 +1,61 @@
|
|
|
1
|
-
import { defineHandler } from '@kb-labs/sdk';
|
|
1
|
+
import { defineHandler, rethrowForRest } from '@kb-labs/sdk';
|
|
2
2
|
import { SessionManager } from '@kb-labs/agent-core';
|
|
3
3
|
import { SnapshotStorage } from '@kb-labs/agent-history';
|
|
4
4
|
|
|
5
5
|
// src/rest/handlers/approve-handler.ts
|
|
6
6
|
var approve_handler_default = defineHandler({
|
|
7
7
|
async execute(ctx, input) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
try {
|
|
9
|
+
const params = input.params;
|
|
10
|
+
const sessionId = params?.sessionId;
|
|
11
|
+
if (!sessionId) {
|
|
12
|
+
throw new Error("Session ID is required");
|
|
13
|
+
}
|
|
14
|
+
const body = input.body ?? {};
|
|
15
|
+
const sessionManager = new SessionManager(ctx.cwd);
|
|
16
|
+
const session = await sessionManager.loadSession(sessionId);
|
|
17
|
+
if (!session) {
|
|
18
|
+
throw new Error(`Session not found: ${sessionId}`);
|
|
19
|
+
}
|
|
20
|
+
const workingDir = session.workingDir || ctx.cwd;
|
|
21
|
+
const storage = new SnapshotStorage(workingDir);
|
|
22
|
+
let changes = await storage.listSnapshots(sessionId);
|
|
23
|
+
if (body.runId) {
|
|
24
|
+
changes = changes.filter((c) => c.runId === body.runId);
|
|
25
|
+
} else if (body.changeIds?.length) {
|
|
26
|
+
const ids = new Set(body.changeIds);
|
|
27
|
+
changes = changes.filter((c) => ids.has(c.id));
|
|
28
|
+
}
|
|
29
|
+
const approvedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
30
|
+
const approvedIds = [];
|
|
31
|
+
for (const change of changes) {
|
|
32
|
+
change.approved = true;
|
|
33
|
+
change.approvedAt = approvedAt;
|
|
34
|
+
await storage.saveSnapshot(sessionId, change);
|
|
35
|
+
approvedIds.push(change.id);
|
|
36
|
+
}
|
|
37
|
+
if (body.runId && approvedIds.length > 0) {
|
|
38
|
+
const updatedSummaries = changes.map((c) => ({
|
|
39
|
+
changeId: c.id,
|
|
40
|
+
filePath: c.filePath,
|
|
41
|
+
operation: c.operation,
|
|
42
|
+
timestamp: c.timestamp,
|
|
43
|
+
linesAdded: c.metadata?.linesAdded,
|
|
44
|
+
linesRemoved: c.metadata?.linesRemoved,
|
|
45
|
+
isNew: !c.before,
|
|
46
|
+
sizeAfter: c.after.size,
|
|
47
|
+
approved: true,
|
|
48
|
+
approvedAt
|
|
49
|
+
}));
|
|
50
|
+
await sessionManager.updateTurnFileChanges(sessionId, body.runId, updatedSummaries);
|
|
51
|
+
}
|
|
52
|
+
ctx.platform.logger.info(
|
|
53
|
+
`[approve-handler] Session ${sessionId}: approved ${approvedIds.length} changes`
|
|
54
|
+
);
|
|
55
|
+
return { approved: approvedIds.length, changeIds: approvedIds, approvedAt };
|
|
56
|
+
} catch (err) {
|
|
57
|
+
rethrowForRest(err);
|
|
12
58
|
}
|
|
13
|
-
const body = input.body ?? {};
|
|
14
|
-
const sessionManager = new SessionManager(ctx.cwd);
|
|
15
|
-
const session = await sessionManager.loadSession(sessionId);
|
|
16
|
-
if (!session) {
|
|
17
|
-
throw new Error(`Session not found: ${sessionId}`);
|
|
18
|
-
}
|
|
19
|
-
const workingDir = session.workingDir || ctx.cwd;
|
|
20
|
-
const storage = new SnapshotStorage(workingDir);
|
|
21
|
-
let changes = await storage.listSnapshots(sessionId);
|
|
22
|
-
if (body.runId) {
|
|
23
|
-
changes = changes.filter((c) => c.runId === body.runId);
|
|
24
|
-
} else if (body.changeIds?.length) {
|
|
25
|
-
const ids = new Set(body.changeIds);
|
|
26
|
-
changes = changes.filter((c) => ids.has(c.id));
|
|
27
|
-
}
|
|
28
|
-
const approvedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
29
|
-
const approvedIds = [];
|
|
30
|
-
for (const change of changes) {
|
|
31
|
-
change.approved = true;
|
|
32
|
-
change.approvedAt = approvedAt;
|
|
33
|
-
await storage.saveSnapshot(sessionId, change);
|
|
34
|
-
approvedIds.push(change.id);
|
|
35
|
-
}
|
|
36
|
-
if (body.runId && approvedIds.length > 0) {
|
|
37
|
-
const updatedSummaries = changes.map((c) => ({
|
|
38
|
-
changeId: c.id,
|
|
39
|
-
filePath: c.filePath,
|
|
40
|
-
operation: c.operation,
|
|
41
|
-
timestamp: c.timestamp,
|
|
42
|
-
linesAdded: c.metadata?.linesAdded,
|
|
43
|
-
linesRemoved: c.metadata?.linesRemoved,
|
|
44
|
-
isNew: !c.before,
|
|
45
|
-
sizeAfter: c.after.size,
|
|
46
|
-
approved: true,
|
|
47
|
-
approvedAt
|
|
48
|
-
}));
|
|
49
|
-
await sessionManager.updateTurnFileChanges(sessionId, body.runId, updatedSummaries);
|
|
50
|
-
}
|
|
51
|
-
ctx.platform.logger.info(
|
|
52
|
-
`[approve-handler] Session ${sessionId}: approved ${approvedIds.length} changes`
|
|
53
|
-
);
|
|
54
|
-
return { approved: approvedIds.length, changeIds: approvedIds, approvedAt };
|
|
55
59
|
}
|
|
56
60
|
});
|
|
57
61
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/rest/handlers/approve-handler.ts"],"names":[],"mappings":";;;;;AAoBA,IAAO,0BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EAC0B;AAC1B,IAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/approve-handler.ts"],"names":[],"mappings":"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","file":"approve-handler.js","sourcesContent":["/**\n * POST /sessions/:sessionId/approve\n * Mark file changes as explicitly approved by the user.\n */\n\nimport { defineHandler, rethrowForRest, type RestInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport { SessionManager } from '@kb-labs/agent-core';\nimport { SnapshotStorage } from '@kb-labs/agent-history';\n\ninterface ApproveRequest {\n runId?: string;\n changeIds?: string[];\n}\n\ninterface ApproveResponse {\n approved: number;\n changeIds: string[];\n approvedAt: string;\n}\n\nexport default defineHandler({\n async execute(\n ctx: PluginContextV3,\n input: RestInput<ApproveRequest>\n ): Promise<ApproveResponse> {\n try {\n const params = input.params as Record<string, string> | undefined;\n const sessionId = params?.sessionId;\n\n if (!sessionId) {throw new Error('Session ID is required');}\n\n const body = (input.body ?? {}) as ApproveRequest;\n\n const sessionManager = new SessionManager(ctx.cwd);\n const session = await sessionManager.loadSession(sessionId);\n if (!session) {\n throw new Error(`Session not found: ${sessionId}`);\n }\n\n // Use session's own workingDir for snapshot lookup (may differ from ctx.cwd)\n const workingDir = session.workingDir || ctx.cwd;\n const storage = new SnapshotStorage(workingDir);\n let changes = await storage.listSnapshots(sessionId);\n\n if (body.runId) {\n changes = changes.filter((c) => c.runId === body.runId);\n } else if (body.changeIds?.length) {\n const ids = new Set(body.changeIds);\n changes = changes.filter((c) => ids.has(c.id));\n }\n\n const approvedAt = new Date().toISOString();\n const approvedIds: string[] = [];\n\n for (const change of changes) {\n change.approved = true;\n change.approvedAt = approvedAt;\n await storage.saveSnapshot(sessionId, change);\n approvedIds.push(change.id);\n }\n\n // Patch turns.json so the UI reflects approved state after page reload\n if (body.runId && approvedIds.length > 0) {\n const updatedSummaries = changes.map((c) => ({\n changeId: c.id,\n filePath: c.filePath,\n operation: c.operation,\n timestamp: c.timestamp,\n linesAdded: c.metadata?.linesAdded,\n linesRemoved: c.metadata?.linesRemoved,\n isNew: !c.before,\n sizeAfter: c.after.size,\n approved: true,\n approvedAt,\n }));\n await sessionManager.updateTurnFileChanges(sessionId, body.runId, updatedSummaries);\n }\n\n ctx.platform.logger.info(\n `[approve-handler] Session ${sessionId}: approved ${approvedIds.length} changes`\n );\n\n return { approved: approvedIds.length, changeIds: approvedIds, approvedAt };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineHandler } from '@kb-labs/sdk';
|
|
1
|
+
import { defineHandler, rethrowForRest } from '@kb-labs/sdk';
|
|
2
2
|
import { SessionManager } from '@kb-labs/agent-core';
|
|
3
3
|
import { promises } from 'fs';
|
|
4
4
|
|
|
@@ -9,41 +9,45 @@ async function loadPlan(planPath) {
|
|
|
9
9
|
}
|
|
10
10
|
var approve_session_plan_handler_default = defineHandler({
|
|
11
11
|
async execute(ctx, input) {
|
|
12
|
-
const params = input.params;
|
|
13
|
-
const sessionId = params?.sessionId;
|
|
14
|
-
const body = input.body ?? {};
|
|
15
|
-
if (!sessionId) {
|
|
16
|
-
throw new Error("Session ID is required");
|
|
17
|
-
}
|
|
18
|
-
const baseManager = new SessionManager(ctx.cwd);
|
|
19
|
-
const session = await baseManager.loadSession(sessionId);
|
|
20
|
-
if (!session) {
|
|
21
|
-
throw new Error(`Session not found: ${sessionId}`);
|
|
22
|
-
}
|
|
23
|
-
const workingDir = session.workingDir || ctx.cwd;
|
|
24
|
-
const sessionManager = new SessionManager(workingDir);
|
|
25
|
-
const planPath = sessionManager.getSessionPlanPath(sessionId);
|
|
26
|
-
let plan;
|
|
27
12
|
try {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
13
|
+
const params = input.params;
|
|
14
|
+
const sessionId = params?.sessionId;
|
|
15
|
+
const body = input.body ?? {};
|
|
16
|
+
if (!sessionId) {
|
|
17
|
+
throw new Error("Session ID is required");
|
|
18
|
+
}
|
|
19
|
+
const baseManager = new SessionManager(ctx.cwd);
|
|
20
|
+
const session = await baseManager.loadSession(sessionId);
|
|
21
|
+
if (!session) {
|
|
22
|
+
throw new Error(`Session not found: ${sessionId}`);
|
|
23
|
+
}
|
|
24
|
+
const workingDir = session.workingDir || ctx.cwd;
|
|
25
|
+
const sessionManager = new SessionManager(workingDir);
|
|
26
|
+
const planPath = sessionManager.getSessionPlanPath(sessionId);
|
|
27
|
+
let plan;
|
|
28
|
+
try {
|
|
29
|
+
plan = await loadPlan(planPath);
|
|
30
|
+
} catch {
|
|
31
|
+
throw new Error(`Plan not found for session ${sessionId}`);
|
|
32
|
+
}
|
|
33
|
+
const approvedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
34
|
+
const approvedPlan = {
|
|
35
|
+
...plan,
|
|
36
|
+
status: "approved",
|
|
37
|
+
updatedAt: approvedAt,
|
|
38
|
+
approvalComment: body.comment?.trim() || void 0,
|
|
39
|
+
approvedAt
|
|
40
|
+
};
|
|
41
|
+
await promises.writeFile(planPath, JSON.stringify(approvedPlan, null, 2), "utf-8");
|
|
42
|
+
ctx.platform.logger.info(`[approve-session-plan] Session ${sessionId}: plan approved`);
|
|
43
|
+
return {
|
|
44
|
+
sessionId,
|
|
45
|
+
plan: approvedPlan,
|
|
46
|
+
approvedAt
|
|
47
|
+
};
|
|
48
|
+
} catch (err) {
|
|
49
|
+
rethrowForRest(err);
|
|
31
50
|
}
|
|
32
|
-
const approvedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
33
|
-
const approvedPlan = {
|
|
34
|
-
...plan,
|
|
35
|
-
status: "approved",
|
|
36
|
-
updatedAt: approvedAt,
|
|
37
|
-
approvalComment: body.comment?.trim() || void 0,
|
|
38
|
-
approvedAt
|
|
39
|
-
};
|
|
40
|
-
await promises.writeFile(planPath, JSON.stringify(approvedPlan, null, 2), "utf-8");
|
|
41
|
-
ctx.platform.logger.info(`[approve-session-plan] Session ${sessionId}: plan approved`);
|
|
42
|
-
return {
|
|
43
|
-
sessionId,
|
|
44
|
-
plan: approvedPlan,
|
|
45
|
-
approvedAt
|
|
46
|
-
};
|
|
47
51
|
}
|
|
48
52
|
});
|
|
49
53
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/rest/handlers/approve-session-plan-handler.ts"],"names":["fs"],"mappings":";;;;;AAcA,eAAe,SAAS,QAAA,EAAqC;AAC3D,EAAA,MAAM,OAAA,GAAU,MAAMA,QAAA,CAAG,QAAA,CAAS,UAAU,OAAO,CAAA;AACnD,EAAA,OAAO,IAAA,CAAK,MAAM,OAAO,CAAA;AAC3B;AAEA,IAAO,uCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EACqC;AACrC,IAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/approve-session-plan-handler.ts"],"names":["fs"],"mappings":";;;;;AAcA,eAAe,SAAS,QAAA,EAAqC;AAC3D,EAAA,MAAM,OAAA,GAAU,MAAMA,QAAA,CAAG,QAAA,CAAS,UAAU,OAAO,CAAA;AACnD,EAAA,OAAO,IAAA,CAAK,MAAM,OAAO,CAAA;AAC3B;AAEA,IAAO,uCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EACqC;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,MAAA,MAAM,YAAY,MAAA,EAAQ,SAAA;AAC1B,MAAA,MAAM,IAAA,GAAQ,KAAA,CAAM,IAAA,IAAQ,EAAC;AAE7B,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,MAAM,IAAI,MAAM,wBAAwB,CAAA;AAAA,MAC1C;AAEA,MAAA,MAAM,WAAA,GAAc,IAAI,cAAA,CAAe,GAAA,CAAI,GAAG,CAAA;AAC9C,MAAA,MAAM,OAAA,GAAU,MAAM,WAAA,CAAY,WAAA,CAAY,SAAS,CAAA;AACvD,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,SAAS,CAAA,CAAE,CAAA;AAAA,MACnD;AAEA,MAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,UAAA,IAAc,GAAA,CAAI,GAAA;AAC7C,MAAA,MAAM,cAAA,GAAiB,IAAI,cAAA,CAAe,UAAU,CAAA;AACpD,MAAA,MAAM,QAAA,GAAW,cAAA,CAAe,kBAAA,CAAmB,SAAS,CAAA;AAE5D,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI;AACF,QAAA,IAAA,GAAO,MAAM,SAAS,QAAQ,CAAA;AAAA,MAChC,CAAA,CAAA,MAAQ;AACN,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,SAAS,CAAA,CAAE,CAAA;AAAA,MAC3D;AAEA,MAAA,MAAM,UAAA,GAAA,iBAAa,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAC1C,MAAA,MAAM,YAAA,GAAe;AAAA,QACnB,GAAG,IAAA;AAAA,QACH,MAAA,EAAQ,UAAA;AAAA,QACR,SAAA,EAAW,UAAA;AAAA,QACX,eAAA,EAAiB,IAAA,CAAK,OAAA,EAAS,IAAA,EAAK,IAAK,KAAA,CAAA;AAAA,QACzC;AAAA,OACF;AAEA,MAAA,MAAMA,QAAA,CAAG,UAAU,QAAA,EAAU,IAAA,CAAK,UAAU,YAAA,EAAc,IAAA,EAAM,CAAC,CAAA,EAAG,OAAO,CAAA;AAE3E,MAAA,GAAA,CAAI,QAAA,CAAS,MAAA,CAAO,IAAA,CAAK,CAAA,+BAAA,EAAkC,SAAS,CAAA,eAAA,CAAiB,CAAA;AAErF,MAAA,OAAO;AAAA,QACL,SAAA;AAAA,QACA,IAAA,EAAM,YAAA;AAAA,QACN;AAAA,OACF;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"approve-session-plan-handler.js","sourcesContent":["/**\n * POST /sessions/:sessionId/plan/approve\n * Mark current session plan as approved.\n */\n\nimport { defineHandler, rethrowForRest, type RestInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport { SessionManager } from '@kb-labs/agent-core';\nimport type { ApproveSessionPlanRequest, ApproveSessionPlanResponse, TaskPlan } from '@kb-labs/agent-contracts';\nimport { promises as fs } from 'node:fs';\n\ninterface ApprovePlanRouteParams {\n sessionId?: string;\n}\n\nasync function loadPlan(planPath: string): Promise<TaskPlan> {\n const content = await fs.readFile(planPath, 'utf-8');\n return JSON.parse(content) as TaskPlan;\n}\n\nexport default defineHandler({\n async execute(\n ctx: PluginContextV3,\n input: RestInput<ApproveSessionPlanRequest, unknown, ApprovePlanRouteParams>\n ): Promise<ApproveSessionPlanResponse> {\n try {\n const params = input.params as Record<string, string> | undefined;\n const sessionId = params?.sessionId;\n const body = (input.body ?? {}) as ApproveSessionPlanRequest;\n\n if (!sessionId) {\n throw new Error('Session ID is required');\n }\n\n const baseManager = new SessionManager(ctx.cwd);\n const session = await baseManager.loadSession(sessionId);\n if (!session) {\n throw new Error(`Session not found: ${sessionId}`);\n }\n\n const workingDir = session.workingDir || ctx.cwd;\n const sessionManager = new SessionManager(workingDir);\n const planPath = sessionManager.getSessionPlanPath(sessionId);\n\n let plan: TaskPlan;\n try {\n plan = await loadPlan(planPath);\n } catch {\n throw new Error(`Plan not found for session ${sessionId}`);\n }\n\n const approvedAt = new Date().toISOString();\n const approvedPlan = {\n ...plan,\n status: 'approved' as const,\n updatedAt: approvedAt,\n approvalComment: body.comment?.trim() || undefined,\n approvedAt,\n } as TaskPlan;\n\n await fs.writeFile(planPath, JSON.stringify(approvedPlan, null, 2), 'utf-8');\n\n ctx.platform.logger.info(`[approve-session-plan] Session ${sessionId}: plan approved`);\n\n return {\n sessionId,\n plan: approvedPlan,\n approvedAt,\n };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineHandler, useAnalytics, useCache, usePlatform } from '@kb-labs/sdk';
|
|
1
|
+
import { defineHandler, useAnalytics, rethrowForRest, useCache, usePlatform } from '@kb-labs/sdk';
|
|
2
2
|
import { AGENT_ANALYTICS_EVENTS } from '@kb-labs/agent-contracts';
|
|
3
3
|
|
|
4
4
|
// src/rest/handlers/correct-handler.ts
|
|
@@ -272,52 +272,56 @@ var RunManager = globalThis[GLOBAL_KEY];
|
|
|
272
272
|
// src/rest/handlers/correct-handler.ts
|
|
273
273
|
var correct_handler_default = defineHandler({
|
|
274
274
|
async execute(ctx, input) {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
275
|
+
try {
|
|
276
|
+
const { runId } = input.params;
|
|
277
|
+
const body = input.body;
|
|
278
|
+
if (!body?.message) {
|
|
279
|
+
throw new Error("Correction message is required");
|
|
280
|
+
}
|
|
281
|
+
ctx.platform.logger.info(`[correct-handler] Correction for run ${runId}: ${body.message.slice(0, 50)}...`);
|
|
282
|
+
const run = RunManager.get(runId);
|
|
283
|
+
if (!run) {
|
|
284
|
+
return {
|
|
285
|
+
correctionId: "",
|
|
286
|
+
routedTo: [],
|
|
287
|
+
reason: `Run ${runId} not found`,
|
|
288
|
+
applied: false
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
if (run.status !== "running") {
|
|
292
|
+
return {
|
|
293
|
+
correctionId: "",
|
|
294
|
+
routedTo: [],
|
|
295
|
+
reason: `Run ${runId} is not running (status: ${run.status})`,
|
|
296
|
+
applied: false
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
const correctionId = `corr-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
300
|
+
run.agent?.injectUserContext(body.message);
|
|
301
|
+
const result = {
|
|
302
|
+
correctionId,
|
|
303
|
+
routedTo: [run.agent?.agentId ?? runId],
|
|
304
|
+
reason: "Injected via injectUserContext",
|
|
305
|
+
applied: !!run.agent
|
|
296
306
|
};
|
|
307
|
+
const analytics = useAnalytics();
|
|
308
|
+
await analytics?.track(
|
|
309
|
+
result.applied ? AGENT_ANALYTICS_EVENTS.CORRECTION_APPLIED : AGENT_ANALYTICS_EVENTS.CORRECTION_REJECTED,
|
|
310
|
+
{
|
|
311
|
+
runId,
|
|
312
|
+
correctionId: result.correctionId,
|
|
313
|
+
routedTo: result.routedTo,
|
|
314
|
+
messageLength: body.message.length,
|
|
315
|
+
targetAgentId: body.targetAgentId
|
|
316
|
+
}
|
|
317
|
+
);
|
|
318
|
+
ctx.platform.logger.info(
|
|
319
|
+
`[correct-handler] Correction ${result.correctionId} routed to: ${result.routedTo.join(", ")}`
|
|
320
|
+
);
|
|
321
|
+
return result;
|
|
322
|
+
} catch (err) {
|
|
323
|
+
rethrowForRest(err);
|
|
297
324
|
}
|
|
298
|
-
const correctionId = `corr-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
299
|
-
run.agent?.injectUserContext(body.message);
|
|
300
|
-
const result = {
|
|
301
|
-
correctionId,
|
|
302
|
-
routedTo: [run.agent?.agentId ?? runId],
|
|
303
|
-
reason: "Injected via injectUserContext",
|
|
304
|
-
applied: !!run.agent
|
|
305
|
-
};
|
|
306
|
-
const analytics = useAnalytics();
|
|
307
|
-
await analytics?.track(
|
|
308
|
-
result.applied ? AGENT_ANALYTICS_EVENTS.CORRECTION_APPLIED : AGENT_ANALYTICS_EVENTS.CORRECTION_REJECTED,
|
|
309
|
-
{
|
|
310
|
-
runId,
|
|
311
|
-
correctionId: result.correctionId,
|
|
312
|
-
routedTo: result.routedTo,
|
|
313
|
-
messageLength: body.message.length,
|
|
314
|
-
targetAgentId: body.targetAgentId
|
|
315
|
-
}
|
|
316
|
-
);
|
|
317
|
-
ctx.platform.logger.info(
|
|
318
|
-
`[correct-handler] Correction ${result.correctionId} routed to: ${result.routedTo.join(", ")}`
|
|
319
|
-
);
|
|
320
|
-
return result;
|
|
321
325
|
}
|
|
322
326
|
});
|
|
323
327
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/rest/run-manager.ts","../../../src/rest/handlers/correct-handler.ts"],"names":["run"],"mappings":"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","file":"correct-handler.js","sourcesContent":["/**\n * Run Manager - tracks active agent runs for REST/WS API\n *\n * Uses platform cache for persistence and in-memory Map for active agents.\n * Cache stores serializable run state, Map stores live agent references.\n * Uses platform eventBus for cross-process event broadcasting.\n */\n\nimport type { IAgentRunner } from '@kb-labs/agent-sdk';\nimport type { SessionManager } from '@kb-labs/agent-core';\nimport type { AgentEvent, AgentEventCallback } from '@kb-labs/agent-contracts';\nimport { useCache, usePlatform } from '@kb-labs/sdk';\n\nconst CACHE_PREFIX = 'agent:run:';\nconst EVENT_TOPIC_PREFIX = 'agent:events:';\nconst CACHE_TTL = 3600000; // 1 hour\n\n/**\n * Run status\n */\nexport type RunStatus = 'pending' | 'running' | 'completed' | 'failed' | 'stopped';\n\n/**\n * Serializable run state (stored in cache)\n */\nexport interface RunState {\n runId: string;\n task: string;\n status: RunStatus;\n startedAt: string;\n completedAt?: string;\n durationMs?: number;\n summary?: string;\n error?: string;\n}\n\n/**\n * Active run with live agent (in-memory only)\n */\nexport interface ActiveRun extends RunState {\n agent?: IAgentRunner;\n sessionManager: SessionManager;\n listeners: Set<AgentEventCallback>;\n /** Monotonic sequence counter for event ordering */\n lastSeq: number;\n /** Replay buffer: all events emitted since run start (for late WS connections) */\n eventBuffer: AgentEvent[];\n}\n\n/**\n * Run Manager implementation\n */\nclass RunManagerImpl {\n /** Live agents and listeners (not cacheable) */\n private activeRuns: Map<string, ActiveRun> = new Map();\n\n /** Session-level listeners: sessionId → Set<callback> — receive events from ALL runs in session */\n private sessionListeners: Map<string, Set<AgentEventCallback>> = new Map();\n\n /** sessionId per runId — set when run is registered */\n private runSessionMap: Map<string, string> = new Map();\n\n /**\n * Generate unique run ID\n */\n generateRunId(): string {\n return `run-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n }\n\n /**\n * Register a new run\n */\n async register(\n runId: string,\n task: string,\n agent: IAgentRunner | undefined,\n sessionManager: SessionManager,\n sessionId?: string\n ): Promise<ActiveRun> {\n const now = new Date().toISOString();\n\n const run: ActiveRun = {\n runId,\n task,\n status: 'pending',\n agent,\n sessionManager,\n startedAt: now,\n listeners: new Set(),\n lastSeq: 0,\n eventBuffer: [],\n };\n\n // Store in memory (for live agent)\n this.activeRuns.set(runId, run);\n\n // Track sessionId → runId mapping for session-level listeners\n if (sessionId) {\n this.runSessionMap.set(runId, sessionId);\n }\n\n // Store serializable state in cache\n await this.saveToCache(run);\n\n return run;\n }\n\n /**\n * Get run by ID (from memory first, then cache for state)\n */\n get(runId: string): ActiveRun | undefined {\n return this.activeRuns.get(runId);\n }\n\n /**\n * Check if run exists (in memory or cache)\n */\n async exists(runId: string): Promise<boolean> {\n // Check memory first\n if (this.activeRuns.has(runId)) {\n return true;\n }\n // Fallback to cache\n const state = await this.getState(runId);\n return state !== null;\n }\n\n /**\n * Get run state from cache (for completed runs or cross-process access)\n */\n async getState(runId: string): Promise<RunState | null> {\n const cache = useCache();\n if (!cache) {return null;}\n\n return cache.get<RunState>(`${CACHE_PREFIX}${runId}`);\n }\n\n /**\n * Update run status\n */\n async updateStatus(runId: string, status: RunStatus, extra?: Partial<RunState>): Promise<void> {\n const run = this.activeRuns.get(runId);\n if (run) {\n run.status = status;\n if (extra) {\n Object.assign(run, extra);\n }\n await this.saveToCache(run);\n }\n }\n\n /**\n * Save run state to cache\n */\n private async saveToCache(run: ActiveRun): Promise<void> {\n const cache = useCache();\n if (!cache) {return;}\n\n const state: RunState = {\n runId: run.runId,\n task: run.task,\n status: run.status,\n startedAt: run.startedAt,\n completedAt: run.completedAt,\n durationMs: run.durationMs,\n summary: run.summary,\n error: run.error,\n };\n\n await cache.set(`${CACHE_PREFIX}${run.runId}`, state, CACHE_TTL);\n }\n\n /** Track subscriptions for cleanup */\n private subscriptions: Map<string, Map<AgentEventCallback, () => void>> = new Map();\n\n /**\n * Add event listener to run (uses eventBus for cross-process)\n */\n addListener(runId: string, callback: AgentEventCallback): boolean {\n const platform = usePlatform();\n if (!platform?.eventBus) {\n // Fallback to in-memory only\n const run = this.activeRuns.get(runId);\n if (run) {\n run.listeners.add(callback);\n return true;\n }\n return false;\n }\n\n // Subscribe to eventBus topic for this run\n const topic = `${EVENT_TOPIC_PREFIX}${runId}`;\n const unsubscribe = platform.eventBus.subscribe<AgentEvent>(topic, async (event) => {\n try {\n callback(event);\n } catch {\n // Ignore callback errors\n }\n });\n\n // Track subscription for cleanup\n if (!this.subscriptions.has(runId)) {\n this.subscriptions.set(runId, new Map());\n }\n this.subscriptions.get(runId)!.set(callback, unsubscribe);\n\n // Also add to in-memory if run exists locally\n const run = this.activeRuns.get(runId);\n if (run) {\n run.listeners.add(callback);\n }\n\n return true;\n }\n\n /**\n * Remove event listener from run\n */\n removeListener(runId: string, callback: AgentEventCallback): void {\n // Unsubscribe from eventBus\n const runSubs = this.subscriptions.get(runId);\n if (runSubs) {\n const unsubscribe = runSubs.get(callback);\n if (unsubscribe) {\n unsubscribe();\n runSubs.delete(callback);\n }\n if (runSubs.size === 0) {\n this.subscriptions.delete(runId);\n }\n }\n\n // Also remove from in-memory\n const run = this.activeRuns.get(runId);\n if (run) {\n run.listeners.delete(callback);\n }\n }\n\n /**\n * Broadcast event to all listeners of a run (uses eventBus for cross-process)\n * Assigns monotonic sequence number for reliable ordering\n * @returns The event with seq assigned (for persistence)\n */\n broadcast(runId: string, event: AgentEvent): AgentEvent {\n const platform = usePlatform();\n const run = this.activeRuns.get(runId);\n\n // Assign sequence number for ordering\n let seqEvent = event;\n if (run) {\n run.lastSeq++;\n seqEvent = { ...event, seq: run.lastSeq, runId };\n\n // Store in replay buffer (for late WS connections)\n run.eventBuffer.push(seqEvent);\n }\n\n // Publish to eventBus for cross-process delivery\n if (platform?.eventBus) {\n const topic = `${EVENT_TOPIC_PREFIX}${runId}`;\n platform.eventBus.publish(topic, seqEvent).catch(() => {\n // Ignore publish errors\n });\n }\n\n // Also notify local in-memory listeners (for same-process)\n if (run) {\n for (const listener of run.listeners) {\n try {\n listener(seqEvent);\n } catch {\n // Ignore listener errors\n }\n }\n }\n\n // Notify session-level listeners (persistent connections)\n const sessionId = this.runSessionMap.get(runId);\n if (sessionId) {\n const sListeners = this.sessionListeners.get(sessionId);\n if (sListeners) {\n for (const listener of sListeners) {\n try {\n listener(seqEvent);\n } catch {\n // Ignore listener errors\n }\n }\n }\n }\n\n return seqEvent;\n }\n\n /**\n * Add a session-level listener — receives events from ALL runs in this session.\n */\n addSessionListener(sessionId: string, callback: AgentEventCallback): void {\n if (!this.sessionListeners.has(sessionId)) {\n this.sessionListeners.set(sessionId, new Set());\n }\n this.sessionListeners.get(sessionId)!.add(callback);\n }\n\n /**\n * Remove a session-level listener.\n */\n removeSessionListener(sessionId: string, callback: AgentEventCallback): void {\n const listeners = this.sessionListeners.get(sessionId);\n if (listeners) {\n listeners.delete(callback);\n if (listeners.size === 0) {\n this.sessionListeners.delete(sessionId);\n }\n }\n }\n\n /**\n * Get replay buffer for a run (all events emitted since start).\n * Used by WS handler to send missed events on late connection.\n * Optionally filter by afterSeq to only get events the client hasn't seen.\n */\n getEventBuffer(runId: string, afterSeq?: number): AgentEvent[] {\n const run = this.activeRuns.get(runId);\n if (!run) {return [];}\n\n if (afterSeq != null) {\n return run.eventBuffer.filter((e) => e.seq != null && e.seq > afterSeq);\n }\n return [...run.eventBuffer];\n }\n\n /**\n * List all active runs\n */\n listActive(): Array<{ runId: string; task: string; status: RunStatus; startedAt: string }> {\n return Array.from(this.activeRuns.values()).map(r => ({\n runId: r.runId,\n task: r.task,\n status: r.status,\n startedAt: r.startedAt,\n }));\n }\n\n /**\n * Request graceful stop of a running agent (and its child agents via propagated AbortSignal).\n * Agent finishes its current tool call then exits at the next iteration boundary.\n */\n requestStop(runId: string): boolean {\n const run = this.activeRuns.get(runId);\n if (!run || run.status !== 'running' || !run.agent) {\n return false;\n }\n run.agent.requestStop();\n return true;\n }\n\n /**\n * Clean up completed runs from memory (cache handles its own TTL)\n */\n cleanup(): void {\n for (const [runId, run] of this.activeRuns) {\n if (run.status === 'completed' || run.status === 'failed' || run.status === 'stopped') {\n // Remove from memory but keep in cache\n this.activeRuns.delete(runId);\n }\n }\n }\n}\n\n/**\n * Singleton instance — stored on globalThis so all bundled modules share one instance.\n * When tsup compiles multiple entry points, each gets its own module scope,\n * so a plain `export const RunManager = new RunManagerImpl()` creates separate instances.\n * Using globalThis ensures run-handler.js and session-stream-handler.js share one RunManager.\n */\nconst GLOBAL_KEY = '__kb_agent_run_manager__';\nif (!(globalThis as Record<string, unknown>)[GLOBAL_KEY]) {\n (globalThis as Record<string, unknown>)[GLOBAL_KEY] = new RunManagerImpl();\n}\nexport const RunManager = (globalThis as Record<string, unknown>)[GLOBAL_KEY] as RunManagerImpl;\n","/**\n * POST /run/:runId/correct handler\n *\n * Injects user correction into running agent(s)\n */\n\nimport { defineHandler, useAnalytics, type RestInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport type { CorrectionRequest, CorrectionResponse } from '@kb-labs/agent-contracts';\nimport { AGENT_ANALYTICS_EVENTS } from '@kb-labs/agent-contracts';\nimport { RunManager } from '../run-manager.js';\n\nexport default defineHandler({\n async execute(\n ctx: PluginContextV3,\n input: RestInput<CorrectionRequest>\n ): Promise<CorrectionResponse> {\n const { runId } = input.params as { runId: string };\n const body = input.body as CorrectionRequest | undefined;\n\n if (!body?.message) {\n throw new Error('Correction message is required');\n }\n\n ctx.platform.logger.info(`[correct-handler] Correction for run ${runId}: ${body.message.slice(0, 50)}...`);\n\n const run = RunManager.get(runId);\n\n if (!run) {\n return {\n correctionId: '',\n routedTo: [],\n reason: `Run ${runId} not found`,\n applied: false,\n };\n }\n\n if (run.status !== 'running') {\n return {\n correctionId: '',\n routedTo: [],\n reason: `Run ${runId} is not running (status: ${run.status})`,\n applied: false,\n };\n }\n\n // Inject correction into the running agent via the public IAgentRunner API\n const correctionId = `corr-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n run.agent?.injectUserContext(body.message);\n const result: CorrectionResponse = {\n correctionId,\n routedTo: [run.agent?.agentId ?? runId],\n reason: 'Injected via injectUserContext',\n applied: !!run.agent,\n };\n\n // Track correction\n const analytics = useAnalytics();\n await analytics?.track(\n result.applied ? AGENT_ANALYTICS_EVENTS.CORRECTION_APPLIED : AGENT_ANALYTICS_EVENTS.CORRECTION_REJECTED,\n {\n runId,\n correctionId: result.correctionId,\n routedTo: result.routedTo,\n messageLength: body.message.length,\n targetAgentId: body.targetAgentId,\n }\n );\n\n ctx.platform.logger.info(\n `[correct-handler] Correction ${result.correctionId} routed to: ${result.routedTo.join(', ')}`\n );\n\n return result;\n },\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/run-manager.ts","../../../src/rest/handlers/correct-handler.ts"],"names":["run"],"mappings":"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","file":"correct-handler.js","sourcesContent":["/**\n * Run Manager - tracks active agent runs for REST/WS API\n *\n * Uses platform cache for persistence and in-memory Map for active agents.\n * Cache stores serializable run state, Map stores live agent references.\n * Uses platform eventBus for cross-process event broadcasting.\n */\n\nimport type { IAgentRunner } from '@kb-labs/agent-sdk';\nimport type { SessionManager } from '@kb-labs/agent-core';\nimport type { AgentEvent, AgentEventCallback } from '@kb-labs/agent-contracts';\nimport { useCache, usePlatform } from '@kb-labs/sdk';\n\nconst CACHE_PREFIX = 'agent:run:';\nconst EVENT_TOPIC_PREFIX = 'agent:events:';\nconst CACHE_TTL = 3600000; // 1 hour\n\n/**\n * Run status\n */\nexport type RunStatus = 'pending' | 'running' | 'completed' | 'failed' | 'stopped';\n\n/**\n * Serializable run state (stored in cache)\n */\nexport interface RunState {\n runId: string;\n task: string;\n status: RunStatus;\n startedAt: string;\n completedAt?: string;\n durationMs?: number;\n summary?: string;\n error?: string;\n}\n\n/**\n * Active run with live agent (in-memory only)\n */\nexport interface ActiveRun extends RunState {\n agent?: IAgentRunner;\n sessionManager: SessionManager;\n listeners: Set<AgentEventCallback>;\n /** Monotonic sequence counter for event ordering */\n lastSeq: number;\n /** Replay buffer: all events emitted since run start (for late WS connections) */\n eventBuffer: AgentEvent[];\n}\n\n/**\n * Run Manager implementation\n */\nclass RunManagerImpl {\n /** Live agents and listeners (not cacheable) */\n private activeRuns: Map<string, ActiveRun> = new Map();\n\n /** Session-level listeners: sessionId → Set<callback> — receive events from ALL runs in session */\n private sessionListeners: Map<string, Set<AgentEventCallback>> = new Map();\n\n /** sessionId per runId — set when run is registered */\n private runSessionMap: Map<string, string> = new Map();\n\n /**\n * Generate unique run ID\n */\n generateRunId(): string {\n return `run-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n }\n\n /**\n * Register a new run\n */\n async register(\n runId: string,\n task: string,\n agent: IAgentRunner | undefined,\n sessionManager: SessionManager,\n sessionId?: string\n ): Promise<ActiveRun> {\n const now = new Date().toISOString();\n\n const run: ActiveRun = {\n runId,\n task,\n status: 'pending',\n agent,\n sessionManager,\n startedAt: now,\n listeners: new Set(),\n lastSeq: 0,\n eventBuffer: [],\n };\n\n // Store in memory (for live agent)\n this.activeRuns.set(runId, run);\n\n // Track sessionId → runId mapping for session-level listeners\n if (sessionId) {\n this.runSessionMap.set(runId, sessionId);\n }\n\n // Store serializable state in cache\n await this.saveToCache(run);\n\n return run;\n }\n\n /**\n * Get run by ID (from memory first, then cache for state)\n */\n get(runId: string): ActiveRun | undefined {\n return this.activeRuns.get(runId);\n }\n\n /**\n * Check if run exists (in memory or cache)\n */\n async exists(runId: string): Promise<boolean> {\n // Check memory first\n if (this.activeRuns.has(runId)) {\n return true;\n }\n // Fallback to cache\n const state = await this.getState(runId);\n return state !== null;\n }\n\n /**\n * Get run state from cache (for completed runs or cross-process access)\n */\n async getState(runId: string): Promise<RunState | null> {\n const cache = useCache();\n if (!cache) {return null;}\n\n return cache.get<RunState>(`${CACHE_PREFIX}${runId}`);\n }\n\n /**\n * Update run status\n */\n async updateStatus(runId: string, status: RunStatus, extra?: Partial<RunState>): Promise<void> {\n const run = this.activeRuns.get(runId);\n if (run) {\n run.status = status;\n if (extra) {\n Object.assign(run, extra);\n }\n await this.saveToCache(run);\n }\n }\n\n /**\n * Save run state to cache\n */\n private async saveToCache(run: ActiveRun): Promise<void> {\n const cache = useCache();\n if (!cache) {return;}\n\n const state: RunState = {\n runId: run.runId,\n task: run.task,\n status: run.status,\n startedAt: run.startedAt,\n completedAt: run.completedAt,\n durationMs: run.durationMs,\n summary: run.summary,\n error: run.error,\n };\n\n await cache.set(`${CACHE_PREFIX}${run.runId}`, state, CACHE_TTL);\n }\n\n /** Track subscriptions for cleanup */\n private subscriptions: Map<string, Map<AgentEventCallback, () => void>> = new Map();\n\n /**\n * Add event listener to run (uses eventBus for cross-process)\n */\n addListener(runId: string, callback: AgentEventCallback): boolean {\n const platform = usePlatform();\n if (!platform?.eventBus) {\n // Fallback to in-memory only\n const run = this.activeRuns.get(runId);\n if (run) {\n run.listeners.add(callback);\n return true;\n }\n return false;\n }\n\n // Subscribe to eventBus topic for this run\n const topic = `${EVENT_TOPIC_PREFIX}${runId}`;\n const unsubscribe = platform.eventBus.subscribe<AgentEvent>(topic, async (event) => {\n try {\n callback(event);\n } catch {\n // Ignore callback errors\n }\n });\n\n // Track subscription for cleanup\n if (!this.subscriptions.has(runId)) {\n this.subscriptions.set(runId, new Map());\n }\n this.subscriptions.get(runId)!.set(callback, unsubscribe);\n\n // Also add to in-memory if run exists locally\n const run = this.activeRuns.get(runId);\n if (run) {\n run.listeners.add(callback);\n }\n\n return true;\n }\n\n /**\n * Remove event listener from run\n */\n removeListener(runId: string, callback: AgentEventCallback): void {\n // Unsubscribe from eventBus\n const runSubs = this.subscriptions.get(runId);\n if (runSubs) {\n const unsubscribe = runSubs.get(callback);\n if (unsubscribe) {\n unsubscribe();\n runSubs.delete(callback);\n }\n if (runSubs.size === 0) {\n this.subscriptions.delete(runId);\n }\n }\n\n // Also remove from in-memory\n const run = this.activeRuns.get(runId);\n if (run) {\n run.listeners.delete(callback);\n }\n }\n\n /**\n * Broadcast event to all listeners of a run (uses eventBus for cross-process)\n * Assigns monotonic sequence number for reliable ordering\n * @returns The event with seq assigned (for persistence)\n */\n broadcast(runId: string, event: AgentEvent): AgentEvent {\n const platform = usePlatform();\n const run = this.activeRuns.get(runId);\n\n // Assign sequence number for ordering\n let seqEvent = event;\n if (run) {\n run.lastSeq++;\n seqEvent = { ...event, seq: run.lastSeq, runId };\n\n // Store in replay buffer (for late WS connections)\n run.eventBuffer.push(seqEvent);\n }\n\n // Publish to eventBus for cross-process delivery\n if (platform?.eventBus) {\n const topic = `${EVENT_TOPIC_PREFIX}${runId}`;\n platform.eventBus.publish(topic, seqEvent).catch(() => {\n // Ignore publish errors\n });\n }\n\n // Also notify local in-memory listeners (for same-process)\n if (run) {\n for (const listener of run.listeners) {\n try {\n listener(seqEvent);\n } catch {\n // Ignore listener errors\n }\n }\n }\n\n // Notify session-level listeners (persistent connections)\n const sessionId = this.runSessionMap.get(runId);\n if (sessionId) {\n const sListeners = this.sessionListeners.get(sessionId);\n if (sListeners) {\n for (const listener of sListeners) {\n try {\n listener(seqEvent);\n } catch {\n // Ignore listener errors\n }\n }\n }\n }\n\n return seqEvent;\n }\n\n /**\n * Add a session-level listener — receives events from ALL runs in this session.\n */\n addSessionListener(sessionId: string, callback: AgentEventCallback): void {\n if (!this.sessionListeners.has(sessionId)) {\n this.sessionListeners.set(sessionId, new Set());\n }\n this.sessionListeners.get(sessionId)!.add(callback);\n }\n\n /**\n * Remove a session-level listener.\n */\n removeSessionListener(sessionId: string, callback: AgentEventCallback): void {\n const listeners = this.sessionListeners.get(sessionId);\n if (listeners) {\n listeners.delete(callback);\n if (listeners.size === 0) {\n this.sessionListeners.delete(sessionId);\n }\n }\n }\n\n /**\n * Get replay buffer for a run (all events emitted since start).\n * Used by WS handler to send missed events on late connection.\n * Optionally filter by afterSeq to only get events the client hasn't seen.\n */\n getEventBuffer(runId: string, afterSeq?: number): AgentEvent[] {\n const run = this.activeRuns.get(runId);\n if (!run) {return [];}\n\n if (afterSeq != null) {\n return run.eventBuffer.filter((e) => e.seq != null && e.seq > afterSeq);\n }\n return [...run.eventBuffer];\n }\n\n /**\n * List all active runs\n */\n listActive(): Array<{ runId: string; task: string; status: RunStatus; startedAt: string }> {\n return Array.from(this.activeRuns.values()).map(r => ({\n runId: r.runId,\n task: r.task,\n status: r.status,\n startedAt: r.startedAt,\n }));\n }\n\n /**\n * Request graceful stop of a running agent (and its child agents via propagated AbortSignal).\n * Agent finishes its current tool call then exits at the next iteration boundary.\n */\n requestStop(runId: string): boolean {\n const run = this.activeRuns.get(runId);\n if (!run || run.status !== 'running' || !run.agent) {\n return false;\n }\n run.agent.requestStop();\n return true;\n }\n\n /**\n * Clean up completed runs from memory (cache handles its own TTL)\n */\n cleanup(): void {\n for (const [runId, run] of this.activeRuns) {\n if (run.status === 'completed' || run.status === 'failed' || run.status === 'stopped') {\n // Remove from memory but keep in cache\n this.activeRuns.delete(runId);\n }\n }\n }\n}\n\n/**\n * Singleton instance — stored on globalThis so all bundled modules share one instance.\n * When tsup compiles multiple entry points, each gets its own module scope,\n * so a plain `export const RunManager = new RunManagerImpl()` creates separate instances.\n * Using globalThis ensures run-handler.js and session-stream-handler.js share one RunManager.\n */\nconst GLOBAL_KEY = '__kb_agent_run_manager__';\nif (!(globalThis as Record<string, unknown>)[GLOBAL_KEY]) {\n (globalThis as Record<string, unknown>)[GLOBAL_KEY] = new RunManagerImpl();\n}\nexport const RunManager = (globalThis as Record<string, unknown>)[GLOBAL_KEY] as RunManagerImpl;\n","/**\n * POST /run/:runId/correct handler\n *\n * Injects user correction into running agent(s)\n */\n\nimport { defineHandler, rethrowForRest, useAnalytics, type RestInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport type { CorrectionRequest, CorrectionResponse } from '@kb-labs/agent-contracts';\nimport { AGENT_ANALYTICS_EVENTS } from '@kb-labs/agent-contracts';\nimport { RunManager } from '../run-manager.js';\n\nexport default defineHandler({\n async execute(\n ctx: PluginContextV3,\n input: RestInput<CorrectionRequest>\n ): Promise<CorrectionResponse> {\n try {\n const { runId } = input.params as { runId: string };\n const body = input.body as CorrectionRequest | undefined;\n\n if (!body?.message) {\n throw new Error('Correction message is required');\n }\n\n ctx.platform.logger.info(`[correct-handler] Correction for run ${runId}: ${body.message.slice(0, 50)}...`);\n\n const run = RunManager.get(runId);\n\n if (!run) {\n return {\n correctionId: '',\n routedTo: [],\n reason: `Run ${runId} not found`,\n applied: false,\n };\n }\n\n if (run.status !== 'running') {\n return {\n correctionId: '',\n routedTo: [],\n reason: `Run ${runId} is not running (status: ${run.status})`,\n applied: false,\n };\n }\n\n // Inject correction into the running agent via the public IAgentRunner API\n const correctionId = `corr-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n run.agent?.injectUserContext(body.message);\n const result: CorrectionResponse = {\n correctionId,\n routedTo: [run.agent?.agentId ?? runId],\n reason: 'Injected via injectUserContext',\n applied: !!run.agent,\n };\n\n // Track correction\n const analytics = useAnalytics();\n await analytics?.track(\n result.applied ? AGENT_ANALYTICS_EVENTS.CORRECTION_APPLIED : AGENT_ANALYTICS_EVENTS.CORRECTION_REJECTED,\n {\n runId,\n correctionId: result.correctionId,\n routedTo: result.routedTo,\n messageLength: body.message.length,\n targetAgentId: body.targetAgentId,\n }\n );\n\n ctx.platform.logger.info(\n `[correct-handler] Correction ${result.correctionId} routed to: ${result.routedTo.join(', ')}`\n );\n\n return result;\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|
|
@@ -1,22 +1,26 @@
|
|
|
1
|
-
import { defineHandler } from '@kb-labs/sdk';
|
|
1
|
+
import { defineHandler, rethrowForRest } from '@kb-labs/sdk';
|
|
2
2
|
import { SessionManager } from '@kb-labs/agent-core';
|
|
3
3
|
|
|
4
4
|
// src/rest/handlers/create-session-handler.ts
|
|
5
5
|
var create_session_handler_default = defineHandler({
|
|
6
6
|
async execute(ctx, input) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
try {
|
|
8
|
+
const body = input.body;
|
|
9
|
+
if (!body?.agentId) {
|
|
10
|
+
throw new Error("Agent ID is required");
|
|
11
|
+
}
|
|
12
|
+
const sessionManager = new SessionManager(ctx.cwd);
|
|
13
|
+
const session = await sessionManager.createSession({
|
|
14
|
+
mode: "execute",
|
|
15
|
+
task: body.task ?? "",
|
|
16
|
+
agentId: body.agentId,
|
|
17
|
+
name: body.name
|
|
18
|
+
});
|
|
19
|
+
ctx.platform.logger.info(`[create-session] Created session ${session.id} for agent ${body.agentId}`);
|
|
20
|
+
return { session };
|
|
21
|
+
} catch (err) {
|
|
22
|
+
rethrowForRest(err);
|
|
10
23
|
}
|
|
11
|
-
const sessionManager = new SessionManager(ctx.cwd);
|
|
12
|
-
const session = await sessionManager.createSession({
|
|
13
|
-
mode: "execute",
|
|
14
|
-
task: body.task ?? "",
|
|
15
|
-
agentId: body.agentId,
|
|
16
|
-
name: body.name
|
|
17
|
-
});
|
|
18
|
-
ctx.platform.logger.info(`[create-session] Created session ${session.id} for agent ${body.agentId}`);
|
|
19
|
-
return { session };
|
|
20
24
|
}
|
|
21
25
|
});
|
|
22
26
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/rest/handlers/create-session-handler.ts"],"names":[],"mappings":";;;;AAQA,IAAO,iCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EACgC;AAChC,IAAA,MAAM,OAAO,KAAA,CAAM,IAAA;AAEnB,
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/create-session-handler.ts"],"names":[],"mappings":";;;;AAQA,IAAO,iCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EACgC;AAChC,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,KAAA,CAAM,IAAA;AAEnB,MAAA,IAAI,CAAC,MAAM,OAAA,EAAS;AAClB,QAAA,MAAM,IAAI,MAAM,sBAAsB,CAAA;AAAA,MACxC;AAEA,MAAA,MAAM,cAAA,GAAiB,IAAI,cAAA,CAAe,GAAA,CAAI,GAAG,CAAA;AAEjD,MAAA,MAAM,OAAA,GAAU,MAAM,cAAA,CAAe,aAAA,CAAc;AAAA,QACjD,IAAA,EAAM,SAAA;AAAA,QACN,IAAA,EAAM,KAAK,IAAA,IAAQ,EAAA;AAAA,QACnB,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,MAAM,IAAA,CAAK;AAAA,OACZ,CAAA;AAED,MAAA,GAAA,CAAI,QAAA,CAAS,OAAO,IAAA,CAAK,CAAA,iCAAA,EAAoC,QAAQ,EAAE,CAAA,WAAA,EAAc,IAAA,CAAK,OAAO,CAAA,CAAE,CAAA;AAEnG,MAAA,OAAO,EAAE,OAAA,EAAQ;AAAA,IACnB,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"create-session-handler.js","sourcesContent":["/**\n * POST /sessions - Create a new session\n */\n\nimport { defineHandler, rethrowForRest, type RestInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport { SessionManager } from '@kb-labs/agent-core';\nimport type { CreateSessionRequest, CreateSessionResponse } from '@kb-labs/agent-contracts';\n\nexport default defineHandler({\n async execute(\n ctx: PluginContextV3,\n input: RestInput<CreateSessionRequest>\n ): Promise<CreateSessionResponse> {\n try {\n const body = input.body as CreateSessionRequest | undefined;\n\n if (!body?.agentId) {\n throw new Error('Agent ID is required');\n }\n\n const sessionManager = new SessionManager(ctx.cwd);\n\n const session = await sessionManager.createSession({\n mode: 'execute',\n task: body.task ?? '',\n agentId: body.agentId,\n name: body.name,\n });\n\n ctx.platform.logger.info(`[create-session] Created session ${session.id} for agent ${body.agentId}`);\n\n return { session };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|