bareloop 0.40.0 → 0.41.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/CHANGELOG.md +33 -0
- package/bareloop.context.md +97 -124
- package/package.json +2 -2
- package/src/authorflow.js +9 -9
- package/src/authorjob.js +4 -4
- package/src/authorrun.js +25 -25
- package/src/authorscout.js +4 -4
- package/src/bundle.js +7 -4
- package/src/bundlerun.js +4 -1
- package/src/cli.js +1 -1
- package/src/config.js +129 -29
- package/src/draftspend.js +4 -4
- package/src/index.js +2 -4
- package/src/interviewrun.js +17 -25
- package/src/job.js +13 -7
- package/src/judged.js +11 -43
- package/src/keysfile.js +15 -7
- package/src/kinds.js +2 -2
- package/src/modellist.js +84 -0
- package/src/monthly.js +23 -43
- package/src/panel/authorroutes.js +19 -14
- package/src/panel/authorsession.js +62 -58
- package/src/panel/index.html +520 -145
- package/src/panel/runroutes.js +3 -0
- package/src/panel/server.js +35 -15
- package/src/panel/settingsroutes.js +232 -173
- package/src/planrun.js +2 -2
- package/src/providerrows.js +226 -141
- package/src/providers.js +58 -332
- package/src/providershapes.js +18 -0
- package/src/replay.js +1 -1
- package/src/thinking.js +130 -0
- package/src/userrun.js +50 -73
- package/types/authorflow.d.ts +5 -5
- package/types/authorjob.d.ts +2 -2
- package/types/authorscout.d.ts +2 -2
- package/types/config.d.ts +23 -6
- package/types/draftspend.d.ts +8 -8
- package/types/index.d.ts +1 -1
- package/types/job.d.ts +5 -5
- package/types/judged.d.ts +5 -36
- package/types/keysfile.d.ts +15 -4
- package/types/modellist.d.ts +50 -0
- package/types/monthly.d.ts +4 -3
- package/types/panel/authorsession.d.ts +2 -9
- package/types/panel/server.d.ts +14 -4
- package/types/providerrows.d.ts +192 -99
- package/types/providers.d.ts +34 -159
- package/types/providershapes.d.ts +10 -0
- package/types/thinking.d.ts +90 -0
- package/types/userrun.d.ts +6 -1
package/src/userrun.js
CHANGED
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
// authored is preserved from the spine as a reusable artifact, and the next run of
|
|
26
26
|
// this shape reuses and fine-tunes it rather than starting cold.
|
|
27
27
|
import { readFileSync, writeFileSync, appendFileSync, mkdirSync, existsSync, rmSync, readdirSync, openSync, readSync, closeSync, fstatSync, unlinkSync } from 'node:fs';
|
|
28
|
-
import { createRequire } from 'node:module';
|
|
29
28
|
import { fileURLToPath } from 'node:url';
|
|
30
29
|
import { execFileSync, spawn } from 'node:child_process';
|
|
31
30
|
import { join, resolve, dirname, basename } from 'node:path';
|
|
@@ -83,14 +82,11 @@ import { parseJsonl } from './replayio.js';
|
|
|
83
82
|
import { claimRun, monthlyRefusalText, legSpend, chainSpend } from './monthly.js';
|
|
84
83
|
import { ConfigError } from './config.js';
|
|
85
84
|
import { commandFor } from './invoke.js';
|
|
86
|
-
import {
|
|
85
|
+
import { judgeRatesFor, keyNameFor, keyValueOf, priceReadout, ratesFor, ratesOfLine, resolveWorker, judgeRowFor, rowsForHome, REFUSE_NAME_MODEL } from './providerrows.js';
|
|
87
86
|
// the banner's wall arithmetic, extracted so it is reachable by a test (F83): the
|
|
88
87
|
// end-of-run readout sits past the approval gate, so nothing could ever drive it here
|
|
89
88
|
import { wallLine, doomedResume, deathAtOf, evidencePackage, doorLines, resumeAtLines, reviewDoorPackage, runDoorLines, tokensLine, doorTimingRedLines } from './u-readout.js';
|
|
90
89
|
|
|
91
|
-
const require = createRequire(import.meta.url);
|
|
92
|
-
const { AnthropicProvider } = require('bare-agent/providers');
|
|
93
|
-
|
|
94
90
|
const JOBS = {
|
|
95
91
|
'aurora-spawner': {
|
|
96
92
|
spec: 'aurora-u-spawner-types.json',
|
|
@@ -174,10 +170,10 @@ const JOBS = {
|
|
|
174
170
|
},
|
|
175
171
|
// PRD item 28 / 30.9 — the openai-api probe through THIS runner (the shipped
|
|
176
172
|
// one), not poc-run-param.mjs. Same job shape, same seed, its own patient copy.
|
|
177
|
-
'bareguard-types-
|
|
178
|
-
spec: 'bareguard-u-types-
|
|
179
|
-
workdir: '/home/hamr/PycharmProjects/bareloop-patients/bareguard-u-
|
|
180
|
-
spine: 'bareguard-u-
|
|
173
|
+
'bareguard-types-gateway': {
|
|
174
|
+
spec: 'bareguard-u-types-gateway.json',
|
|
175
|
+
workdir: '/home/hamr/PycharmProjects/bareloop-patients/bareguard-u-gateway',
|
|
176
|
+
spine: 'bareguard-u-gateway-bareloop',
|
|
181
177
|
seed: '2ae8fcd37041c186524a6eb5e953b9752cd602fa',
|
|
182
178
|
},
|
|
183
179
|
// N4's hitl PROVING job (build plan §Proving; hamr's ruling, 2026-08-13). The job
|
|
@@ -273,7 +269,8 @@ class ExitSignal extends Error {
|
|
|
273
269
|
* @property {string} [into] the source door's own directory (`source.json`, and the spine directory beside it).
|
|
274
270
|
* Default `dirname(workdir)` — the copied-tree layout, where the tree is `<into>/tree`. A repo job on a WORKTREE
|
|
275
271
|
* (P6 item 1) has its tree inside the person's repo, so its `into` is passed explicitly.
|
|
276
|
-
* @property {string|null} [model] the raw `--model
|
|
272
|
+
* @property {string|null} [model] the raw `--model <id>` (a model id of a ticked Settings line), or null
|
|
273
|
+
* @property {string|null} [providerKey] the raw `--provider <KEY>` (a key's env name), or null
|
|
277
274
|
* @property {string|null} [readShim] the raw `--read-shim` arm name, or null for the default
|
|
278
275
|
* @property {string|null} [scout] the raw `--scout` value (`on`/`off`), or null for the default
|
|
279
276
|
* @property {string|null} [draftSpentUsd] the raw `--draft-spent-usd` value (hamr's
|
|
@@ -306,6 +303,7 @@ class ExitSignal extends Error {
|
|
|
306
303
|
* @property {string} spineName
|
|
307
304
|
* @property {string} [into] see `RunOpts.into`
|
|
308
305
|
* @property {string|null} model
|
|
306
|
+
* @property {string|null} providerKey
|
|
309
307
|
* @property {string|null} readShim
|
|
310
308
|
* @property {string|null} scout
|
|
311
309
|
* @property {string|null} draftSpentUsd
|
|
@@ -389,25 +387,13 @@ async function execute(ctx) {
|
|
|
389
387
|
/** @type {{workdir: string, seed: string, spine: string}} */
|
|
390
388
|
const target = { workdir: ctx.workdir, seed: ctx.seed, spine: ctx.spineName };
|
|
391
389
|
|
|
392
|
-
// --model
|
|
393
|
-
//
|
|
394
|
-
//
|
|
395
|
-
//
|
|
396
|
-
//
|
|
397
|
-
// (provider-gated, battery rule) — nothing to gate yet since neither tier sets effort.
|
|
398
|
-
// PRD v1.36 floor: the drafter/default tier is sonnet MINIMUM — measured, a haiku
|
|
399
|
-
// drafter died plan-red twice on the same rejection (ms7gne7s). `--model haiku` runs
|
|
400
|
-
// BELOW the floor: an explicit operator probe whose rows are probes, never battery
|
|
401
|
-
// evidence.
|
|
402
|
-
const DEFAULT_TIER_MODELS = { sonnet: 'claude-sonnet-5', haiku: 'claude-haiku-4-5-20251001' };
|
|
403
|
-
// `modelFlagArg` is null when --model was never passed at all — distinct from a
|
|
404
|
-
// flag that happens to resolve to the default tier's own id, because the SPEC
|
|
405
|
-
// (below, once loaded) needs to know whether a flag was actually given, not just
|
|
406
|
-
// what it resolved to (build-list #3: spec wins, a mismatched flag is refused).
|
|
390
|
+
// --model <id> names the Settings line a run works on when the SPEC names no model (an older spec, signed before a job carried its
|
|
391
|
+
// own); a spec's own `model` still wins and a different --model is refused. --provider <KEY> narrows to one key when two keys tick the
|
|
392
|
+
// same id. Runner territory: the spec names neither, so the signed hash is unaffected. There are no tier aliases and no built-in model.
|
|
393
|
+
// `modelFlagArg` is null when --model was never passed — distinct from a flag that happens to equal the spec's model, because the SPEC
|
|
394
|
+
// (below, once loaded) needs to know whether a flag was actually given (build-list #3: spec wins, a mismatched flag is refused).
|
|
407
395
|
const modelFlagArg = ctx.model ?? null;
|
|
408
|
-
const
|
|
409
|
-
const FLAG_TIER_MODEL = DEFAULT_TIER_MODELS[/** @type {keyof typeof DEFAULT_TIER_MODELS} */ (tierArg)];
|
|
410
|
-
if (!FLAG_TIER_MODEL) { err(`unknown --model "${tierArg}" — one of: ${Object.keys(DEFAULT_TIER_MODELS).join(', ')}`); throw new ExitSignal(2); }
|
|
396
|
+
const providerFlagArg = ctx.providerKey ?? null;
|
|
411
397
|
// --read-shim picks the READ SHIM's ARM (src/readshim.js, Phase 2 A0/A1/A2/A3). Runner
|
|
412
398
|
// territory exactly like --model: the spec names no shim, so the signed hash is
|
|
413
399
|
// unaffected. Phase 2 itself never flipped this default — its own "what this
|
|
@@ -545,11 +531,12 @@ async function execute(ctx) {
|
|
|
545
531
|
try {
|
|
546
532
|
modelResolution = resolveWorkerModel({
|
|
547
533
|
specModel: spec.model,
|
|
548
|
-
flagModel: modelFlagArg === null ? undefined :
|
|
549
|
-
|
|
534
|
+
flagModel: modelFlagArg === null ? undefined : modelFlagArg,
|
|
535
|
+
// a scripted provider handed in by a test IS the run: it names its own model; a real run has no default
|
|
536
|
+
suppliedModel: deps.provider ? String(/** @type {any} */ (deps.provider).model ?? 'scripted') : undefined,
|
|
550
537
|
});
|
|
551
538
|
} catch (e) {
|
|
552
|
-
die(/** @type {Error} */ (e).message);
|
|
539
|
+
die(spec.model === undefined && modelFlagArg === null ? REFUSE_NAME_MODEL : /** @type {Error} */ (e).message);
|
|
553
540
|
}
|
|
554
541
|
const MODEL = modelResolution.model;
|
|
555
542
|
const MODEL_LABEL = modelResolution.source === 'spec' ? `${MODEL} (spec)` : MODEL;
|
|
@@ -1022,16 +1009,20 @@ async function execute(ctx) {
|
|
|
1022
1009
|
// spine, then handed down as data (`runJob`'s `rates`) — nothing deep in the run re-reads config. A bad
|
|
1023
1010
|
// price refuses here; it never falls back to the built-in guess. No price set = `null` = no `rates` key
|
|
1024
1011
|
// passed anywhere, byte-identical to before. The judge's own row is resolved below, beside its key.
|
|
1025
|
-
const keyCfg = cfgOn ? rowsForHome(cfgHome) : [];
|
|
1012
|
+
const keyCfg = cfgOn ? rowsForHome(cfgHome, env) : [];
|
|
1026
1013
|
/** @type {ReturnType<typeof ratesFor>} */
|
|
1027
1014
|
let workerPrice = null;
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1015
|
+
// WHICH SETTINGS LINE THIS RUN WORKS ON (P8): the row is the key, the Base URL and the old-max_tokens tick; the line is the model
|
|
1016
|
+
// and its price. A scripted provider handed in by a test IS the run (no row). A refusal here is $0, before anything else.
|
|
1017
|
+
const W = deps.provider ? null : resolveWorker(keyCfg, spec, { model: modelFlagArg, provider: providerFlagArg });
|
|
1018
|
+
const refuseWorker = () => { if (W && !W.ok) { err(W.say.includes('Nothing was spent') ? W.say : `${W.say} Nothing was spent.`); throw new ExitSignal(2); } };
|
|
1019
|
+
// the preview cannot name its key without a line: refuse it here. A SIGNED run meets its other gates first (pause door, wall) and
|
|
1020
|
+
// is refused at the key check below — still before anything is spent
|
|
1021
|
+
if ((ctx.approve ?? null) === null) refuseWorker();
|
|
1022
|
+
/** the endpoint the worker talks to: the chosen row's own Base URL (a spec signed before addresses were required carries none) */
|
|
1023
|
+
const baseUrl = W && W.ok ? W.baseUrl : (typeof spec.baseUrl === 'string' ? spec.baseUrl : undefined);
|
|
1024
|
+
const wLine = W && W.ok ? ratesOfLine(W.line) : null;
|
|
1025
|
+
workerPrice = W ? (wLine && W.ok ? { ...wLine, envName: W.row.envName } : null) : ratesFor(spec.provider, spec.baseUrl, keyCfg, spec.model);
|
|
1035
1026
|
|
|
1036
1027
|
if ((ctx.approve ?? null) !== specHash) {
|
|
1037
1028
|
out(dead ? 'U — RESUME, continuing a halted run, REAL dollars' : 'U — user-mode e2e, ONE run, REAL dollars');
|
|
@@ -1192,7 +1183,7 @@ async function execute(ctx) {
|
|
|
1192
1183
|
// right key only by accident of the runner's own generic error message,
|
|
1193
1184
|
// never from this hint. `keyNameFor` is the same resolved name
|
|
1194
1185
|
// the real key check at launch reads (the person's row variable, else the provider's built-in one).
|
|
1195
|
-
const invoke = (/** @type {string} */ tail) => ` ${keyNameFor(spec.provider, spec.baseUrl, keyCfg, spec.model).name}=... ${INVOKE}${dead ? ` --resume ${RESUME}` : ''}${SHIM_TAIL}${SCOUT_TAIL}${DRAFT_TAIL}${REGISTRY_TAIL}${tail} --approve ${PRINT_APPROVE}`;
|
|
1186
|
+
const invoke = (/** @type {string} */ tail) => ` ${(W && W.ok ? W.row.envName : null) ?? keyNameFor(spec.provider, spec.baseUrl, keyCfg, spec.model).name ?? '<KEY>'}=... ${INVOKE}${dead ? ` --resume ${RESUME}` : ''}${SHIM_TAIL}${SCOUT_TAIL}${DRAFT_TAIL}${REGISTRY_TAIL}${tail} --approve ${PRINT_APPROVE}`;
|
|
1196
1187
|
/** the door the operator has already picked, as flags — hoisted out of the else
|
|
1197
1188
|
* below so the inhibitor line at the bottom can print the WHOLE command rather
|
|
1198
1189
|
* than a shape the operator has to assemble. Empty on an ordinary run and on the
|
|
@@ -1446,13 +1437,15 @@ async function execute(ctx) {
|
|
|
1446
1437
|
let judgePrice = null;
|
|
1447
1438
|
if (JUDGES) {
|
|
1448
1439
|
try {
|
|
1449
|
-
judgePrice = judgeRatesFor(judge, spec.provider,
|
|
1440
|
+
judgePrice = judgeRatesFor(judge, spec.provider, baseUrl, workerPrice, keyCfg);
|
|
1450
1441
|
} catch (e) {
|
|
1451
1442
|
if (!(e instanceof ConfigError)) throw e;
|
|
1452
1443
|
err(`${e.message} — refusing to start rather than guess a price. Nothing spent.`);
|
|
1453
1444
|
throw new ExitSignal(2);
|
|
1454
1445
|
}
|
|
1455
1446
|
}
|
|
1447
|
+
/** the row the judge's key (and endpoint) comes from: the worker's own row when the judge shares its provider, else the judge provider's row */
|
|
1448
|
+
const judgeRow = judgeRowFor(keyCfg, judge, spec.provider, W && W.ok ? W.row : null);
|
|
1456
1449
|
// undefined, not null: both come straight off `env[...]` lookups below, which
|
|
1457
1450
|
// (like process.env) never produce null for a missing key.
|
|
1458
1451
|
/** @type {string|undefined} */
|
|
@@ -1468,13 +1461,10 @@ async function execute(ctx) {
|
|
|
1468
1461
|
// row = the built-in. Names only — values come from the
|
|
1469
1462
|
// env / keys file. The judge follows the worker's choice when it is the same provider
|
|
1470
1463
|
// (the same rule that gives it the worker's baseUrl below).
|
|
1471
|
-
|
|
1472
|
-
const
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
// A green anthropic-api job's behaviour is byte-identical to before: its
|
|
1476
|
-
// worker key IS `ANTHROPIC_API_KEY`, demanded as ever.
|
|
1477
|
-
workerApiKey = workerEnv[providerEntry.envKey];
|
|
1464
|
+
refuseWorker();
|
|
1465
|
+
const workerKeyName = /** @type {NonNullable<typeof W> & {ok: true}} */ (W).row.envName;
|
|
1466
|
+
// A job's worker key is its Settings row's own variable — there is no built-in name.
|
|
1467
|
+
workerApiKey = keyValueOf(env, workerKeyName);
|
|
1478
1468
|
if (!workerApiKey) { err(`${workerKeyName} not set (secrets load from the environment — never the tree)`); throw new ExitSignal(2); }
|
|
1479
1469
|
// F181 — a key that reads as "set" above can still carry a line break/
|
|
1480
1470
|
// control char/stray whitespace (a two-line secret-store entry, e.g.) and
|
|
@@ -1487,10 +1477,10 @@ async function execute(ctx) {
|
|
|
1487
1477
|
// override matters most in the case this item exists for: a job whose worker and
|
|
1488
1478
|
// judge are the SAME provider but different accounts, and the anthropic case
|
|
1489
1479
|
// where one variable used to do two jobs.
|
|
1490
|
-
judgeApiKey = env.JUDGE_API_KEY ??
|
|
1480
|
+
judgeApiKey = env.JUDGE_API_KEY ?? keyValueOf(env, judgeRow?.envName);
|
|
1491
1481
|
if (JUDGES && !judgeApiKey) {
|
|
1492
1482
|
err(`This job's close JUDGES (${judgedStages(spec.closeDecl).length} judged stage(s)) and its judge is ${judge.model} on ${judge.provider}${spec.judge ? ' (signed override)' : " (this job's own worker model — no `judge` override signed)"}.`);
|
|
1493
|
-
err(`Neither JUDGE_API_KEY nor ${
|
|
1483
|
+
err(`Neither JUDGE_API_KEY nor ${judgeRow?.envName ?? `a key row for ${judge.provider}`} is set — secrets load from the environment, never the tree.`);
|
|
1494
1484
|
err('Refused at $0, BEFORE the worker spends anything: a judged run that discovers this at the close has paid for a verdict it cannot render.');
|
|
1495
1485
|
throw new ExitSignal(2);
|
|
1496
1486
|
}
|
|
@@ -1500,7 +1490,7 @@ async function execute(ctx) {
|
|
|
1500
1490
|
if (JUDGES) {
|
|
1501
1491
|
const judgeKeyProblem = apiKeyProblem(/** @type {string} */ (judgeApiKey));
|
|
1502
1492
|
if (judgeKeyProblem) {
|
|
1503
|
-
const judgeEnvName = env.JUDGE_API_KEY ? 'JUDGE_API_KEY' :
|
|
1493
|
+
const judgeEnvName = env.JUDGE_API_KEY ? 'JUDGE_API_KEY' : (judgeRow?.envName ?? judge.provider);
|
|
1504
1494
|
err(`${judgeEnvName} ${judgeKeyProblem} — refusing rather than crashing mid-call (never trimmed or repaired; fix the value at its source)`);
|
|
1505
1495
|
throw new ExitSignal(2);
|
|
1506
1496
|
}
|
|
@@ -1640,7 +1630,7 @@ async function execute(ctx) {
|
|
|
1640
1630
|
// OpenAI-compatible gateway/endpoint. Undefined for anthropic-api jobs and
|
|
1641
1631
|
// for an openai-api job that names none (bare-agent's OpenAIProvider then
|
|
1642
1632
|
// defaults to api.openai.com/v1 on its own).
|
|
1643
|
-
|
|
1633
|
+
// (`baseUrl` — the worker row's Base URL — was resolved above with the Settings line)
|
|
1644
1634
|
// TEST SEAM — same shape as the bundle door (src/bundlerun.js): a caller that supplies
|
|
1645
1635
|
// `deps.provider` skips the real-key check above entirely and this
|
|
1646
1636
|
// construction never runs (a scripted provider IS the run).
|
|
@@ -1648,26 +1638,11 @@ async function execute(ctx) {
|
|
|
1648
1638
|
let providerFor = deps.providerFor;
|
|
1649
1639
|
let judgeProvider = deps.judgeProvider ?? null;
|
|
1650
1640
|
if (!provider) {
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
//
|
|
1654
|
-
//
|
|
1655
|
-
|
|
1656
|
-
// battery rule) - nothing to gate yet since neither tier sets effort params.
|
|
1657
|
-
// `sonnet` maps to the RESOLVED worker model (MODEL — spec/flag/default), not the
|
|
1658
|
-
// bare provider-table id, so a spec-named model reaches every plan step's own
|
|
1659
|
-
// provider (STEP_MODELS is sonnet-only), not just the top-level `provider` above.
|
|
1660
|
-
// ONLY when the SPEC named it: a `--model haiku` probe keeps its old reach (the
|
|
1661
|
-
// top-level provider), never silently widening into every step's tier. The tier
|
|
1662
|
-
// table itself comes from `providerEntry` (src/providers.js) — for openai-api
|
|
1663
|
-
// today that means BOTH tiers resolve to the same `deepseek-flash` id (hamr's
|
|
1664
|
-
// ruling, PRD 30.7: one secondary provider, not a menu; swapped from the
|
|
1665
|
-
// retired `deepseek-chat`, F171), so a `--model haiku` probe against an
|
|
1666
|
-
// openai-api job harmlessly re-resolves to the same model.
|
|
1667
|
-
const TIER_MODELS = modelResolution.source === 'spec' ? { ...providerEntry.tiers, sonnet: MODEL } : providerEntry.tiers;
|
|
1668
|
-
/** @type {Record<string, any>} */
|
|
1669
|
-
const tierCache = {};
|
|
1670
|
-
providerFor = (/** @type {string} */ tier) => (tierCache[tier] ??= TIER_MODELS[/** @type {keyof typeof TIER_MODELS} */ (tier)] === MODEL ? provider : makeProvider(spec.provider, { apiKey: /** @type {string} */ (workerApiKey), model: TIER_MODELS[/** @type {keyof typeof TIER_MODELS} */ (tier)], baseUrl }));
|
|
1641
|
+
const legacyMaxTokens = W && W.ok ? W.row.legacyMaxTokens : false;
|
|
1642
|
+
provider = makeProvider(spec.provider, { apiKey: /** @type {string} */ (workerApiKey), model: MODEL, baseUrl, legacyMaxTokens });
|
|
1643
|
+
// P: the per-step model factory. The ONLY tier a plan may name is the schema token `sonnet` (STEP_MODELS, src/plan.js — a
|
|
1644
|
+
// documented schema token, not a model id); it means THIS job's worker model, so every step's provider is the one above.
|
|
1645
|
+
providerFor = () => provider;
|
|
1671
1646
|
// SOFTGREEN — the JUDGED stage's own provider. Since PRD item 32.1 its identity is
|
|
1672
1647
|
// RESOLVED (`judge` above), not pinned: the spec's signed `judge` override, else this
|
|
1673
1648
|
// job's own worker model. It is still never a step knob and never agent-selectable —
|
|
@@ -1684,7 +1659,7 @@ async function execute(ctx) {
|
|
|
1684
1659
|
// every live softgreen run would have done: run-author wired this seam and this
|
|
1685
1660
|
// runner never did.
|
|
1686
1661
|
judgeProvider = judgeApiKey
|
|
1687
|
-
? makeProvider(judge.provider, { apiKey: /** @type {string} */ (judgeApiKey), model: judge.model, baseUrl: judge.provider === spec.provider ? baseUrl : undefined })
|
|
1662
|
+
? makeProvider(judge.provider, { apiKey: /** @type {string} */ (judgeApiKey), model: judge.model, baseUrl: judge.provider === spec.provider ? baseUrl : (judgeRow && judgeRow.baseUrl.trim() !== '' ? judgeRow.baseUrl.trim() : undefined), legacyMaxTokens: judgeRow ? judgeRow.legacyMaxTokens : false })
|
|
1688
1663
|
: null;
|
|
1689
1664
|
}
|
|
1690
1665
|
|
|
@@ -2433,6 +2408,7 @@ function buildCtx(mode, opts) {
|
|
|
2433
2408
|
spineName: /** @type {string} */ (opts.spineName),
|
|
2434
2409
|
...(opts.into === undefined ? {} : { into: opts.into }),
|
|
2435
2410
|
model: opts.model ?? null,
|
|
2411
|
+
providerKey: opts.providerKey ?? null,
|
|
2436
2412
|
readShim: opts.readShim ?? null,
|
|
2437
2413
|
scout: opts.scout ?? null,
|
|
2438
2414
|
draftSpentUsd: opts.draftSpentUsd ?? null,
|
|
@@ -2661,6 +2637,7 @@ export async function main(argv, deps = {}) {
|
|
|
2661
2637
|
spineName: target.spine,
|
|
2662
2638
|
...(target.into === undefined ? {} : { into: target.into }),
|
|
2663
2639
|
model: argFlag('model'),
|
|
2640
|
+
providerKey: argFlag('provider'),
|
|
2664
2641
|
readShim: argFlag('read-shim'),
|
|
2665
2642
|
scout: argFlag('scout'),
|
|
2666
2643
|
draftSpentUsd: argFlag('draft-spent-usd'),
|
package/types/authorflow.d.ts
CHANGED
|
@@ -619,7 +619,7 @@ export function resolveSourcePrefixes({ workdir, sourcePaths, seedFiles }: {
|
|
|
619
619
|
*/
|
|
620
620
|
/**
|
|
621
621
|
* @param {{ceilingUsd?: number|null,
|
|
622
|
-
* onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number,
|
|
622
|
+
* onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number, thinkingStatus?: string}) => void}} [o]
|
|
623
623
|
* `ceilingUsd` is the OPERATOR's ceiling; `null`/absent is UNBOUNDED.
|
|
624
624
|
* `onCall` is a REPORTING seam fired as each metered call lands — the shell's
|
|
625
625
|
* only chance to know what has been spent while the run is still alive. It is
|
|
@@ -635,7 +635,7 @@ export function makeCostBook({ ceilingUsd, onCall }?: {
|
|
|
635
635
|
label: string;
|
|
636
636
|
costUsd: number | null;
|
|
637
637
|
unpricedRounds: number;
|
|
638
|
-
|
|
638
|
+
thinkingStatus?: string;
|
|
639
639
|
}) => void;
|
|
640
640
|
}): {
|
|
641
641
|
/** @param {string} label @param {any} r a bare-agent run result @param {number} [attempt] */
|
|
@@ -700,7 +700,7 @@ export function makeCostBook({ ceilingUsd, onCall }?: {
|
|
|
700
700
|
* `cacheMessages` (F18) and `maxTokens` (F30) are not optional on this stack.
|
|
701
701
|
* `rates` is the customer's own price for this provider's key row (USD per 1K, `ratesFor`);
|
|
702
702
|
* absent = bare-agent's built-in guess, exactly as before.
|
|
703
|
-
* `draftThinking` ('on' | 'off',
|
|
703
|
+
* `draftThinking` ('on' | 'off', the job's "Thinking on" tick spelled as a word; default 'off') adds the drafter's per-call thinking option via `thinkingCallOptions` (src/thinking.js, the one owner).
|
|
704
704
|
* @param {any} provider @param {{system?: string, maxTokens?: number, rates?: {in: number, out: number}|null, draftThinking?: string}} [o]
|
|
705
705
|
* @returns {(messages: any[], tools: any[], opts?: any) => Promise<any>}
|
|
706
706
|
*/
|
|
@@ -936,7 +936,7 @@ export function runConfirmTurn({ verdictType, answers, questions, labels, facts,
|
|
|
936
936
|
* generate: Function, seedReadFn?: Function, closeCtx?: any,
|
|
937
937
|
* ceilingUsd?: number|null,
|
|
938
938
|
* onPhase?: (phase: string, data?: any) => void,
|
|
939
|
-
* onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number,
|
|
939
|
+
* onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number, thinkingStatus?: string}) => void,
|
|
940
940
|
* maxRevisions?: number, structureRetries?: number,
|
|
941
941
|
* structuredMode?: 'tool'|'text', catalogue?: Record<string, any>, writeScope?: string[]|null,
|
|
942
942
|
* priorCalls?: {label: string, costUsd: number|null, unpricedRounds: number}[]|null,
|
|
@@ -976,7 +976,7 @@ export function authorClose({ workdir, seedRef, lang, verdictType, answers, ques
|
|
|
976
976
|
label: string;
|
|
977
977
|
costUsd: number | null;
|
|
978
978
|
unpricedRounds: number;
|
|
979
|
-
|
|
979
|
+
thinkingStatus?: string;
|
|
980
980
|
}) => void;
|
|
981
981
|
maxRevisions?: number;
|
|
982
982
|
structureRetries?: number;
|
package/types/authorjob.d.ts
CHANGED
|
@@ -85,7 +85,7 @@ export function refuseLockedKind(kind: string): Refusal;
|
|
|
85
85
|
* seedRef?: string|null, scout?: any, listing?: any, ceilingUsd?: number|null, judgeModel?: string|null,
|
|
86
86
|
* rates?: {in: number, out: number}|null, draftThinking?: 'on'|'off',
|
|
87
87
|
* onPhase?: (phase: string, data?: any) => void,
|
|
88
|
-
* onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number,
|
|
88
|
+
* onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number, thinkingStatus?: string}) => void,
|
|
89
89
|
* seedFn?: Function, scoutFn?: Function, listingFn?: Function,
|
|
90
90
|
* authorFn?: Function, authorOpts?: object, writeScope?: string[]|null,
|
|
91
91
|
* signerFix?: Function|any, proposeFn?: Function, compileOpts?: object,
|
|
@@ -130,7 +130,7 @@ export function authorCloseForJob({ answers, repoPath, lang, verdictType, questi
|
|
|
130
130
|
label: string;
|
|
131
131
|
costUsd: number | null;
|
|
132
132
|
unpricedRounds: number;
|
|
133
|
-
|
|
133
|
+
thinkingStatus?: string;
|
|
134
134
|
}) => void;
|
|
135
135
|
seedFn?: Function;
|
|
136
136
|
scoutFn?: Function;
|
package/types/authorscout.d.ts
CHANGED
|
@@ -92,7 +92,7 @@ export function defaultSurveyor({ workdir, granted, auditPath, ctx }: {
|
|
|
92
92
|
* @param {{workdir: string, provider?: any,
|
|
93
93
|
* rounds?: number, minBytes?: number, blobMax?: number, maxTokens?: number, ctx?: boolean,
|
|
94
94
|
* attempts?: number, ceilingUsd?: number|null, callTimeoutMs?: number,
|
|
95
|
-
* onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number,
|
|
95
|
+
* onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number, thinkingStatus?: string}) => void,
|
|
96
96
|
* createLoop?: (o: {system: string, policy: any, onLlmResult: any, provider: any, rates?: {in: number, out: number}}) => any,
|
|
97
97
|
* rates?: {in: number, out: number}|null, callOptions?: Record<string, any>,
|
|
98
98
|
* createSurveyor?: (o: {workdir: string, granted: readonly string[], ctx: boolean}) => Promise<any>}} o
|
|
@@ -115,7 +115,7 @@ export function runAuthorScout({ workdir, provider, rounds, minBytes, blobMax, m
|
|
|
115
115
|
label: string;
|
|
116
116
|
costUsd: number | null;
|
|
117
117
|
unpricedRounds: number;
|
|
118
|
-
|
|
118
|
+
thinkingStatus?: string;
|
|
119
119
|
}) => void;
|
|
120
120
|
createLoop?: (o: {
|
|
121
121
|
system: string;
|
package/types/config.d.ts
CHANGED
|
@@ -16,15 +16,31 @@ export function configPath(home?: string): string;
|
|
|
16
16
|
export function readConfig(opts?: {
|
|
17
17
|
home?: string;
|
|
18
18
|
}): ConfigRead;
|
|
19
|
+
/**
|
|
20
|
+
* One key-row field's value problem in plain words, or null when fine.
|
|
21
|
+
* @param {string} field `model` | `shape` | `baseUrl` | `legacyMaxTokens`
|
|
22
|
+
* @param {unknown} v
|
|
23
|
+
* @returns {string|null}
|
|
24
|
+
*/
|
|
25
|
+
export function providerFieldProblem(field: string, v: unknown): string | null;
|
|
26
|
+
/**
|
|
27
|
+
* THE one rule for a row's model lines, used by config validation and the Settings routes. A price
|
|
28
|
+
* is a PAIR (`inPerM` and `outPerM`, each a finite number >= 0 — 0 / 0 typed is a chosen price) or
|
|
29
|
+
* neither (null / absent). A ticked line (`use`) needs both. Plain words, or null.
|
|
30
|
+
* @param {unknown} list
|
|
31
|
+
* @returns {string|null}
|
|
32
|
+
*/
|
|
33
|
+
export function modelsProblem(list: unknown): string | null;
|
|
19
34
|
/**
|
|
20
35
|
* Apply a patch and write. `null` deletes a field. Top-level fields shallow-merge;
|
|
21
|
-
* `keys` merges per key variable name, then per field
|
|
22
|
-
* written; nothing is written on a refusal.
|
|
36
|
+
* `keys` merges per key variable name, then per field; `models.<ENV>` is REPLACED WHOLE (`null`
|
|
37
|
+
* clears it). Validated before anything is written; nothing is written on a refusal.
|
|
23
38
|
*
|
|
24
|
-
* Patch fields understood: `monthlyLimitUsd` (finite > 0), `
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
39
|
+
* Patch fields understood: `monthlyLimitUsd` (finite > 0), `keys.<ENV>.{shape,baseUrl,legacyMaxTokens}`,
|
|
40
|
+
* `models.<ENV>` (a list judged by {@link modelsProblem}). The first write of a row's `models` list
|
|
41
|
+
* removes that row's older `name` / `priceInPerM` / `priceOutPerM` in the SAME write (never two
|
|
42
|
+
* sources); a retired top-level `anthropicBalanceNote` is dropped on any write. Any other field is
|
|
43
|
+
* kept, but the whole document is swept for secret-shaped strings first.
|
|
28
44
|
* @param {Record<string, any>} patch
|
|
29
45
|
* @param {{ home?: string }} [opts]
|
|
30
46
|
* @returns {Record<string, any>} the document as written
|
|
@@ -35,6 +51,7 @@ export function updateConfig(patch: Record<string, any>, opts?: {
|
|
|
35
51
|
/** A plain-words config failure (bad value, secret-shaped string, unreadable file). */
|
|
36
52
|
export class ConfigError extends Error {
|
|
37
53
|
}
|
|
54
|
+
export function cleanBaseUrl(v: string): string;
|
|
38
55
|
export type ConfigRead = {
|
|
39
56
|
/**
|
|
40
57
|
* the parsed document ({} when missing/unreadable)
|
package/types/draftspend.d.ts
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* One line of the drafting log. `no` = the step's position in the session's progress list (a step id can repeat).
|
|
3
3
|
* - `step-start` {no, id, label, at}
|
|
4
4
|
* - `step-end` {no, status: 'done'|'failed', label, at} (a re-opened step writes `step-reopen` {no, at} first)
|
|
5
|
-
* - `step-label` {no, label, at} (the step reads `label` from now on, status and times untouched: the thinking row's "the model thought anyway")
|
|
6
|
-
* - `call` {no, step, label, model, thinking,
|
|
7
|
-
* (`thinking` =
|
|
8
|
-
* call's run
|
|
5
|
+
* - `step-label` {no, label, at} (the step reads `label` from now on, status and times untouched: the thinking row's "the model thought anyway" / "can't change it" / "not confirmed")
|
|
6
|
+
* - `call` {no, step, label, model, thinking, thinkingSupport, thinkingStatus?, costUsd (null stays null), unpricedRounds, at}: one METERED model call
|
|
7
|
+
* (`thinking` = the tick's mode: off | on; `thinkingSupport` = bare-agent's lookup for the model: true | false | 'unverified';
|
|
8
|
+
* `thinkingStatus` = bare-agent's own verdict for the call's run: applied | unsupported | ignored | unknown, present only when thinkingMode was sent)
|
|
9
9
|
* (no token counts: the call path does not carry them without reworking the library, so none are recorded)
|
|
10
10
|
* @typedef {{kind: string, no: number, at: string, [k: string]: any}} DraftEvent
|
|
11
11
|
*/
|
|
@@ -108,10 +108,10 @@ export const DRAFT_LOG_FILE: "draft-log.jsonl";
|
|
|
108
108
|
* One line of the drafting log. `no` = the step's position in the session's progress list (a step id can repeat).
|
|
109
109
|
* - `step-start` {no, id, label, at}
|
|
110
110
|
* - `step-end` {no, status: 'done'|'failed', label, at} (a re-opened step writes `step-reopen` {no, at} first)
|
|
111
|
-
* - `step-label` {no, label, at} (the step reads `label` from now on, status and times untouched: the thinking row's "the model thought anyway")
|
|
112
|
-
* - `call` {no, step, label, model, thinking,
|
|
113
|
-
* (`thinking` =
|
|
114
|
-
* call's run
|
|
111
|
+
* - `step-label` {no, label, at} (the step reads `label` from now on, status and times untouched: the thinking row's "the model thought anyway" / "can't change it" / "not confirmed")
|
|
112
|
+
* - `call` {no, step, label, model, thinking, thinkingSupport, thinkingStatus?, costUsd (null stays null), unpricedRounds, at}: one METERED model call
|
|
113
|
+
* (`thinking` = the tick's mode: off | on; `thinkingSupport` = bare-agent's lookup for the model: true | false | 'unverified';
|
|
114
|
+
* `thinkingStatus` = bare-agent's own verdict for the call's run: applied | unsupported | ignored | unknown, present only when thinkingMode was sent)
|
|
115
115
|
* (no token counts: the call path does not carry them without reworking the library, so none are recorded)
|
|
116
116
|
*/
|
|
117
117
|
export type DraftEvent = {
|
package/types/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export { validateEnvelope, resolveTrySpec, resolveReuse, reuseSpecHash, selectBr
|
|
|
15
15
|
export { classifyIncidents, foldLedger, ledgerDeltas, updateLedger, LEDGER_CLASSES, VOUCHED_RATE_SOURCES, rateProvenance, spendProvenance } from "./ledger.js";
|
|
16
16
|
export { readShimArm, READ_SHIM_CAP, READ_SHIM_STRATEGY, READ_SHIM_DIFF_STRATEGY } from "./readshim.js";
|
|
17
17
|
export { runDeclaredClose, runStage, seedRead, seedAtHead, LIVE_KINDS, STOP_FAULTS, JUDGED_MARKER, HUMAN_DECISIONS, SEED_EXEMPT_KINDS, normalizeHumanRuling, resolveHumanRuling, JUDGE_ATTEMPTS, MAX_JUDGED_PATHS, DOOR_OPEN_OUTCOMES, REVIEW_DOOR_CLASSES, doorOpens, mechanicalStages } from "./kinds.js";
|
|
18
|
-
export {
|
|
18
|
+
export { resolveJudge, JUDGE_RULES, JUDGE_RULE_IDS, runLocate, decide, CALIBRATION_SIZE, validateCalibrationSet, expectedOf } from "./judged.js";
|
|
19
19
|
export { proposeJudgedArtifacts, signJudgedArtifacts, foldJudgedArtifacts } from "./cardauthor.js";
|
|
20
20
|
export { runCalibration, INJECTION_LOCATE_BATTERY, CASUALTY_AXES } from "./calibrate.js";
|
|
21
21
|
export { validateDeclaration, KIND_CATALOGUE, LOCKED_KINDS, genreEnv, genreInstruments, LOCKED_CLASSES, CLASS_BATTERIES, classGuards, closeCeiling, NEVER_OFFERED_KINDS } from "./authoring.js";
|
package/types/job.d.ts
CHANGED
|
@@ -122,18 +122,18 @@ export function checkApproval(job: object, approvals: unknown): boolean;
|
|
|
122
122
|
* mismatched flag is a mistake worth stopping on, never a silent swap); the
|
|
123
123
|
* same id from both is not a conflict. Extracted from scripts/run-u.mjs so
|
|
124
124
|
* the decision is testable without running the script or touching a provider.
|
|
125
|
-
* @param {{ specModel?: string, flagModel?: string,
|
|
125
|
+
* @param {{ specModel?: string, flagModel?: string, suppliedModel?: string }} args
|
|
126
126
|
* `specModel` — `job.model` if the signed spec carries one, else undefined.
|
|
127
127
|
* `flagModel` — the model id an explicit `--model <tier>` resolved to, else
|
|
128
128
|
* undefined (a flag that was never passed, not merely a default tier name).
|
|
129
|
-
* `
|
|
129
|
+
* `suppliedModel` — a model the CALLER supplies when neither spec nor flag says (bareloop keeps none of its own).
|
|
130
130
|
* @returns {{ model: string, source: 'spec'|'flag'|'default' }}
|
|
131
|
-
* @throws {Error} when the spec names a model and the flag names a different one
|
|
131
|
+
* @throws {Error} when the spec names a model and the flag names a different one, or when no model is named at all
|
|
132
132
|
*/
|
|
133
|
-
export function resolveWorkerModel({ specModel, flagModel,
|
|
133
|
+
export function resolveWorkerModel({ specModel, flagModel, suppliedModel }: {
|
|
134
134
|
specModel?: string;
|
|
135
135
|
flagModel?: string;
|
|
136
|
-
|
|
136
|
+
suppliedModel?: string;
|
|
137
137
|
}): {
|
|
138
138
|
model: string;
|
|
139
139
|
source: "spec" | "flag" | "default";
|
package/types/judged.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* item 31.4 a green job runs on its own key alone, and this is what lets a
|
|
18
18
|
* JUDGED one do the same.
|
|
19
19
|
*
|
|
20
|
-
* There is deliberately NO third fallback to
|
|
20
|
+
* There is deliberately NO third fallback to a library-pinned model. A caller that cannot
|
|
21
21
|
* say which model will grade has not wired a judge, and the grading path stops
|
|
22
22
|
* as a wiring gap rather than grading under an identity nobody chose — the same
|
|
23
23
|
* answer an absent `judgeLoop` already gets. A silent default here would be the
|
|
@@ -79,7 +79,7 @@ export function resolveJudge({ specJudge, workerProvider, workerModel }?: {
|
|
|
79
79
|
*
|
|
80
80
|
* @param {{provider?: string, model?: string, judge?: any}} source draft or spec
|
|
81
81
|
* @param {string} fallbackProviderName used only when `source.provider` is absent
|
|
82
|
-
* @param {(o: {specModel?: string, flagModel?: string,
|
|
82
|
+
* @param {(o: {specModel?: string, flagModel?: string, suppliedModel?: string}) => {model: string, source: string}} resolveWorkerModelFn `resolveWorkerModel` from `./job.js`
|
|
83
83
|
* @returns {{provider: string, model: string}}
|
|
84
84
|
*/
|
|
85
85
|
export function resolveJobJudge(source: {
|
|
@@ -89,7 +89,7 @@ export function resolveJobJudge(source: {
|
|
|
89
89
|
}, fallbackProviderName: string, resolveWorkerModelFn: (o: {
|
|
90
90
|
specModel?: string;
|
|
91
91
|
flagModel?: string;
|
|
92
|
-
|
|
92
|
+
suppliedModel?: string;
|
|
93
93
|
}) => {
|
|
94
94
|
model: string;
|
|
95
95
|
source: string;
|
|
@@ -309,38 +309,6 @@ export function decide(facts: any, card: any, { artifactText }?: {
|
|
|
309
309
|
firstRed: string | null;
|
|
310
310
|
reason: string | null;
|
|
311
311
|
};
|
|
312
|
-
/**
|
|
313
|
-
* THE JUDGE'S HISTORICAL PIN. Until PRD item 32 (2026-09-10) this constant WAS
|
|
314
|
-
* the judge: every grading path imported it, so bareloop could run a worker on
|
|
315
|
-
* any provider and still judge only on Claude.
|
|
316
|
-
*
|
|
317
|
-
* It is no longer read by any grading path. The judge identity is now RESOLVED
|
|
318
|
-
* per job (`resolveJudge` below) and travels as data — `ctx.judgeModel` into
|
|
319
|
-
* `runJudgedFloor`, an explicit argument into the calibration gate, and
|
|
320
|
-
* `closeDecl.calibration.judgeModel` into the signed spec, exactly as before.
|
|
321
|
-
* Keeping the export is deliberate: it is part of the public API
|
|
322
|
-
* (`src/index.js`) and an adopter importing it should not break on a minor.
|
|
323
|
-
* What it means now is "the judge bareloop pinned before item 32", which is
|
|
324
|
-
* still the right DEFAULT for an anthropic-api job and still the only tier with
|
|
325
|
-
* established injection resistance upstream (BA-20's `INJECTION_BATTERY` is
|
|
326
|
-
* haiku-4.5 only).
|
|
327
|
-
*
|
|
328
|
-
* THE ENFORCEMENT IS UNCHANGED, and still lives in three wired places because a
|
|
329
|
-
* rule with no detector is prose (F45) — only the value being compared moved
|
|
330
|
-
* from this constant to the resolved identity:
|
|
331
|
-
* 1. the identity is STORED with the set it graded — `foldJudgedArtifacts`
|
|
332
|
-
* writes it as `closeDecl.calibration.judgeModel`, inside the spec, so
|
|
333
|
-
* `jobSpecHash` covers it by construction. Change the judge and every
|
|
334
|
-
* signed judged spec hashes differently: the signature dies, and re-signing
|
|
335
|
-
* is what re-runs the calibration gate.
|
|
336
|
-
* 2. `validateCloseDecl` REQUIRES it on any stored set — a set nobody can
|
|
337
|
-
* attribute to a judge is a floor nobody can tell apart from a moved one.
|
|
338
|
-
* 3. `runJudgedFloor` refuses to grade when the stored identity is not the one
|
|
339
|
-
* about to grade, naming both. It does not degrade in either direction:
|
|
340
|
-
* grading on the new judge judges against a floor nobody calibrated, and
|
|
341
|
-
* the old judge is not on offer.
|
|
342
|
-
*/
|
|
343
|
-
export const JUDGE_MODEL: "claude-haiku-4-5";
|
|
344
312
|
/**
|
|
345
313
|
* The locate call's token ceiling. The POC's two real artifacts came back well
|
|
346
314
|
* inside 2000; this doubles that for headroom on a longer artifact, and the
|
|
@@ -402,13 +370,14 @@ export const JUDGE_RULE_IDS: readonly string[];
|
|
|
402
370
|
export const CALIBRATION_SIZE: 10;
|
|
403
371
|
/** the two verdicts a case may expect — `decide()`'s own closed set */
|
|
404
372
|
export const CASE_VERDICTS: readonly string[];
|
|
405
|
-
export function defaultJudgeLoop({ provider, system, rates }: {
|
|
373
|
+
export function defaultJudgeLoop({ provider, system, rates, thinking }: {
|
|
406
374
|
provider: any;
|
|
407
375
|
system: string;
|
|
408
376
|
rates?: {
|
|
409
377
|
in: number;
|
|
410
378
|
out: number;
|
|
411
379
|
} | null;
|
|
380
|
+
thinking?: boolean;
|
|
412
381
|
}): {
|
|
413
382
|
run: (msgs: any[], tools: any[], opts?: any) => Promise<any>;
|
|
414
383
|
};
|
package/types/keysfile.d.ts
CHANGED
|
@@ -25,19 +25,20 @@ export function parseKeysText(text: string): Record<string, string>;
|
|
|
25
25
|
*/
|
|
26
26
|
export function filledKeyNames(home?: string): string[];
|
|
27
27
|
/**
|
|
28
|
-
* Create the keys file with
|
|
29
|
-
* exist (mode 600). An existing file is never touched.
|
|
30
|
-
* @param {readonly string[]} presetNames the names to seed, in order
|
|
28
|
+
* Create the keys file with {@link KEYS_FILE_BODY} when — and only when — it does not
|
|
29
|
+
* exist (mode 600, dir 700). An existing file is never touched.
|
|
31
30
|
* @param {string} [home]
|
|
32
31
|
* @returns {boolean} true if it was created
|
|
33
32
|
*/
|
|
34
|
-
export function ensureKeysFile(
|
|
33
|
+
export function ensureKeysFile(home?: string): boolean;
|
|
35
34
|
/**
|
|
36
35
|
* @typedef {object} KeysLoad
|
|
37
36
|
* @property {boolean} exists the file is there
|
|
38
37
|
* @property {string[]} names the NAMES the file defines (sorted; never values)
|
|
39
38
|
* @property {string|null} warning a plain-words warning (file readable by others, or
|
|
40
39
|
* unreadable), else null — a warning, never a refusal
|
|
40
|
+
* @property {boolean} [unreadable] true only when the file is there but could not be read (the Settings row then
|
|
41
|
+
* reads "refused — see above"); absent otherwise
|
|
41
42
|
* @property {Record<string,string|undefined>} env shell env with the file filling the
|
|
42
43
|
* names the shell does not set. THE ONLY place values leave this module.
|
|
43
44
|
*/
|
|
@@ -68,6 +69,11 @@ export function keysForDoor(deps: {
|
|
|
68
69
|
env: Record<string, string | undefined>;
|
|
69
70
|
home: string | undefined;
|
|
70
71
|
};
|
|
72
|
+
/**
|
|
73
|
+
* The two comment lines a fresh keys file is created with — no provider name, no preset key.
|
|
74
|
+
* Each key the person types becomes a row in Settings > Providers.
|
|
75
|
+
*/
|
|
76
|
+
export const KEYS_FILE_BODY: string;
|
|
71
77
|
export type KeysLoad = {
|
|
72
78
|
/**
|
|
73
79
|
* the file is there
|
|
@@ -82,6 +88,11 @@ export type KeysLoad = {
|
|
|
82
88
|
* unreadable), else null — a warning, never a refusal
|
|
83
89
|
*/
|
|
84
90
|
warning: string | null;
|
|
91
|
+
/**
|
|
92
|
+
* true only when the file is there but could not be read (the Settings row then
|
|
93
|
+
* reads "refused — see above"); absent otherwise
|
|
94
|
+
*/
|
|
95
|
+
unreadable?: boolean | undefined;
|
|
85
96
|
/**
|
|
86
97
|
* shell env with the file filling the
|
|
87
98
|
* names the shell does not set. THE ONLY place values leave this module.
|