@whittlelabs/sifter 0.31.0 → 0.32.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 +263 -35
- package/bin.js.map +4 -4
- package/package.json +1 -1
package/bin.js
CHANGED
|
@@ -10263,6 +10263,54 @@ var require_json_answer = __commonJS({
|
|
|
10263
10263
|
}
|
|
10264
10264
|
});
|
|
10265
10265
|
|
|
10266
|
+
// ../../packages/shuttle/dist/executors/models.js
|
|
10267
|
+
var require_models = __commonJS({
|
|
10268
|
+
"../../packages/shuttle/dist/executors/models.js"(exports2) {
|
|
10269
|
+
"use strict";
|
|
10270
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
10271
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
10272
|
+
};
|
|
10273
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
10274
|
+
exports2.LIST_MODELS_TIMEOUT_MS = exports2.CLAUDE_CODE_EFFORTS = exports2.REASONING_EFFORTS = void 0;
|
|
10275
|
+
exports2.parseReasoningEffort = parseReasoningEffort;
|
|
10276
|
+
exports2.hintedEffort = hintedEffort;
|
|
10277
|
+
exports2.runListing = runListing;
|
|
10278
|
+
var os_1 = __importDefault(require("os"));
|
|
10279
|
+
var agent_process_1 = require_agent_process();
|
|
10280
|
+
exports2.REASONING_EFFORTS = ["none", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
10281
|
+
exports2.CLAUDE_CODE_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
|
|
10282
|
+
function parseReasoningEffort(value, levels) {
|
|
10283
|
+
if (value === void 0)
|
|
10284
|
+
return void 0;
|
|
10285
|
+
if (!levels.includes(value)) {
|
|
10286
|
+
throw new Error(`"reasoningEffort" must be one of ${levels.join(", ")}`);
|
|
10287
|
+
}
|
|
10288
|
+
return value;
|
|
10289
|
+
}
|
|
10290
|
+
function hintedEffort(hints) {
|
|
10291
|
+
const effort = hints.effort;
|
|
10292
|
+
return typeof effort === "string" && /^[a-z]+$/.test(effort) ? effort : void 0;
|
|
10293
|
+
}
|
|
10294
|
+
exports2.LIST_MODELS_TIMEOUT_MS = 15e3;
|
|
10295
|
+
async function runListing(bin, args, signal, env) {
|
|
10296
|
+
try {
|
|
10297
|
+
const run = await (0, agent_process_1.runAgentProcess)({
|
|
10298
|
+
bin,
|
|
10299
|
+
args,
|
|
10300
|
+
cwd: os_1.default.tmpdir(),
|
|
10301
|
+
...env ? { env } : {},
|
|
10302
|
+
idleTimeoutMs: exports2.LIST_MODELS_TIMEOUT_MS,
|
|
10303
|
+
toolName: bin,
|
|
10304
|
+
signal
|
|
10305
|
+
});
|
|
10306
|
+
return run.spawnError || run.code !== 0 ? null : run.stdout;
|
|
10307
|
+
} catch {
|
|
10308
|
+
return null;
|
|
10309
|
+
}
|
|
10310
|
+
}
|
|
10311
|
+
}
|
|
10312
|
+
});
|
|
10313
|
+
|
|
10266
10314
|
// ../../packages/shuttle/dist/executors/workspace-telemetry.js
|
|
10267
10315
|
var require_workspace_telemetry = __commonJS({
|
|
10268
10316
|
"../../packages/shuttle/dist/executors/workspace-telemetry.js"(exports2) {
|
|
@@ -10499,6 +10547,7 @@ var require_claude_code = __commonJS({
|
|
|
10499
10547
|
var progress_1 = require_progress();
|
|
10500
10548
|
var agent_process_1 = require_agent_process();
|
|
10501
10549
|
var json_answer_1 = require_json_answer();
|
|
10550
|
+
var models_1 = require_models();
|
|
10502
10551
|
var workspace_telemetry_1 = require_workspace_telemetry();
|
|
10503
10552
|
var apply_1 = require_apply();
|
|
10504
10553
|
var DEFAULT_TIMEOUT = 6e5;
|
|
@@ -10544,6 +10593,12 @@ var require_claude_code = __commonJS({
|
|
|
10544
10593
|
const subtype = meta.subtype && meta.subtype !== "success" ? `: ${meta.subtype}` : "";
|
|
10545
10594
|
return `${fallback}${subtype}${status}`;
|
|
10546
10595
|
}
|
|
10596
|
+
var CLAUDE_CODE_MODELS = [
|
|
10597
|
+
{ id: "opus", label: "Claude Opus (latest)", efforts: [...models_1.CLAUDE_CODE_EFFORTS] },
|
|
10598
|
+
{ id: "fable", label: "Claude Fable (latest)", efforts: [...models_1.CLAUDE_CODE_EFFORTS] },
|
|
10599
|
+
{ id: "sonnet", label: "Claude Sonnet (latest)", efforts: [...models_1.CLAUDE_CODE_EFFORTS] },
|
|
10600
|
+
{ id: "haiku", label: "Claude Haiku (latest)", efforts: [...models_1.CLAUDE_CODE_EFFORTS] }
|
|
10601
|
+
];
|
|
10547
10602
|
var READINESS_PROMPT = "Reply with the single word: ok";
|
|
10548
10603
|
var READINESS_TIMEOUT_MS = 12e4;
|
|
10549
10604
|
var INSTALL_REMEDY = "install Claude Code (npm install -g @anthropic-ai/claude-code) where this process can find it on PATH";
|
|
@@ -10624,6 +10679,7 @@ var require_claude_code = __commonJS({
|
|
|
10624
10679
|
const childEnv = buildChildEnv(modelKey, configDir);
|
|
10625
10680
|
const claudeHints = (0, loom_1.pickProviderHints)(spec, "claude-code");
|
|
10626
10681
|
const hintedModel = typeof claudeHints.model === "string" && claudeHints.model.length > 0 ? claudeHints.model : void 0;
|
|
10682
|
+
const effort = (0, models_1.hintedEffort)(claudeHints);
|
|
10627
10683
|
if (!workspace) {
|
|
10628
10684
|
promptOnlyScratch = await fs_1.promises.mkdtemp(path_1.default.join(tmpBase, "shuttle-cc-run-"));
|
|
10629
10685
|
}
|
|
@@ -10641,7 +10697,8 @@ var require_claude_code = __commonJS({
|
|
|
10641
10697
|
// Local mode is the operator's own login: a failure of THAT is the
|
|
10642
10698
|
// machine's, and the runner pauses on it. With a revealed key it is one
|
|
10643
10699
|
// customer's, and only their job fails.
|
|
10644
|
-
modelKey === null
|
|
10700
|
+
modelKey === null,
|
|
10701
|
+
effort
|
|
10645
10702
|
);
|
|
10646
10703
|
if (workspace) {
|
|
10647
10704
|
response.outputs.push(...(0, workspace_telemetry_1.workspaceOutputs)(workspace, runCwd, readPaths, toolInputs));
|
|
@@ -10677,7 +10734,7 @@ var require_claude_code = __commonJS({
|
|
|
10677
10734
|
outputLabel: handle.outputLabel,
|
|
10678
10735
|
outputSchema: handle.outputSchema
|
|
10679
10736
|
};
|
|
10680
|
-
const { response } = await this.runClaude(followUp, spec, scratch, handle.childEnv, signal, handle.model, null, handle.sessionId, `${handle.sessionId}-repair`, handle.childEnv === void 0);
|
|
10737
|
+
const { response } = await this.runClaude(followUp, spec, scratch, handle.childEnv, signal, handle.model, null, handle.sessionId, `${handle.sessionId}-repair`, handle.childEnv === void 0, handle.effort);
|
|
10681
10738
|
return response;
|
|
10682
10739
|
} finally {
|
|
10683
10740
|
await fs_1.promises.rm(scratch, { recursive: true, force: true }).catch(() => {
|
|
@@ -10723,9 +10780,14 @@ var require_claude_code = __commonJS({
|
|
|
10723
10780
|
const said = meta?.detail ?? (0, agent_process_1.firstLine)(run.stderr) ?? (0, agent_process_1.firstLine)(run.stdout);
|
|
10724
10781
|
return { ready: false, reason: said ?? `the claude CLI exited with code ${run.code}` };
|
|
10725
10782
|
}
|
|
10726
|
-
|
|
10783
|
+
/** The CLI's aliases (see CLAUDE_CODE_MODELS); nothing to ask, so nothing can fail. */
|
|
10784
|
+
async listModels() {
|
|
10785
|
+
return CLAUDE_CODE_MODELS;
|
|
10786
|
+
}
|
|
10787
|
+
async runClaude(prompt, spec, cwd, childEnv, signal, modelOverride, reporter, resumeSessionId, transcriptName, local = false, effortOverride) {
|
|
10727
10788
|
const outputLabel = spec.outputLabel;
|
|
10728
10789
|
const model = modelOverride ?? this.config.model;
|
|
10790
|
+
const effort = effortOverride ?? this.config.reasoningEffort;
|
|
10729
10791
|
const allowedTools = local ? this.config.allowedTools : checkoutScopedTools(this.config.allowedTools);
|
|
10730
10792
|
if (!local && this.config.claudeSettings === "user") {
|
|
10731
10793
|
throw new Error("claude-code: `claudeSettings: user` is for an installed Sifter whose login lives in Claude Code settings; a hosted run authenticates with the key it is handed and loads no settings");
|
|
@@ -10739,6 +10801,8 @@ var require_claude_code = __commonJS({
|
|
|
10739
10801
|
}
|
|
10740
10802
|
if (model)
|
|
10741
10803
|
args.push("--model", model);
|
|
10804
|
+
if (effort)
|
|
10805
|
+
args.push("--effort", effort);
|
|
10742
10806
|
if (this.config.maxTurns !== void 0)
|
|
10743
10807
|
args.push("--max-turns", String(this.config.maxTurns));
|
|
10744
10808
|
if (allowedTools && allowedTools.length > 0) {
|
|
@@ -10810,7 +10874,9 @@ var require_claude_code = __commonJS({
|
|
|
10810
10874
|
parsed,
|
|
10811
10875
|
usage: {
|
|
10812
10876
|
aiProvider: "claude-code",
|
|
10813
|
-
|
|
10877
|
+
// The model that ran (an alias resolved), over the one asked for.
|
|
10878
|
+
...stream.model ?? model ? { aiModel: stream.model ?? model } : {},
|
|
10879
|
+
...effort ? { aiEffort: effort } : {},
|
|
10814
10880
|
...stream.usage ?? {}
|
|
10815
10881
|
},
|
|
10816
10882
|
// In-session repair handle (ADR 0017): present only when the run
|
|
@@ -10819,6 +10885,7 @@ var require_claude_code = __commonJS({
|
|
|
10819
10885
|
continuation: {
|
|
10820
10886
|
sessionId: stream.sessionId,
|
|
10821
10887
|
model,
|
|
10888
|
+
effort,
|
|
10822
10889
|
childEnv,
|
|
10823
10890
|
outputLabel,
|
|
10824
10891
|
outputSchema: spec.outputSchema
|
|
@@ -10843,6 +10910,9 @@ var require_claude_code = __commonJS({
|
|
|
10843
10910
|
throw new Error('"model" must be a string');
|
|
10844
10911
|
validated.model = config.model;
|
|
10845
10912
|
}
|
|
10913
|
+
const effort = (0, models_1.parseReasoningEffort)(config.reasoningEffort, models_1.CLAUDE_CODE_EFFORTS);
|
|
10914
|
+
if (effort)
|
|
10915
|
+
validated.reasoningEffort = effort;
|
|
10846
10916
|
if (config.maxTurns !== void 0) {
|
|
10847
10917
|
if (typeof config.maxTurns !== "number" || !Number.isInteger(config.maxTurns) || config.maxTurns < 1) {
|
|
10848
10918
|
throw new Error('"maxTurns" must be a positive integer');
|
|
@@ -10917,6 +10987,7 @@ var require_claude_code = __commonJS({
|
|
|
10917
10987
|
let resultMeta = null;
|
|
10918
10988
|
let structuredOutput = null;
|
|
10919
10989
|
let sessionId = null;
|
|
10990
|
+
let model = null;
|
|
10920
10991
|
const toolInputs = [];
|
|
10921
10992
|
for (const line of stdout.split("\n")) {
|
|
10922
10993
|
const trimmed = line.trim();
|
|
@@ -10930,7 +11001,9 @@ var require_claude_code = __commonJS({
|
|
|
10930
11001
|
}
|
|
10931
11002
|
if (typeof event.session_id === "string")
|
|
10932
11003
|
sessionId = event.session_id;
|
|
10933
|
-
if (event.type === "
|
|
11004
|
+
if (event.type === "system" && event.subtype === "init" && typeof event.model === "string" && event.model) {
|
|
11005
|
+
model = event.model;
|
|
11006
|
+
} else if (event.type === "assistant") {
|
|
10934
11007
|
const content = event.message?.content;
|
|
10935
11008
|
if (!Array.isArray(content))
|
|
10936
11009
|
continue;
|
|
@@ -10971,7 +11044,7 @@ var require_claude_code = __commonJS({
|
|
|
10971
11044
|
};
|
|
10972
11045
|
}
|
|
10973
11046
|
}
|
|
10974
|
-
return { finalText, readPaths, usage, resultMeta, structuredOutput, sessionId, toolInputs };
|
|
11047
|
+
return { finalText, readPaths, usage, resultMeta, structuredOutput, sessionId, model, toolInputs };
|
|
10975
11048
|
}
|
|
10976
11049
|
}
|
|
10977
11050
|
});
|
|
@@ -11142,6 +11215,7 @@ var require_codex = __commonJS({
|
|
|
11142
11215
|
exports2.resolveCodex = resolveCodex;
|
|
11143
11216
|
exports2.codexReviewArgs = codexReviewArgs;
|
|
11144
11217
|
exports2.parseCodexEvents = parseCodexEvents;
|
|
11218
|
+
exports2.parseCodexModels = parseCodexModels;
|
|
11145
11219
|
exports2.createCodexExecutor = createCodexExecutor;
|
|
11146
11220
|
var fs_1 = require("fs");
|
|
11147
11221
|
var os_1 = __importDefault(require("os"));
|
|
@@ -11153,6 +11227,7 @@ var require_codex = __commonJS({
|
|
|
11153
11227
|
var agent_process_1 = require_agent_process();
|
|
11154
11228
|
var agent_common_1 = require_agent_common();
|
|
11155
11229
|
var json_answer_1 = require_json_answer();
|
|
11230
|
+
var models_1 = require_models();
|
|
11156
11231
|
var strict_schema_1 = require_strict_schema();
|
|
11157
11232
|
var workspace_telemetry_1 = require_workspace_telemetry();
|
|
11158
11233
|
var apply_1 = require_apply();
|
|
@@ -11226,7 +11301,6 @@ var require_codex = __commonJS({
|
|
|
11226
11301
|
...DISABLED_FEATURES.flatMap((f) => ["--disable", f])
|
|
11227
11302
|
];
|
|
11228
11303
|
}
|
|
11229
|
-
var REASONING_EFFORTS = ["none", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
11230
11304
|
var CODEX_FAULTS = {
|
|
11231
11305
|
installRemedy: "install Codex (brew install codex, or npm install -g @openai/codex) where this process can find it on PATH",
|
|
11232
11306
|
loginRemedy: "run `codex login` and sign in (or `codex login --with-api-key`)",
|
|
@@ -11260,6 +11334,7 @@ var require_codex = __commonJS({
|
|
|
11260
11334
|
const workspace = ctx?.workspace ?? null;
|
|
11261
11335
|
const hints = (0, loom_1.pickProviderHints)(spec, "codex");
|
|
11262
11336
|
const model = typeof hints.model === "string" && hints.model.length > 0 ? hints.model : this.config.model;
|
|
11337
|
+
const effort = (0, models_1.hintedEffort)(hints) ?? this.config.reasoningEffort;
|
|
11263
11338
|
const reporter = spec.progressChannel && ctx?.reportProgress ? new progress_1.ProgressReporter((frames) => ctx.reportProgress(spec.progressChannel, frames)) : null;
|
|
11264
11339
|
const codex = requireCodex();
|
|
11265
11340
|
const scratch = await fs_1.promises.mkdtemp(path_1.default.join(this.tmpBase(), "shuttle-codex-"));
|
|
@@ -11277,6 +11352,7 @@ var require_codex = __commonJS({
|
|
|
11277
11352
|
cwd: runCwd,
|
|
11278
11353
|
scratch,
|
|
11279
11354
|
model,
|
|
11355
|
+
effort,
|
|
11280
11356
|
signal,
|
|
11281
11357
|
reporter,
|
|
11282
11358
|
transcriptName: dispatch.job.id
|
|
@@ -11319,6 +11395,7 @@ var require_codex = __commonJS({
|
|
|
11319
11395
|
cwd: scratch,
|
|
11320
11396
|
scratch,
|
|
11321
11397
|
model: handle.model,
|
|
11398
|
+
effort: handle.effort,
|
|
11322
11399
|
signal,
|
|
11323
11400
|
reporter: null,
|
|
11324
11401
|
transcriptName: `${handle.threadId}-repair`
|
|
@@ -11373,11 +11450,24 @@ var require_codex = __commonJS({
|
|
|
11373
11450
|
});
|
|
11374
11451
|
}
|
|
11375
11452
|
}
|
|
11453
|
+
/**
|
|
11454
|
+
* The catalog `codex debug models` prints: the models codex itself offers
|
|
11455
|
+
* in its picker, each with the reasoning levels it supports. A `debug`
|
|
11456
|
+
* subcommand, so not a stable contract; any failure or unknown shape
|
|
11457
|
+
* reports nothing.
|
|
11458
|
+
*/
|
|
11459
|
+
async listModels(signal) {
|
|
11460
|
+
const codex = resolveCodex();
|
|
11461
|
+
if (!codex)
|
|
11462
|
+
return [];
|
|
11463
|
+
const stdout = await (0, models_1.runListing)(codex.bin, ["debug", "models"], signal);
|
|
11464
|
+
return stdout === null ? [] : parseCodexModels(stdout);
|
|
11465
|
+
}
|
|
11376
11466
|
tmpBase() {
|
|
11377
11467
|
return this.config.tmpDir ? (0, apply_1.expandHome)(this.config.tmpDir) : os_1.default.tmpdir();
|
|
11378
11468
|
}
|
|
11379
11469
|
async runCodex(opts) {
|
|
11380
|
-
const { spec, model } = opts;
|
|
11470
|
+
const { spec, model, effort } = opts;
|
|
11381
11471
|
const args = [...opts.args];
|
|
11382
11472
|
const hasSchema = spec.outputSchema && typeof spec.outputSchema === "object" && Object.keys(spec.outputSchema).length > 0;
|
|
11383
11473
|
if (hasSchema) {
|
|
@@ -11387,8 +11477,8 @@ var require_codex = __commonJS({
|
|
|
11387
11477
|
}
|
|
11388
11478
|
if (model)
|
|
11389
11479
|
args.push("-m", model);
|
|
11390
|
-
if (
|
|
11391
|
-
args.push("-c", `model_reasoning_effort="${
|
|
11480
|
+
if (effort)
|
|
11481
|
+
args.push("-c", `model_reasoning_effort="${effort}"`);
|
|
11392
11482
|
args.push("-");
|
|
11393
11483
|
const tap = opts.reporter ? codexProgressTap(opts.reporter) : null;
|
|
11394
11484
|
const run = await (0, agent_process_1.runAgentProcess)({
|
|
@@ -11435,12 +11525,14 @@ var require_codex = __commonJS({
|
|
|
11435
11525
|
usage: {
|
|
11436
11526
|
aiProvider: "codex",
|
|
11437
11527
|
...model ? { aiModel: model } : {},
|
|
11528
|
+
...effort ? { aiEffort: effort } : {},
|
|
11438
11529
|
...events.usage ?? {}
|
|
11439
11530
|
},
|
|
11440
11531
|
...events.threadId ? {
|
|
11441
11532
|
continuation: {
|
|
11442
11533
|
threadId: events.threadId,
|
|
11443
11534
|
model,
|
|
11535
|
+
effort,
|
|
11444
11536
|
outputLabel: spec.outputLabel,
|
|
11445
11537
|
outputSchema: spec.outputSchema
|
|
11446
11538
|
}
|
|
@@ -11544,14 +11636,40 @@ var require_codex = __commonJS({
|
|
|
11544
11636
|
failure: turnFailure ?? (finalText === null ? lastError : null)
|
|
11545
11637
|
};
|
|
11546
11638
|
}
|
|
11639
|
+
function parseCodexModels(stdout) {
|
|
11640
|
+
let body;
|
|
11641
|
+
try {
|
|
11642
|
+
body = JSON.parse(stdout);
|
|
11643
|
+
} catch {
|
|
11644
|
+
return [];
|
|
11645
|
+
}
|
|
11646
|
+
const entries = body?.models;
|
|
11647
|
+
if (!Array.isArray(entries))
|
|
11648
|
+
return [];
|
|
11649
|
+
const listed = entries.flatMap((entry) => {
|
|
11650
|
+
if (!entry || typeof entry !== "object")
|
|
11651
|
+
return [];
|
|
11652
|
+
const e = entry;
|
|
11653
|
+
if (typeof e.slug !== "string" || e.slug.length === 0 || e.visibility !== "list")
|
|
11654
|
+
return [];
|
|
11655
|
+
const levels = Array.isArray(e.supported_reasoning_levels) ? e.supported_reasoning_levels.flatMap((level) => {
|
|
11656
|
+
const effort = level?.effort;
|
|
11657
|
+
return typeof effort === "string" && /^[a-z]+$/.test(effort) ? [effort] : [];
|
|
11658
|
+
}) : [];
|
|
11659
|
+
const model = {
|
|
11660
|
+
id: e.slug,
|
|
11661
|
+
label: typeof e.display_name === "string" && e.display_name ? e.display_name : e.slug,
|
|
11662
|
+
...levels.length > 0 ? { efforts: levels } : {}
|
|
11663
|
+
};
|
|
11664
|
+
return [{ model, priority: typeof e.priority === "number" ? e.priority : Number.MAX_SAFE_INTEGER }];
|
|
11665
|
+
});
|
|
11666
|
+
return listed.sort((a, b) => a.priority - b.priority).map((entry) => entry.model);
|
|
11667
|
+
}
|
|
11547
11668
|
function createCodexExecutor(config, capabilityId = "codex") {
|
|
11548
11669
|
const validated = (0, agent_common_1.parseAgentCommonConfig)(config, capabilityId);
|
|
11549
|
-
|
|
11550
|
-
|
|
11551
|
-
|
|
11552
|
-
}
|
|
11553
|
-
validated.reasoningEffort = config.reasoningEffort;
|
|
11554
|
-
}
|
|
11670
|
+
const effort = (0, models_1.parseReasoningEffort)(config.reasoningEffort, models_1.REASONING_EFFORTS);
|
|
11671
|
+
if (effort)
|
|
11672
|
+
validated.reasoningEffort = effort;
|
|
11555
11673
|
return new CodexExecutor(validated);
|
|
11556
11674
|
}
|
|
11557
11675
|
}
|
|
@@ -11569,6 +11687,7 @@ var require_copilot = __commonJS({
|
|
|
11569
11687
|
exports2.withSchema = withSchema;
|
|
11570
11688
|
exports2.usageOf = usageOf;
|
|
11571
11689
|
exports2.parseCopilotEvents = parseCopilotEvents;
|
|
11690
|
+
exports2.parseCopilotModels = parseCopilotModels;
|
|
11572
11691
|
exports2.createCopilotExecutor = createCopilotExecutor;
|
|
11573
11692
|
var crypto_1 = require("crypto");
|
|
11574
11693
|
var fs_1 = require("fs");
|
|
@@ -11581,6 +11700,7 @@ var require_copilot = __commonJS({
|
|
|
11581
11700
|
var agent_process_1 = require_agent_process();
|
|
11582
11701
|
var agent_common_1 = require_agent_common();
|
|
11583
11702
|
var json_answer_1 = require_json_answer();
|
|
11703
|
+
var models_1 = require_models();
|
|
11584
11704
|
var workspace_telemetry_1 = require_workspace_telemetry();
|
|
11585
11705
|
var apply_1 = require_apply();
|
|
11586
11706
|
var REVIEW_TOOLS = ["view", "grep", "glob"];
|
|
@@ -11601,7 +11721,6 @@ var require_copilot = __commonJS({
|
|
|
11601
11721
|
];
|
|
11602
11722
|
}
|
|
11603
11723
|
var RUN_SETTINGS = { disableAllHooks: true, autoUpdate: false };
|
|
11604
|
-
var REASONING_EFFORTS = ["none", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
11605
11724
|
var COPILOT_FAULTS = {
|
|
11606
11725
|
installRemedy: "install GitHub Copilot CLI (brew install --cask copilot-cli, or npm install -g @github/copilot) where this process can find it on PATH",
|
|
11607
11726
|
loginRemedy: "run `copilot login` and sign in with a GitHub account that has a Copilot seat (a COPILOT_GITHUB_TOKEN, GH_TOKEN or GITHUB_TOKEN in the environment wins over that login)",
|
|
@@ -11639,6 +11758,7 @@ var require_copilot = __commonJS({
|
|
|
11639
11758
|
const workspace = ctx?.workspace ?? null;
|
|
11640
11759
|
const hints = (0, loom_1.pickProviderHints)(spec, "copilot");
|
|
11641
11760
|
const model = typeof hints.model === "string" && hints.model.length > 0 ? hints.model : this.config.model;
|
|
11761
|
+
const effort = (0, models_1.hintedEffort)(hints) ?? this.config.reasoningEffort;
|
|
11642
11762
|
const reporter = spec.progressChannel && ctx?.reportProgress ? new progress_1.ProgressReporter((frames) => ctx.reportProgress(spec.progressChannel, frames)) : null;
|
|
11643
11763
|
const runs = path_1.default.join(this.tmpBase(), "shuttle-copilot-runs");
|
|
11644
11764
|
await fs_1.promises.mkdir(runs, { recursive: true, mode: 448 });
|
|
@@ -11661,6 +11781,7 @@ var require_copilot = __commonJS({
|
|
|
11661
11781
|
home,
|
|
11662
11782
|
scratch,
|
|
11663
11783
|
model,
|
|
11784
|
+
effort,
|
|
11664
11785
|
signal,
|
|
11665
11786
|
reporter,
|
|
11666
11787
|
transcriptName: dispatch.job.id
|
|
@@ -11669,6 +11790,7 @@ var require_copilot = __commonJS({
|
|
|
11669
11790
|
sessionId,
|
|
11670
11791
|
home,
|
|
11671
11792
|
model,
|
|
11793
|
+
effort,
|
|
11672
11794
|
outputLabel: spec.outputLabel,
|
|
11673
11795
|
outputSchema: spec.outputSchema
|
|
11674
11796
|
};
|
|
@@ -11706,6 +11828,7 @@ var require_copilot = __commonJS({
|
|
|
11706
11828
|
home: handle.home,
|
|
11707
11829
|
scratch,
|
|
11708
11830
|
model: handle.model,
|
|
11831
|
+
effort: handle.effort,
|
|
11709
11832
|
signal,
|
|
11710
11833
|
reporter: null,
|
|
11711
11834
|
transcriptName: `${handle.sessionId}-repair`
|
|
@@ -11751,17 +11874,27 @@ var require_copilot = __commonJS({
|
|
|
11751
11874
|
});
|
|
11752
11875
|
}
|
|
11753
11876
|
}
|
|
11877
|
+
/**
|
|
11878
|
+
* The `model` setting's values as `copilot help config` lists them: the
|
|
11879
|
+
* CLI's built-in set. It does not reflect an organization's model policy,
|
|
11880
|
+
* so a model listed here can still be refused for one account, and that
|
|
11881
|
+
* review fails in copilot's own words. Each takes the CLI-wide effort list.
|
|
11882
|
+
*/
|
|
11883
|
+
async listModels(signal) {
|
|
11884
|
+
const stdout = await (0, models_1.runListing)("copilot", ["help", "config"], signal);
|
|
11885
|
+
return stdout === null ? [] : parseCopilotModels(stdout);
|
|
11886
|
+
}
|
|
11754
11887
|
tmpBase() {
|
|
11755
11888
|
return this.config.tmpDir ? (0, apply_1.expandHome)(this.config.tmpDir) : os_1.default.tmpdir();
|
|
11756
11889
|
}
|
|
11757
11890
|
async runCopilot(opts) {
|
|
11758
|
-
const { spec, model } = opts;
|
|
11891
|
+
const { spec, model, effort } = opts;
|
|
11759
11892
|
const usageFile = path_1.default.join(opts.scratch, `usage-${(0, crypto_1.randomUUID)()}.json`);
|
|
11760
11893
|
const args = [...opts.args, `--usage-output-file=${usageFile}`, `--log-dir=${path_1.default.join(opts.home, "logs")}`];
|
|
11761
11894
|
if (model)
|
|
11762
11895
|
args.push(`--model=${model}`);
|
|
11763
|
-
if (
|
|
11764
|
-
args.push(`--reasoning-effort=${
|
|
11896
|
+
if (effort)
|
|
11897
|
+
args.push(`--reasoning-effort=${effort}`);
|
|
11765
11898
|
const tap = opts.reporter ? copilotProgressTap(opts.reporter) : null;
|
|
11766
11899
|
const run = await withOperatorLogin(opts.home, () => (0, agent_process_1.runAgentProcess)({
|
|
11767
11900
|
bin: "copilot",
|
|
@@ -11807,7 +11940,12 @@ var require_copilot = __commonJS({
|
|
|
11807
11940
|
rawText: answerText,
|
|
11808
11941
|
parsed,
|
|
11809
11942
|
// The model the session actually ran, from its usage file, over the one asked for.
|
|
11810
|
-
usage: {
|
|
11943
|
+
usage: {
|
|
11944
|
+
aiProvider: "copilot",
|
|
11945
|
+
...model ? { aiModel: model } : {},
|
|
11946
|
+
...effort ? { aiEffort: effort } : {},
|
|
11947
|
+
...usage ?? {}
|
|
11948
|
+
}
|
|
11811
11949
|
},
|
|
11812
11950
|
reads: events.readPaths,
|
|
11813
11951
|
toolInputs: events.toolInputs
|
|
@@ -11995,14 +12133,25 @@ ${JSON.stringify(spec.outputSchema)}
|
|
|
11995
12133
|
}
|
|
11996
12134
|
return { finalText, readPaths, toolInputs, failure: finalText === null ? lastError : null };
|
|
11997
12135
|
}
|
|
12136
|
+
function parseCopilotModels(helpText) {
|
|
12137
|
+
const lines = helpText.split("\n");
|
|
12138
|
+
const start = lines.findIndex((line) => /^\s*`model`:/.test(line));
|
|
12139
|
+
if (start === -1)
|
|
12140
|
+
return [];
|
|
12141
|
+
const models = [];
|
|
12142
|
+
for (const line of lines.slice(start + 1)) {
|
|
12143
|
+
const value = /^\s+-\s+"([^"]+)"\s*$/.exec(line);
|
|
12144
|
+
if (!value)
|
|
12145
|
+
break;
|
|
12146
|
+
models.push({ id: value[1], label: value[1], efforts: [...models_1.REASONING_EFFORTS] });
|
|
12147
|
+
}
|
|
12148
|
+
return models;
|
|
12149
|
+
}
|
|
11998
12150
|
function createCopilotExecutor(config, capabilityId = "copilot") {
|
|
11999
12151
|
const validated = (0, agent_common_1.parseAgentCommonConfig)(config, capabilityId);
|
|
12000
|
-
|
|
12001
|
-
|
|
12002
|
-
|
|
12003
|
-
}
|
|
12004
|
-
validated.reasoningEffort = config.reasoningEffort;
|
|
12005
|
-
}
|
|
12152
|
+
const effort = (0, models_1.parseReasoningEffort)(config.reasoningEffort, models_1.REASONING_EFFORTS);
|
|
12153
|
+
if (effort)
|
|
12154
|
+
validated.reasoningEffort = effort;
|
|
12006
12155
|
return new CopilotExecutor(validated);
|
|
12007
12156
|
}
|
|
12008
12157
|
}
|
|
@@ -12033,6 +12182,14 @@ var require_http_api = __commonJS({
|
|
|
12033
12182
|
outputTokens: spec.costCapHint?.estimatedOutputTokens
|
|
12034
12183
|
};
|
|
12035
12184
|
}
|
|
12185
|
+
/**
|
|
12186
|
+
* The one model it runs. This executor takes no model hint (every call
|
|
12187
|
+
* names the configured model), so reporting the endpoint's catalog would
|
|
12188
|
+
* offer picks it would silently ignore.
|
|
12189
|
+
*/
|
|
12190
|
+
async listModels() {
|
|
12191
|
+
return [{ id: this.config.model, label: this.config.model }];
|
|
12192
|
+
}
|
|
12036
12193
|
async execute(dispatch, signal) {
|
|
12037
12194
|
const { prompt, spec } = (0, loom_1.renderPromptExecution)(dispatch.inputs);
|
|
12038
12195
|
const outputLabel = spec.outputLabel;
|
|
@@ -12973,10 +13130,12 @@ var require_anthropic_api = __commonJS({
|
|
|
12973
13130
|
"use strict";
|
|
12974
13131
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
12975
13132
|
exports2.createAnthropicApiExecutor = createAnthropicApiExecutor;
|
|
13133
|
+
exports2.parseAnthropicModels = parseAnthropicModels;
|
|
12976
13134
|
var loom_1 = require_dist();
|
|
12977
13135
|
var keep_1 = require_dist2();
|
|
12978
13136
|
var env_ref_1 = require_env_ref();
|
|
12979
13137
|
var validate_output_1 = require_validate_output();
|
|
13138
|
+
var models_1 = require_models();
|
|
12980
13139
|
var DEFAULT_BASE_URL = "https://api.anthropic.com/v1/messages";
|
|
12981
13140
|
var DEFAULT_MODEL = "claude-sonnet-4-6";
|
|
12982
13141
|
var DEFAULT_MAX_TOKENS = 4096;
|
|
@@ -13032,6 +13191,37 @@ var require_anthropic_api = __commonJS({
|
|
|
13032
13191
|
};
|
|
13033
13192
|
return this.callApi(handle.apiKey, body, spec, handle.outputLabel, signal);
|
|
13034
13193
|
}
|
|
13194
|
+
/**
|
|
13195
|
+
* The provider's own catalog, `/v1/models` beside the configured Messages
|
|
13196
|
+
* URL, asked with the operator's key. Dynamic mode reports nothing: its key
|
|
13197
|
+
* is a customer's, revealed per job, and there is none to ask with at start.
|
|
13198
|
+
*/
|
|
13199
|
+
async listModels(signal) {
|
|
13200
|
+
const apiKey = this.instance.staticKey;
|
|
13201
|
+
if (!apiKey)
|
|
13202
|
+
return [];
|
|
13203
|
+
const url = modelsUrl(this.instance.baseUrl);
|
|
13204
|
+
if (!url)
|
|
13205
|
+
return [];
|
|
13206
|
+
const controller = new AbortController();
|
|
13207
|
+
const abort = () => controller.abort();
|
|
13208
|
+
const timer = setTimeout(abort, models_1.LIST_MODELS_TIMEOUT_MS);
|
|
13209
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
13210
|
+
try {
|
|
13211
|
+
const response = await fetch(url, {
|
|
13212
|
+
headers: { "x-api-key": apiKey, "anthropic-version": ANTHROPIC_API_VERSION },
|
|
13213
|
+
signal: controller.signal
|
|
13214
|
+
});
|
|
13215
|
+
if (!response.ok)
|
|
13216
|
+
return [];
|
|
13217
|
+
return parseAnthropicModels(await response.json());
|
|
13218
|
+
} catch {
|
|
13219
|
+
return [];
|
|
13220
|
+
} finally {
|
|
13221
|
+
clearTimeout(timer);
|
|
13222
|
+
signal.removeEventListener("abort", abort);
|
|
13223
|
+
}
|
|
13224
|
+
}
|
|
13035
13225
|
/** Shared Messages-API call + parse + validate, used by execute and continue. */
|
|
13036
13226
|
async callApi(apiKey, body, spec, outputLabel, signal) {
|
|
13037
13227
|
const timeoutController = new AbortController();
|
|
@@ -13073,7 +13263,8 @@ var require_anthropic_api = __commonJS({
|
|
|
13073
13263
|
inputTokens: u.input_tokens,
|
|
13074
13264
|
outputTokens: u.output_tokens,
|
|
13075
13265
|
aiProvider: "anthropic",
|
|
13076
|
-
|
|
13266
|
+
// The model this call ran, which a hint may have chosen.
|
|
13267
|
+
aiModel: body.model
|
|
13077
13268
|
} : void 0;
|
|
13078
13269
|
const parsed = safeJsonParse(rawText);
|
|
13079
13270
|
(0, validate_output_1.assertOutputValid)(spec, parsed);
|
|
@@ -13105,7 +13296,8 @@ var require_anthropic_api = __commonJS({
|
|
|
13105
13296
|
if (rawApiKeyFrom !== void 0 && rawApiKey !== void 0) {
|
|
13106
13297
|
throw new Error('AnthropicApiExecutor accepts either "apiKey" (static) or "apiKeyFrom" (dynamic), not both');
|
|
13107
13298
|
}
|
|
13108
|
-
const
|
|
13299
|
+
const staticKey = rawApiKeyFrom === void 0 ? resolveStaticKey(rawApiKey) : null;
|
|
13300
|
+
const resolveKey = staticKey === null ? buildDynamicResolver(config, deps) : async () => staticKey;
|
|
13109
13301
|
let baseUrl = DEFAULT_BASE_URL;
|
|
13110
13302
|
if (config.baseUrl !== void 0) {
|
|
13111
13303
|
if (typeof config.baseUrl !== "string" || config.baseUrl.length === 0) {
|
|
@@ -13136,6 +13328,7 @@ var require_anthropic_api = __commonJS({
|
|
|
13136
13328
|
}
|
|
13137
13329
|
return new AnthropicApiExecutor({
|
|
13138
13330
|
resolveKey,
|
|
13331
|
+
staticKey,
|
|
13139
13332
|
baseUrl,
|
|
13140
13333
|
model,
|
|
13141
13334
|
maxTokens,
|
|
@@ -13143,12 +13336,25 @@ var require_anthropic_api = __commonJS({
|
|
|
13143
13336
|
capabilityId
|
|
13144
13337
|
});
|
|
13145
13338
|
}
|
|
13146
|
-
function
|
|
13339
|
+
function resolveStaticKey(rawApiKey) {
|
|
13147
13340
|
if (typeof rawApiKey !== "string" || rawApiKey.length === 0) {
|
|
13148
13341
|
throw new Error('AnthropicApiExecutor requires a non-empty "apiKey" string in config (or "apiKeyFrom: \\"job-metadata\\"" for dynamic key mode)');
|
|
13149
13342
|
}
|
|
13150
|
-
|
|
13151
|
-
|
|
13343
|
+
return (0, env_ref_1.resolveEnvRef)(rawApiKey, "apiKey");
|
|
13344
|
+
}
|
|
13345
|
+
function modelsUrl(messagesUrl) {
|
|
13346
|
+
return /\/messages\/?$/.test(messagesUrl) ? messagesUrl.replace(/\/messages\/?$/, "/models") : null;
|
|
13347
|
+
}
|
|
13348
|
+
function parseAnthropicModels(body) {
|
|
13349
|
+
const data = body?.data;
|
|
13350
|
+
if (!Array.isArray(data))
|
|
13351
|
+
return [];
|
|
13352
|
+
return data.flatMap((entry) => {
|
|
13353
|
+
const { id, display_name: displayName } = entry ?? {};
|
|
13354
|
+
if (typeof id !== "string" || id.length === 0)
|
|
13355
|
+
return [];
|
|
13356
|
+
return [{ id, label: typeof displayName === "string" && displayName ? displayName : id }];
|
|
13357
|
+
});
|
|
13152
13358
|
}
|
|
13153
13359
|
function buildDynamicResolver(config, deps) {
|
|
13154
13360
|
if (config.apiKeyFrom !== "job-metadata") {
|
|
@@ -22142,12 +22348,14 @@ var require_subscribe = __commonJS({
|
|
|
22142
22348
|
if (id === STOPPED)
|
|
22143
22349
|
return;
|
|
22144
22350
|
resolvedPoolIds.push(id);
|
|
22351
|
+
const perPool = opts.subscriber.poolMetadata?.(ref);
|
|
22352
|
+
const metadata = opts.subscriber.metadata !== void 0 || perPool !== void 0 ? { ...opts.subscriber.metadata, ...perPool } : void 0;
|
|
22145
22353
|
const registered = await untilAvailable(() => opts.jobsClient.registerMember(id, {
|
|
22146
22354
|
identityType: opts.subscriber.identityType,
|
|
22147
22355
|
identityId: opts.subscriber.identityId,
|
|
22148
22356
|
intelligence: opts.subscriber.intelligence,
|
|
22149
22357
|
...opts.subscriber.displayName !== void 0 ? { displayName: opts.subscriber.displayName } : {},
|
|
22150
|
-
...
|
|
22358
|
+
...metadata !== void 0 ? { metadata } : {}
|
|
22151
22359
|
}), mySession);
|
|
22152
22360
|
if (registered === STOPPED)
|
|
22153
22361
|
return;
|
|
@@ -27234,6 +27442,13 @@ var require_shuttle = __commonJS({
|
|
|
27234
27442
|
});
|
|
27235
27443
|
return { promise, resolve, reject };
|
|
27236
27444
|
}
|
|
27445
|
+
async function listExecutorModels(executors, signal) {
|
|
27446
|
+
const listed = await Promise.all(executors.map(async (executor) => {
|
|
27447
|
+
const models = executor.listModels ? await executor.listModels(signal).catch(() => []) : [];
|
|
27448
|
+
return [executor.capability.id, models];
|
|
27449
|
+
}));
|
|
27450
|
+
return new Map(listed);
|
|
27451
|
+
}
|
|
27237
27452
|
function isKeepUnavailable(err) {
|
|
27238
27453
|
return err instanceof Error && err.name === "KeepUnavailableError";
|
|
27239
27454
|
}
|
|
@@ -27382,6 +27597,10 @@ var require_shuttle = __commonJS({
|
|
|
27382
27597
|
registerBuiltInExecutors(registry, this.brand.executorAllowlist);
|
|
27383
27598
|
const executors = registry.build(mergeExecutorDefaults((0, environment_1.executorDefaultsFor)(this.brand, this.config.auth.jobsApiUrl), this.config.executors));
|
|
27384
27599
|
const executorFor = (0, demux_1.createDemux)(executors, this.config.pools);
|
|
27600
|
+
const modelsByExecutor = await listExecutorModels(executors, this.stopping.signal);
|
|
27601
|
+
if (this.stopping.signal.aborted)
|
|
27602
|
+
return;
|
|
27603
|
+
logger.info("executor models listed", Object.fromEntries([...modelsByExecutor].map(([id, m]) => [id, m.length])));
|
|
27385
27604
|
this.spendTracker = (0, spend_tracker_1.createSpendTrackerObserver)(this.brand, paths.spendStateFile);
|
|
27386
27605
|
const observers = [
|
|
27387
27606
|
(0, logger_2.createLoggerObserver)(),
|
|
@@ -27497,6 +27716,14 @@ var require_shuttle = __commonJS({
|
|
|
27497
27716
|
return { status: "completed", outputs };
|
|
27498
27717
|
};
|
|
27499
27718
|
const pools = this.config.pools.map((p) => p.id ? { id: p.id } : { name: p.name });
|
|
27719
|
+
const poolExecutors = new Map(pools.map((ref, i) => [ref, this.config.pools[i].executor]));
|
|
27720
|
+
const poolMetadata = (ref) => {
|
|
27721
|
+
const executor = poolExecutors.get(ref);
|
|
27722
|
+
const models = executor ? modelsByExecutor.get(executor) : void 0;
|
|
27723
|
+
if (!executor || !models)
|
|
27724
|
+
return void 0;
|
|
27725
|
+
return { executor, ...models.length > 0 ? { models } : {} };
|
|
27726
|
+
};
|
|
27500
27727
|
const attemptedUpgrades = /* @__PURE__ */ new Set();
|
|
27501
27728
|
this.subscription = (0, jobs_1.subscribe)({
|
|
27502
27729
|
jobsClient,
|
|
@@ -27513,7 +27740,8 @@ var require_shuttle = __commonJS({
|
|
|
27513
27740
|
...this.config.agent.metadata,
|
|
27514
27741
|
client_version: this.brand.product.version,
|
|
27515
27742
|
hostname: (0, os_1.hostname)()
|
|
27516
|
-
}
|
|
27743
|
+
},
|
|
27744
|
+
poolMetadata
|
|
27517
27745
|
},
|
|
27518
27746
|
onJob,
|
|
27519
27747
|
onDirectives: async (directives) => {
|
|
@@ -28375,7 +28603,7 @@ var import_path = require("path");
|
|
|
28375
28603
|
var import_promises = require("fs/promises");
|
|
28376
28604
|
var import_yaml = __toESM(require_dist3());
|
|
28377
28605
|
var import_shuttle = __toESM(require_dist5());
|
|
28378
|
-
var buildVersion = true ? "0.
|
|
28606
|
+
var buildVersion = true ? "0.32.0" : pkg.version;
|
|
28379
28607
|
var AGENT_EXECUTORS = ["claude-code", "codex", "copilot"];
|
|
28380
28608
|
var sifterBrand = {
|
|
28381
28609
|
product: {
|