@whittlelabs/sifter 0.33.3 → 0.34.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/bin.js +578 -139
- package/bin.js.map +4 -4
- package/package.json +1 -1
package/bin.js
CHANGED
|
@@ -3122,6 +3122,37 @@ var require_registry = __commonJS({
|
|
|
3122
3122
|
}
|
|
3123
3123
|
});
|
|
3124
3124
|
|
|
3125
|
+
// ../../packages/loom/dist/runtime/requirements.js
|
|
3126
|
+
var require_requirements = __commonJS({
|
|
3127
|
+
"../../packages/loom/dist/runtime/requirements.js"(exports2) {
|
|
3128
|
+
"use strict";
|
|
3129
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3130
|
+
exports2.REQUIRES_EXECUTOR_TAG = exports2.EXECUTOR_ID = void 0;
|
|
3131
|
+
exports2.requirementTags = requirementTags;
|
|
3132
|
+
exports2.readRequiredExecutor = readRequiredExecutor;
|
|
3133
|
+
exports2.EXECUTOR_ID = /^[a-z][a-z0-9-]{0,63}$/;
|
|
3134
|
+
exports2.REQUIRES_EXECUTOR_TAG = "requires-executor:";
|
|
3135
|
+
function requirementTags(requires) {
|
|
3136
|
+
if (!requires?.executor)
|
|
3137
|
+
return [];
|
|
3138
|
+
if (!exports2.EXECUTOR_ID.test(requires.executor)) {
|
|
3139
|
+
throw new Error(`prompt-execution: requires.executor "${requires.executor}" is not an executor id`);
|
|
3140
|
+
}
|
|
3141
|
+
return [`${exports2.REQUIRES_EXECUTOR_TAG}${requires.executor}`];
|
|
3142
|
+
}
|
|
3143
|
+
function readRequiredExecutor(tags) {
|
|
3144
|
+
for (const tag of tags ?? []) {
|
|
3145
|
+
if (!tag.startsWith(exports2.REQUIRES_EXECUTOR_TAG))
|
|
3146
|
+
continue;
|
|
3147
|
+
const executor = tag.slice(exports2.REQUIRES_EXECUTOR_TAG.length);
|
|
3148
|
+
if (exports2.EXECUTOR_ID.test(executor))
|
|
3149
|
+
return executor;
|
|
3150
|
+
}
|
|
3151
|
+
return null;
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3154
|
+
});
|
|
3155
|
+
|
|
3125
3156
|
// ../../packages/loom/dist/runtime/prompt-execution.js
|
|
3126
3157
|
var require_prompt_execution = __commonJS({
|
|
3127
3158
|
"../../packages/loom/dist/runtime/prompt-execution.js"(exports2) {
|
|
@@ -3131,6 +3162,7 @@ var require_prompt_execution = __commonJS({
|
|
|
3131
3162
|
exports2.renderPromptExecution = renderPromptExecution;
|
|
3132
3163
|
exports2.pickProviderHints = pickProviderHints;
|
|
3133
3164
|
exports2.renderTemplate = renderTemplate;
|
|
3165
|
+
var requirements_1 = require_requirements();
|
|
3134
3166
|
function readPromptExecutionSpec(inputs) {
|
|
3135
3167
|
const specRow = inputs.find((i) => i.label === "spec");
|
|
3136
3168
|
if (!specRow)
|
|
@@ -3162,6 +3194,15 @@ var require_prompt_execution = __commonJS({
|
|
|
3162
3194
|
}
|
|
3163
3195
|
}
|
|
3164
3196
|
}
|
|
3197
|
+
if (spec.requires !== void 0) {
|
|
3198
|
+
const req = spec.requires;
|
|
3199
|
+
if (typeof req !== "object" || req === null || Array.isArray(req)) {
|
|
3200
|
+
throw new Error("prompt-execution: spec.requires must be an object when present");
|
|
3201
|
+
}
|
|
3202
|
+
if (req.executor !== void 0 && (typeof req.executor !== "string" || !requirements_1.EXECUTOR_ID.test(req.executor))) {
|
|
3203
|
+
throw new Error("prompt-execution: spec.requires.executor must be an executor id");
|
|
3204
|
+
}
|
|
3205
|
+
}
|
|
3165
3206
|
if (spec.gates !== void 0) {
|
|
3166
3207
|
if (!Array.isArray(spec.gates)) {
|
|
3167
3208
|
throw new Error("prompt-execution: spec.gates must be an array when present");
|
|
@@ -3337,7 +3378,7 @@ var require_runtime = __commonJS({
|
|
|
3337
3378
|
"../../packages/loom/dist/runtime/index.js"(exports2) {
|
|
3338
3379
|
"use strict";
|
|
3339
3380
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3340
|
-
exports2.validateAgainstSchema = exports2.readShuttleStrategy = exports2.shuttleStrategyInput = exports2.PROMPT_EXECUTION_STRATEGY = exports2.SHUTTLE_STRATEGY_LABEL = exports2.pickProviderHints = exports2.renderTemplate = exports2.renderPromptExecution = exports2.readPromptExecutionSpec = void 0;
|
|
3381
|
+
exports2.validateAgainstSchema = exports2.readRequiredExecutor = exports2.requirementTags = exports2.REQUIRES_EXECUTOR_TAG = exports2.EXECUTOR_ID = exports2.readShuttleStrategy = exports2.shuttleStrategyInput = exports2.PROMPT_EXECUTION_STRATEGY = exports2.SHUTTLE_STRATEGY_LABEL = exports2.pickProviderHints = exports2.renderTemplate = exports2.renderPromptExecution = exports2.readPromptExecutionSpec = void 0;
|
|
3341
3382
|
var prompt_execution_1 = require_prompt_execution();
|
|
3342
3383
|
Object.defineProperty(exports2, "readPromptExecutionSpec", { enumerable: true, get: function() {
|
|
3343
3384
|
return prompt_execution_1.readPromptExecutionSpec;
|
|
@@ -3364,6 +3405,19 @@ var require_runtime = __commonJS({
|
|
|
3364
3405
|
Object.defineProperty(exports2, "readShuttleStrategy", { enumerable: true, get: function() {
|
|
3365
3406
|
return strategy_1.readShuttleStrategy;
|
|
3366
3407
|
} });
|
|
3408
|
+
var requirements_1 = require_requirements();
|
|
3409
|
+
Object.defineProperty(exports2, "EXECUTOR_ID", { enumerable: true, get: function() {
|
|
3410
|
+
return requirements_1.EXECUTOR_ID;
|
|
3411
|
+
} });
|
|
3412
|
+
Object.defineProperty(exports2, "REQUIRES_EXECUTOR_TAG", { enumerable: true, get: function() {
|
|
3413
|
+
return requirements_1.REQUIRES_EXECUTOR_TAG;
|
|
3414
|
+
} });
|
|
3415
|
+
Object.defineProperty(exports2, "requirementTags", { enumerable: true, get: function() {
|
|
3416
|
+
return requirements_1.requirementTags;
|
|
3417
|
+
} });
|
|
3418
|
+
Object.defineProperty(exports2, "readRequiredExecutor", { enumerable: true, get: function() {
|
|
3419
|
+
return requirements_1.readRequiredExecutor;
|
|
3420
|
+
} });
|
|
3367
3421
|
var validate_1 = require_validate();
|
|
3368
3422
|
Object.defineProperty(exports2, "validateAgainstSchema", { enumerable: true, get: function() {
|
|
3369
3423
|
return validate_1.validateAgainstSchema;
|
|
@@ -3377,7 +3431,9 @@ var require_prompt_execution2 = __commonJS({
|
|
|
3377
3431
|
"use strict";
|
|
3378
3432
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3379
3433
|
exports2.buildPromptExecutionInputs = buildPromptExecutionInputs;
|
|
3434
|
+
exports2.promptExecutionTags = promptExecutionTags;
|
|
3380
3435
|
var strategy_1 = require_strategy();
|
|
3436
|
+
var requirements_1 = require_requirements();
|
|
3381
3437
|
function buildPromptExecutionInputs(options) {
|
|
3382
3438
|
const spec = {
|
|
3383
3439
|
rendering: options.rendering,
|
|
@@ -3386,6 +3442,10 @@ var require_prompt_execution2 = __commonJS({
|
|
|
3386
3442
|
};
|
|
3387
3443
|
if (options.workspace)
|
|
3388
3444
|
spec.workspace = options.workspace;
|
|
3445
|
+
if (options.requires?.executor) {
|
|
3446
|
+
(0, requirements_1.requirementTags)(options.requires);
|
|
3447
|
+
spec.requires = { executor: options.requires.executor };
|
|
3448
|
+
}
|
|
3389
3449
|
if (options.providerHints)
|
|
3390
3450
|
spec.providerHints = options.providerHints;
|
|
3391
3451
|
if (options.costCapHint)
|
|
@@ -3423,6 +3483,10 @@ var require_prompt_execution2 = __commonJS({
|
|
|
3423
3483
|
}
|
|
3424
3484
|
return inputs;
|
|
3425
3485
|
}
|
|
3486
|
+
function promptExecutionTags(options) {
|
|
3487
|
+
const tags = [.../* @__PURE__ */ new Set([...options.tags ?? [], ...(0, requirements_1.requirementTags)(options.requires)])];
|
|
3488
|
+
return tags.length > 0 ? tags : void 0;
|
|
3489
|
+
}
|
|
3426
3490
|
}
|
|
3427
3491
|
});
|
|
3428
3492
|
|
|
@@ -9780,12 +9844,15 @@ var require_dist = __commonJS({
|
|
|
9780
9844
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
9781
9845
|
};
|
|
9782
9846
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
9783
|
-
exports2.SeedWorkflowsError = exports2.WorkflowBuilderError = exports2.seedWorkflows = exports2.canonicaliseWorkflow = exports2.synthesiseLinearChain = exports2.describeJobPoolRef = exports2.literalJobPool = exports2.principalJobPool = exports2.jobsCreateNode = exports2.httpNode = exports2.promptNode = exports2.defineWorkflow = exports2.buildPromptExecutionInputs = void 0;
|
|
9847
|
+
exports2.SeedWorkflowsError = exports2.WorkflowBuilderError = exports2.seedWorkflows = exports2.canonicaliseWorkflow = exports2.synthesiseLinearChain = exports2.describeJobPoolRef = exports2.literalJobPool = exports2.principalJobPool = exports2.jobsCreateNode = exports2.httpNode = exports2.promptNode = exports2.defineWorkflow = exports2.promptExecutionTags = exports2.buildPromptExecutionInputs = void 0;
|
|
9784
9848
|
__exportStar(require_runtime(), exports2);
|
|
9785
9849
|
var prompt_execution_1 = require_prompt_execution2();
|
|
9786
9850
|
Object.defineProperty(exports2, "buildPromptExecutionInputs", { enumerable: true, get: function() {
|
|
9787
9851
|
return prompt_execution_1.buildPromptExecutionInputs;
|
|
9788
9852
|
} });
|
|
9853
|
+
Object.defineProperty(exports2, "promptExecutionTags", { enumerable: true, get: function() {
|
|
9854
|
+
return prompt_execution_1.promptExecutionTags;
|
|
9855
|
+
} });
|
|
9789
9856
|
var define_workflow_1 = require_define_workflow();
|
|
9790
9857
|
Object.defineProperty(exports2, "defineWorkflow", { enumerable: true, get: function() {
|
|
9791
9858
|
return define_workflow_1.defineWorkflow;
|
|
@@ -9837,8 +9904,9 @@ var require_types2 = __commonJS({
|
|
|
9837
9904
|
"../../packages/shuttle/dist/executors/types.js"(exports2) {
|
|
9838
9905
|
"use strict";
|
|
9839
9906
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
9840
|
-
exports2.ExecutorEnvironmentError = void 0;
|
|
9907
|
+
exports2.MODEL_UNAVAILABLE = exports2.ExecutorModelUnavailableError = exports2.ExecutorEnvironmentError = void 0;
|
|
9841
9908
|
exports2.isExecutorEnvironmentError = isExecutorEnvironmentError;
|
|
9909
|
+
exports2.isExecutorModelUnavailableError = isExecutorModelUnavailableError;
|
|
9842
9910
|
var ExecutorEnvironmentError = class extends Error {
|
|
9843
9911
|
/** What the operator should do, as one clause: "run `claude` and sign in". */
|
|
9844
9912
|
remedy;
|
|
@@ -9852,6 +9920,17 @@ var require_types2 = __commonJS({
|
|
|
9852
9920
|
function isExecutorEnvironmentError(err) {
|
|
9853
9921
|
return err instanceof Error && err.name === "ExecutorEnvironmentError";
|
|
9854
9922
|
}
|
|
9923
|
+
var ExecutorModelUnavailableError = class extends Error {
|
|
9924
|
+
constructor(message) {
|
|
9925
|
+
super(message);
|
|
9926
|
+
this.name = "ExecutorModelUnavailableError";
|
|
9927
|
+
}
|
|
9928
|
+
};
|
|
9929
|
+
exports2.ExecutorModelUnavailableError = ExecutorModelUnavailableError;
|
|
9930
|
+
function isExecutorModelUnavailableError(err) {
|
|
9931
|
+
return err instanceof Error && err.name === "ExecutorModelUnavailableError";
|
|
9932
|
+
}
|
|
9933
|
+
exports2.MODEL_UNAVAILABLE = "model-unavailable";
|
|
9855
9934
|
}
|
|
9856
9935
|
});
|
|
9857
9936
|
|
|
@@ -10070,6 +10149,7 @@ var require_agent_process = __commonJS({
|
|
|
10070
10149
|
exports2.firstLine = firstLine;
|
|
10071
10150
|
exports2.keepTranscript = keepTranscript;
|
|
10072
10151
|
exports2.classifyAgentFault = classifyAgentFault;
|
|
10152
|
+
exports2.isModelUnavailable = isModelUnavailable;
|
|
10073
10153
|
exports2.agentFailure = agentFailure;
|
|
10074
10154
|
var types_1 = require_types2();
|
|
10075
10155
|
var child_process_1 = require("child_process");
|
|
@@ -10187,11 +10267,16 @@ var require_agent_process = __commonJS({
|
|
|
10187
10267
|
}
|
|
10188
10268
|
return null;
|
|
10189
10269
|
}
|
|
10270
|
+
function isModelUnavailable(failure, vocab) {
|
|
10271
|
+
return failure.apiErrorStatus === 404 || vocab.modelUnavailable.test(failure.text ?? "");
|
|
10272
|
+
}
|
|
10190
10273
|
function agentFailure(local, message, facts, vocab) {
|
|
10191
|
-
|
|
10192
|
-
|
|
10193
|
-
|
|
10194
|
-
|
|
10274
|
+
const remedy = local ? classifyAgentFault(facts, vocab) : null;
|
|
10275
|
+
if (remedy)
|
|
10276
|
+
return new types_1.ExecutorEnvironmentError(message, remedy);
|
|
10277
|
+
if (isModelUnavailable(facts, vocab))
|
|
10278
|
+
return new types_1.ExecutorModelUnavailableError(message);
|
|
10279
|
+
return new Error(message);
|
|
10195
10280
|
}
|
|
10196
10281
|
}
|
|
10197
10282
|
});
|
|
@@ -10611,7 +10696,10 @@ var require_claude_code = __commonJS({
|
|
|
10611
10696
|
loginRemedy: LOGIN_REMEDY,
|
|
10612
10697
|
limitRemedy: LIMIT_REMEDY,
|
|
10613
10698
|
signedOut: SIGNED_OUT,
|
|
10614
|
-
outOfUsage: OUT_OF_USAGE
|
|
10699
|
+
outOfUsage: OUT_OF_USAGE,
|
|
10700
|
+
// claude 2.x: "There's an issue with the selected model (x). It may not
|
|
10701
|
+
// exist or you may not have access to it." beside the provider's 404.
|
|
10702
|
+
modelUnavailable: /issue with the selected model|may not exist or you may not have access/i
|
|
10615
10703
|
};
|
|
10616
10704
|
function classifyEnvironmentFault(failure) {
|
|
10617
10705
|
return (0, agent_process_1.classifyAgentFault)(failure, CLAUDE_FAULTS);
|
|
@@ -11306,7 +11394,10 @@ var require_codex = __commonJS({
|
|
|
11306
11394
|
loginRemedy: "run `codex login` and sign in (or `codex login --with-api-key`)",
|
|
11307
11395
|
limitRemedy: "wait for the plan's usage limit to reset, or raise it",
|
|
11308
11396
|
signedOut: /not logged in|run `?codex login|401 unauthorized|invalid api key|refresh token|token (?:has )?expired|sign in again/i,
|
|
11309
|
-
outOfUsage: /usage limit|hit your (?:\w+ )?limit|insufficient_quota|exceeded your current quota|429 too many requests/i
|
|
11397
|
+
outOfUsage: /usage limit|hit your (?:\w+ )?limit|insufficient_quota|exceeded your current quota|429 too many requests/i,
|
|
11398
|
+
// OpenAI's words for a model the key may not use, and codex's for one a
|
|
11399
|
+
// ChatGPT sign-in does not include.
|
|
11400
|
+
modelUnavailable: /model_not_found|model .*(?:does not exist|you do not have access to it)|model is not supported|404 not found.*model/i
|
|
11310
11401
|
};
|
|
11311
11402
|
var READINESS_PROMPT = "Reply with the single word: ok";
|
|
11312
11403
|
var READINESS_TIMEOUT_MS = 12e4;
|
|
@@ -11727,6 +11818,10 @@ var require_copilot = __commonJS({
|
|
|
11727
11818
|
limitRemedy: "the account has no Copilot allowance left: on an organization seat, an owner must allow paid usage in the organization's Copilot policies and fund a budget for it; otherwise wait for the monthly reset",
|
|
11728
11819
|
signedOut: /not (?:logged|signed) in|run `?copilot login|no authentication|authentication (?:failed|required)|bad credentials/i,
|
|
11729
11820
|
outOfUsage: /exceeded your monthly quota|premium request|usage limit|hit your (?:\w+ )?limit|exceeded .*(?:allowance|limit)/i,
|
|
11821
|
+
// copilot 1.0.98 offers only the models the account may use, so a model
|
|
11822
|
+
// that does not exist and one a policy disables both read: Model "x" from
|
|
11823
|
+
// --model flag is not available.
|
|
11824
|
+
modelUnavailable: /model "?[^"\n]*"? (?:from --model flag )?is not available|model .*is not (?:enabled|supported)/i,
|
|
11730
11825
|
notEntitled: {
|
|
11731
11826
|
pattern: /access denied by policy|not authorized to use this copilot feature/i,
|
|
11732
11827
|
remedy: "this account's Copilot does not allow the Copilot CLI: on an organization seat, an owner must assign the seat and enable the Copilot CLI policy, then run `copilot login` again so the new seat is picked up"
|
|
@@ -13135,6 +13230,7 @@ var require_anthropic_api = __commonJS({
|
|
|
13135
13230
|
var keep_1 = require_dist2();
|
|
13136
13231
|
var env_ref_1 = require_env_ref();
|
|
13137
13232
|
var validate_output_1 = require_validate_output();
|
|
13233
|
+
var types_1 = require_types2();
|
|
13138
13234
|
var models_1 = require_models();
|
|
13139
13235
|
var DEFAULT_BASE_URL = "https://api.anthropic.com/v1/messages";
|
|
13140
13236
|
var DEFAULT_MODEL = "claude-sonnet-4-6";
|
|
@@ -13251,7 +13347,11 @@ var require_anthropic_api = __commonJS({
|
|
|
13251
13347
|
const apiErr = envelope?.error;
|
|
13252
13348
|
if (apiErr?.message) {
|
|
13253
13349
|
const kind = apiErr.type ? ` (${apiErr.type})` : "";
|
|
13254
|
-
|
|
13350
|
+
const message = `Anthropic API error${kind}: ${apiErr.message} [HTTP ${response.status}]`;
|
|
13351
|
+
if (response.status === 404 && apiErr.type === "not_found_error") {
|
|
13352
|
+
throw new types_1.ExecutorModelUnavailableError(message);
|
|
13353
|
+
}
|
|
13354
|
+
throw new Error(message);
|
|
13255
13355
|
}
|
|
13256
13356
|
throw new Error(`HTTP ${response.status}${bodyText ? `: ${bodyText}` : ""}`);
|
|
13257
13357
|
}
|
|
@@ -13832,10 +13932,11 @@ var require_scaffold = __commonJS({
|
|
|
13832
13932
|
function planScaffold2(brand, setupOptions, existing) {
|
|
13833
13933
|
const pools = Array.isArray(existing.pools) ? existing.pools : [];
|
|
13834
13934
|
const first = pools[0];
|
|
13835
|
-
const
|
|
13935
|
+
const pooled = first !== null && typeof first === "object" && typeof first.executor === "string" ? first.executor : void 0;
|
|
13936
|
+
const executors = existing.executors !== null && typeof existing.executors === "object" ? existing.executors : {};
|
|
13937
|
+
const prior = pooled ?? Object.keys(executors)[0];
|
|
13836
13938
|
const executor = setupOptions.executor ?? prior ?? brand.defaultExecutor;
|
|
13837
13939
|
const source = setupOptions.executor !== void 0 ? "flag" : prior !== void 0 ? "existing" : "default";
|
|
13838
|
-
const executors = existing.executors !== null && typeof existing.executors === "object" ? existing.executors : {};
|
|
13839
13940
|
const block = executor === void 0 ? void 0 : executors[executor];
|
|
13840
13941
|
const keptBlock = setupOptions.executor === void 0 && block !== null && typeof block === "object" ? block : void 0;
|
|
13841
13942
|
return { executor, source, keptBlock };
|
|
@@ -13910,7 +14011,7 @@ var require_checks = __commonJS({
|
|
|
13910
14011
|
}
|
|
13911
14012
|
function activeAgent(config) {
|
|
13912
14013
|
const configured = configuredExecutors(config);
|
|
13913
|
-
const pooled = config.pools.map((p) => p.executor).find((e) => AGENT_EXECUTORS2.includes(e) && configured.includes(e));
|
|
14014
|
+
const pooled = config.pools.map((p) => p.executor).find((e) => e !== void 0 && AGENT_EXECUTORS2.includes(e) && configured.includes(e));
|
|
13914
14015
|
return pooled ?? configured.find((e) => AGENT_EXECUTORS2.includes(e)) ?? null;
|
|
13915
14016
|
}
|
|
13916
14017
|
function agentSettings(config, subject) {
|
|
@@ -22240,6 +22341,8 @@ var require_subscribe = __commonJS({
|
|
|
22240
22341
|
return outcome;
|
|
22241
22342
|
}
|
|
22242
22343
|
var STOPPED = Symbol("stopped");
|
|
22344
|
+
var DECLINE_WINDOW = 25;
|
|
22345
|
+
var DECLINED_MEMORY = 1e3;
|
|
22243
22346
|
function subscribe(opts) {
|
|
22244
22347
|
const logger = opts.logger ?? NULL_LOGGER;
|
|
22245
22348
|
const pollIntervalMs = opts.pollIntervalMs ?? 2e3;
|
|
@@ -22257,6 +22360,16 @@ var require_subscribe = __commonJS({
|
|
|
22257
22360
|
let wakeStartup = null;
|
|
22258
22361
|
let unavailableSince = null;
|
|
22259
22362
|
let rateLimited = null;
|
|
22363
|
+
const accepts = opts.accepts;
|
|
22364
|
+
const declined = /* @__PURE__ */ new Set();
|
|
22365
|
+
function noteDeclined(jobId) {
|
|
22366
|
+
if (declined.has(jobId))
|
|
22367
|
+
return;
|
|
22368
|
+
if (declined.size >= DECLINED_MEMORY)
|
|
22369
|
+
declined.clear();
|
|
22370
|
+
declined.add(jobId);
|
|
22371
|
+
logger.debug?.("declined a job this subscriber cannot run; it stays queued for another member", { jobId });
|
|
22372
|
+
}
|
|
22260
22373
|
function noteReachable() {
|
|
22261
22374
|
if (unavailableSince !== null) {
|
|
22262
22375
|
logger.info(`Sift is reachable again after ${formatDuration(Date.now() - unavailableSince)}`);
|
|
@@ -22422,9 +22535,10 @@ var require_subscribe = __commonJS({
|
|
|
22422
22535
|
}
|
|
22423
22536
|
try {
|
|
22424
22537
|
const paused = holds.size > 0;
|
|
22538
|
+
const free = maxConcurrency - inflight;
|
|
22425
22539
|
const { data, directives } = await opts.jobsClient.listDispatchableJobs({
|
|
22426
22540
|
pools: resolvedPoolIds,
|
|
22427
|
-
limit: paused ? 1 :
|
|
22541
|
+
limit: paused ? 1 : accepts ? Math.max(free, DECLINE_WINDOW) : free,
|
|
22428
22542
|
sort: "priority:desc,queued_at:asc"
|
|
22429
22543
|
});
|
|
22430
22544
|
noteReachable();
|
|
@@ -22447,6 +22561,10 @@ var require_subscribe = __commonJS({
|
|
|
22447
22561
|
for (const job of data) {
|
|
22448
22562
|
if (inflight >= maxConcurrency)
|
|
22449
22563
|
break;
|
|
22564
|
+
if (accepts && !accepts(job)) {
|
|
22565
|
+
noteDeclined(job.id);
|
|
22566
|
+
continue;
|
|
22567
|
+
}
|
|
22450
22568
|
inflight++;
|
|
22451
22569
|
void runOnce(job).finally(() => {
|
|
22452
22570
|
inflight--;
|
|
@@ -22542,7 +22660,8 @@ var require_subscribe = __commonJS({
|
|
|
22542
22660
|
}
|
|
22543
22661
|
await opts.jobsClient.submit(dispatch.job.id, {
|
|
22544
22662
|
status: result.status,
|
|
22545
|
-
...result.reason !== void 0 ? { reason: result.reason } : {}
|
|
22663
|
+
...result.reason !== void 0 ? { reason: result.reason } : {},
|
|
22664
|
+
...result.status === "failed" && result.failureCode !== void 0 ? { failureCode: result.failureCode } : {}
|
|
22546
22665
|
});
|
|
22547
22666
|
} catch (err) {
|
|
22548
22667
|
if (isFatal(err)) {
|
|
@@ -22664,7 +22783,12 @@ var require_schema4 = __commonJS({
|
|
|
22664
22783
|
name: zod_1.z.string().optional(),
|
|
22665
22784
|
tags: zod_1.z.array(zod_1.z.string()).optional(),
|
|
22666
22785
|
minPriority: zod_1.z.number().int().optional(),
|
|
22667
|
-
|
|
22786
|
+
/**
|
|
22787
|
+
* Deprecated (whittlelabs ADR 0118): a Sifter chooses the executor for
|
|
22788
|
+
* each job from `executors`, in their order. A pool that still names one,
|
|
22789
|
+
* as configs before 0.34 did, tries it first for its own jobs.
|
|
22790
|
+
*/
|
|
22791
|
+
executor: zod_1.z.string().optional()
|
|
22668
22792
|
}).refine((pool) => pool.id !== void 0 || pool.name !== void 0, {
|
|
22669
22793
|
message: 'Each pool must specify at least one of "id" or "name"'
|
|
22670
22794
|
});
|
|
@@ -22704,6 +22828,11 @@ var require_schema4 = __commonJS({
|
|
|
22704
22828
|
concurrency: zod_1.z.object({
|
|
22705
22829
|
maxJobs: zod_1.z.number().int().positive().default(defaults_1.DEFAULTS.concurrency.maxJobs)
|
|
22706
22830
|
}).default(defaults_1.DEFAULTS.concurrency),
|
|
22831
|
+
/**
|
|
22832
|
+
* The executors this runner may run jobs on, keyed by id. The order they
|
|
22833
|
+
* are written in is the order a job tries them (ADR 0118): a job that
|
|
22834
|
+
* requires none runs on the first that can run jobs on this machine.
|
|
22835
|
+
*/
|
|
22707
22836
|
executors: zod_1.z.record(zod_1.z.string(), executorSchema),
|
|
22708
22837
|
logging: zod_1.z.object({
|
|
22709
22838
|
level: zod_1.z.enum(["debug", "info", "warn", "error"]).default(defaults_1.DEFAULTS.logging.level),
|
|
@@ -22719,6 +22848,7 @@ var require_loader = __commonJS({
|
|
|
22719
22848
|
"../../packages/shuttle/dist/config/loader.js"(exports2) {
|
|
22720
22849
|
"use strict";
|
|
22721
22850
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
22851
|
+
exports2.resolveConfigPath = resolveConfigPath;
|
|
22722
22852
|
exports2.loadConfig = loadConfig;
|
|
22723
22853
|
var fs_1 = require("fs");
|
|
22724
22854
|
var path_1 = require("path");
|
|
@@ -26837,32 +26967,51 @@ var require_logger = __commonJS({
|
|
|
26837
26967
|
}
|
|
26838
26968
|
});
|
|
26839
26969
|
|
|
26840
|
-
// ../../packages/shuttle/dist/core/
|
|
26841
|
-
var
|
|
26842
|
-
"../../packages/shuttle/dist/core/
|
|
26970
|
+
// ../../packages/shuttle/dist/core/executor-choice.js
|
|
26971
|
+
var require_executor_choice = __commonJS({
|
|
26972
|
+
"../../packages/shuttle/dist/core/executor-choice.js"(exports2) {
|
|
26843
26973
|
"use strict";
|
|
26844
26974
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
26845
|
-
exports2.
|
|
26846
|
-
|
|
26847
|
-
|
|
26848
|
-
for (const executor of executors) {
|
|
26849
|
-
for (const strategy of executor.strategies)
|
|
26850
|
-
byStrategy.set(strategy, executor);
|
|
26851
|
-
}
|
|
26975
|
+
exports2.createExecutorChooser = createExecutorChooser;
|
|
26976
|
+
var loom_1 = require_dist();
|
|
26977
|
+
function createExecutorChooser(executors, pools) {
|
|
26852
26978
|
const byName = new Map(executors.map((e) => [e.capability.id, e]));
|
|
26853
|
-
const
|
|
26979
|
+
const legacyFirst = /* @__PURE__ */ new Map();
|
|
26854
26980
|
for (const pool of pools) {
|
|
26855
|
-
|
|
26856
|
-
if (!named)
|
|
26981
|
+
if (!pool.executor || !byName.has(pool.executor))
|
|
26857
26982
|
continue;
|
|
26858
26983
|
if (pool.id)
|
|
26859
|
-
|
|
26984
|
+
legacyFirst.set(`id:${pool.id}`, pool.executor);
|
|
26860
26985
|
if (pool.name)
|
|
26861
|
-
|
|
26986
|
+
legacyFirst.set(`name:${pool.name}`, pool.executor);
|
|
26862
26987
|
}
|
|
26863
|
-
|
|
26864
|
-
const
|
|
26865
|
-
|
|
26988
|
+
const orderFor = (pool) => {
|
|
26989
|
+
const first = (pool.id !== void 0 ? legacyFirst.get(`id:${pool.id}`) : void 0) ?? (pool.name !== void 0 ? legacyFirst.get(`name:${pool.name}`) : void 0);
|
|
26990
|
+
const head = first ? byName.get(first) : void 0;
|
|
26991
|
+
return head ? [head, ...executors.filter((e) => e !== head)] : [...executors];
|
|
26992
|
+
};
|
|
26993
|
+
return {
|
|
26994
|
+
accepts(tags) {
|
|
26995
|
+
const required = (0, loom_1.readRequiredExecutor)(tags);
|
|
26996
|
+
return required === null || byName.has(required);
|
|
26997
|
+
},
|
|
26998
|
+
choose({ pool, strategy, required }) {
|
|
26999
|
+
if (required !== null) {
|
|
27000
|
+
const named = byName.get(required);
|
|
27001
|
+
if (!named) {
|
|
27002
|
+
return { ok: false, reason: `this job requires the ${required} executor, which this runner does not have` };
|
|
27003
|
+
}
|
|
27004
|
+
if (!named.strategies.includes(strategy)) {
|
|
27005
|
+
return { ok: false, reason: `this job requires the ${required} executor, which does not run "${strategy}" jobs` };
|
|
27006
|
+
}
|
|
27007
|
+
return { ok: true, executors: [named], required };
|
|
27008
|
+
}
|
|
27009
|
+
const capable = orderFor(pool).filter((e) => e.strategies.includes(strategy));
|
|
27010
|
+
if (capable.length === 0)
|
|
27011
|
+
return { ok: false, reason: `no executor for shuttle strategy "${strategy}"` };
|
|
27012
|
+
return { ok: true, executors: capable, required: null };
|
|
27013
|
+
},
|
|
27014
|
+
orderFor
|
|
26866
27015
|
};
|
|
26867
27016
|
}
|
|
26868
27017
|
}
|
|
@@ -27389,7 +27538,7 @@ var require_shuttle = __commonJS({
|
|
|
27389
27538
|
var logger_1 = require_logger();
|
|
27390
27539
|
var registry_1 = require_registry();
|
|
27391
27540
|
var claude_code_1 = require_claude_code();
|
|
27392
|
-
var
|
|
27541
|
+
var executor_choice_1 = require_executor_choice();
|
|
27393
27542
|
var codex_1 = require_codex();
|
|
27394
27543
|
var copilot_1 = require_copilot();
|
|
27395
27544
|
var http_api_1 = require_http_api();
|
|
@@ -27402,6 +27551,15 @@ var require_shuttle = __commonJS({
|
|
|
27402
27551
|
var store_1 = require_store();
|
|
27403
27552
|
var GATE_REPAIR_BUDGET = 2;
|
|
27404
27553
|
var ENVIRONMENT_HOLD = "executor-environment";
|
|
27554
|
+
function requiredExecutor(dispatch, strategy) {
|
|
27555
|
+
if (strategy !== loom_1.PROMPT_EXECUTION_STRATEGY)
|
|
27556
|
+
return null;
|
|
27557
|
+
try {
|
|
27558
|
+
return (0, loom_1.readPromptExecutionSpec)(dispatch.inputs).requires?.executor ?? null;
|
|
27559
|
+
} catch {
|
|
27560
|
+
return null;
|
|
27561
|
+
}
|
|
27562
|
+
}
|
|
27405
27563
|
var RECHECK_INITIAL_MS = 15e3;
|
|
27406
27564
|
var RECHECK_MAX_MS = 3e5;
|
|
27407
27565
|
var KEEP_RETRY_INITIAL_MS = 2e3;
|
|
@@ -27511,8 +27669,15 @@ var require_shuttle = __commonJS({
|
|
|
27511
27669
|
lifetime = deferred();
|
|
27512
27670
|
/** Aborted by `stop()`: ends the startup waits and the readiness re-checks. */
|
|
27513
27671
|
stopping = new AbortController();
|
|
27514
|
-
/**
|
|
27515
|
-
|
|
27672
|
+
/**
|
|
27673
|
+
* The executors that cannot run jobs on this machine just now (signed out,
|
|
27674
|
+
* missing, out of plan), with why and since when. Empty while every one can.
|
|
27675
|
+
*/
|
|
27676
|
+
unwell = /* @__PURE__ */ new Map();
|
|
27677
|
+
/** Every configured executor, in the configured order. */
|
|
27678
|
+
executors = [];
|
|
27679
|
+
/** Whether claiming is paused because no executor can run jobs. */
|
|
27680
|
+
environmentHeld = false;
|
|
27516
27681
|
constructor(options) {
|
|
27517
27682
|
this.brand = options.brand;
|
|
27518
27683
|
this.config = options.config;
|
|
@@ -27596,7 +27761,8 @@ var require_shuttle = __commonJS({
|
|
|
27596
27761
|
const registry = new registry_1.ExecutorRegistry(this.brand.executorAllowlist);
|
|
27597
27762
|
registerBuiltInExecutors(registry, this.brand.executorAllowlist);
|
|
27598
27763
|
const executors = registry.build(mergeExecutorDefaults((0, environment_1.executorDefaultsFor)(this.brand, this.config.auth.jobsApiUrl), this.config.executors));
|
|
27599
|
-
|
|
27764
|
+
this.executors = executors;
|
|
27765
|
+
const chooser = (0, executor_choice_1.createExecutorChooser)(executors, this.config.pools);
|
|
27600
27766
|
const modelsByExecutor = await listExecutorModels(executors, this.stopping.signal);
|
|
27601
27767
|
if (this.stopping.signal.aborted)
|
|
27602
27768
|
return;
|
|
@@ -27621,12 +27787,31 @@ var require_shuttle = __commonJS({
|
|
|
27621
27787
|
const attendanceId = dispatch.attendanceId;
|
|
27622
27788
|
const startedAt = Date.now();
|
|
27623
27789
|
const strategy = (0, loom_1.readShuttleStrategy)(dispatch.inputs) ?? "";
|
|
27624
|
-
const
|
|
27625
|
-
|
|
27626
|
-
|
|
27627
|
-
|
|
27628
|
-
|
|
27790
|
+
const close = async (result) => {
|
|
27791
|
+
await observerChain.notify({
|
|
27792
|
+
kind: "attendance.closed",
|
|
27793
|
+
jobId,
|
|
27794
|
+
attendanceId,
|
|
27795
|
+
status: result.status === "completed" ? "completed" : "failed",
|
|
27796
|
+
...result.reason !== void 0 ? { reason: result.reason } : {},
|
|
27797
|
+
totalDurationMs: Date.now() - startedAt
|
|
27798
|
+
}, onObserverError);
|
|
27799
|
+
return result;
|
|
27800
|
+
};
|
|
27801
|
+
const choice = chooser.choose({ pool: dispatch.pool, strategy, required: requiredExecutor(dispatch, strategy) });
|
|
27802
|
+
if (!choice.ok)
|
|
27803
|
+
return close({ status: "failed", reason: choice.reason });
|
|
27804
|
+
if (choice.required !== null) {
|
|
27805
|
+
const fault = this.unwell.get(choice.required);
|
|
27806
|
+
if (fault) {
|
|
27807
|
+
return close({
|
|
27808
|
+
status: "failed",
|
|
27809
|
+
reason: `executor failed: ${choice.required} cannot run jobs on this machine (${fault.err.message}). To fix it, ${fault.err.remedy}.`
|
|
27810
|
+
});
|
|
27811
|
+
}
|
|
27629
27812
|
}
|
|
27813
|
+
const well = choice.executors.filter((e) => !this.unwell.has(e.capability.id));
|
|
27814
|
+
const candidates = well.length > 0 ? well : choice.executors;
|
|
27630
27815
|
await observerChain.notify({
|
|
27631
27816
|
kind: "job.claimed",
|
|
27632
27817
|
jobId,
|
|
@@ -27637,9 +27822,9 @@ var require_shuttle = __commonJS({
|
|
|
27637
27822
|
dispatch
|
|
27638
27823
|
}, onObserverError);
|
|
27639
27824
|
let estimate = {};
|
|
27640
|
-
if (
|
|
27825
|
+
if (candidates[0].estimate) {
|
|
27641
27826
|
try {
|
|
27642
|
-
estimate = await
|
|
27827
|
+
estimate = await candidates[0].estimate(dispatch);
|
|
27643
27828
|
} catch {
|
|
27644
27829
|
}
|
|
27645
27830
|
}
|
|
@@ -27647,85 +27832,102 @@ var require_shuttle = __commonJS({
|
|
|
27647
27832
|
await observerChain.notify({ kind: "spend.preflight", jobId, attendanceId, estimate });
|
|
27648
27833
|
} catch (err) {
|
|
27649
27834
|
const reason = err instanceof chain_1.SpendCapExceeded ? "refused_over_cap" : `preflight rejected: ${err instanceof Error ? err.message : String(err)}`;
|
|
27650
|
-
|
|
27651
|
-
|
|
27652
|
-
|
|
27653
|
-
|
|
27654
|
-
|
|
27655
|
-
|
|
27656
|
-
|
|
27657
|
-
|
|
27835
|
+
return close({ status: "failed", reason });
|
|
27836
|
+
}
|
|
27837
|
+
const runOn = async (executor) => {
|
|
27838
|
+
await observerChain.notify({ kind: "executor.dispatch.started", jobId, attendanceId, executor: executor.capability.id, strategy }, onObserverError);
|
|
27839
|
+
const dispatchStartedAt = Date.now();
|
|
27840
|
+
const environment = executor.prepareEnvironment ? await executor.prepareEnvironment(dispatch) : void 0;
|
|
27841
|
+
let preparedWorkspace = null;
|
|
27842
|
+
if (environment?.workspaceRequest) {
|
|
27843
|
+
try {
|
|
27844
|
+
preparedWorkspace = await (0, workspace_1.materializeWorkspace)(environment.workspaceRequest, {
|
|
27845
|
+
...environment.materializeOptions ?? {},
|
|
27846
|
+
credentials: this.broker,
|
|
27847
|
+
signal
|
|
27848
|
+
});
|
|
27849
|
+
} catch (err) {
|
|
27850
|
+
(0, logger_1.getLogger)().warn("workspace materialization failed; running prompt-only", {
|
|
27851
|
+
jobId,
|
|
27852
|
+
error: err instanceof Error ? err.message : String(err)
|
|
27853
|
+
});
|
|
27854
|
+
preparedWorkspace = null;
|
|
27855
|
+
}
|
|
27856
|
+
}
|
|
27857
|
+
const executionCtx = {
|
|
27858
|
+
reportProgress: (channel, frames) => {
|
|
27859
|
+
void jobsClient.postProgress(jobId, { channel, frames }).then(() => activity.record()).catch(() => {
|
|
27860
|
+
});
|
|
27861
|
+
},
|
|
27862
|
+
workspace: preparedWorkspace,
|
|
27863
|
+
credentials: this.broker
|
|
27864
|
+
};
|
|
27865
|
+
let response;
|
|
27658
27866
|
try {
|
|
27659
|
-
|
|
27660
|
-
...environment.materializeOptions ?? {},
|
|
27661
|
-
credentials: this.broker,
|
|
27662
|
-
signal
|
|
27663
|
-
});
|
|
27867
|
+
response = await executor.execute(dispatch, signal, executionCtx);
|
|
27664
27868
|
} catch (err) {
|
|
27665
|
-
|
|
27666
|
-
|
|
27667
|
-
|
|
27668
|
-
|
|
27669
|
-
|
|
27869
|
+
const reason = `executor failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
27870
|
+
if (this.broker === null && (0, types_1.isExecutorEnvironmentError)(err)) {
|
|
27871
|
+
this.markUnwell(executor, err, subscribeLogger);
|
|
27872
|
+
return { kind: "environment", reason };
|
|
27873
|
+
}
|
|
27874
|
+
if ((0, types_1.isExecutorModelUnavailableError)(err)) {
|
|
27875
|
+
return { kind: "result", result: { status: "failed", reason, failureCode: types_1.MODEL_UNAVAILABLE } };
|
|
27876
|
+
}
|
|
27877
|
+
return { kind: "result", result: { status: "failed", reason } };
|
|
27878
|
+
} finally {
|
|
27879
|
+
if (preparedWorkspace)
|
|
27880
|
+
await preparedWorkspace.cleanup();
|
|
27670
27881
|
}
|
|
27671
|
-
|
|
27672
|
-
|
|
27673
|
-
|
|
27674
|
-
|
|
27882
|
+
const gated = await runOutputGates(dispatch, response, executor, signal, executionCtx);
|
|
27883
|
+
if (!gated.ok)
|
|
27884
|
+
return { kind: "result", result: { status: "failed", reason: gated.reason } };
|
|
27885
|
+
response = gated.response;
|
|
27886
|
+
await observerChain.notify({
|
|
27887
|
+
kind: "executor.dispatch.completed",
|
|
27888
|
+
jobId,
|
|
27889
|
+
attendanceId,
|
|
27890
|
+
executor: executor.capability.id,
|
|
27891
|
+
response: { rawText: response.rawText ?? "", parsed: response.parsed, usage: response.usage },
|
|
27892
|
+
durationMs: Date.now() - dispatchStartedAt
|
|
27893
|
+
}, onObserverError);
|
|
27894
|
+
const outputs = [...response.outputs];
|
|
27895
|
+
if (response.usage) {
|
|
27896
|
+
outputs.push({
|
|
27897
|
+
label: "usage",
|
|
27898
|
+
content: { ...response.usage, executor: executor.capability.id }
|
|
27675
27899
|
});
|
|
27676
|
-
},
|
|
27677
|
-
workspace: preparedWorkspace,
|
|
27678
|
-
credentials: this.broker
|
|
27679
|
-
};
|
|
27680
|
-
let response;
|
|
27681
|
-
try {
|
|
27682
|
-
response = await executor.execute(dispatch, signal, executionCtx);
|
|
27683
|
-
} catch (err) {
|
|
27684
|
-
const reason = `executor failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
27685
|
-
if (this.broker === null && (0, types_1.isExecutorEnvironmentError)(err)) {
|
|
27686
|
-
this.pauseForEnvironment(executor, err, subscribeLogger);
|
|
27687
27900
|
}
|
|
27688
|
-
|
|
27689
|
-
|
|
27690
|
-
|
|
27691
|
-
|
|
27692
|
-
|
|
27693
|
-
|
|
27694
|
-
|
|
27695
|
-
|
|
27696
|
-
|
|
27697
|
-
|
|
27698
|
-
|
|
27699
|
-
|
|
27700
|
-
|
|
27701
|
-
|
|
27702
|
-
|
|
27703
|
-
attendanceId,
|
|
27704
|
-
executor: executor.capability.id,
|
|
27705
|
-
response: { rawText: response.rawText ?? "", parsed: response.parsed, usage: response.usage },
|
|
27706
|
-
durationMs: Date.now() - dispatchStartedAt
|
|
27707
|
-
}, onObserverError);
|
|
27708
|
-
const outputs = [...response.outputs];
|
|
27709
|
-
if (response.usage) {
|
|
27710
|
-
outputs.push({
|
|
27711
|
-
label: "usage",
|
|
27712
|
-
content: { ...response.usage, executor: executor.capability.id }
|
|
27713
|
-
});
|
|
27714
|
-
}
|
|
27715
|
-
for (const output of outputs) {
|
|
27716
|
-
await observerChain.notify({ kind: "output.submitted", jobId, attendanceId, label: output.label, content: output.content }, onObserverError);
|
|
27717
|
-
}
|
|
27718
|
-
await observerChain.notify({ kind: "attendance.closed", jobId, attendanceId, status: "completed", totalDurationMs: Date.now() - startedAt }, onObserverError);
|
|
27719
|
-
return { status: "completed", outputs };
|
|
27901
|
+
for (const output of outputs) {
|
|
27902
|
+
await observerChain.notify({ kind: "output.submitted", jobId, attendanceId, label: output.label, content: output.content }, onObserverError);
|
|
27903
|
+
}
|
|
27904
|
+
return { kind: "result", result: { status: "completed", outputs } };
|
|
27905
|
+
};
|
|
27906
|
+
for (const [i, executor] of candidates.entries()) {
|
|
27907
|
+
const outcome = await runOn(executor);
|
|
27908
|
+
if (outcome.kind === "result")
|
|
27909
|
+
return close(outcome.result);
|
|
27910
|
+
const next = candidates[i + 1];
|
|
27911
|
+
if (!next)
|
|
27912
|
+
return close({ status: "failed", reason: outcome.reason });
|
|
27913
|
+
subscribeLogger.info(`${executor.capability.id} cannot run jobs on this machine, so job ${jobId} runs on ${next.capability.id} instead.`);
|
|
27914
|
+
}
|
|
27915
|
+
return close({ status: "failed", reason: `no executor for shuttle strategy "${strategy}"` });
|
|
27720
27916
|
};
|
|
27721
27917
|
const pools = this.config.pools.map((p) => p.id ? { id: p.id } : { name: p.name });
|
|
27722
|
-
const poolExecutors = new Map(pools.map((ref, i) => [ref, this.config.pools[i].executor]));
|
|
27723
27918
|
const poolMetadata = (ref) => {
|
|
27724
|
-
const
|
|
27725
|
-
|
|
27726
|
-
|
|
27919
|
+
const reported = chooser.orderFor(ref).map((e) => {
|
|
27920
|
+
const models = modelsByExecutor.get(e.capability.id) ?? [];
|
|
27921
|
+
return { id: e.capability.id, ...models.length > 0 ? { models } : {} };
|
|
27922
|
+
});
|
|
27923
|
+
const [first] = reported;
|
|
27924
|
+
if (!first)
|
|
27727
27925
|
return void 0;
|
|
27728
|
-
return {
|
|
27926
|
+
return {
|
|
27927
|
+
executors: reported,
|
|
27928
|
+
executor: first.id,
|
|
27929
|
+
...first.models ? { models: first.models } : {}
|
|
27930
|
+
};
|
|
27729
27931
|
};
|
|
27730
27932
|
const attemptedUpgrades = /* @__PURE__ */ new Set();
|
|
27731
27933
|
this.subscription = (0, jobs_1.subscribe)({
|
|
@@ -27747,6 +27949,9 @@ var require_shuttle = __commonJS({
|
|
|
27747
27949
|
poolMetadata
|
|
27748
27950
|
},
|
|
27749
27951
|
onJob,
|
|
27952
|
+
// Decline, at discovery, a job that requires an executor this runner
|
|
27953
|
+
// does not have; it stays queued for a member that has it (ADR 0118).
|
|
27954
|
+
accepts: (job) => chooser.accepts(job.tags),
|
|
27750
27955
|
onDirectives: async (directives) => {
|
|
27751
27956
|
const decommission = (0, decommission_1.readDecommissionDirective)(directives);
|
|
27752
27957
|
if (decommission) {
|
|
@@ -27831,20 +28036,31 @@ var require_shuttle = __commonJS({
|
|
|
27831
28036
|
this.subscription?.done().catch((err) => this.lifetime.reject(err));
|
|
27832
28037
|
}
|
|
27833
28038
|
/**
|
|
27834
|
-
*
|
|
27835
|
-
*
|
|
27836
|
-
*
|
|
27837
|
-
* a
|
|
28039
|
+
* Note that an executor cannot run jobs on this machine, and keep checking
|
|
28040
|
+
* until it can. While another executor can, jobs that do not require this
|
|
28041
|
+
* one run there; once none can, claiming pauses, so a signed-out laptop does
|
|
28042
|
+
* not burn a queue of reviews one failure at a time. One warning says why
|
|
28043
|
+
* and what to do; the re-checks stay at debug; one line says when it works
|
|
28044
|
+
* again. Idempotent: a second failing job on the same executor changes
|
|
28045
|
+
* nothing.
|
|
27838
28046
|
*/
|
|
27839
|
-
|
|
27840
|
-
|
|
28047
|
+
markUnwell(executor, err, logger) {
|
|
28048
|
+
const id = executor.capability.id;
|
|
28049
|
+
if (this.unwell.has(id) || !this.subscription)
|
|
27841
28050
|
return;
|
|
27842
|
-
this.
|
|
27843
|
-
this.
|
|
27844
|
-
|
|
28051
|
+
this.unwell.set(id, { since: Date.now(), err });
|
|
28052
|
+
const others = this.executors.filter((e) => !this.unwell.has(e.capability.id)).map((e) => e.capability.id);
|
|
28053
|
+
if (others.length === 0) {
|
|
28054
|
+
this.environmentHeld = true;
|
|
28055
|
+
this.subscription.pause(ENVIRONMENT_HOLD);
|
|
28056
|
+
logger.warn(`Claiming paused: ${id} cannot run jobs on this machine (${err.message}). To fix it, ${err.remedy}. The ${this.brand.product.title} checks again on its own and resumes claiming when it works.`);
|
|
28057
|
+
} else {
|
|
28058
|
+
logger.warn(`${id} cannot run jobs on this machine (${err.message}). To fix it, ${err.remedy}. Until then, jobs that do not require ${id} run on ${others.join(", ")}; the ${this.brand.product.title} checks ${id} again on its own.`);
|
|
28059
|
+
}
|
|
27845
28060
|
void this.recheckEnvironment(executor, logger);
|
|
27846
28061
|
}
|
|
27847
28062
|
async recheckEnvironment(executor, logger) {
|
|
28063
|
+
const id = executor.capability.id;
|
|
27848
28064
|
const signal = this.stopping.signal;
|
|
27849
28065
|
let delay = this.environmentRecheck.initialMs;
|
|
27850
28066
|
for (; ; ) {
|
|
@@ -27860,15 +28076,21 @@ var require_shuttle = __commonJS({
|
|
|
27860
28076
|
if (signal.aborted)
|
|
27861
28077
|
return;
|
|
27862
28078
|
if (readiness.ready) {
|
|
27863
|
-
const
|
|
27864
|
-
this.
|
|
27865
|
-
|
|
27866
|
-
|
|
28079
|
+
const since = this.unwell.get(id)?.since ?? Date.now();
|
|
28080
|
+
this.unwell.delete(id);
|
|
28081
|
+
const lasted = formatDuration(Date.now() - since);
|
|
28082
|
+
if (this.environmentHeld) {
|
|
28083
|
+
this.environmentHeld = false;
|
|
28084
|
+
this.subscription?.resume(ENVIRONMENT_HOLD);
|
|
28085
|
+
logger.info(`${id} can run jobs again; claiming resumed after ${lasted} paused.`);
|
|
28086
|
+
} else {
|
|
28087
|
+
logger.info(`${id} can run jobs again after ${lasted}.`);
|
|
28088
|
+
}
|
|
27867
28089
|
return;
|
|
27868
28090
|
}
|
|
27869
28091
|
delay = Math.min(delay * 2, this.environmentRecheck.maxMs);
|
|
27870
28092
|
logger.debug?.("executor still cannot run jobs", {
|
|
27871
|
-
executor:
|
|
28093
|
+
executor: id,
|
|
27872
28094
|
reason: readiness.reason,
|
|
27873
28095
|
nextCheckIn: formatDuration(delay)
|
|
27874
28096
|
});
|
|
@@ -28356,6 +28578,212 @@ var require_revoke = __commonJS({
|
|
|
28356
28578
|
}
|
|
28357
28579
|
});
|
|
28358
28580
|
|
|
28581
|
+
// ../../packages/shuttle/dist/config/executor-order.js
|
|
28582
|
+
var require_executor_order = __commonJS({
|
|
28583
|
+
"../../packages/shuttle/dist/config/executor-order.js"(exports2) {
|
|
28584
|
+
"use strict";
|
|
28585
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
28586
|
+
exports2.executorOrder = executorOrder;
|
|
28587
|
+
exports2.foldPoolExecutors = foldPoolExecutors;
|
|
28588
|
+
exports2.addExecutor = addExecutor;
|
|
28589
|
+
exports2.removeExecutor = removeExecutor;
|
|
28590
|
+
var yaml_1 = require_dist3();
|
|
28591
|
+
function executorOrder(doc) {
|
|
28592
|
+
const map = doc.get("executors", true);
|
|
28593
|
+
if (!(0, yaml_1.isMap)(map))
|
|
28594
|
+
return [];
|
|
28595
|
+
return map.items.flatMap((pair) => (0, yaml_1.isScalar)(pair.key) ? [String(pair.key.value)] : []);
|
|
28596
|
+
}
|
|
28597
|
+
function executorsMap(doc) {
|
|
28598
|
+
const existing = doc.get("executors", true);
|
|
28599
|
+
if ((0, yaml_1.isMap)(existing))
|
|
28600
|
+
return existing;
|
|
28601
|
+
const created = doc.createNode({});
|
|
28602
|
+
doc.set("executors", created);
|
|
28603
|
+
return created;
|
|
28604
|
+
}
|
|
28605
|
+
function indexOf(map, id) {
|
|
28606
|
+
return map.items.findIndex((pair) => (0, yaml_1.isScalar)(pair.key) && pair.key.value === id);
|
|
28607
|
+
}
|
|
28608
|
+
function foldPoolExecutors(doc) {
|
|
28609
|
+
const pools = doc.get("pools", true);
|
|
28610
|
+
if (!(0, yaml_1.isSeq)(pools))
|
|
28611
|
+
return null;
|
|
28612
|
+
let named = null;
|
|
28613
|
+
for (const pool of pools.items) {
|
|
28614
|
+
if (!(0, yaml_1.isMap)(pool))
|
|
28615
|
+
continue;
|
|
28616
|
+
const value = pool.get("executor");
|
|
28617
|
+
if (typeof value === "string" && named === null)
|
|
28618
|
+
named = value;
|
|
28619
|
+
pool.delete("executor");
|
|
28620
|
+
}
|
|
28621
|
+
if (named === null)
|
|
28622
|
+
return null;
|
|
28623
|
+
const map = executorsMap(doc);
|
|
28624
|
+
const at = indexOf(map, named);
|
|
28625
|
+
if (at > 0) {
|
|
28626
|
+
const [pair] = map.items.splice(at, 1);
|
|
28627
|
+
map.items.unshift(pair);
|
|
28628
|
+
}
|
|
28629
|
+
return named;
|
|
28630
|
+
}
|
|
28631
|
+
function addExecutor(doc, id, block, options = {}) {
|
|
28632
|
+
const map = executorsMap(doc);
|
|
28633
|
+
const at = indexOf(map, id);
|
|
28634
|
+
if (at >= 0) {
|
|
28635
|
+
if (!options.first || at === 0)
|
|
28636
|
+
return "unchanged";
|
|
28637
|
+
const [pair2] = map.items.splice(at, 1);
|
|
28638
|
+
map.items.unshift(pair2);
|
|
28639
|
+
return "moved";
|
|
28640
|
+
}
|
|
28641
|
+
const pair = doc.createPair(id, block);
|
|
28642
|
+
if (options.first)
|
|
28643
|
+
map.items.unshift(pair);
|
|
28644
|
+
else
|
|
28645
|
+
map.items.push(pair);
|
|
28646
|
+
return "added";
|
|
28647
|
+
}
|
|
28648
|
+
function removeExecutor(doc, id) {
|
|
28649
|
+
const map = executorsMap(doc);
|
|
28650
|
+
const at = indexOf(map, id);
|
|
28651
|
+
if (at < 0)
|
|
28652
|
+
return "absent";
|
|
28653
|
+
if (map.items.length === 1)
|
|
28654
|
+
return "last";
|
|
28655
|
+
map.items.splice(at, 1);
|
|
28656
|
+
return "removed";
|
|
28657
|
+
}
|
|
28658
|
+
}
|
|
28659
|
+
});
|
|
28660
|
+
|
|
28661
|
+
// ../../packages/shuttle/dist/cli/executors.js
|
|
28662
|
+
var require_executors = __commonJS({
|
|
28663
|
+
"../../packages/shuttle/dist/cli/executors.js"(exports2) {
|
|
28664
|
+
"use strict";
|
|
28665
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
28666
|
+
exports2.buildAddCommand = buildAddCommand;
|
|
28667
|
+
exports2.buildRemoveCommand = buildRemoveCommand;
|
|
28668
|
+
var fs_1 = require("fs");
|
|
28669
|
+
var commander_1 = require_commander();
|
|
28670
|
+
var yaml_1 = require_dist3();
|
|
28671
|
+
var apply_1 = require_apply();
|
|
28672
|
+
var loader_1 = require_loader();
|
|
28673
|
+
var executor_order_1 = require_executor_order();
|
|
28674
|
+
var preflight_1 = require_preflight();
|
|
28675
|
+
function target(brand, options) {
|
|
28676
|
+
const profile = (0, apply_1.resolveProfile)(brand, options.profile);
|
|
28677
|
+
try {
|
|
28678
|
+
const path = (0, loader_1.resolveConfigPath)({
|
|
28679
|
+
explicitPath: options.config,
|
|
28680
|
+
searchPaths: (0, apply_1.runConfigSearchPaths)(brand, profile),
|
|
28681
|
+
productId: brand.product.id
|
|
28682
|
+
});
|
|
28683
|
+
return { path, profile };
|
|
28684
|
+
} catch (err) {
|
|
28685
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
28686
|
+
console.error(`Run \`${brand.product.cliBinary} init\` first: it writes the config this edits.`);
|
|
28687
|
+
process.exit(1);
|
|
28688
|
+
}
|
|
28689
|
+
}
|
|
28690
|
+
function allowed(brand, id) {
|
|
28691
|
+
return brand.executorAllowlist[0] === "*" || brand.executorAllowlist.includes(id);
|
|
28692
|
+
}
|
|
28693
|
+
function orderLine(order) {
|
|
28694
|
+
return order.length === 1 ? `Every job runs on ${order[0]}.` : `A job that names no executor tries them in this order: ${order.join(", ")}. A job that names one runs on that one or fails.`;
|
|
28695
|
+
}
|
|
28696
|
+
function foldedLine(folded) {
|
|
28697
|
+
return folded === null ? [] : [`Your pools named ${folded} as their executor, a setting from before 0.34; it is first in the order instead now.`];
|
|
28698
|
+
}
|
|
28699
|
+
async function newFailures(brand, t, write, restore) {
|
|
28700
|
+
const paths = (0, apply_1.resolvePaths)(brand, t.profile);
|
|
28701
|
+
const run = () => (0, preflight_1.runPreflight)((0, preflight_1.createProbes)({
|
|
28702
|
+
brand,
|
|
28703
|
+
paths,
|
|
28704
|
+
configSearchPaths: (0, apply_1.runConfigSearchPaths)(brand, t.profile),
|
|
28705
|
+
explicitConfigPath: t.path
|
|
28706
|
+
}), { brand, paths, phase: "doctor", deep: false });
|
|
28707
|
+
const before = await run();
|
|
28708
|
+
write();
|
|
28709
|
+
try {
|
|
28710
|
+
const after = await run();
|
|
28711
|
+
const failedBefore = new Set(before.verdicts.filter((v) => v.status === "FAIL").map((v) => v.name));
|
|
28712
|
+
return after.verdicts.filter((v) => v.status === "FAIL" && !failedBefore.has(v.name));
|
|
28713
|
+
} catch (err) {
|
|
28714
|
+
restore();
|
|
28715
|
+
throw err;
|
|
28716
|
+
}
|
|
28717
|
+
}
|
|
28718
|
+
function buildAddCommand(brand) {
|
|
28719
|
+
const add = new commander_1.Command("add").description(`Add to this ${brand.product.title}'s setup`);
|
|
28720
|
+
add.command("executor <id>").description(`Add an executor this ${brand.product.title} may run jobs on`).option("--first", "Put it first in the order, so a job that names no executor tries it first").option("--tmp-dir <dir>", "Base directory for each job's throwaway checkout (agent executors)").option("--config <path>", "Path to the runtime YAML to edit").option("-p, --profile <name>", 'Config profile to edit (default "default")').action(async (id, options) => {
|
|
28721
|
+
if (!allowed(brand, id)) {
|
|
28722
|
+
console.error(`${id} is not an executor this build runs. It runs: ${brand.executorAllowlist.join(", ")}.`);
|
|
28723
|
+
process.exit(1);
|
|
28724
|
+
}
|
|
28725
|
+
const t = target(brand, options);
|
|
28726
|
+
const original = (0, fs_1.readFileSync)(t.path, "utf8");
|
|
28727
|
+
const doc = (0, yaml_1.parseDocument)(original);
|
|
28728
|
+
const folded = (0, executor_order_1.foldPoolExecutors)(doc);
|
|
28729
|
+
const block = brand.executorBlock?.(id, { ...options.tmpDir ? { tmpDir: options.tmpDir } : {} }) ?? { type: id };
|
|
28730
|
+
const outcome = (0, executor_order_1.addExecutor)(doc, id, block, { first: options.first === true });
|
|
28731
|
+
if (outcome === "unchanged" && folded === null) {
|
|
28732
|
+
console.log(`${id} is already set up. ${orderLine((0, executor_order_1.executorOrder)(doc))}`);
|
|
28733
|
+
return;
|
|
28734
|
+
}
|
|
28735
|
+
const write = () => (0, fs_1.writeFileSync)(t.path, doc.toString());
|
|
28736
|
+
const restore = () => (0, fs_1.writeFileSync)(t.path, original);
|
|
28737
|
+
if (outcome === "added") {
|
|
28738
|
+
const failures = await newFailures(brand, t, write, restore);
|
|
28739
|
+
if (failures.length > 0) {
|
|
28740
|
+
restore();
|
|
28741
|
+
(0, preflight_1.printReport)(failures, false);
|
|
28742
|
+
console.error("");
|
|
28743
|
+
console.error(`${id} was not added: it could not run jobs on this machine. Fix what is above, then run this again.`);
|
|
28744
|
+
process.exit(preflight_1.PREFLIGHT_EXIT_CODE);
|
|
28745
|
+
}
|
|
28746
|
+
} else {
|
|
28747
|
+
write();
|
|
28748
|
+
}
|
|
28749
|
+
const verb = outcome === "added" ? "Added" : outcome === "moved" ? "Moved" : "Kept";
|
|
28750
|
+
console.log(`${verb} ${id}${outcome === "moved" ? " to the front" : ""} in ${t.path}.`);
|
|
28751
|
+
for (const line of foldedLine(folded))
|
|
28752
|
+
console.log(line);
|
|
28753
|
+
console.log(orderLine((0, executor_order_1.executorOrder)(doc)));
|
|
28754
|
+
console.log(`Restart \`${brand.product.cliBinary} run\` for it to take effect.`);
|
|
28755
|
+
});
|
|
28756
|
+
return add;
|
|
28757
|
+
}
|
|
28758
|
+
function buildRemoveCommand(brand) {
|
|
28759
|
+
const remove = new commander_1.Command("remove").description(`Remove from this ${brand.product.title}'s setup`);
|
|
28760
|
+
remove.command("executor <id>").description(`Stop this ${brand.product.title} running jobs on an executor`).option("--config <path>", "Path to the runtime YAML to edit").option("-p, --profile <name>", 'Config profile to edit (default "default")').action((id, options) => {
|
|
28761
|
+
const t = target(brand, options);
|
|
28762
|
+
const doc = (0, yaml_1.parseDocument)((0, fs_1.readFileSync)(t.path, "utf8"));
|
|
28763
|
+
const folded = (0, executor_order_1.foldPoolExecutors)(doc);
|
|
28764
|
+
const outcome = (0, executor_order_1.removeExecutor)(doc, id);
|
|
28765
|
+
if (outcome === "last") {
|
|
28766
|
+
console.error(`${id} is the only executor set up, so it stays: with none, nothing could run.`);
|
|
28767
|
+
console.error(`Add another first with \`${brand.product.cliBinary} add executor <id>\`.`);
|
|
28768
|
+
process.exit(1);
|
|
28769
|
+
}
|
|
28770
|
+
if (outcome === "absent" && folded === null) {
|
|
28771
|
+
console.log(`${id} is not set up. ${orderLine((0, executor_order_1.executorOrder)(doc))}`);
|
|
28772
|
+
return;
|
|
28773
|
+
}
|
|
28774
|
+
(0, fs_1.writeFileSync)(t.path, doc.toString());
|
|
28775
|
+
if (outcome === "removed")
|
|
28776
|
+
console.log(`Removed ${id} from ${t.path}.`);
|
|
28777
|
+
for (const line of foldedLine(folded))
|
|
28778
|
+
console.log(line);
|
|
28779
|
+
console.log(orderLine((0, executor_order_1.executorOrder)(doc)));
|
|
28780
|
+
console.log(`Restart \`${brand.product.cliBinary} run\` for it to take effect.`);
|
|
28781
|
+
});
|
|
28782
|
+
return remove;
|
|
28783
|
+
}
|
|
28784
|
+
}
|
|
28785
|
+
});
|
|
28786
|
+
|
|
28359
28787
|
// ../../packages/shuttle/dist/cli.js
|
|
28360
28788
|
var require_cli = __commonJS({
|
|
28361
28789
|
"../../packages/shuttle/dist/cli.js"(exports2) {
|
|
@@ -28371,6 +28799,7 @@ var require_cli = __commonJS({
|
|
|
28371
28799
|
var caps_1 = require_caps();
|
|
28372
28800
|
var list_1 = require_list();
|
|
28373
28801
|
var revoke_1 = require_revoke();
|
|
28802
|
+
var executors_1 = require_executors();
|
|
28374
28803
|
function createCli2(brand) {
|
|
28375
28804
|
const program = new commander_1.Command();
|
|
28376
28805
|
program.name(brand.product.cliBinary).description(brand.product.description).version(brand.product.version);
|
|
@@ -28382,6 +28811,8 @@ var require_cli = __commonJS({
|
|
|
28382
28811
|
program.addCommand((0, caps_1.buildCapsCommand)(brand));
|
|
28383
28812
|
program.addCommand((0, list_1.buildListCommand)(brand));
|
|
28384
28813
|
program.addCommand((0, revoke_1.buildRevokeCommand)(brand));
|
|
28814
|
+
program.addCommand((0, executors_1.buildAddCommand)(brand));
|
|
28815
|
+
program.addCommand((0, executors_1.buildRemoveCommand)(brand));
|
|
28385
28816
|
return program;
|
|
28386
28817
|
}
|
|
28387
28818
|
}
|
|
@@ -28392,8 +28823,8 @@ var require_dist5 = __commonJS({
|
|
|
28392
28823
|
"../../packages/shuttle/dist/index.js"(exports2) {
|
|
28393
28824
|
"use strict";
|
|
28394
28825
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
28395
|
-
exports2.
|
|
28396
|
-
exports2.revokePairing = exports2.listPairings = exports2.PairingConfigStore = exports2.pair = exports2.scaffoldedConfigPath = exports2.planScaffold = exports2.DEFAULT_REFUSAL_MESSAGE = exports2.DEFAULT_MONTHLY_PERIOD = void 0;
|
|
28826
|
+
exports2.verificationJson = exports2.resolveEnvironment = exports2.renderVerificationLine = exports2.renderEnvironmentReport = exports2.isWorthReporting = exports2.hostOf = exports2.executorDefaultsFor = exports2.environmentReportJson = exports2.environmentPolledBy = exports2.applyEnvironment = exports2.renderTemplate = exports2.expandHome = exports2.resolvePaths = exports2.SpendStore = exports2.AuditLogStore = exports2.createSpendTrackerObserver = exports2.createAuditLogObserver = exports2.createLoggerObserver = exports2.SpendCapExceeded = exports2.ObserverChain = exports2.createCustomScriptExecutor = exports2.createWebhookExecutor = exports2.createHttpApiExecutor = exports2.createCopilotExecutor = exports2.createCodexExecutor = exports2.createClaudeCodeExecutor = exports2.MODEL_UNAVAILABLE = exports2.ExecutorModelUnavailableError = exports2.ExecutorEnvironmentError = exports2.ExecutorRegistry = exports2.AgentCredentialRevokedError = exports2.runPreflight = exports2.renderLines = exports2.renderJson = exports2.printReport = exports2.hasFailure = exports2.createProbes = exports2.checksFor = exports2.PREFLIGHT_FLOORS = exports2.PREFLIGHT_EXIT_CODE = exports2.CHECKS = exports2.readResponseLatestVersion = exports2.checkResponseMinVersion = exports2.compareSemver = exports2.UpgradeRequiredError = exports2.LATEST_VERSION_HEADER = exports2.MIN_VERSION_HEADER = exports2.loadConfig = exports2.Shuttle = exports2.createCli = void 0;
|
|
28827
|
+
exports2.revokePairing = exports2.listPairings = exports2.PairingConfigStore = exports2.pair = exports2.scaffoldedConfigPath = exports2.planScaffold = exports2.DEFAULT_REFUSAL_MESSAGE = exports2.DEFAULT_MONTHLY_PERIOD = exports2.DEFAULT_DAILY_PERIOD = exports2.SUBSTRATE_BRAND = void 0;
|
|
28397
28828
|
var cli_1 = require_cli();
|
|
28398
28829
|
Object.defineProperty(exports2, "createCli", { enumerable: true, get: function() {
|
|
28399
28830
|
return cli_1.createCli;
|
|
@@ -28468,6 +28899,12 @@ var require_dist5 = __commonJS({
|
|
|
28468
28899
|
Object.defineProperty(exports2, "ExecutorEnvironmentError", { enumerable: true, get: function() {
|
|
28469
28900
|
return types_1.ExecutorEnvironmentError;
|
|
28470
28901
|
} });
|
|
28902
|
+
Object.defineProperty(exports2, "ExecutorModelUnavailableError", { enumerable: true, get: function() {
|
|
28903
|
+
return types_1.ExecutorModelUnavailableError;
|
|
28904
|
+
} });
|
|
28905
|
+
Object.defineProperty(exports2, "MODEL_UNAVAILABLE", { enumerable: true, get: function() {
|
|
28906
|
+
return types_1.MODEL_UNAVAILABLE;
|
|
28907
|
+
} });
|
|
28471
28908
|
var claude_code_1 = require_claude_code();
|
|
28472
28909
|
Object.defineProperty(exports2, "createClaudeCodeExecutor", { enumerable: true, get: function() {
|
|
28473
28910
|
return claude_code_1.createClaudeCodeExecutor;
|
|
@@ -28606,7 +29043,7 @@ var import_path = require("path");
|
|
|
28606
29043
|
var import_promises = require("fs/promises");
|
|
28607
29044
|
var import_yaml = __toESM(require_dist3());
|
|
28608
29045
|
var import_shuttle = __toESM(require_dist5());
|
|
28609
|
-
var buildVersion = true ? "0.
|
|
29046
|
+
var buildVersion = true ? "0.34.0" : pkg.version;
|
|
28610
29047
|
var AGENT_EXECUTORS = ["claude-code", "codex", "copilot"];
|
|
28611
29048
|
var sifterBrand = {
|
|
28612
29049
|
product: {
|
|
@@ -28635,6 +29072,8 @@ var sifterBrand = {
|
|
|
28635
29072
|
// sifter.yaml names one. The init pre-flight reads it too, to check git and
|
|
28636
29073
|
// claude before the pairing code is spent.
|
|
28637
29074
|
defaultExecutor: "claude-code",
|
|
29075
|
+
// The block a fresh executor gets, from `init` and from `add executor`.
|
|
29076
|
+
executorBlock: buildExecutorBlock,
|
|
28638
29077
|
// Floors the pre-flight enforces on the binaries the claude-code executor
|
|
28639
29078
|
// spawns. Both are deliberately conservative — below the floor FAILS, so a
|
|
28640
29079
|
// number chosen for tidiness rather than necessity would refuse a working
|
|
@@ -28778,7 +29217,8 @@ var sifterBrand = {
|
|
|
28778
29217
|
const executorBlock = plan.keptBlock !== void 0 ? {
|
|
28779
29218
|
...plan.keptBlock,
|
|
28780
29219
|
...AGENT_EXECUTORS.includes(executor) && ctx.setupOptions.tmpDir ? { tmpDir: ctx.setupOptions.tmpDir } : {}
|
|
28781
|
-
} :
|
|
29220
|
+
} : buildExecutorBlock(executor, { ...ctx.setupOptions.tmpDir ? { tmpDir: ctx.setupOptions.tmpDir } : {} });
|
|
29221
|
+
const { [executor]: _replaced, ...otherExecutors } = existingExecutors;
|
|
28782
29222
|
const doc = {
|
|
28783
29223
|
auth: {
|
|
28784
29224
|
jobsApiUrl: pairing.jobsApiUrl
|
|
@@ -28789,12 +29229,11 @@ var sifterBrand = {
|
|
|
28789
29229
|
},
|
|
28790
29230
|
pools: pairing.jobPools.map((p) => ({
|
|
28791
29231
|
id: p.id,
|
|
28792
|
-
name: p.name
|
|
28793
|
-
executor
|
|
29232
|
+
name: p.name
|
|
28794
29233
|
})),
|
|
28795
29234
|
executors: {
|
|
28796
|
-
|
|
28797
|
-
|
|
29235
|
+
[executor]: executorBlock,
|
|
29236
|
+
...otherExecutors
|
|
28798
29237
|
}
|
|
28799
29238
|
};
|
|
28800
29239
|
const pollIntervalMs = ctx.setupOptions.pollIntervalMs ?? existing.polling?.intervalMs;
|
|
@@ -28813,14 +29252,14 @@ var sifterBrand = {
|
|
|
28813
29252
|
function overlayOrigin(origin) {
|
|
28814
29253
|
return Object.fromEntries(AGENT_EXECUTORS.map((e) => [e, { overlayAllowedHosts: [origin] }]));
|
|
28815
29254
|
}
|
|
28816
|
-
|
|
29255
|
+
function buildExecutorBlock(executor, options) {
|
|
28817
29256
|
switch (executor) {
|
|
28818
29257
|
case "claude-code":
|
|
28819
29258
|
case "codex":
|
|
28820
29259
|
case "copilot": {
|
|
28821
29260
|
return {
|
|
28822
29261
|
type: executor,
|
|
28823
|
-
...
|
|
29262
|
+
...options.tmpDir ? { tmpDir: options.tmpDir } : {}
|
|
28824
29263
|
};
|
|
28825
29264
|
}
|
|
28826
29265
|
case "anthropic-api": {
|