@edgehero/pi-dispatch-receiver 4.1.0 → 4.2.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/package.json +2 -2
- package/src/config.mjs +5 -5
- package/src/filter-azure.mjs +6 -3
- package/src/filter-forgejo.mjs +8 -5
- package/src/filter-gitlab.mjs +8 -5
- package/src/filter.mjs +7 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edgehero/pi-dispatch-receiver",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The pi-dispatch trigger edge: verifies GitHub, GitLab, Forgejo and Azure DevOps webhooks, or polls GitHub with no public URL, and queues one pi coding agent job per event (per replica, if set) for the worker.",
|
|
6
6
|
"keywords": [
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@octokit/webhooks": "14.2.0",
|
|
51
|
-
"@edgehero/pi-dispatch": "^4.
|
|
51
|
+
"@edgehero/pi-dispatch": "^4.2.0",
|
|
52
52
|
"bullmq": "5.80.4",
|
|
53
53
|
"ioredis": "5.11.1"
|
|
54
54
|
}
|
package/src/config.mjs
CHANGED
|
@@ -318,9 +318,9 @@ function loadTriggers(env, readFile, fileExists) {
|
|
|
318
318
|
}
|
|
319
319
|
const group = groups[run.kind];
|
|
320
320
|
if (on.type === "label") {
|
|
321
|
-
group.label.push({ index, predicate: { any: on.any, all: on.all, none: on.none }, flow: run.flow, command: run.command, packages: run.packages, image: run.image, backend: run.backend, excludeTools: run.excludeTools, provider: run.provider, model: run.model, maxTurns: run.maxTurns, models: run.models, maxCostUsd: run.maxCostUsd, skillsDir: run.skillsDir, instructions: run.instructions, resume: run.resume, secrets: run.secrets, secretsProfile: run.secretsProfile, waitFor: run.waitFor, replicas: run.replicas, repository: run.repository });
|
|
321
|
+
group.label.push({ index, predicate: { any: on.any, all: on.all, none: on.none }, flow: run.flow, command: run.command, packages: run.packages, image: run.image, backend: run.backend, excludeTools: run.excludeTools, mcp: run.mcp, provider: run.provider, model: run.model, maxTurns: run.maxTurns, models: run.models, maxCostUsd: run.maxCostUsd, skillsDir: run.skillsDir, instructions: run.instructions, resume: run.resume, secrets: run.secrets, secretsProfile: run.secretsProfile, waitFor: run.waitFor, replicas: run.replicas, repository: run.repository });
|
|
322
322
|
} else if (on.type === "comment") {
|
|
323
|
-
group.comment = { index, phrase: on.phrase, defaultFlow: run.flow, command: run.command, packages: run.packages, image: run.image, backend: run.backend, excludeTools: run.excludeTools, provider: run.provider, model: run.model, maxTurns: run.maxTurns, models: run.models, maxCostUsd: run.maxCostUsd, skillsDir: run.skillsDir, instructions: run.instructions, resume: run.resume, secrets: run.secrets, secretsProfile: run.secretsProfile, waitFor: run.waitFor, replicas: run.replicas, repository: run.repository }; // parseTriggers guarantees at most one per forge
|
|
323
|
+
group.comment = { index, phrase: on.phrase, defaultFlow: run.flow, command: run.command, packages: run.packages, image: run.image, backend: run.backend, excludeTools: run.excludeTools, mcp: run.mcp, provider: run.provider, model: run.model, maxTurns: run.maxTurns, models: run.models, maxCostUsd: run.maxCostUsd, skillsDir: run.skillsDir, instructions: run.instructions, resume: run.resume, secrets: run.secrets, secretsProfile: run.secretsProfile, waitFor: run.waitFor, replicas: run.replicas, repository: run.repository }; // parseTriggers guarantees at most one per forge
|
|
324
324
|
} else if (on.type === "pull_request") {
|
|
325
325
|
// The close-only split (issue #231): a close rule routes through the close gate (the CLOSER's
|
|
326
326
|
// resolved authority) and every other PR rule through the author gate, so they live in separate
|
|
@@ -329,17 +329,17 @@ function loadTriggers(env, readFile, fileExists) {
|
|
|
329
329
|
// split reads the SHARED close-word table, never a re-typed word.
|
|
330
330
|
const closeWord = PR_CLOSE_ACTIONS[run.kind];
|
|
331
331
|
if (closeWord !== undefined && on.action.includes(closeWord)) {
|
|
332
|
-
group.prClose.push({ index, actions: new Set(on.action), number: on.number, once: on.once, flow: run.flow, command: run.command, packages: run.packages, image: run.image, backend: run.backend, excludeTools: run.excludeTools, provider: run.provider, model: run.model, maxTurns: run.maxTurns, models: run.models, maxCostUsd: run.maxCostUsd, skillsDir: run.skillsDir, instructions: run.instructions, resume: run.resume, secrets: run.secrets, secretsProfile: run.secretsProfile, waitFor: run.waitFor, replicas: run.replicas });
|
|
332
|
+
group.prClose.push({ index, actions: new Set(on.action), number: on.number, once: on.once, flow: run.flow, command: run.command, packages: run.packages, image: run.image, backend: run.backend, excludeTools: run.excludeTools, mcp: run.mcp, provider: run.provider, model: run.model, maxTurns: run.maxTurns, models: run.models, maxCostUsd: run.maxCostUsd, skillsDir: run.skillsDir, instructions: run.instructions, resume: run.resume, secrets: run.secrets, secretsProfile: run.secretsProfile, waitFor: run.waitFor, replicas: run.replicas });
|
|
333
333
|
} else {
|
|
334
334
|
// `reviewStates` is null rather than an empty Set when unnarrowed: the filter tests it for
|
|
335
335
|
// presence, and an empty Set would read as "no verdict matches" and silently refuse everything.
|
|
336
|
-
group.pullRequest.push({ index, actions: new Set(on.action), reviewStates: on.reviewState ? new Set(on.reviewState) : null, predicate: { any: on.any, all: on.all, none: on.none }, flow: run.flow, command: run.command, packages: run.packages, image: run.image, backend: run.backend, excludeTools: run.excludeTools, provider: run.provider, model: run.model, maxTurns: run.maxTurns, models: run.models, maxCostUsd: run.maxCostUsd, skillsDir: run.skillsDir, instructions: run.instructions, resume: run.resume, secrets: run.secrets, secretsProfile: run.secretsProfile, waitFor: run.waitFor, replicas: run.replicas });
|
|
336
|
+
group.pullRequest.push({ index, actions: new Set(on.action), reviewStates: on.reviewState ? new Set(on.reviewState) : null, predicate: { any: on.any, all: on.all, none: on.none }, flow: run.flow, command: run.command, packages: run.packages, image: run.image, backend: run.backend, excludeTools: run.excludeTools, mcp: run.mcp, provider: run.provider, model: run.model, maxTurns: run.maxTurns, models: run.models, maxCostUsd: run.maxCostUsd, skillsDir: run.skillsDir, instructions: run.instructions, resume: run.resume, secrets: run.secrets, secretsProfile: run.secretsProfile, waitFor: run.waitFor, replicas: run.replicas });
|
|
337
337
|
}
|
|
338
338
|
} else if (on.type === "issue") {
|
|
339
339
|
// The close-trigger kind (issue #231). No predicate and no reviewStates by construction (the
|
|
340
340
|
// loader refused both), and `number`/`once` ride conditionally-present exactly as the loader
|
|
341
341
|
// normalized them -- the filter's close route reads them, nothing else does.
|
|
342
|
-
group.issue.push({ index, actions: new Set(on.action), number: on.number, once: on.once, flow: run.flow, command: run.command, packages: run.packages, image: run.image, backend: run.backend, excludeTools: run.excludeTools, provider: run.provider, model: run.model, maxTurns: run.maxTurns, models: run.models, maxCostUsd: run.maxCostUsd, skillsDir: run.skillsDir, instructions: run.instructions, resume: run.resume, secrets: run.secrets, secretsProfile: run.secretsProfile, waitFor: run.waitFor, replicas: run.replicas });
|
|
342
|
+
group.issue.push({ index, actions: new Set(on.action), number: on.number, once: on.once, flow: run.flow, command: run.command, packages: run.packages, image: run.image, backend: run.backend, excludeTools: run.excludeTools, mcp: run.mcp, provider: run.provider, model: run.model, maxTurns: run.maxTurns, models: run.models, maxCostUsd: run.maxCostUsd, skillsDir: run.skillsDir, instructions: run.instructions, resume: run.resume, secrets: run.secrets, secretsProfile: run.secretsProfile, waitFor: run.waitFor, replicas: run.replicas });
|
|
343
343
|
}
|
|
344
344
|
}
|
|
345
345
|
|
package/src/filter-azure.mjs
CHANGED
|
@@ -117,6 +117,9 @@ export function filterAzure(subset, triggers, knownFlows, selfId, authorized, de
|
|
|
117
117
|
...(resolved.backend !== undefined ? { backend: resolved.backend } : {}),
|
|
118
118
|
// #291. A separate spread, filter.mjs's backend rule: a dropped exclusion runs the job WITH the tool.
|
|
119
119
|
...(resolved.excludeTools !== undefined ? { excludeTools: resolved.excludeTools } : {}),
|
|
120
|
+
// REQ-MCP-OPERATOR-SERVERS. Its own spread, the excludeTools rule above: a dropped list runs
|
|
121
|
+
// the job without its servers.
|
|
122
|
+
...(resolved.mcp !== undefined ? { mcp: resolved.mcp } : {}),
|
|
120
123
|
// #502. One spread PER FIELD, the excludeTools rule above: folded into one conditional, a trigger
|
|
121
124
|
// that named only a model would have its provider's absence decide whether the model survives,
|
|
122
125
|
// and a dropped model runs the job on the deployment default while the file reads as chosen.
|
|
@@ -203,7 +206,7 @@ function matchLabelRules(subset, triggers, labels, action) {
|
|
|
203
206
|
...(rule.command !== undefined ? { command: rule.command } : { flow: rule.flow }),
|
|
204
207
|
repository: rule.repository,
|
|
205
208
|
packages: rule.packages,
|
|
206
|
-
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools,
|
|
209
|
+
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools, mcp: rule.mcp,
|
|
207
210
|
provider: rule.provider, model: rule.model, maxTurns: rule.maxTurns, models: rule.models, maxCostUsd: rule.maxCostUsd,
|
|
208
211
|
skillsDir: rule.skillsDir,
|
|
209
212
|
secrets: rule.secrets,
|
|
@@ -248,7 +251,7 @@ function routeComment(subset, triggers, knownFlows, targetType) {
|
|
|
248
251
|
...(command !== undefined ? { command } : { flow }),
|
|
249
252
|
repository: triggers.comment.repository,
|
|
250
253
|
packages: triggers.comment.packages,
|
|
251
|
-
image: triggers.comment.image, backend: triggers.comment.backend, excludeTools: triggers.comment.excludeTools,
|
|
254
|
+
image: triggers.comment.image, backend: triggers.comment.backend, excludeTools: triggers.comment.excludeTools, mcp: triggers.comment.mcp,
|
|
252
255
|
provider: triggers.comment.provider, model: triggers.comment.model, maxTurns: triggers.comment.maxTurns, models: triggers.comment.models, maxCostUsd: triggers.comment.maxCostUsd,
|
|
253
256
|
skillsDir: triggers.comment.skillsDir,
|
|
254
257
|
secrets: triggers.comment.secrets,
|
|
@@ -282,7 +285,7 @@ function routePullRequest(subset, triggers, action) {
|
|
|
282
285
|
...(rule.command !== undefined ? { command: rule.command } : { flow: rule.flow }),
|
|
283
286
|
repository: rule.repository,
|
|
284
287
|
packages: rule.packages,
|
|
285
|
-
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools,
|
|
288
|
+
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools, mcp: rule.mcp,
|
|
286
289
|
provider: rule.provider, model: rule.model, maxTurns: rule.maxTurns, models: rule.models, maxCostUsd: rule.maxCostUsd,
|
|
287
290
|
skillsDir: rule.skillsDir,
|
|
288
291
|
secrets: rule.secrets,
|
package/src/filter-forgejo.mjs
CHANGED
|
@@ -131,6 +131,9 @@ export function filterForgejo(eventName, subset, triggers, knownFlows, selfId, a
|
|
|
131
131
|
...(resolved.backend !== undefined ? { backend: resolved.backend } : {}),
|
|
132
132
|
// #291. A separate spread, filter.mjs's backend rule: a dropped exclusion runs the job WITH the tool.
|
|
133
133
|
...(resolved.excludeTools !== undefined ? { excludeTools: resolved.excludeTools } : {}),
|
|
134
|
+
// REQ-MCP-OPERATOR-SERVERS. Its own spread, the excludeTools rule above: a dropped list runs
|
|
135
|
+
// the job without its servers.
|
|
136
|
+
...(resolved.mcp !== undefined ? { mcp: resolved.mcp } : {}),
|
|
134
137
|
// #502. One spread PER FIELD, the excludeTools rule above: folded into one conditional, a trigger
|
|
135
138
|
// that named only a model would have its provider's absence decide whether the model survives,
|
|
136
139
|
// and a dropped model runs the job on the deployment default while the file reads as chosen.
|
|
@@ -183,7 +186,7 @@ function routeIssueLabel(subset, triggers) {
|
|
|
183
186
|
// A command rule (issue #189) skips flow resolution entirely: the label match IS the dispatch.
|
|
184
187
|
...(rule.command !== undefined ? { command: rule.command } : { flow: rule.flow }),
|
|
185
188
|
packages: rule.packages, // the MATCHED rule's fields -- rules in one file may differ on them
|
|
186
|
-
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools,
|
|
189
|
+
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools, mcp: rule.mcp,
|
|
187
190
|
provider: rule.provider, model: rule.model, maxTurns: rule.maxTurns, models: rule.models, maxCostUsd: rule.maxCostUsd,
|
|
188
191
|
skillsDir: rule.skillsDir,
|
|
189
192
|
secrets: rule.secrets,
|
|
@@ -233,7 +236,7 @@ function routeComment(subset, triggers, knownFlows) {
|
|
|
233
236
|
enqueue: true,
|
|
234
237
|
...(command !== undefined ? { command } : { flow }),
|
|
235
238
|
packages: triggers.comment.packages,
|
|
236
|
-
image: triggers.comment.image, backend: triggers.comment.backend, excludeTools: triggers.comment.excludeTools,
|
|
239
|
+
image: triggers.comment.image, backend: triggers.comment.backend, excludeTools: triggers.comment.excludeTools, mcp: triggers.comment.mcp,
|
|
237
240
|
provider: triggers.comment.provider, model: triggers.comment.model, maxTurns: triggers.comment.maxTurns, models: triggers.comment.models, maxCostUsd: triggers.comment.maxCostUsd,
|
|
238
241
|
skillsDir: triggers.comment.skillsDir,
|
|
239
242
|
secrets: triggers.comment.secrets,
|
|
@@ -265,7 +268,7 @@ function routePullRequest(subset, triggers, action) {
|
|
|
265
268
|
// A command rule (issue #189) skips flow resolution entirely: the rule match IS the dispatch.
|
|
266
269
|
...(rule.command !== undefined ? { command: rule.command } : { flow: rule.flow }),
|
|
267
270
|
packages: rule.packages,
|
|
268
|
-
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools,
|
|
271
|
+
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools, mcp: rule.mcp,
|
|
269
272
|
provider: rule.provider, model: rule.model, maxTurns: rule.maxTurns, models: rule.models, maxCostUsd: rule.maxCostUsd,
|
|
270
273
|
skillsDir: rule.skillsDir,
|
|
271
274
|
secrets: rule.secrets,
|
|
@@ -321,7 +324,7 @@ function routeIssueClose(subset, triggers, authorized) {
|
|
|
321
324
|
enqueue: true,
|
|
322
325
|
...(rule.command !== undefined ? { command: rule.command } : { flow: rule.flow }),
|
|
323
326
|
packages: rule.packages, // the MATCHED rule's fields -- rules in one file may differ on them
|
|
324
|
-
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools,
|
|
327
|
+
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools, mcp: rule.mcp,
|
|
325
328
|
provider: rule.provider, model: rule.model, maxTurns: rule.maxTurns, models: rule.models, maxCostUsd: rule.maxCostUsd,
|
|
326
329
|
skillsDir: rule.skillsDir,
|
|
327
330
|
secrets: rule.secrets,
|
|
@@ -358,7 +361,7 @@ function routePullRequestClose(subset, triggers, authorized) {
|
|
|
358
361
|
enqueue: true,
|
|
359
362
|
...(rule.command !== undefined ? { command: rule.command } : { flow: rule.flow }),
|
|
360
363
|
packages: rule.packages,
|
|
361
|
-
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools,
|
|
364
|
+
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools, mcp: rule.mcp,
|
|
362
365
|
provider: rule.provider, model: rule.model, maxTurns: rule.maxTurns, models: rule.models, maxCostUsd: rule.maxCostUsd,
|
|
363
366
|
skillsDir: rule.skillsDir,
|
|
364
367
|
secrets: rule.secrets,
|
package/src/filter-gitlab.mjs
CHANGED
|
@@ -134,6 +134,9 @@ export function filterGitLab(subset, triggers, knownFlows, selfId, authorized, d
|
|
|
134
134
|
...(resolved.backend !== undefined ? { backend: resolved.backend } : {}),
|
|
135
135
|
// #291. A separate spread, filter.mjs's backend rule: a dropped exclusion runs the job WITH the tool.
|
|
136
136
|
...(resolved.excludeTools !== undefined ? { excludeTools: resolved.excludeTools } : {}),
|
|
137
|
+
// REQ-MCP-OPERATOR-SERVERS. Its own spread, the excludeTools rule above: a dropped list runs
|
|
138
|
+
// the job without its servers.
|
|
139
|
+
...(resolved.mcp !== undefined ? { mcp: resolved.mcp } : {}),
|
|
137
140
|
// #502. One spread PER FIELD, the excludeTools rule above: folded into one conditional, a trigger
|
|
138
141
|
// that named only a model would have its provider's absence decide whether the model survives,
|
|
139
142
|
// and a dropped model runs the job on the deployment default while the file reads as chosen.
|
|
@@ -193,7 +196,7 @@ function routeLabel(subset, triggers, targetType) {
|
|
|
193
196
|
// A command rule (issue #189) skips flow resolution entirely: the label match IS the dispatch.
|
|
194
197
|
...(rule.command !== undefined ? { command: rule.command } : { flow: rule.flow }),
|
|
195
198
|
packages: rule.packages,
|
|
196
|
-
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools,
|
|
199
|
+
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools, mcp: rule.mcp,
|
|
197
200
|
provider: rule.provider, model: rule.model, maxTurns: rule.maxTurns, models: rule.models, maxCostUsd: rule.maxCostUsd,
|
|
198
201
|
skillsDir: rule.skillsDir,
|
|
199
202
|
secrets: rule.secrets,
|
|
@@ -258,7 +261,7 @@ function mrResult(subset, rule, matched) {
|
|
|
258
261
|
// A command rule (issue #189) skips flow resolution entirely: the rule match IS the dispatch.
|
|
259
262
|
...(rule.command !== undefined ? { command: rule.command } : { flow: rule.flow }),
|
|
260
263
|
packages: rule.packages,
|
|
261
|
-
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools,
|
|
264
|
+
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools, mcp: rule.mcp,
|
|
262
265
|
provider: rule.provider, model: rule.model, maxTurns: rule.maxTurns, models: rule.models, maxCostUsd: rule.maxCostUsd,
|
|
263
266
|
skillsDir: rule.skillsDir,
|
|
264
267
|
secrets: rule.secrets,
|
|
@@ -305,7 +308,7 @@ function routeIssueClose(subset, triggers, authorized) {
|
|
|
305
308
|
enqueue: true,
|
|
306
309
|
...(rule.command !== undefined ? { command: rule.command } : { flow: rule.flow }),
|
|
307
310
|
packages: rule.packages, // the MATCHED rule's fields -- rules in one file may differ on them
|
|
308
|
-
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools,
|
|
311
|
+
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools, mcp: rule.mcp,
|
|
309
312
|
provider: rule.provider, model: rule.model, maxTurns: rule.maxTurns, models: rule.models, maxCostUsd: rule.maxCostUsd,
|
|
310
313
|
skillsDir: rule.skillsDir,
|
|
311
314
|
secrets: rule.secrets,
|
|
@@ -340,7 +343,7 @@ function routeMergeRequestClose(subset, triggers, authorized) {
|
|
|
340
343
|
enqueue: true,
|
|
341
344
|
...(rule.command !== undefined ? { command: rule.command } : { flow: rule.flow }),
|
|
342
345
|
packages: rule.packages,
|
|
343
|
-
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools,
|
|
346
|
+
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools, mcp: rule.mcp,
|
|
344
347
|
provider: rule.provider, model: rule.model, maxTurns: rule.maxTurns, models: rule.models, maxCostUsd: rule.maxCostUsd,
|
|
345
348
|
skillsDir: rule.skillsDir,
|
|
346
349
|
secrets: rule.secrets,
|
|
@@ -393,7 +396,7 @@ function routeNote(subset, triggers, knownFlows) {
|
|
|
393
396
|
enqueue: true,
|
|
394
397
|
...(command !== undefined ? { command } : { flow }),
|
|
395
398
|
packages: triggers.comment.packages,
|
|
396
|
-
image: triggers.comment.image, backend: triggers.comment.backend, excludeTools: triggers.comment.excludeTools,
|
|
399
|
+
image: triggers.comment.image, backend: triggers.comment.backend, excludeTools: triggers.comment.excludeTools, mcp: triggers.comment.mcp,
|
|
397
400
|
provider: triggers.comment.provider, model: triggers.comment.model, maxTurns: triggers.comment.maxTurns, models: triggers.comment.models, maxCostUsd: triggers.comment.maxCostUsd,
|
|
398
401
|
skillsDir: triggers.comment.skillsDir,
|
|
399
402
|
secrets: triggers.comment.secrets,
|
package/src/filter.mjs
CHANGED
|
@@ -157,6 +157,9 @@ export function filter(eventName, subset, cfg, selfId, deliveryId, closerAuthori
|
|
|
157
157
|
// dropped exclusion runs the job WITH the tool, the destructive absence the loader's own sweep
|
|
158
158
|
// refuses a misspelling for, arriving through the plumbing instead of the spelling.
|
|
159
159
|
...(resolved.excludeTools !== undefined ? { excludeTools: resolved.excludeTools } : {}),
|
|
160
|
+
// REQ-MCP-OPERATOR-SERVERS. Its own spread, the excludeTools rule above: a dropped list runs
|
|
161
|
+
// the job without its servers.
|
|
162
|
+
...(resolved.mcp !== undefined ? { mcp: resolved.mcp } : {}),
|
|
160
163
|
// #502. One spread PER FIELD, the excludeTools rule above: folded into one conditional, a trigger
|
|
161
164
|
// that named only a model would have its provider's absence decide whether the model survives,
|
|
162
165
|
// and a dropped model runs the job on the deployment default while the file reads as chosen.
|
|
@@ -221,7 +224,7 @@ function routeIssueLabel(subset, triggers) {
|
|
|
221
224
|
// A command rule (issue #189) skips flow resolution entirely: the label match IS the dispatch.
|
|
222
225
|
...(rule.command !== undefined ? { command: rule.command } : { flow: rule.flow }),
|
|
223
226
|
packages: rule.packages, // the MATCHED rule's fields -- rules in one file may differ on them
|
|
224
|
-
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools,
|
|
227
|
+
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools, mcp: rule.mcp,
|
|
225
228
|
provider: rule.provider, model: rule.model, maxTurns: rule.maxTurns, models: rule.models, maxCostUsd: rule.maxCostUsd,
|
|
226
229
|
skillsDir: rule.skillsDir,
|
|
227
230
|
secrets: rule.secrets,
|
|
@@ -282,7 +285,7 @@ function routeComment(subset, triggers, knownFlows) {
|
|
|
282
285
|
// The single comment trigger IS the matched rule here, so its opt-in is the job's. A `<phrase>
|
|
283
286
|
// <flow>` override changes WHICH flow runs, never which triggers.json entry authorized it.
|
|
284
287
|
packages: triggers.comment.packages,
|
|
285
|
-
image: triggers.comment.image, backend: triggers.comment.backend, excludeTools: triggers.comment.excludeTools,
|
|
288
|
+
image: triggers.comment.image, backend: triggers.comment.backend, excludeTools: triggers.comment.excludeTools, mcp: triggers.comment.mcp,
|
|
286
289
|
provider: triggers.comment.provider, model: triggers.comment.model, maxTurns: triggers.comment.maxTurns, models: triggers.comment.models, maxCostUsd: triggers.comment.maxCostUsd,
|
|
287
290
|
skillsDir: triggers.comment.skillsDir,
|
|
288
291
|
secrets: triggers.comment.secrets,
|
|
@@ -381,7 +384,7 @@ function routePullRequest(subset, triggers, action) {
|
|
|
381
384
|
// A command rule (issue #189) skips flow resolution entirely: the rule match IS the dispatch.
|
|
382
385
|
...(rule.command !== undefined ? { command: rule.command } : { flow: rule.flow }),
|
|
383
386
|
packages: rule.packages, // the MATCHED rule's fields -- rules in one file may differ on them
|
|
384
|
-
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools,
|
|
387
|
+
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools, mcp: rule.mcp,
|
|
385
388
|
provider: rule.provider, model: rule.model, maxTurns: rule.maxTurns, models: rule.models, maxCostUsd: rule.maxCostUsd,
|
|
386
389
|
skillsDir: rule.skillsDir,
|
|
387
390
|
secrets: rule.secrets,
|
|
@@ -498,7 +501,7 @@ function routeClose(rules, number, closerAuthorized, matchedFor, targetFor) {
|
|
|
498
501
|
// A command rule (issue #189) skips flow resolution entirely: the rule match IS the dispatch.
|
|
499
502
|
...(rule.command !== undefined ? { command: rule.command } : { flow: rule.flow }),
|
|
500
503
|
packages: rule.packages, // the MATCHED rule's fields -- rules in one file may differ on them
|
|
501
|
-
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools,
|
|
504
|
+
image: rule.image, backend: rule.backend, excludeTools: rule.excludeTools, mcp: rule.mcp,
|
|
502
505
|
provider: rule.provider, model: rule.model, maxTurns: rule.maxTurns, models: rule.models, maxCostUsd: rule.maxCostUsd,
|
|
503
506
|
skillsDir: rule.skillsDir,
|
|
504
507
|
secrets: rule.secrets,
|