@exaudeus/workrail 3.72.4 → 3.73.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.
@@ -137,7 +137,7 @@ export interface SignalEmittedEvent {
137
137
  export interface AgentStuckEvent {
138
138
  readonly kind: 'agent_stuck';
139
139
  readonly sessionId: string;
140
- readonly reason: 'repeated_tool_call' | 'no_progress' | 'timeout_imminent';
140
+ readonly reason: 'repeated_tool_call' | 'no_progress' | 'timeout_imminent' | 'stall';
141
141
  readonly detail: string;
142
142
  readonly toolName?: string;
143
143
  readonly argsSummary?: string;
@@ -46,7 +46,7 @@ function makeSpawnAgentTool(sessionId, ctx, apiKey, thisWorkrailSessionId, curre
46
46
  workspacePath: String(params.workspacePath),
47
47
  goal: String(params.goal),
48
48
  };
49
- const startResult = await (0, start_js_1.executeStartWorkflow)(startInput, ctx, { is_autonomous: 'true', workspacePath: String(params.workspacePath), parentSessionId: thisWorkrailSessionId });
49
+ const startResult = await (0, start_js_1.executeStartWorkflow)(startInput, ctx, { is_autonomous: 'true', workspacePath: String(params.workspacePath), parentSessionId: thisWorkrailSessionId, triggerSource: 'daemon' });
50
50
  if (startResult.isErr()) {
51
51
  const errResult = {
52
52
  childSessionId: null,
@@ -26,6 +26,7 @@ export { DAEMON_SIGNALS_DIR } from './tools/signal-coordinator.js';
26
26
  export { makeContinueWorkflowTool, makeCompleteStepTool, makeBashTool, makeReadTool, makeWriteTool, makeEditTool, makeGlobTool, makeGrepTool, makeSpawnAgentTool, makeReportIssueTool, makeSignalCoordinatorTool, };
27
27
  export declare const DEFAULT_SESSION_TIMEOUT_MINUTES = 30;
28
28
  export declare const DEFAULT_MAX_TURNS = 200;
29
+ export declare const DEFAULT_STALL_TIMEOUT_SECONDS = 120;
29
30
  export declare const WORKTREES_DIR: string;
30
31
  export { DAEMON_SOUL_DEFAULT, DAEMON_SOUL_TEMPLATE } from './soul-template.js';
31
32
  export type ReadFileState = {
@@ -47,6 +48,7 @@ export interface WorkflowTrigger {
47
48
  readonly maxSubagentDepth?: number;
48
49
  readonly stuckAbortPolicy?: 'abort' | 'notify_only';
49
50
  readonly noProgressAbortEnabled?: boolean;
51
+ readonly stallTimeoutSeconds?: number;
50
52
  };
51
53
  readonly parentSessionId?: string;
52
54
  readonly spawnDepth?: number;
@@ -105,7 +107,7 @@ export interface WorkflowRunTimeout {
105
107
  export interface WorkflowRunStuck {
106
108
  readonly _tag: 'stuck';
107
109
  readonly workflowId: string;
108
- readonly reason: 'repeated_tool_call' | 'no_progress';
110
+ readonly reason: 'repeated_tool_call' | 'no_progress' | 'stall';
109
111
  readonly message: string;
110
112
  readonly stopReason: string;
111
113
  readonly issueSummaries?: readonly string[];
@@ -170,7 +172,7 @@ export interface SessionState {
170
172
  }>;
171
173
  issueSummaries: string[];
172
174
  pendingSteerParts: string[];
173
- stuckReason: 'repeated_tool_call' | 'no_progress' | null;
175
+ stuckReason: 'repeated_tool_call' | 'no_progress' | 'stall' | null;
174
176
  timeoutReason: 'wall_clock' | 'max_turns' | null;
175
177
  turnCount: number;
176
178
  }
@@ -260,6 +262,7 @@ export interface SessionContext {
260
262
  readonly initialPrompt: string;
261
263
  readonly sessionTimeoutMs: number;
262
264
  readonly maxTurns: number;
265
+ readonly stallTimeoutMs: number;
263
266
  }
264
267
  export declare function buildSessionContext(trigger: WorkflowTrigger, context: import('./context-loader.js').ContextBundle, firstStepPrompt: string, effectiveWorkspacePath: string): SessionContext;
265
268
  export declare function buildPreAgentSession(trigger: WorkflowTrigger, ctx: V2ToolContext, apiKey: string, sessionId: string, startMs: number, statsDir: string, sessionsDir: string, emitter: DaemonEventEmitter | undefined, daemonRegistry: DaemonRegistry | undefined, activeSessionSet: ActiveSessionSet | undefined, source?: SessionSource): Promise<PreAgentSessionResult>;
@@ -277,6 +280,6 @@ export interface TurnEndSubscriberContext {
277
280
  readonly stuckRepeatThreshold: number;
278
281
  }
279
282
  export declare function buildTurnEndSubscriber(ctx: TurnEndSubscriberContext): (event: AgentEvent) => Promise<void>;
280
- export declare function buildAgentCallbacks(sessionId: string, state: SessionState, modelId: string, emitter: DaemonEventEmitter | undefined, stuckRepeatThreshold: number): AgentLoopCallbacks;
283
+ export declare function buildAgentCallbacks(sessionId: string, state: SessionState, modelId: string, emitter: DaemonEventEmitter | undefined, stuckRepeatThreshold: number, workflowId?: string): AgentLoopCallbacks;
281
284
  export declare function buildSessionResult(state: Readonly<SessionState>, stopReason: string, errorMessage: string | undefined, trigger: WorkflowTrigger, sessionId: string, sessionWorktreePath: string | undefined): WorkflowRunResult;
282
285
  export declare function runWorkflow(trigger: WorkflowTrigger, ctx: V2ToolContext, apiKey: string, daemonRegistry?: DaemonRegistry, emitter?: DaemonEventEmitter, activeSessionSet?: ActiveSessionSet, _statsDir?: string, _sessionsDir?: string, source?: SessionSource): Promise<WorkflowRunResult>;
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.DAEMON_SOUL_TEMPLATE = exports.DAEMON_SOUL_DEFAULT = exports.WORKTREES_DIR = exports.DEFAULT_MAX_TURNS = exports.DEFAULT_SESSION_TIMEOUT_MINUTES = exports.makeSignalCoordinatorTool = exports.makeReportIssueTool = exports.makeSpawnAgentTool = exports.makeGrepTool = exports.makeGlobTool = exports.makeEditTool = exports.makeWriteTool = exports.makeReadTool = exports.makeBashTool = exports.makeCompleteStepTool = exports.makeContinueWorkflowTool = exports.DAEMON_SIGNALS_DIR = exports.DAEMON_SESSIONS_DIR = void 0;
39
+ exports.DAEMON_SOUL_TEMPLATE = exports.DAEMON_SOUL_DEFAULT = exports.WORKTREES_DIR = exports.DEFAULT_STALL_TIMEOUT_SECONDS = exports.DEFAULT_MAX_TURNS = exports.DEFAULT_SESSION_TIMEOUT_MINUTES = exports.makeSignalCoordinatorTool = exports.makeReportIssueTool = exports.makeSpawnAgentTool = exports.makeGrepTool = exports.makeGlobTool = exports.makeEditTool = exports.makeWriteTool = exports.makeReadTool = exports.makeBashTool = exports.makeCompleteStepTool = exports.makeContinueWorkflowTool = exports.DAEMON_SIGNALS_DIR = exports.DAEMON_SESSIONS_DIR = void 0;
40
40
  exports.readDaemonSessionState = readDaemonSessionState;
41
41
  exports.readAllDaemonSessions = readAllDaemonSessions;
42
42
  exports.runStartupRecovery = runStartupRecovery;
@@ -110,6 +110,7 @@ const MAX_SESSION_RECAP_NOTES = 3;
110
110
  const MAX_SESSION_NOTE_CHARS = 800;
111
111
  exports.DEFAULT_SESSION_TIMEOUT_MINUTES = 30;
112
112
  exports.DEFAULT_MAX_TURNS = 200;
113
+ exports.DEFAULT_STALL_TIMEOUT_SECONDS = 120;
113
114
  const MAX_ORPHAN_AGE_MS = 2 * 60 * 60 * 1000;
114
115
  const MAX_WORKTREE_ORPHAN_AGE_MS = 24 * 60 * 60 * 1000;
115
116
  const WORKRAIL_DIR = path.join(os.homedir(), '.workrail');
@@ -980,7 +981,8 @@ function buildSessionContext(trigger, context, firstStepPrompt, effectiveWorkspa
980
981
  '\n\nComplete all step work, then call complete_step with your notes to advance.';
981
982
  const sessionTimeoutMs = (trigger.agentConfig?.maxSessionMinutes ?? exports.DEFAULT_SESSION_TIMEOUT_MINUTES) * 60 * 1000;
982
983
  const maxTurns = trigger.agentConfig?.maxTurns ?? exports.DEFAULT_MAX_TURNS;
983
- return { systemPrompt, initialPrompt, sessionTimeoutMs, maxTurns };
984
+ const stallTimeoutMs = (trigger.agentConfig?.stallTimeoutSeconds ?? exports.DEFAULT_STALL_TIMEOUT_SECONDS) * 1000;
985
+ return { systemPrompt, initialPrompt, sessionTimeoutMs, maxTurns, stallTimeoutMs };
984
986
  }
985
987
  async function buildPreAgentSession(trigger, ctx, apiKey, sessionId, startMs, statsDir, sessionsDir, emitter, daemonRegistry, activeSessionSet, source) {
986
988
  let agentClient;
@@ -1019,7 +1021,7 @@ async function buildPreAgentSession(trigger, ctx, apiKey, sessionId, startMs, st
1019
1021
  isComplete = s.isComplete;
1020
1022
  }
1021
1023
  else {
1022
- const startResult = await (0, start_js_1.executeStartWorkflow)({ workflowId: trigger.workflowId, workspacePath: trigger.workspacePath, goal: trigger.goal }, ctx, { is_autonomous: 'true', workspacePath: trigger.workspacePath });
1024
+ const startResult = await (0, start_js_1.executeStartWorkflow)({ workflowId: trigger.workflowId, workspacePath: trigger.workspacePath, goal: trigger.goal }, ctx, { is_autonomous: 'true', workspacePath: trigger.workspacePath, triggerSource: 'daemon' });
1023
1025
  if (startResult.isErr()) {
1024
1026
  writeExecutionStats(statsDir, sessionId, trigger.workflowId, startMs, 'error', 0);
1025
1027
  return {
@@ -1241,7 +1243,7 @@ function buildTurnEndSubscriber(ctx) {
1241
1243
  (0, step_injector_js_1.injectPendingSteps)(ctx.state, ctx.agent);
1242
1244
  };
1243
1245
  }
1244
- function buildAgentCallbacks(sessionId, state, modelId, emitter, stuckRepeatThreshold) {
1246
+ function buildAgentCallbacks(sessionId, state, modelId, emitter, stuckRepeatThreshold, workflowId) {
1245
1247
  return {
1246
1248
  onLlmTurnStarted: ({ messageCount }) => {
1247
1249
  emitter?.emit({ kind: 'llm_turn_started', sessionId, messageCount, modelId, ...(0, _shared_js_1.withWorkrailSession)(state.workrailSessionId) });
@@ -1261,6 +1263,21 @@ function buildAgentCallbacks(sessionId, state, modelId, emitter, stuckRepeatThre
1261
1263
  onToolCallFailed: ({ toolName, durationMs, errorMessage }) => {
1262
1264
  emitter?.emit({ kind: 'tool_call_failed', sessionId, toolName, durationMs, errorMessage, ...(0, _shared_js_1.withWorkrailSession)(state.workrailSessionId) });
1263
1265
  },
1266
+ onStallDetected: () => {
1267
+ state.stuckReason = 'stall';
1268
+ emitter?.emit({
1269
+ kind: 'agent_stuck',
1270
+ sessionId,
1271
+ reason: 'stall',
1272
+ detail: `No LLM API call started within the stall timeout window. Last tool calls: ${state.lastNToolCalls.map((c) => c.toolName).join(', ') || 'none'}`,
1273
+ ...(0, _shared_js_1.withWorkrailSession)(state.workrailSessionId),
1274
+ });
1275
+ void writeStuckOutboxEntry({
1276
+ workflowId: workflowId ?? sessionId,
1277
+ reason: 'stall',
1278
+ ...(state.issueSummaries.length > 0 ? { issueSummaries: [...state.issueSummaries] } : {}),
1279
+ });
1280
+ },
1264
1281
  };
1265
1282
  }
1266
1283
  function buildSessionResult(state, stopReason, errorMessage, trigger, sessionId, sessionWorktreePath) {
@@ -1355,7 +1372,7 @@ async function buildAgentReadySession(preAgentSession, trigger, ctx, apiKey, ses
1355
1372
  const contextBundle = await contextLoader.loadSession(startContinueToken, baseCtx);
1356
1373
  const effectiveWorkspacePath = sessionWorkspacePath ?? trigger.workspacePath;
1357
1374
  const sessionCtx = buildSessionContext(trigger, contextBundle, firstStepPrompt || 'No step content available', effectiveWorkspacePath);
1358
- const agentCallbacks = buildAgentCallbacks(sessionId, state, modelId, emitter, STUCK_REPEAT_THRESHOLD);
1375
+ const agentCallbacks = buildAgentCallbacks(sessionId, state, modelId, emitter, STUCK_REPEAT_THRESHOLD, trigger.workflowId);
1359
1376
  const agent = new agent_loop_js_1.AgentLoop({
1360
1377
  systemPrompt: sessionCtx.systemPrompt,
1361
1378
  modelId,
@@ -1366,6 +1383,7 @@ async function buildAgentReadySession(preAgentSession, trigger, ctx, apiKey, ses
1366
1383
  ...(trigger.agentConfig?.maxOutputTokens !== undefined
1367
1384
  ? { maxTokens: trigger.agentConfig.maxOutputTokens }
1368
1385
  : {}),
1386
+ stallTimeoutMs: sessionCtx.stallTimeoutMs,
1369
1387
  });
1370
1388
  handle?.setAgent(agent);
1371
1389
  return {
@@ -473,16 +473,16 @@
473
473
  "sha256": "5fe866e54f796975dec5d8ba9983aefd86074db212d3fccd64eed04bc9f0b3da",
474
474
  "bytes": 8011
475
475
  },
476
- "console-ui/assets/index-BuJ0Md-A.js": {
477
- "sha256": "46734452959931b997a5b226b2adff3c9eacdcfa310961cb2c5a916c96d57a1e",
478
- "bytes": 768234
479
- },
480
476
  "console-ui/assets/index-DHrKiMCf.css": {
481
477
  "sha256": "40290b50e21ee7e82433efe13b1aa31c1ea608bd057a5c4e324982f284bc928b",
482
478
  "bytes": 60673
483
479
  },
480
+ "console-ui/assets/index-HnM-KywY.js": {
481
+ "sha256": "dceb8f4d616f8c18643b6705b96f0749436f32c5c39fb71df7cadd9cb8def8a0",
482
+ "bytes": 768234
483
+ },
484
484
  "console-ui/index.html": {
485
- "sha256": "c3af8a37cd5723e4a0d804e37645a0cd37360058a2086bbbe30ff83a0b402cfd",
485
+ "sha256": "73bcca58451f05a95e6b4cbad9ce993f2bbbc5bddb4d92ebbef8969fb3422bec",
486
486
  "bytes": 417
487
487
  },
488
488
  "console/standalone-console.d.ts": {
@@ -606,12 +606,12 @@
606
606
  "bytes": 1330
607
607
  },
608
608
  "daemon/agent-loop.d.ts": {
609
- "sha256": "a05b27f2cdc7bacd35bb41b9b271367ba9d1f550c9cbf873f1a9b4fa092e8bbb",
610
- "bytes": 3779
609
+ "sha256": "01e2a49307b62fb035861bb50b4022f2d76f5207151f4faabc194e116a1f9d44",
610
+ "bytes": 3891
611
611
  },
612
612
  "daemon/agent-loop.js": {
613
- "sha256": "aa47bea99cf9a5ce35d2bc375b6dd51a9fbb68d36f2b185ee0a98176f67d647d",
614
- "bytes": 9803
613
+ "sha256": "fb154e46790a89fe4a92cfa5e3c37361b1d1a41c2443437105cfda9d6c78a981",
614
+ "bytes": 10607
615
615
  },
616
616
  "daemon/context-loader.d.ts": {
617
617
  "sha256": "db099ae68c8f0fd69503afd49daaf2f84fa0ada9791dc3c5e3278382506b13c5",
@@ -630,8 +630,8 @@
630
630
  "bytes": 1216
631
631
  },
632
632
  "daemon/daemon-events.d.ts": {
633
- "sha256": "469cc9b6954e19a5eb87c3fac42f96fd66cd31321b33ce741fb9c1aa64cb2b80",
634
- "bytes": 5369
633
+ "sha256": "465a4e3e034c11cbe5eb05693e6bbed9eb4c1d9a892b72249b6d5f8adb7b0339",
634
+ "bytes": 5379
635
635
  },
636
636
  "daemon/daemon-events.js": {
637
637
  "sha256": "b6841eef4634bb266faf81961c1e387b535dd64a74d58582f3f2bad8c3469d95",
@@ -738,8 +738,8 @@
738
738
  "bytes": 605
739
739
  },
740
740
  "daemon/tools/spawn-agent.js": {
741
- "sha256": "f740326855d0b051a4d99ce000046df2bc01d446c057980bfb0fe4539605738a",
742
- "bytes": 7847
741
+ "sha256": "59a552a553a48921cc6e0b4720de5006a8c871637f2d6f3b78d0fed1adaece4d",
742
+ "bytes": 7872
743
743
  },
744
744
  "daemon/turn-end/conversation-flusher.d.ts": {
745
745
  "sha256": "5a8c1666ad18c31f49cb34ad2f4b5f134437bfb902dc5f89ea3db568ca44976d",
@@ -766,12 +766,12 @@
766
766
  "bytes": 429
767
767
  },
768
768
  "daemon/workflow-runner.d.ts": {
769
- "sha256": "cdea9422bff42b6c5833b343c100d947e164eb015a2a2777c89ab32fca70c426",
770
- "bytes": 13073
769
+ "sha256": "757ac2f51eb800f1b7d714fdf86695fac10322829f334166f0a083abdabe0cb1",
770
+ "bytes": 13256
771
771
  },
772
772
  "daemon/workflow-runner.js": {
773
- "sha256": "6215f84e30e538168e8a4c489255890c7e8f40eef34efb1c2ecb2525af4a2b90",
774
- "bytes": 78720
773
+ "sha256": "9d25e56934be6a7cfdfc54086faacee6e3119e7b7d01240cb958749ea33f8bcd",
774
+ "bytes": 79776
775
775
  },
776
776
  "di/container.d.ts": {
777
777
  "sha256": "003bb7fb7478d627524b9b1e76bd0a963a243794a687ff233b96dc0e33a06d9f",
@@ -1274,8 +1274,8 @@
1274
1274
  "bytes": 1437
1275
1275
  },
1276
1276
  "mcp/handlers/v2-execution/index.js": {
1277
- "sha256": "dff4cf30eee4efc6f37257995e9e9bee6824d8a3eeaa14bfcc63abf452e0e057",
1278
- "bytes": 7731
1277
+ "sha256": "ab5ca7e41236fcbcbb0116b3a11bd931478f8ec4be1073884c33d6aee86cc22e",
1278
+ "bytes": 7757
1279
1279
  },
1280
1280
  "mcp/handlers/v2-execution/replay.d.ts": {
1281
1281
  "sha256": "4f1601755e98c336f7d98c096753c38559d76ab5ebbacb1aed679983d46cb6b7",
@@ -1290,8 +1290,8 @@
1290
1290
  "bytes": 3558
1291
1291
  },
1292
1292
  "mcp/handlers/v2-execution/start.js": {
1293
- "sha256": "be45c65e839a4dc6ab41fe3562fa16059e3719d82ea38007edeb570b642987d0",
1294
- "bytes": 21576
1293
+ "sha256": "18e0998fad89943f975b7a59eaecf976871076c2952772cd141952d5dbbd2169",
1294
+ "bytes": 21784
1295
1295
  },
1296
1296
  "mcp/handlers/v2-execution/workflow-object-cache.d.ts": {
1297
1297
  "sha256": "7e58a2a020fd8443821dbe4e6a2702a9882c517f032a340c1b393cdebf4af907",
@@ -1786,8 +1786,8 @@
1786
1786
  "bytes": 854
1787
1787
  },
1788
1788
  "trigger/coordinator-deps.js": {
1789
- "sha256": "a1f112821bde6c31037442bb3679a3e8b5e9103e6801764cdba6ac9ab191d2bd",
1790
- "bytes": 15023
1789
+ "sha256": "ade7810cf782d88e58074e75a937de08b350ff2ffae533b563fb37753c7ef49c",
1790
+ "bytes": 15048
1791
1791
  },
1792
1792
  "trigger/delivery-action.d.ts": {
1793
1793
  "sha256": "559e2b2645aa60528f73de351cd35ebf45c5b82f47797aa15ddd681319315d39",
@@ -1854,12 +1854,12 @@
1854
1854
  "bytes": 6968
1855
1855
  },
1856
1856
  "trigger/polling-scheduler.d.ts": {
1857
- "sha256": "c8bcd28794a23906feabe276725e63fe7af79749e0517a46c6e0ed41da0cabb2",
1858
- "bytes": 1152
1857
+ "sha256": "0f3fe224d8aa4449831a46037a84b68a5cf5fe03b82379141b6b1cddac420e12",
1858
+ "bytes": 1241
1859
1859
  },
1860
1860
  "trigger/polling-scheduler.js": {
1861
- "sha256": "f920526c08cbed491ede6215e227eb3af7c57e46006e5587bb072cc1987e4081",
1862
- "bytes": 27720
1861
+ "sha256": "49c2c436476d3bebb753cace02be650d318f3c2bfb223dc40a4d36e0d11b156d",
1862
+ "bytes": 28320
1863
1863
  },
1864
1864
  "trigger/trigger-listener.d.ts": {
1865
1865
  "sha256": "57192a2e0e01d472985acd6d17be41930d2c189e029a11137661f990e1446ed3",
@@ -1882,12 +1882,12 @@
1882
1882
  "bytes": 1830
1883
1883
  },
1884
1884
  "trigger/trigger-store.js": {
1885
- "sha256": "9c8ef1c06464e325cc904e215a0cd370a49631db371c06f5f3e64510d200bc70",
1886
- "bytes": 49788
1885
+ "sha256": "79e7fe516eede2008fc3a32c439c2840a4895b265b13dba8977a76a51d0903e4",
1886
+ "bytes": 50609
1887
1887
  },
1888
1888
  "trigger/types.d.ts": {
1889
- "sha256": "0061e573b1ed3cc5217d6b88636a3c5bde6773b692f3c3ad9a7d3f115ee34c8b",
1890
- "bytes": 4443
1889
+ "sha256": "68887851741b85262c438d602f1892cd1a4c8ce8adf9f3aeb483965b3011aecf",
1890
+ "bytes": 4490
1891
1891
  },
1892
1892
  "trigger/types.js": {
1893
1893
  "sha256": "45b4e4f23a6d1a2b07350196871b0c53840e5d8142b47f7acedd2f40ae7a6b73",
@@ -2478,8 +2478,8 @@
2478
2478
  "bytes": 3397
2479
2479
  },
2480
2480
  "v2/durable-core/schemas/export-bundle/index.d.ts": {
2481
- "sha256": "823a96b41bc27defef5ba7fc2eb34ab0cf09db2f2d71dd9820d02564b1cce788",
2482
- "bytes": 551200
2481
+ "sha256": "ae48214ae394702c323a6a4ccd0498ba54c3abcc3104ea9396f5f226b633423e",
2482
+ "bytes": 552192
2483
2483
  },
2484
2484
  "v2/durable-core/schemas/export-bundle/index.js": {
2485
2485
  "sha256": "6e3566b2d05ea6302bbf4d311b8ec3e94725a8523834efe7670a79e7bd7dc40d",
@@ -2534,12 +2534,12 @@
2534
2534
  "bytes": 2138
2535
2535
  },
2536
2536
  "v2/durable-core/schemas/session/events.d.ts": {
2537
- "sha256": "c5117fba94923bbc61dfcf705c96bde3d1ee6f0e27dd558ad728cb851ed29a50",
2538
- "bytes": 84590
2537
+ "sha256": "878c97d2442d782d202316606b46ad8bf51ba98b0f8b892fd1f6a1c1a6e8eb70",
2538
+ "bytes": 84874
2539
2539
  },
2540
2540
  "v2/durable-core/schemas/session/events.js": {
2541
- "sha256": "6b1f80f3d9d7329a59b4afd433e939c2c0e22da5b1e9b0cb1586e124522ed31f",
2542
- "bytes": 13831
2541
+ "sha256": "23651dfa8219a75318474629c45e37bdad2f91f48d1555dfbed649c5c2ed830a",
2542
+ "bytes": 13894
2543
2543
  },
2544
2544
  "v2/durable-core/schemas/session/gaps.d.ts": {
2545
2545
  "sha256": "85d17b865a1ebe9deaa0c99d69039c514b217362715c6697b0bc5908cbf9fff0",
@@ -3218,20 +3218,20 @@
3218
3218
  "bytes": 572
3219
3219
  },
3220
3220
  "v2/usecases/console-routes.js": {
3221
- "sha256": "02e3be4472172bf03efb573376885fdb893af9b81b157370e25597750f77b03e",
3222
- "bytes": 31729
3221
+ "sha256": "a99eabcb4c1e6ed5d3c9e06e4475e28a2e6dba62b74997ac08503f24f1a78f54",
3222
+ "bytes": 31754
3223
3223
  },
3224
3224
  "v2/usecases/console-service.d.ts": {
3225
3225
  "sha256": "fc8fe65427fa9f4f3535344b385b36f66ca06b7e3bfaea708931817a3edcad2b",
3226
3226
  "bytes": 1701
3227
3227
  },
3228
3228
  "v2/usecases/console-service.js": {
3229
- "sha256": "0d0296877eeb561603d55d5e48e31e69a8e338995cebacdecff20f887012c4c8",
3230
- "bytes": 39213
3229
+ "sha256": "46c126cc1edee0e672629ec546bc80dcd0700044d89867277dfb285277fff206",
3230
+ "bytes": 40380
3231
3231
  },
3232
3232
  "v2/usecases/console-types.d.ts": {
3233
- "sha256": "a45892442f1581feb00e2ad9bbe172d34703d03855801288cf9269ad35eaa6aa",
3234
- "bytes": 8002
3233
+ "sha256": "854975a0735590ac2981c1c4b5b93a0518eb97493567e88af4ffa101e596195f",
3234
+ "bytes": 8094
3235
3235
  },
3236
3236
  "v2/usecases/console-types.js": {
3237
3237
  "sha256": "d43aa81f5bc89faa359e0f97c814ba25155591ff078fbb9bfd40f8c7c9683230",
@@ -35,7 +35,7 @@ async function handleV2StartWorkflow(input, ctx) {
35
35
  const rememberedRootFailure = await (0, remembered_roots_js_1.rememberExplicitWorkspaceRoot)(input.workspacePath, guard.ctx.v2.rememberedRootsStore);
36
36
  if (rememberedRootFailure)
37
37
  return rememberedRootFailure;
38
- return (0, start_js_1.executeStartWorkflow)(input, guard.ctx).match((result) => (0, types_js_1.success)((0, render_envelope_js_1.attachV2ExecutionRenderMetadata)({
38
+ return (0, start_js_1.executeStartWorkflow)(input, guard.ctx, { triggerSource: 'mcp' }).match((result) => (0, types_js_1.success)((0, render_envelope_js_1.attachV2ExecutionRenderMetadata)({
39
39
  response: result.response,
40
40
  lifecycle: 'start',
41
41
  contentEnvelope: result.contentEnvelope,
@@ -140,6 +140,9 @@ function buildInitialEvents(args) {
140
140
  workflowHash,
141
141
  workflowSourceKind,
142
142
  workflowSourceRef,
143
+ ...(extraContext?.['triggerSource'] === 'daemon' || extraContext?.['triggerSource'] === 'mcp'
144
+ ? { triggerSource: extraContext['triggerSource'] }
145
+ : {}),
143
146
  },
144
147
  },
145
148
  {
@@ -57,7 +57,7 @@ function createCoordinatorDeps(deps) {
57
57
  if (dispatch === null) {
58
58
  return { kind: 'err', error: 'in-process router not initialized -- coordinator deps not ready' };
59
59
  }
60
- const startResult = await (0, start_js_1.executeStartWorkflow)({ workflowId, workspacePath: workspace, goal }, ctx, { is_autonomous: 'true', workspacePath: workspace });
60
+ const startResult = await (0, start_js_1.executeStartWorkflow)({ workflowId, workspacePath: workspace, goal }, ctx, { is_autonomous: 'true', workspacePath: workspace, triggerSource: 'daemon' });
61
61
  if (startResult.isErr()) {
62
62
  const detail = `${startResult.error.kind}${'message' in startResult.error ? ': ' + startResult.error.message : ''}`;
63
63
  return { kind: 'err', error: `Session creation failed: ${detail}` };
@@ -31,3 +31,4 @@ export declare class PollingScheduler {
31
31
  private dispatchAndRecord;
32
32
  private doPollGitHubQueue;
33
33
  }
34
+ export declare function rotateLogFile(logPath: string, maxBytes: number): Promise<void>;
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.PollingScheduler = void 0;
37
+ exports.rotateLogFile = rotateLogFile;
37
38
  const gitlab_poller_js_1 = require("./adapters/gitlab-poller.js");
38
39
  const github_poller_js_1 = require("./adapters/github-poller.js");
39
40
  const github_queue_poller_js_1 = require("./adapters/github-queue-poller.js");
@@ -457,17 +458,35 @@ async function countActiveSessions(sessionsDir) {
457
458
  }
458
459
  }
459
460
  const MAX_QUEUE_POLL_FILE_SIZE = 10 * 1024 * 1024;
460
- async function appendQueuePollLog(entry) {
461
- const logPath = path.join(os.homedir(), '.workrail', 'queue-poll.jsonl');
461
+ async function rotateLogFile(logPath, maxBytes) {
462
462
  try {
463
+ const stat = await fs.stat(logPath);
464
+ if (stat.size < maxBytes)
465
+ return;
466
+ const backup2 = logPath + '.2';
463
467
  try {
464
- const stat = await fs.stat(logPath);
465
- if (stat.size >= MAX_QUEUE_POLL_FILE_SIZE) {
466
- await fs.rename(logPath, logPath + '.1');
467
- }
468
+ await fs.unlink(backup2);
469
+ }
470
+ catch {
471
+ }
472
+ const backup1 = logPath + '.1';
473
+ try {
474
+ await fs.rename(backup1, backup2);
468
475
  }
469
476
  catch {
470
477
  }
478
+ await fs.rename(logPath, backup1);
479
+ }
480
+ catch (e) {
481
+ const isEnoent = e instanceof Error && 'code' in e && e.code === 'ENOENT';
482
+ if (!isEnoent) {
483
+ console.warn(`[rotateLogFile] Failed to rotate ${logPath}: ${e instanceof Error ? e.message : String(e)}`);
484
+ }
485
+ }
486
+ }
487
+ async function appendQueuePollLog(entry, logPath = path.join(os.homedir(), '.workrail', 'queue-poll.jsonl')) {
488
+ try {
489
+ await rotateLogFile(logPath, MAX_QUEUE_POLL_FILE_SIZE);
471
490
  await fs.appendFile(logPath, JSON.stringify(entry) + '\n', 'utf8');
472
491
  }
473
492
  catch (e) {
@@ -221,6 +221,8 @@ function parseTriggersYaml(content) {
221
221
  agentConfig.maxOutputTokens = acValueResult.value;
222
222
  else if (acKey === 'stuckAbortPolicy')
223
223
  agentConfig.stuckAbortPolicy = acValueResult.value;
224
+ else if (acKey === 'stallTimeoutSeconds')
225
+ agentConfig.stallTimeoutSeconds = acValueResult.value;
224
226
  }
225
227
  lineIndex++;
226
228
  }
@@ -667,13 +669,26 @@ function validateAndResolveTrigger(raw, env, workspaces = {}) {
667
669
  }
668
670
  stuckAbortPolicy = rawSap;
669
671
  }
670
- if (model !== undefined || maxSessionMinutes !== undefined || maxTurns !== undefined || maxOutputTokens !== undefined || stuckAbortPolicy !== undefined) {
672
+ let stallTimeoutSeconds;
673
+ if (raw.agentConfig.stallTimeoutSeconds !== undefined) {
674
+ const asNumber = Number(raw.agentConfig.stallTimeoutSeconds);
675
+ if (!Number.isInteger(asNumber) || asNumber <= 0) {
676
+ return (0, result_js_1.err)({
677
+ kind: 'invalid_field_value',
678
+ field: 'agentConfig.stallTimeoutSeconds (must be a positive integer)',
679
+ triggerId: rawId,
680
+ });
681
+ }
682
+ stallTimeoutSeconds = asNumber;
683
+ }
684
+ if (model !== undefined || maxSessionMinutes !== undefined || maxTurns !== undefined || maxOutputTokens !== undefined || stuckAbortPolicy !== undefined || stallTimeoutSeconds !== undefined) {
671
685
  agentConfig = {
672
686
  ...(model !== undefined ? { model } : {}),
673
687
  ...(maxSessionMinutes !== undefined ? { maxSessionMinutes } : {}),
674
688
  ...(maxTurns !== undefined ? { maxTurns } : {}),
675
689
  ...(maxOutputTokens !== undefined ? { maxOutputTokens } : {}),
676
690
  ...(stuckAbortPolicy !== undefined ? { stuckAbortPolicy } : {}),
691
+ ...(stallTimeoutSeconds !== undefined ? { stallTimeoutSeconds } : {}),
677
692
  };
678
693
  }
679
694
  }
@@ -80,6 +80,7 @@ export interface TriggerDefinition {
80
80
  readonly maxOutputTokens?: number;
81
81
  readonly stuckAbortPolicy?: 'abort' | 'notify_only';
82
82
  readonly noProgressAbortEnabled?: boolean;
83
+ readonly stallTimeoutSeconds?: number;
83
84
  };
84
85
  readonly concurrencyMode: 'serial' | 'parallel';
85
86
  readonly maxQueueDepth?: number;
@@ -269,16 +269,19 @@ export declare const SessionContentsV1Schema: z.ZodObject<{
269
269
  workflowHash: z.ZodEffects<z.ZodString, never, string>;
270
270
  workflowSourceKind: z.ZodEnum<["bundled", "user", "project", "remote", "plugin"]>;
271
271
  workflowSourceRef: z.ZodString;
272
+ triggerSource: z.ZodOptional<z.ZodEnum<["daemon", "mcp"]>>;
272
273
  }, "strip", z.ZodTypeAny, {
273
274
  workflowHash: never;
274
275
  workflowId: string;
275
276
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
276
277
  workflowSourceRef: string;
278
+ triggerSource?: "daemon" | "mcp" | undefined;
277
279
  }, {
278
280
  workflowHash: string;
279
281
  workflowId: string;
280
282
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
281
283
  workflowSourceRef: string;
284
+ triggerSource?: "daemon" | "mcp" | undefined;
282
285
  }>;
283
286
  }, "strip", z.ZodTypeAny, {
284
287
  kind: "run_started";
@@ -295,6 +298,7 @@ export declare const SessionContentsV1Schema: z.ZodObject<{
295
298
  workflowId: string;
296
299
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
297
300
  workflowSourceRef: string;
301
+ triggerSource?: "daemon" | "mcp" | undefined;
298
302
  };
299
303
  timestampMs: number;
300
304
  }, {
@@ -312,6 +316,7 @@ export declare const SessionContentsV1Schema: z.ZodObject<{
312
316
  workflowId: string;
313
317
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
314
318
  workflowSourceRef: string;
319
+ triggerSource?: "daemon" | "mcp" | undefined;
315
320
  };
316
321
  timestampMs: number;
317
322
  }>, z.ZodObject<{
@@ -4927,6 +4932,7 @@ export declare const SessionContentsV1Schema: z.ZodObject<{
4927
4932
  workflowId: string;
4928
4933
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
4929
4934
  workflowSourceRef: string;
4935
+ triggerSource?: "daemon" | "mcp" | undefined;
4930
4936
  };
4931
4937
  timestampMs: number;
4932
4938
  } | {
@@ -5540,6 +5546,7 @@ export declare const SessionContentsV1Schema: z.ZodObject<{
5540
5546
  workflowId: string;
5541
5547
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
5542
5548
  workflowSourceRef: string;
5549
+ triggerSource?: "daemon" | "mcp" | undefined;
5543
5550
  };
5544
5551
  timestampMs: number;
5545
5552
  } | {
@@ -6199,16 +6206,19 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
6199
6206
  workflowHash: z.ZodEffects<z.ZodString, never, string>;
6200
6207
  workflowSourceKind: z.ZodEnum<["bundled", "user", "project", "remote", "plugin"]>;
6201
6208
  workflowSourceRef: z.ZodString;
6209
+ triggerSource: z.ZodOptional<z.ZodEnum<["daemon", "mcp"]>>;
6202
6210
  }, "strip", z.ZodTypeAny, {
6203
6211
  workflowHash: never;
6204
6212
  workflowId: string;
6205
6213
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
6206
6214
  workflowSourceRef: string;
6215
+ triggerSource?: "daemon" | "mcp" | undefined;
6207
6216
  }, {
6208
6217
  workflowHash: string;
6209
6218
  workflowId: string;
6210
6219
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
6211
6220
  workflowSourceRef: string;
6221
+ triggerSource?: "daemon" | "mcp" | undefined;
6212
6222
  }>;
6213
6223
  }, "strip", z.ZodTypeAny, {
6214
6224
  kind: "run_started";
@@ -6225,6 +6235,7 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
6225
6235
  workflowId: string;
6226
6236
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
6227
6237
  workflowSourceRef: string;
6238
+ triggerSource?: "daemon" | "mcp" | undefined;
6228
6239
  };
6229
6240
  timestampMs: number;
6230
6241
  }, {
@@ -6242,6 +6253,7 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
6242
6253
  workflowId: string;
6243
6254
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
6244
6255
  workflowSourceRef: string;
6256
+ triggerSource?: "daemon" | "mcp" | undefined;
6245
6257
  };
6246
6258
  timestampMs: number;
6247
6259
  }>, z.ZodObject<{
@@ -10857,6 +10869,7 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
10857
10869
  workflowId: string;
10858
10870
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
10859
10871
  workflowSourceRef: string;
10872
+ triggerSource?: "daemon" | "mcp" | undefined;
10860
10873
  };
10861
10874
  timestampMs: number;
10862
10875
  } | {
@@ -11470,6 +11483,7 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
11470
11483
  workflowId: string;
11471
11484
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
11472
11485
  workflowSourceRef: string;
11486
+ triggerSource?: "daemon" | "mcp" | undefined;
11473
11487
  };
11474
11488
  timestampMs: number;
11475
11489
  } | {
@@ -12097,6 +12111,7 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
12097
12111
  workflowId: string;
12098
12112
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
12099
12113
  workflowSourceRef: string;
12114
+ triggerSource?: "daemon" | "mcp" | undefined;
12100
12115
  };
12101
12116
  timestampMs: number;
12102
12117
  } | {
@@ -12727,6 +12742,7 @@ export declare const ExportBundleV1Schema: z.ZodObject<{
12727
12742
  workflowId: string;
12728
12743
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
12729
12744
  workflowSourceRef: string;
12745
+ triggerSource?: "daemon" | "mcp" | undefined;
12730
12746
  };
12731
12747
  timestampMs: number;
12732
12748
  } | {
@@ -257,16 +257,19 @@ export declare const DomainEventV1Schema: z.ZodDiscriminatedUnion<"kind", [z.Zod
257
257
  workflowHash: z.ZodEffects<z.ZodString, never, string>;
258
258
  workflowSourceKind: z.ZodEnum<["bundled", "user", "project", "remote", "plugin"]>;
259
259
  workflowSourceRef: z.ZodString;
260
+ triggerSource: z.ZodOptional<z.ZodEnum<["daemon", "mcp"]>>;
260
261
  }, "strip", z.ZodTypeAny, {
261
262
  workflowHash: never;
262
263
  workflowId: string;
263
264
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
264
265
  workflowSourceRef: string;
266
+ triggerSource?: "daemon" | "mcp" | undefined;
265
267
  }, {
266
268
  workflowHash: string;
267
269
  workflowId: string;
268
270
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
269
271
  workflowSourceRef: string;
272
+ triggerSource?: "daemon" | "mcp" | undefined;
270
273
  }>;
271
274
  }, "strip", z.ZodTypeAny, {
272
275
  kind: "run_started";
@@ -283,6 +286,7 @@ export declare const DomainEventV1Schema: z.ZodDiscriminatedUnion<"kind", [z.Zod
283
286
  workflowId: string;
284
287
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
285
288
  workflowSourceRef: string;
289
+ triggerSource?: "daemon" | "mcp" | undefined;
286
290
  };
287
291
  timestampMs: number;
288
292
  }, {
@@ -300,6 +304,7 @@ export declare const DomainEventV1Schema: z.ZodDiscriminatedUnion<"kind", [z.Zod
300
304
  workflowId: string;
301
305
  workflowSourceKind: "bundled" | "user" | "project" | "remote" | "plugin";
302
306
  workflowSourceRef: string;
307
+ triggerSource?: "daemon" | "mcp" | undefined;
303
308
  };
304
309
  timestampMs: number;
305
310
  }>, z.ZodObject<{