cyrus-edge-worker 0.2.40 → 0.2.42
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/AgentSessionManager.d.ts +4 -58
- package/dist/AgentSessionManager.d.ts.map +1 -1
- package/dist/AgentSessionManager.js +11 -304
- package/dist/AgentSessionManager.js.map +1 -1
- package/dist/ChatSessionHandler.d.ts.map +1 -1
- package/dist/ChatSessionHandler.js +1 -3
- package/dist/ChatSessionHandler.js.map +1 -1
- package/dist/DefaultSkillsDeployer.d.ts +32 -0
- package/dist/DefaultSkillsDeployer.d.ts.map +1 -0
- package/dist/DefaultSkillsDeployer.js +86 -0
- package/dist/DefaultSkillsDeployer.js.map +1 -0
- package/dist/EdgeWorker.d.ts +12 -42
- package/dist/EdgeWorker.d.ts.map +1 -1
- package/dist/EdgeWorker.js +58 -432
- package/dist/EdgeWorker.js.map +1 -1
- package/dist/PromptBuilder.d.ts +1 -7
- package/dist/PromptBuilder.d.ts.map +1 -1
- package/dist/PromptBuilder.js +2 -33
- package/dist/PromptBuilder.js.map +1 -1
- package/dist/RunnerConfigBuilder.d.ts +11 -4
- package/dist/RunnerConfigBuilder.d.ts.map +1 -1
- package/dist/RunnerConfigBuilder.js +43 -23
- package/dist/RunnerConfigBuilder.js.map +1 -1
- package/dist/SkillsPluginResolver.d.ts +66 -0
- package/dist/SkillsPluginResolver.d.ts.map +1 -0
- package/dist/SkillsPluginResolver.js +180 -0
- package/dist/SkillsPluginResolver.js.map +1 -0
- package/dist/ToolPermissionResolver.d.ts +1 -12
- package/dist/ToolPermissionResolver.d.ts.map +1 -1
- package/dist/ToolPermissionResolver.js +0 -23
- package/dist/ToolPermissionResolver.js.map +1 -1
- package/dist/cyrus-skills-plugin/.claude-plugin/plugin.json +4 -0
- package/dist/cyrus-skills-plugin/skills/debug/SKILL.md +29 -0
- package/dist/cyrus-skills-plugin/skills/implementation/SKILL.md +17 -0
- package/dist/cyrus-skills-plugin/skills/investigate/SKILL.md +23 -0
- package/dist/cyrus-skills-plugin/skills/summarize/SKILL.md +47 -0
- package/dist/cyrus-skills-plugin/skills/verify-and-ship/SKILL.md +74 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/prompt-assembly/types.d.ts +1 -3
- package/dist/prompt-assembly/types.d.ts.map +1 -1
- package/package.json +15 -15
- package/dist/procedures/ProcedureAnalyzer.d.ts +0 -69
- package/dist/procedures/ProcedureAnalyzer.d.ts.map +0 -1
- package/dist/procedures/ProcedureAnalyzer.js +0 -274
- package/dist/procedures/ProcedureAnalyzer.js.map +0 -1
- package/dist/procedures/index.d.ts +0 -7
- package/dist/procedures/index.d.ts.map +0 -1
- package/dist/procedures/index.js +0 -7
- package/dist/procedures/index.js.map +0 -1
- package/dist/procedures/registry.d.ts +0 -173
- package/dist/procedures/registry.d.ts.map +0 -1
- package/dist/procedures/registry.js +0 -264
- package/dist/procedures/registry.js.map +0 -1
- package/dist/procedures/types.d.ts +0 -101
- package/dist/procedures/types.d.ts.map +0 -1
- package/dist/procedures/types.js +0 -5
- package/dist/procedures/types.js.map +0 -1
- package/dist/prompts/subroutines/changelog-update-gitlab.md +0 -79
- package/dist/prompts/subroutines/changelog-update.md +0 -79
- package/dist/prompts/subroutines/coding-activity.md +0 -12
- package/dist/prompts/subroutines/concise-summary.md +0 -67
- package/dist/prompts/subroutines/debugger-fix.md +0 -92
- package/dist/prompts/subroutines/debugger-reproduction.md +0 -74
- package/dist/prompts/subroutines/get-approval.md +0 -175
- package/dist/prompts/subroutines/gh-pr.md +0 -110
- package/dist/prompts/subroutines/git-commit.md +0 -37
- package/dist/prompts/subroutines/glab-mr.md +0 -106
- package/dist/prompts/subroutines/plan-summary.md +0 -21
- package/dist/prompts/subroutines/preparation.md +0 -16
- package/dist/prompts/subroutines/question-answer.md +0 -8
- package/dist/prompts/subroutines/question-investigation.md +0 -8
- package/dist/prompts/subroutines/release-execution.md +0 -81
- package/dist/prompts/subroutines/release-summary.md +0 -60
- package/dist/prompts/subroutines/user-testing-summary.md +0 -87
- package/dist/prompts/subroutines/user-testing.md +0 -48
- package/dist/prompts/subroutines/validation-fixer.md +0 -56
- package/dist/prompts/subroutines/verbose-summary.md +0 -46
- package/dist/prompts/subroutines/verifications.md +0 -77
- package/dist/validation/ValidationLoopController.d.ts +0 -54
- package/dist/validation/ValidationLoopController.d.ts.map +0 -1
- package/dist/validation/ValidationLoopController.js +0 -242
- package/dist/validation/ValidationLoopController.js.map +0 -1
- package/dist/validation/index.d.ts +0 -7
- package/dist/validation/index.d.ts.map +0 -1
- package/dist/validation/index.js +0 -7
- package/dist/validation/index.js.map +0 -1
- package/dist/validation/types.d.ts +0 -82
- package/dist/validation/types.d.ts.map +0 -1
- package/dist/validation/types.js +0 -29
- package/dist/validation/types.js.map +0 -1
|
@@ -1,41 +1,11 @@
|
|
|
1
1
|
import { EventEmitter } from "node:events";
|
|
2
2
|
import type { SDKMessage, SDKResultMessage, SDKSystemMessage } from "cyrus-claude-runner";
|
|
3
3
|
import { type CyrusAgentSession, type CyrusAgentSessionEntry, type IAgentRunner, type ILogger, type IssueMinimal, type RepositoryContext, type SerializedCyrusAgentSession, type SerializedCyrusAgentSessionEntry, type Workspace } from "cyrus-core";
|
|
4
|
-
import type { ProcedureAnalyzer } from "./procedures/ProcedureAnalyzer.js";
|
|
5
|
-
import type { SharedApplicationServer } from "./SharedApplicationServer.js";
|
|
6
4
|
import type { IActivitySink } from "./sinks/index.js";
|
|
7
5
|
/**
|
|
8
6
|
* Events emitted by AgentSessionManager
|
|
9
7
|
*/
|
|
10
|
-
export
|
|
11
|
-
subroutineComplete: (data: {
|
|
12
|
-
sessionId: string;
|
|
13
|
-
session: CyrusAgentSession;
|
|
14
|
-
}) => void;
|
|
15
|
-
/**
|
|
16
|
-
* Emitted when validation fails and we need to run the validation-fixer
|
|
17
|
-
* The EdgeWorker should respond by running the fixer prompt and then re-running verifications
|
|
18
|
-
*/
|
|
19
|
-
validationLoopIteration: (data: {
|
|
20
|
-
sessionId: string;
|
|
21
|
-
session: CyrusAgentSession;
|
|
22
|
-
/** The fixer prompt to run (already rendered with failure context) */
|
|
23
|
-
fixerPrompt: string;
|
|
24
|
-
/** Current iteration (1-based) */
|
|
25
|
-
iteration: number;
|
|
26
|
-
/** Maximum iterations allowed */
|
|
27
|
-
maxIterations: number;
|
|
28
|
-
}) => void;
|
|
29
|
-
/**
|
|
30
|
-
* Emitted when we need to re-run the verifications subroutine
|
|
31
|
-
*/
|
|
32
|
-
validationLoopRerun: (data: {
|
|
33
|
-
sessionId: string;
|
|
34
|
-
session: CyrusAgentSession;
|
|
35
|
-
/** Current iteration (1-based) */
|
|
36
|
-
iteration: number;
|
|
37
|
-
}) => void;
|
|
38
|
-
}
|
|
8
|
+
export type AgentSessionManagerEvents = {};
|
|
39
9
|
/**
|
|
40
10
|
* Type-safe event emitter interface for AgentSessionManager
|
|
41
11
|
*/
|
|
@@ -62,11 +32,9 @@ export declare class AgentSessionManager extends EventEmitter {
|
|
|
62
32
|
private taskSubjectsById;
|
|
63
33
|
private activeStatusActivitiesBySession;
|
|
64
34
|
private stopRequestedSessions;
|
|
65
|
-
private procedureAnalyzer?;
|
|
66
|
-
private sharedApplicationServer?;
|
|
67
35
|
private getParentSessionId?;
|
|
68
36
|
private resumeParentSession?;
|
|
69
|
-
constructor(getParentSessionId?: (childSessionId: string) => string | undefined, resumeParentSession?: (parentSessionId: string, prompt: string, childSessionId: string) => Promise<void>,
|
|
37
|
+
constructor(getParentSessionId?: (childSessionId: string) => string | undefined, resumeParentSession?: (parentSessionId: string, prompt: string, childSessionId: string) => Promise<void>, logger?: ILogger);
|
|
70
38
|
/**
|
|
71
39
|
* Register an activity sink for a specific session.
|
|
72
40
|
* This associates the session with the correct issue tracker for activity posting.
|
|
@@ -114,30 +82,12 @@ export declare class AgentSessionManager extends EventEmitter {
|
|
|
114
82
|
*/
|
|
115
83
|
private createSessionEntry;
|
|
116
84
|
/**
|
|
117
|
-
* Complete a session from Claude result message
|
|
85
|
+
* Complete a session from Claude result message.
|
|
86
|
+
* Posts the final result to the issue tracker and handles child session completion.
|
|
118
87
|
*/
|
|
119
88
|
completeSession(sessionId: string, resultMessage: SDKResultMessage): Promise<void>;
|
|
120
|
-
private shouldRecoverFromPreviousSubroutine;
|
|
121
89
|
private consumeStopRequest;
|
|
122
90
|
requestSessionStop(linearAgentActivitySessionId: string): void;
|
|
123
|
-
/**
|
|
124
|
-
* Handle completion using procedure routing system
|
|
125
|
-
*/
|
|
126
|
-
private handleProcedureCompletion;
|
|
127
|
-
/**
|
|
128
|
-
* Handle validation loop completion for subroutines that use usesValidationLoop
|
|
129
|
-
* Returns true if the validation loop took over control flow (needs fixer or retry)
|
|
130
|
-
* Returns false if validation passed or max retries reached (continue with normal advancement)
|
|
131
|
-
*/
|
|
132
|
-
private handleValidationLoopCompletion;
|
|
133
|
-
/**
|
|
134
|
-
* Update validation loop state in session metadata
|
|
135
|
-
*/
|
|
136
|
-
private updateValidationLoopState;
|
|
137
|
-
/**
|
|
138
|
-
* Clear validation loop state from session metadata
|
|
139
|
-
*/
|
|
140
|
-
private clearValidationLoopState;
|
|
141
91
|
/**
|
|
142
92
|
* Handle child session completion and resume parent
|
|
143
93
|
*/
|
|
@@ -297,10 +247,6 @@ export declare class AgentSessionManager extends EventEmitter {
|
|
|
297
247
|
* Post an ephemeral "Analyzing your request..." thought and return the activity ID
|
|
298
248
|
*/
|
|
299
249
|
postAnalyzingThought(sessionId: string): Promise<string | null>;
|
|
300
|
-
/**
|
|
301
|
-
* Post the procedure selection result as a non-ephemeral thought
|
|
302
|
-
*/
|
|
303
|
-
postProcedureSelectionThought(sessionId: string, procedureName: string, classification: string): Promise<void>;
|
|
304
250
|
/**
|
|
305
251
|
* Handle status messages (compacting, etc.)
|
|
306
252
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentSessionManager.d.ts","sourceRoot":"","sources":["../src/AgentSessionManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAIX,UAAU,EAEV,gBAAgB,EAEhB,gBAAgB,EAEhB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGN,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAE3B,KAAK,YAAY,EACjB,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,2BAA2B,EAChC,KAAK,gCAAgC,EACrC,KAAK,SAAS,EACd,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"AgentSessionManager.d.ts","sourceRoot":"","sources":["../src/AgentSessionManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from "node:events";
|
|
2
2
|
import { AgentSessionStatus, AgentSessionType, createLogger, } from "cyrus-core";
|
|
3
|
-
import { DEFAULT_VALIDATION_LOOP_CONFIG, parseValidationResult, renderValidationFixerPrompt, } from "./validation/index.js";
|
|
4
3
|
/**
|
|
5
4
|
* Manages Agent Sessions integration with Claude Code SDK
|
|
6
5
|
* Transforms Claude streaming messages into Agent Session format
|
|
@@ -20,17 +19,13 @@ export class AgentSessionManager extends EventEmitter {
|
|
|
20
19
|
taskSubjectsById = new Map(); // Cache task subjects by task ID (e.g., "1" → "Fix login bug")
|
|
21
20
|
activeStatusActivitiesBySession = new Map(); // Maps session ID to active compacting status activity ID
|
|
22
21
|
stopRequestedSessions = new Set(); // Sessions explicitly stopped by user signal
|
|
23
|
-
procedureAnalyzer;
|
|
24
|
-
sharedApplicationServer;
|
|
25
22
|
getParentSessionId;
|
|
26
23
|
resumeParentSession;
|
|
27
|
-
constructor(getParentSessionId, resumeParentSession,
|
|
24
|
+
constructor(getParentSessionId, resumeParentSession, logger) {
|
|
28
25
|
super();
|
|
29
26
|
this.logger = logger ?? createLogger({ component: "AgentSessionManager" });
|
|
30
27
|
this.getParentSessionId = getParentSessionId;
|
|
31
28
|
this.resumeParentSession = resumeParentSession;
|
|
32
|
-
this.procedureAnalyzer = procedureAnalyzer;
|
|
33
|
-
this.sharedApplicationServer = sharedApplicationServer;
|
|
34
29
|
}
|
|
35
30
|
/**
|
|
36
31
|
* Register an activity sink for a specific session.
|
|
@@ -224,7 +219,8 @@ export class AgentSessionManager extends EventEmitter {
|
|
|
224
219
|
return sessionEntry;
|
|
225
220
|
}
|
|
226
221
|
/**
|
|
227
|
-
* Complete a session from Claude result message
|
|
222
|
+
* Complete a session from Claude result message.
|
|
223
|
+
* Posts the final result to the issue tracker and handles child session completion.
|
|
228
224
|
*/
|
|
229
225
|
async completeSession(sessionId, resultMessage) {
|
|
230
226
|
const session = this.sessions.get(sessionId);
|
|
@@ -236,9 +232,6 @@ export class AgentSessionManager extends EventEmitter {
|
|
|
236
232
|
const log = this.sessionLog(sessionId);
|
|
237
233
|
// Clear any active Task when session completes
|
|
238
234
|
this.activeTasksBySession.delete(sessionId);
|
|
239
|
-
// Clear tool calls tracking for this session
|
|
240
|
-
// Note: We should ideally track by session, but for now clearing all is safer
|
|
241
|
-
// to prevent memory leaks
|
|
242
235
|
const wasStopRequested = this.consumeStopRequest(sessionId);
|
|
243
236
|
const status = wasStopRequested
|
|
244
237
|
? AgentSessionStatus.Error
|
|
@@ -250,62 +243,18 @@ export class AgentSessionManager extends EventEmitter {
|
|
|
250
243
|
totalCostUsd: resultMessage.total_cost_usd,
|
|
251
244
|
usage: resultMessage.usage,
|
|
252
245
|
});
|
|
253
|
-
// Handle result using procedure routing system (skip for sessions without procedures, e.g. Slack)
|
|
254
|
-
if (!this.procedureAnalyzer) {
|
|
255
|
-
log.info(`Session completed (no procedure routing)`);
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
246
|
if (wasStopRequested) {
|
|
259
|
-
log.info(`Session
|
|
247
|
+
log.info(`Session was stopped by user`);
|
|
260
248
|
return;
|
|
261
249
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
// recover from the last completed subroutine's result so the procedure can still complete.
|
|
269
|
-
const recoveredText = this.procedureAnalyzer?.getLastSubroutineResult(session);
|
|
270
|
-
if (recoveredText) {
|
|
271
|
-
log.info(`Recovered result from previous subroutine (subtype: ${resultMessage.subtype}), treating as success for procedure completion`);
|
|
272
|
-
// Create a synthetic success result for procedure routing
|
|
273
|
-
const syntheticResult = {
|
|
274
|
-
...resultMessage,
|
|
275
|
-
subtype: "success",
|
|
276
|
-
result: recoveredText,
|
|
277
|
-
is_error: false,
|
|
278
|
-
};
|
|
279
|
-
await this.handleProcedureCompletion(session, sessionId, syntheticResult);
|
|
280
|
-
}
|
|
281
|
-
else {
|
|
282
|
-
log.warn(`Error result with no recoverable text (subtype: ${resultMessage.subtype}), posting error to Linear`);
|
|
283
|
-
await this.addResultEntry(sessionId, resultMessage);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
else if (resultMessage.subtype !== "success") {
|
|
287
|
-
// Non-recoverable errors (e.g. stop/abort) should not advance procedures.
|
|
288
|
-
await this.addResultEntry(sessionId, resultMessage);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
shouldRecoverFromPreviousSubroutine(resultMessage) {
|
|
292
|
-
if (resultMessage.subtype === "error_max_turns") {
|
|
293
|
-
return true;
|
|
250
|
+
// Post final result to issue tracker
|
|
251
|
+
await this.addResultEntry(sessionId, resultMessage);
|
|
252
|
+
// Handle child session completion
|
|
253
|
+
const parentSessionId = this.getParentSessionId?.(sessionId);
|
|
254
|
+
if (parentSessionId && this.resumeParentSession) {
|
|
255
|
+
await this.handleChildSessionCompletion(sessionId, resultMessage);
|
|
294
256
|
}
|
|
295
|
-
|
|
296
|
-
resultMessage.subtype,
|
|
297
|
-
...("errors" in resultMessage && Array.isArray(resultMessage.errors)
|
|
298
|
-
? resultMessage.errors
|
|
299
|
-
: []),
|
|
300
|
-
"result" in resultMessage && typeof resultMessage.result === "string"
|
|
301
|
-
? resultMessage.result
|
|
302
|
-
: "",
|
|
303
|
-
]
|
|
304
|
-
.join(" ")
|
|
305
|
-
.toLowerCase();
|
|
306
|
-
return (errorText.includes("max turn") ||
|
|
307
|
-
errorText.includes("turn limit") ||
|
|
308
|
-
errorText.includes("turns limit"));
|
|
257
|
+
log.info(`Session completed (subtype: ${resultMessage.subtype})`);
|
|
309
258
|
}
|
|
310
259
|
consumeStopRequest(linearAgentActivitySessionId) {
|
|
311
260
|
if (!this.stopRequestedSessions.has(linearAgentActivitySessionId)) {
|
|
@@ -317,226 +266,6 @@ export class AgentSessionManager extends EventEmitter {
|
|
|
317
266
|
requestSessionStop(linearAgentActivitySessionId) {
|
|
318
267
|
this.stopRequestedSessions.add(linearAgentActivitySessionId);
|
|
319
268
|
}
|
|
320
|
-
/**
|
|
321
|
-
* Handle completion using procedure routing system
|
|
322
|
-
*/
|
|
323
|
-
async handleProcedureCompletion(session, sessionId, resultMessage) {
|
|
324
|
-
const log = this.sessionLog(sessionId);
|
|
325
|
-
if (!this.procedureAnalyzer) {
|
|
326
|
-
throw new Error("ProcedureAnalyzer not available");
|
|
327
|
-
}
|
|
328
|
-
// Check if error occurred
|
|
329
|
-
if (resultMessage.subtype !== "success") {
|
|
330
|
-
log.info(`Subroutine completed with error, not triggering next subroutine`);
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
// Get the runner session ID (Claude, Gemini, Codex, or Cursor)
|
|
334
|
-
const runnerSessionId = session.claudeSessionId ||
|
|
335
|
-
session.geminiSessionId ||
|
|
336
|
-
session.codexSessionId ||
|
|
337
|
-
session.cursorSessionId;
|
|
338
|
-
if (!runnerSessionId) {
|
|
339
|
-
log.error(`No runner session ID found for procedure session`);
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
// Check if there's a next subroutine
|
|
343
|
-
const nextSubroutine = this.procedureAnalyzer.getNextSubroutine(session);
|
|
344
|
-
if (nextSubroutine) {
|
|
345
|
-
// More subroutines to run - check if current subroutine requires approval
|
|
346
|
-
const currentSubroutine = this.procedureAnalyzer.getCurrentSubroutine(session);
|
|
347
|
-
if (currentSubroutine?.requiresApproval) {
|
|
348
|
-
log.info(`Current subroutine "${currentSubroutine.name}" requires approval before proceeding`);
|
|
349
|
-
// Check if SharedApplicationServer is available
|
|
350
|
-
if (!this.sharedApplicationServer) {
|
|
351
|
-
log.error(`SharedApplicationServer not available for approval workflow`);
|
|
352
|
-
await this.createErrorActivity(sessionId, "Approval workflow failed: Server not available");
|
|
353
|
-
return;
|
|
354
|
-
}
|
|
355
|
-
// Extract the final result from the completed subroutine
|
|
356
|
-
const subroutineResult = "result" in resultMessage && resultMessage.result
|
|
357
|
-
? resultMessage.result
|
|
358
|
-
: "No result available";
|
|
359
|
-
try {
|
|
360
|
-
// Register approval request with server
|
|
361
|
-
const approvalRequest = this.sharedApplicationServer.registerApprovalRequest(sessionId);
|
|
362
|
-
// Post approval elicitation to Linear with auth signal URL
|
|
363
|
-
const approvalMessage = `The previous step has completed. Please review the result below and approve to continue:\n\n${subroutineResult}`;
|
|
364
|
-
await this.createApprovalElicitation(sessionId, approvalMessage, approvalRequest.url);
|
|
365
|
-
log.info(`Waiting for approval at URL: ${approvalRequest.url}`);
|
|
366
|
-
// Wait for approval with timeout (30 minutes)
|
|
367
|
-
const approvalTimeout = 30 * 60 * 1000;
|
|
368
|
-
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("Approval timeout")), approvalTimeout));
|
|
369
|
-
const { approved, feedback } = await Promise.race([
|
|
370
|
-
approvalRequest.promise,
|
|
371
|
-
timeoutPromise,
|
|
372
|
-
]);
|
|
373
|
-
if (!approved) {
|
|
374
|
-
log.info(`Approval rejected`);
|
|
375
|
-
await this.createErrorActivity(sessionId, `Workflow stopped: User rejected approval.${feedback ? `\n\nFeedback: ${feedback}` : ""}`);
|
|
376
|
-
return; // Stop workflow
|
|
377
|
-
}
|
|
378
|
-
log.info(`Approval granted, continuing to next subroutine`);
|
|
379
|
-
// Optionally post feedback as a thought
|
|
380
|
-
if (feedback) {
|
|
381
|
-
await this.createThoughtActivity(sessionId, `User feedback: ${feedback}`);
|
|
382
|
-
}
|
|
383
|
-
// Continue with advancement (fall through to existing code)
|
|
384
|
-
}
|
|
385
|
-
catch (error) {
|
|
386
|
-
const errorMessage = error.message;
|
|
387
|
-
if (errorMessage === "Approval timeout") {
|
|
388
|
-
log.info(`Approval timed out`);
|
|
389
|
-
await this.createErrorActivity(sessionId, "Workflow stopped: Approval request timed out after 30 minutes.");
|
|
390
|
-
}
|
|
391
|
-
else {
|
|
392
|
-
log.error(`Approval request failed:`, error);
|
|
393
|
-
await this.createErrorActivity(sessionId, `Workflow stopped: Approval request failed - ${errorMessage}`);
|
|
394
|
-
}
|
|
395
|
-
return; // Stop workflow
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
// Check if current subroutine uses validation loop
|
|
399
|
-
if (currentSubroutine?.usesValidationLoop) {
|
|
400
|
-
const handled = await this.handleValidationLoopCompletion(session, sessionId, resultMessage, runnerSessionId, nextSubroutine);
|
|
401
|
-
if (handled) {
|
|
402
|
-
return; // Validation loop took over control flow
|
|
403
|
-
}
|
|
404
|
-
// If not handled (validation passed or max retries), continue with normal advancement
|
|
405
|
-
}
|
|
406
|
-
// Advance procedure state
|
|
407
|
-
log.info(`Subroutine completed, advancing to next: ${nextSubroutine.name}`);
|
|
408
|
-
const subroutineResult = "result" in resultMessage ? resultMessage.result : undefined;
|
|
409
|
-
this.procedureAnalyzer.advanceToNextSubroutine(session, runnerSessionId, subroutineResult);
|
|
410
|
-
// Emit event for EdgeWorker to handle subroutine transition
|
|
411
|
-
// This replaces the callback pattern and allows EdgeWorker to subscribe
|
|
412
|
-
this.emit("subroutineComplete", {
|
|
413
|
-
sessionId,
|
|
414
|
-
session,
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
else {
|
|
418
|
-
// Procedure complete - post final result
|
|
419
|
-
log.info(`All subroutines completed, posting final result to Linear`);
|
|
420
|
-
await this.addResultEntry(sessionId, resultMessage);
|
|
421
|
-
// Handle child session completion
|
|
422
|
-
const isChildSession = this.getParentSessionId?.(sessionId);
|
|
423
|
-
if (isChildSession && this.resumeParentSession) {
|
|
424
|
-
await this.handleChildSessionCompletion(sessionId, resultMessage);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Handle validation loop completion for subroutines that use usesValidationLoop
|
|
430
|
-
* Returns true if the validation loop took over control flow (needs fixer or retry)
|
|
431
|
-
* Returns false if validation passed or max retries reached (continue with normal advancement)
|
|
432
|
-
*/
|
|
433
|
-
async handleValidationLoopCompletion(session, sessionId, resultMessage, _runnerSessionId, _nextSubroutine) {
|
|
434
|
-
const log = this.sessionLog(sessionId);
|
|
435
|
-
const maxIterations = DEFAULT_VALIDATION_LOOP_CONFIG.maxIterations;
|
|
436
|
-
// Get or initialize validation loop state
|
|
437
|
-
let validationLoop = session.metadata?.procedure?.validationLoop;
|
|
438
|
-
if (!validationLoop) {
|
|
439
|
-
validationLoop = {
|
|
440
|
-
iteration: 0,
|
|
441
|
-
inFixerMode: false,
|
|
442
|
-
attempts: [],
|
|
443
|
-
};
|
|
444
|
-
}
|
|
445
|
-
// Check if we're coming back from the fixer
|
|
446
|
-
if (validationLoop.inFixerMode) {
|
|
447
|
-
// Fixer completed, now we need to re-run verifications
|
|
448
|
-
log.info(`Validation fixer completed for iteration ${validationLoop.iteration}, re-running verifications`);
|
|
449
|
-
// Clear fixer mode flag
|
|
450
|
-
validationLoop.inFixerMode = false;
|
|
451
|
-
this.updateValidationLoopState(session, validationLoop);
|
|
452
|
-
// Emit event to re-run verifications
|
|
453
|
-
this.emit("validationLoopRerun", {
|
|
454
|
-
sessionId,
|
|
455
|
-
session,
|
|
456
|
-
iteration: validationLoop.iteration,
|
|
457
|
-
});
|
|
458
|
-
return true;
|
|
459
|
-
}
|
|
460
|
-
// Parse the validation result from the response
|
|
461
|
-
const resultText = "result" in resultMessage ? resultMessage.result : undefined;
|
|
462
|
-
const structuredOutput = "structured_output" in resultMessage
|
|
463
|
-
? resultMessage.structured_output
|
|
464
|
-
: undefined;
|
|
465
|
-
const validationResult = parseValidationResult(resultText, structuredOutput);
|
|
466
|
-
// Record this attempt
|
|
467
|
-
const newIteration = validationLoop.iteration + 1;
|
|
468
|
-
validationLoop.iteration = newIteration;
|
|
469
|
-
validationLoop.attempts.push({
|
|
470
|
-
iteration: newIteration,
|
|
471
|
-
pass: validationResult.pass,
|
|
472
|
-
reason: validationResult.reason,
|
|
473
|
-
timestamp: Date.now(),
|
|
474
|
-
});
|
|
475
|
-
log.info(`Validation result for iteration ${newIteration}/${maxIterations}: pass=${validationResult.pass}, reason="${validationResult.reason.substring(0, 100)}..."`);
|
|
476
|
-
// Update state in session
|
|
477
|
-
this.updateValidationLoopState(session, validationLoop);
|
|
478
|
-
// Check if validation passed
|
|
479
|
-
if (validationResult.pass) {
|
|
480
|
-
log.info(`Validation passed after ${newIteration} iteration(s)`);
|
|
481
|
-
// Clear validation loop state for next subroutine
|
|
482
|
-
this.clearValidationLoopState(session);
|
|
483
|
-
return false; // Continue with normal advancement
|
|
484
|
-
}
|
|
485
|
-
// Check if we've exceeded max retries
|
|
486
|
-
if (newIteration >= maxIterations) {
|
|
487
|
-
log.info(`Validation failed after ${newIteration} iterations, continuing anyway`);
|
|
488
|
-
// Post a thought about the failures
|
|
489
|
-
await this.createThoughtActivity(sessionId, `Validation loop exhausted after ${newIteration} attempts. Last failure: ${validationResult.reason}`);
|
|
490
|
-
// Clear validation loop state for next subroutine
|
|
491
|
-
this.clearValidationLoopState(session);
|
|
492
|
-
return false; // Continue with normal advancement
|
|
493
|
-
}
|
|
494
|
-
// Validation failed and we have retries left - run the fixer
|
|
495
|
-
log.info(`Validation failed, running fixer (iteration ${newIteration}/${maxIterations})`);
|
|
496
|
-
// Set fixer mode flag
|
|
497
|
-
validationLoop.inFixerMode = true;
|
|
498
|
-
this.updateValidationLoopState(session, validationLoop);
|
|
499
|
-
// Render the fixer prompt with context
|
|
500
|
-
const previousAttempts = validationLoop.attempts.slice(0, -1).map((a) => ({
|
|
501
|
-
iteration: a.iteration,
|
|
502
|
-
reason: a.reason,
|
|
503
|
-
}));
|
|
504
|
-
const fixerPrompt = renderValidationFixerPrompt({
|
|
505
|
-
failureReason: validationResult.reason,
|
|
506
|
-
iteration: newIteration,
|
|
507
|
-
maxIterations,
|
|
508
|
-
previousAttempts,
|
|
509
|
-
});
|
|
510
|
-
// Emit event for EdgeWorker to run the fixer
|
|
511
|
-
this.emit("validationLoopIteration", {
|
|
512
|
-
sessionId,
|
|
513
|
-
session,
|
|
514
|
-
fixerPrompt,
|
|
515
|
-
iteration: newIteration,
|
|
516
|
-
maxIterations,
|
|
517
|
-
});
|
|
518
|
-
return true; // Validation loop took over control flow
|
|
519
|
-
}
|
|
520
|
-
/**
|
|
521
|
-
* Update validation loop state in session metadata
|
|
522
|
-
*/
|
|
523
|
-
updateValidationLoopState(session, validationLoop) {
|
|
524
|
-
if (!session.metadata) {
|
|
525
|
-
session.metadata = {};
|
|
526
|
-
}
|
|
527
|
-
if (!session.metadata.procedure) {
|
|
528
|
-
return; // No procedure metadata, can't update
|
|
529
|
-
}
|
|
530
|
-
session.metadata.procedure.validationLoop = validationLoop;
|
|
531
|
-
}
|
|
532
|
-
/**
|
|
533
|
-
* Clear validation loop state from session metadata
|
|
534
|
-
*/
|
|
535
|
-
clearValidationLoopState(session) {
|
|
536
|
-
if (session.metadata?.procedure) {
|
|
537
|
-
delete session.metadata.procedure.validationLoop;
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
269
|
/**
|
|
541
270
|
* Handle child session completion and resume parent
|
|
542
271
|
*/
|
|
@@ -1104,16 +833,6 @@ export class AgentSessionManager extends EventEmitter {
|
|
|
1104
833
|
body: entry.content,
|
|
1105
834
|
};
|
|
1106
835
|
}
|
|
1107
|
-
// Check if current subroutine has suppressThoughtPosting enabled
|
|
1108
|
-
// If so, suppress thoughts and actions (but still post responses and results)
|
|
1109
|
-
const currentSubroutine = this.procedureAnalyzer?.getCurrentSubroutine(session);
|
|
1110
|
-
if (currentSubroutine?.suppressThoughtPosting) {
|
|
1111
|
-
// Only suppress thoughts and actions, not responses or results
|
|
1112
|
-
if (content.type === "thought" || content.type === "action") {
|
|
1113
|
-
log.debug(`Suppressing ${content.type} posting for subroutine "${currentSubroutine.name}"`);
|
|
1114
|
-
return; // Don't post to tracker
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
836
|
// Ensure we have an external session ID for activity posting
|
|
1118
837
|
if (!session.externalSessionId) {
|
|
1119
838
|
log.debug(`Skipping activity sync - no external session ID (platform: ${session.issueContext?.trackerId || "unknown"})`);
|
|
@@ -1432,18 +1151,6 @@ export class AgentSessionManager extends EventEmitter {
|
|
|
1432
1151
|
ephemeral: true,
|
|
1433
1152
|
}, "analyzing thought");
|
|
1434
1153
|
}
|
|
1435
|
-
/**
|
|
1436
|
-
* Post the procedure selection result as a non-ephemeral thought
|
|
1437
|
-
*/
|
|
1438
|
-
async postProcedureSelectionThought(sessionId, procedureName, classification) {
|
|
1439
|
-
await this.postActivity(sessionId, {
|
|
1440
|
-
content: {
|
|
1441
|
-
type: "thought",
|
|
1442
|
-
body: `Selected procedure: **${procedureName}** (classified as: ${classification})`,
|
|
1443
|
-
},
|
|
1444
|
-
ephemeral: false,
|
|
1445
|
-
}, "procedure selection");
|
|
1446
|
-
}
|
|
1447
1154
|
/**
|
|
1448
1155
|
* Handle status messages (compacting, etc.)
|
|
1449
1156
|
*/
|