@exaudeus/workrail 3.79.0 → 3.79.2

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.
@@ -14,7 +14,7 @@ function makeBashTool(workspacePath, schemas, sessionId, emitter, workrailSessio
14
14
  `Maximum execution time: ${_shared_js_1.BASH_TIMEOUT_MS / 1000}s.`,
15
15
  inputSchema: schemas['BashParams'],
16
16
  label: 'Bash',
17
- execute: async (_toolCallId, params) => {
17
+ execute: async (_toolCallId, params, signal) => {
18
18
  if (typeof params.command !== 'string' || !params.command)
19
19
  throw new Error('Bash: command must be a non-empty string');
20
20
  console.log(`[WorkflowRunner] Tool: bash "${String(params.command).slice(0, 80)}"`);
@@ -26,6 +26,7 @@ function makeBashTool(workspacePath, schemas, sessionId, emitter, workrailSessio
26
26
  cwd,
27
27
  timeout: _shared_js_1.BASH_TIMEOUT_MS,
28
28
  shell: '/bin/bash',
29
+ signal,
29
30
  });
30
31
  const output = [stdout, stderr].filter(Boolean).join('\n');
31
32
  return {
@@ -34,11 +35,13 @@ function makeBashTool(workspacePath, schemas, sessionId, emitter, workrailSessio
34
35
  };
35
36
  }
36
37
  catch (err) {
38
+ if (err.code === 'ABORT_ERR')
39
+ throw err;
37
40
  const e = err;
38
41
  const stdout = String(e.stdout ?? '');
39
42
  const stderr = String(e.stderr ?? '');
40
43
  const rawCode = e.code;
41
- const signal = e.signal;
44
+ const killSignal = e.signal;
42
45
  if (rawCode === 1 && !stderr.trim()) {
43
46
  return {
44
47
  content: [{ type: 'text', text: stdout || '(no output)' }],
@@ -47,8 +50,8 @@ function makeBashTool(workspacePath, schemas, sessionId, emitter, workrailSessio
47
50
  }
48
51
  const exitInfo = rawCode != null
49
52
  ? `exit ${String(rawCode)}`
50
- : signal
51
- ? `signal ${String(signal)}`
53
+ : killSignal
54
+ ? `signal ${String(killSignal)}`
52
55
  : 'exit unknown';
53
56
  throw new Error(`Command failed: ${params.command} (${exitInfo})\nSTDOUT:\n${stdout}\nSTDERR:\n${stderr}`);
54
57
  }
@@ -13,7 +13,7 @@ function makeContinueWorkflowTool(sessionId, ctx, onAdvance, onComplete, schemas
13
13
  'When the step requires an assessment gate, include wr.assessment objects in artifacts.',
14
14
  inputSchema: schemas['ContinueWorkflowParams'],
15
15
  label: 'Continue Workflow',
16
- execute: async (_toolCallId, params) => {
16
+ execute: async (_toolCallId, params, _signal) => {
17
17
  console.log(`[WorkflowRunner] Tool: continue_workflow sessionId=${sessionId}`);
18
18
  emitter?.emit({ kind: 'tool_called', sessionId, toolName: 'continue_workflow', summary: params.intent ?? 'advance', ...(0, _shared_js_1.withWorkrailSession)(workrailSessionId) });
19
19
  const result = await _executeContinueWorkflowFn({
@@ -110,7 +110,7 @@ function makeCompleteStepTool(sessionId, ctx, getCurrentToken, onAdvance, onComp
110
110
  'When the step requires an assessment gate, include wr.assessment objects in artifacts.',
111
111
  inputSchema: schemas['CompleteStepParams'],
112
112
  label: 'Complete Step',
113
- execute: async (_toolCallId, params) => {
113
+ execute: async (_toolCallId, params, _signal) => {
114
114
  console.log(`[WorkflowRunner] Tool: complete_step sessionId=${sessionId}`);
115
115
  emitter?.emit({ kind: 'tool_called', sessionId, toolName: 'complete_step', summary: 'advance', ...(0, _shared_js_1.withWorkrailSession)(workrailSessionId) });
116
116
  const notes = params.notes;
@@ -56,7 +56,7 @@ function makeReadTool(workspacePath, readFileState, schemas, sessionId, emitter,
56
56
  'Use offset (0-indexed start line) and limit (max lines) to read a slice of a large file.',
57
57
  inputSchema: schemas['ReadParams'],
58
58
  label: 'Read',
59
- execute: async (_toolCallId, params) => {
59
+ execute: async (_toolCallId, params, _signal) => {
60
60
  if (typeof params.filePath !== 'string' || !params.filePath)
61
61
  throw new Error('Read: filePath must be a non-empty string');
62
62
  const filePath = resolveWithinWorkspace(params.filePath, workspacePath, 'Read');
@@ -96,7 +96,7 @@ function makeWriteTool(workspacePath, readFileState, schemas, sessionId, emitter
96
96
  'For new files (path does not exist): no prior read is required.',
97
97
  inputSchema: schemas['WriteParams'],
98
98
  label: 'Write',
99
- execute: async (_toolCallId, params) => {
99
+ execute: async (_toolCallId, params, _signal) => {
100
100
  if (typeof params.filePath !== 'string' || !params.filePath)
101
101
  throw new Error('Write: filePath must be a non-empty string');
102
102
  if (typeof params.content !== 'string')
@@ -141,7 +141,7 @@ function makeEditTool(workspacePath, readFileState, schemas, sessionId, emitter,
141
141
  'Do NOT include line-number prefixes (e.g. "1\\t") from Read output in old_string or new_string.',
142
142
  inputSchema: schemas['EditParams'],
143
143
  label: 'Edit',
144
- execute: async (_toolCallId, params) => {
144
+ execute: async (_toolCallId, params, _signal) => {
145
145
  if (typeof params.file_path !== 'string' || !params.file_path)
146
146
  throw new Error('Edit: file_path must be a non-empty string');
147
147
  if (typeof params.old_string !== 'string')
@@ -50,7 +50,7 @@ function makeGlobTool(workspacePath, schemas, sessionId, emitter, workrailSessio
50
50
  'Results are capped at 100 files.',
51
51
  inputSchema: schemas['GlobParams'],
52
52
  label: 'Glob',
53
- execute: async (_toolCallId, params) => {
53
+ execute: async (_toolCallId, params, _signal) => {
54
54
  if (typeof params.pattern !== 'string' || !params.pattern)
55
55
  throw new Error('Glob: pattern must be a non-empty string');
56
56
  const pattern = params.pattern;
@@ -101,7 +101,7 @@ function makeGrepTool(workspacePath, schemas, sessionId, emitter, workrailSessio
101
101
  'node_modules and .git are always excluded.',
102
102
  inputSchema: schemas['GrepParams'],
103
103
  label: 'Grep',
104
- execute: async (_toolCallId, params) => {
104
+ execute: async (_toolCallId, params, _signal) => {
105
105
  if (typeof params.pattern !== 'string' || !params.pattern)
106
106
  throw new Error('Grep: pattern must be a non-empty string');
107
107
  const pattern = params.pattern;
@@ -86,7 +86,7 @@ function makeReportIssueTool(sessionId, emitter, workrailSessionId, issuesDirOve
86
86
  additionalProperties: false,
87
87
  },
88
88
  label: 'report_issue',
89
- execute: async (_toolCallId, params) => {
89
+ execute: async (_toolCallId, params, _signal) => {
90
90
  if (typeof params.kind !== 'string' || !params.kind)
91
91
  throw new Error('report_issue: kind must be a non-empty string');
92
92
  if (typeof params.severity !== 'string' || !params.severity)
@@ -69,7 +69,7 @@ function makeSignalCoordinatorTool(sessionId, emitter, workrailSessionId, signal
69
69
  additionalProperties: false,
70
70
  },
71
71
  label: 'signal_coordinator',
72
- execute: async (_toolCallId, params) => {
72
+ execute: async (_toolCallId, params, _signal) => {
73
73
  if (typeof params.signalKind !== 'string' || !params.signalKind)
74
74
  throw new Error('signal_coordinator: signalKind must be a non-empty string');
75
75
  const signalId = 'sig_' + (0, node_crypto_1.randomUUID)().replace(/-/g, '').slice(0, 8);
@@ -19,7 +19,7 @@ function makeSpawnAgentTool(sessionId, ctx, apiKey, thisWorkrailSessionId, curre
19
19
  'Check outcome before using notes -- on error/timeout, notes contains the error message.',
20
20
  inputSchema: schemas['SpawnAgentParams'],
21
21
  label: 'Spawn Agent',
22
- execute: async (_toolCallId, params) => {
22
+ execute: async (_toolCallId, params, _signal) => {
23
23
  if (typeof params.workflowId !== 'string' || !params.workflowId)
24
24
  throw new Error('spawn_agent: workflowId must be a non-empty string');
25
25
  if (typeof params.goal !== 'string' || !params.goal)
@@ -473,16 +473,16 @@
473
473
  "sha256": "5fe866e54f796975dec5d8ba9983aefd86074db212d3fccd64eed04bc9f0b3da",
474
474
  "bytes": 8011
475
475
  },
476
- "console-ui/assets/index-C1ORzpX3.js": {
477
- "sha256": "593e14bb3358a7e9eebe71e1f01c326ad5c1ff0ed634f0854d651d659da160f8",
478
- "bytes": 768377
479
- },
480
476
  "console-ui/assets/index-DHrKiMCf.css": {
481
477
  "sha256": "40290b50e21ee7e82433efe13b1aa31c1ea608bd057a5c4e324982f284bc928b",
482
478
  "bytes": 60673
483
479
  },
480
+ "console-ui/assets/index-aaVieSSm.js": {
481
+ "sha256": "3b99dd98e6839030bde2a1673e51afc1237a68c5dcd0bd5f80a6b13d3516002a",
482
+ "bytes": 768377
483
+ },
484
484
  "console-ui/index.html": {
485
- "sha256": "95b0bf2ad3f5fd759c38e42924de4657b60e2001e3e96ff49d02447ce3590819",
485
+ "sha256": "c3f59569f41ed0e2e61d4209213db743a3f216c935ed42478e119b99e3dc0d57",
486
486
  "bytes": 417
487
487
  },
488
488
  "console/standalone-console.d.ts": {
@@ -630,12 +630,12 @@
630
630
  "bytes": 1330
631
631
  },
632
632
  "daemon/agent-loop.d.ts": {
633
- "sha256": "01e2a49307b62fb035861bb50b4022f2d76f5207151f4faabc194e116a1f9d44",
634
- "bytes": 3891
633
+ "sha256": "b24e3a615f0058165cd06251835baec3b810da2b92c061aea278fbc72deae5a0",
634
+ "bytes": 3912
635
635
  },
636
636
  "daemon/agent-loop.js": {
637
- "sha256": "fb154e46790a89fe4a92cfa5e3c37361b1d1a41c2443437105cfda9d6c78a981",
638
- "bytes": 10607
637
+ "sha256": "5b0b6114cb9858776baff31a66ba6c8ad79392d1cb66ce951b929a07f8f16115",
638
+ "bytes": 10849
639
639
  },
640
640
  "daemon/context-loader.d.ts": {
641
641
  "sha256": "73992e98475c16b94b880c1daac1da0d0650adfb895d1415ac18e73606f99a5c",
@@ -694,12 +694,12 @@
694
694
  "bytes": 1216
695
695
  },
696
696
  "daemon/daemon-events.d.ts": {
697
- "sha256": "465a4e3e034c11cbe5eb05693e6bbed9eb4c1d9a892b72249b6d5f8adb7b0339",
698
- "bytes": 5379
697
+ "sha256": "264cf0ec4ed8af828ce735b34e3310e662cf6d5502200d4be5b5c4491de0bcdc",
698
+ "bytes": 5398
699
699
  },
700
700
  "daemon/daemon-events.js": {
701
- "sha256": "b6841eef4634bb266faf81961c1e387b535dd64a74d58582f3f2bad8c3469d95",
702
- "bytes": 2252
701
+ "sha256": "ac8e2f94608c11ac758e38959339b0056eb18fa91912ae8a5f89609a8799a123",
702
+ "bytes": 2315
703
703
  },
704
704
  "daemon/io/conversation-log.d.ts": {
705
705
  "sha256": "eff40d1f2f707469b94665741de33ca3a505863d5b97aa8a73f070458e3cf5b5",
@@ -898,56 +898,56 @@
898
898
  "bytes": 301
899
899
  },
900
900
  "daemon/tools/bash.js": {
901
- "sha256": "4a0cc6709a9a48a5ef1ca4e6531a1f038960865853dc757b4db58d17070653c1",
902
- "bytes": 2841
901
+ "sha256": "94d1d76a86b5f1e1a78f69c93e77d5c10e8f6378f186d0c336831b844f953095",
902
+ "bytes": 2966
903
903
  },
904
904
  "daemon/tools/continue-workflow.d.ts": {
905
905
  "sha256": "592de45416a858a30069b4d55ef69f456c0da476122735918783f76838b49c75",
906
906
  "bytes": 1124
907
907
  },
908
908
  "daemon/tools/continue-workflow.js": {
909
- "sha256": "9d15df73d901875fe63efcc87533f22c118b6ed5b15b248fc5842e02711d2b0d",
910
- "bytes": 11377
909
+ "sha256": "17389b3356a17d8e82acb6a86260cc82586ff9cdcbb52b93248b42f83ccdc3bd",
910
+ "bytes": 11395
911
911
  },
912
912
  "daemon/tools/file-tools.d.ts": {
913
913
  "sha256": "5ae91a3fab8cd1e42817af93532e135d7a0bfd1efe7ac7d31337376a739c9646",
914
914
  "bytes": 855
915
915
  },
916
916
  "daemon/tools/file-tools.js": {
917
- "sha256": "289a440a337f11b04192884278d85f8a9a0b3240f3b53583a0c3fd0d78eda0d5",
918
- "bytes": 11048
917
+ "sha256": "b90b2976e07b06427c6886e48a5bb4e267dd0834c6bf00d3c20ba0a640beb2d0",
918
+ "bytes": 11075
919
919
  },
920
920
  "daemon/tools/glob-grep.d.ts": {
921
921
  "sha256": "13b79eae6df2fa4b736543b821d868399a1659f3b05c60e5efac63fc5ea41b46",
922
922
  "bytes": 488
923
923
  },
924
924
  "daemon/tools/glob-grep.js": {
925
- "sha256": "44ae5bccd838e255096ff32e75b1f105a1591e605fbf6662a75ceae1dc491441",
926
- "bytes": 7863
925
+ "sha256": "a124b6ab639e774e152e521931a93291513ad824968cdd871190d9d630719c26",
926
+ "bytes": 7881
927
927
  },
928
928
  "daemon/tools/report-issue.d.ts": {
929
929
  "sha256": "5f405011b3db32c72c6459912d698b2dcca50c81d224e18c8abd7db0fa876de0",
930
930
  "bytes": 326
931
931
  },
932
932
  "daemon/tools/report-issue.js": {
933
- "sha256": "33bb5a892edbebcbaa6da0ae94eed0c60ffaa044613acafb72fe02bf118855e7",
934
- "bytes": 6285
933
+ "sha256": "cd59afdc1224590a116faff6454fec36f2ab20a42fc8a318155836243f3a3b2d",
934
+ "bytes": 6294
935
935
  },
936
936
  "daemon/tools/signal-coordinator.d.ts": {
937
937
  "sha256": "63e5a2bdfd6260a57365ae74aeb9d566c3233e52da36e246212b5ac9ab9ffbb8",
938
938
  "bytes": 338
939
939
  },
940
940
  "daemon/tools/signal-coordinator.js": {
941
- "sha256": "da4ffae6dec8930a995bf2452c128fcc05c30f06b96fbbd2a21de9b8c553908b",
942
- "bytes": 4943
941
+ "sha256": "e17b38f0109d505f1d27418d777bf73797036efa5354b2e867df2c9fd910d58f",
942
+ "bytes": 4952
943
943
  },
944
944
  "daemon/tools/spawn-agent.d.ts": {
945
945
  "sha256": "fc6f2f4403c96597041f81abb656fb3499a5d0e9a6f0800f273e444b60912d71",
946
946
  "bytes": 605
947
947
  },
948
948
  "daemon/tools/spawn-agent.js": {
949
- "sha256": "59a552a553a48921cc6e0b4720de5006a8c871637f2d6f3b78d0fed1adaece4d",
950
- "bytes": 7872
949
+ "sha256": "ff46faa59257609b391a181706afd5e162b5413645938a0e77a486f3e57725b8",
950
+ "bytes": 7881
951
951
  },
952
952
  "daemon/turn-end/conversation-flusher.d.ts": {
953
953
  "sha256": "5a8c1666ad18c31f49cb34ad2f4b5f134437bfb902dc5f89ea3db568ca44976d",
@@ -2106,12 +2106,12 @@
2106
2106
  "bytes": 1830
2107
2107
  },
2108
2108
  "trigger/trigger-store.js": {
2109
- "sha256": "79e7fe516eede2008fc3a32c439c2840a4895b265b13dba8977a76a51d0903e4",
2110
- "bytes": 50609
2109
+ "sha256": "7d30f1c3d1d6edc3c8d6a2c6e45098ee6e377cf02d404e6140165679da1d77ec",
2110
+ "bytes": 52050
2111
2111
  },
2112
2112
  "trigger/types.d.ts": {
2113
- "sha256": "68887851741b85262c438d602f1892cd1a4c8ce8adf9f3aeb483965b3011aecf",
2114
- "bytes": 4490
2113
+ "sha256": "fa0573c51c67037629116edeb1aec06fb27f9d31d0b964f52f243b7d6d020ab0",
2114
+ "bytes": 4515
2115
2115
  },
2116
2116
  "trigger/types.js": {
2117
2117
  "sha256": "45b4e4f23a6d1a2b07350196871b0c53840e5d8142b47f7acedd2f40ae7a6b73",
@@ -621,6 +621,18 @@ function validateAndResolveTrigger(raw, env, workspaces = {}) {
621
621
  let agentConfig;
622
622
  if (raw.agentConfig) {
623
623
  const model = raw.agentConfig.model?.trim() || undefined;
624
+ if (model !== undefined) {
625
+ const slashIdx = model.indexOf('/');
626
+ const provider = slashIdx === -1 ? '' : model.slice(0, slashIdx);
627
+ const modelId = slashIdx === -1 ? '' : model.slice(slashIdx + 1);
628
+ if (!provider || !modelId) {
629
+ return (0, result_js_1.err)({
630
+ kind: 'invalid_field_value',
631
+ field: `agentConfig.model (must be in 'provider/model-id' format, e.g. amazon-bedrock/us.anthropic.claude-haiku-4-5-20251001-v1:0, got: "${model}")`,
632
+ triggerId: rawId,
633
+ });
634
+ }
635
+ }
624
636
  let maxSessionMinutes;
625
637
  if (raw.agentConfig.maxSessionMinutes !== undefined) {
626
638
  const asNumber = Number(raw.agentConfig.maxSessionMinutes);
@@ -1064,6 +1076,22 @@ function validateTriggerStrict(trigger) {
1064
1076
  suggestedFix: 'branchPrefix: worktrain/',
1065
1077
  });
1066
1078
  }
1079
+ if (trigger.agentConfig?.model !== undefined) {
1080
+ const m = trigger.agentConfig.model;
1081
+ const slashIdx = m.indexOf('/');
1082
+ const provider = slashIdx === -1 ? '' : m.slice(0, slashIdx);
1083
+ const modelId = slashIdx === -1 ? '' : m.slice(slashIdx + 1);
1084
+ if (!provider || !modelId) {
1085
+ issues.push({
1086
+ rule: 'invalid-model-format',
1087
+ severity: 'error',
1088
+ triggerId: id,
1089
+ message: `agentConfig.model "${m}" is not in 'provider/model-id' format -- ` +
1090
+ 'both provider and model-id must be non-empty (e.g. amazon-bedrock/us.anthropic.claude-haiku-4-5-20251001-v1:0)',
1091
+ suggestedFix: 'model: amazon-bedrock/us.anthropic.claude-haiku-4-5-20251001-v1:0',
1092
+ });
1093
+ }
1094
+ }
1067
1095
  if (trigger.concurrencyMode === 'parallel' &&
1068
1096
  (!trigger.branchStrategy || trigger.branchStrategy === 'none') &&
1069
1097
  (trigger.autoCommit || trigger.autoOpenPR)) {
@@ -115,7 +115,7 @@ export interface WebhookEvent {
115
115
  readonly payload: Readonly<Record<string, unknown>>;
116
116
  readonly signature?: string;
117
117
  }
118
- export type TriggerValidationRule = 'autocommit-needs-worktree' | 'autoopenpr-needs-autocommit' | 'worktree-needs-base-branch' | 'worktree-needs-prefix' | 'parallel-without-worktree' | 'missing-goal-template' | 'missing-max-session-minutes' | 'missing-max-turns' | 'autocommit-on-main-checkout' | 'missing-max-queue-depth';
118
+ export type TriggerValidationRule = 'autocommit-needs-worktree' | 'autoopenpr-needs-autocommit' | 'worktree-needs-base-branch' | 'worktree-needs-prefix' | 'parallel-without-worktree' | 'missing-goal-template' | 'missing-max-session-minutes' | 'missing-max-turns' | 'autocommit-on-main-checkout' | 'missing-max-queue-depth' | 'invalid-model-format';
119
119
  export interface TriggerValidationIssue {
120
120
  readonly rule: TriggerValidationRule;
121
121
  readonly severity: 'error' | 'warning' | 'info';