@foldrun/core 11.1.0 → 11.2.1
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/dist/src/evals.d.ts +9 -0
- package/dist/src/evals.js +14 -3
- package/dist/src/step-exec.d.ts +8 -0
- package/dist/src/step-exec.js +17 -1
- package/package.json +1 -1
- package/src/evals.ts +15 -3
- package/src/step-exec.ts +17 -1
package/dist/src/evals.d.ts
CHANGED
|
@@ -164,6 +164,15 @@ export interface EvalResult {
|
|
|
164
164
|
/** How long one judge may take before it is cut off: a verdict on one
|
|
165
165
|
* sentence is seconds; a stalled model must not hold a grade pass. */
|
|
166
166
|
export declare const JUDGE_TIMEOUT_MS = 120000;
|
|
167
|
+
/**
|
|
168
|
+
* The environment a judge's model process starts with: the host's PATH, HOME
|
|
169
|
+
* and temp folder under the model's own variables. An account's provider env
|
|
170
|
+
* is only its URL, key and models, and a CLI started with no HOME dies on
|
|
171
|
+
* uv_os_homedir in a pod whose user has no passwd entry (FOL-107). Never the
|
|
172
|
+
* host's secrets: hostSafeEnv is an allowlist, as for drafts and the
|
|
173
|
+
* assistant's tool loop.
|
|
174
|
+
*/
|
|
175
|
+
export declare function judgeSdkEnv(env: Record<string, string | undefined>): Record<string, string | undefined>;
|
|
167
176
|
/** One judge call: its words and what it cost (the SDK's result line). */
|
|
168
177
|
export declare function judgeCall(rubric: string, output: string, model: string, effort: Effort | null, env: Record<string, string | undefined>,
|
|
169
178
|
/** What the output was an answer to — a live run's task, so the judge
|
package/dist/src/evals.js
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
// they pass — no point paying a model to grade output already known to be
|
|
32
32
|
// wrong.
|
|
33
33
|
import { accountModelEnv, withModelEnv, ModelKeyError } from "./model-env.js";
|
|
34
|
-
import { sdkEnv } from "./step-exec.js";
|
|
34
|
+
import { sdkEnv, modelProcessError } from "./step-exec.js";
|
|
35
35
|
import { platformModelEnv } from "./runner.js";
|
|
36
36
|
import fs from "node:fs";
|
|
37
37
|
import crypto from "node:crypto";
|
|
@@ -467,6 +467,17 @@ function shell(command, cwd) {
|
|
|
467
467
|
/** How long one judge may take before it is cut off: a verdict on one
|
|
468
468
|
* sentence is seconds; a stalled model must not hold a grade pass. */
|
|
469
469
|
export const JUDGE_TIMEOUT_MS = 120_000;
|
|
470
|
+
/**
|
|
471
|
+
* The environment a judge's model process starts with: the host's PATH, HOME
|
|
472
|
+
* and temp folder under the model's own variables. An account's provider env
|
|
473
|
+
* is only its URL, key and models, and a CLI started with no HOME dies on
|
|
474
|
+
* uv_os_homedir in a pod whose user has no passwd entry (FOL-107). Never the
|
|
475
|
+
* host's secrets: hostSafeEnv is an allowlist, as for drafts and the
|
|
476
|
+
* assistant's tool loop.
|
|
477
|
+
*/
|
|
478
|
+
export function judgeSdkEnv(env) {
|
|
479
|
+
return { ...hostSafeEnv(), ...env };
|
|
480
|
+
}
|
|
470
481
|
/** One judge call: its words and what it cost (the SDK's result line). */
|
|
471
482
|
export async function judgeCall(rubric, output, model, effort, env,
|
|
472
483
|
/** What the output was an answer to — a live run's task, so the judge
|
|
@@ -491,7 +502,7 @@ context) {
|
|
|
491
502
|
allowedTools: [],
|
|
492
503
|
settingSources: [],
|
|
493
504
|
strictMcpConfig: true,
|
|
494
|
-
env,
|
|
505
|
+
env: judgeSdkEnv(env),
|
|
495
506
|
maxTurns: 1,
|
|
496
507
|
abortController: abort,
|
|
497
508
|
},
|
|
@@ -511,7 +522,7 @@ context) {
|
|
|
511
522
|
catch (err) {
|
|
512
523
|
if (abort.signal.aborted)
|
|
513
524
|
throw new Error(`the judge took longer than ${JUDGE_TIMEOUT_MS / 1000}s and was stopped`);
|
|
514
|
-
throw err;
|
|
525
|
+
throw modelProcessError(err, "judge");
|
|
515
526
|
}
|
|
516
527
|
finally {
|
|
517
528
|
clearTimeout(timer);
|
package/dist/src/step-exec.d.ts
CHANGED
|
@@ -332,6 +332,14 @@ export declare function judgePrompt(rubric: string, reply: string, work: string)
|
|
|
332
332
|
* "the only tools I have are the Claude Docs ones". `strictMcpConfig` keeps
|
|
333
333
|
* the rest of the on-disk MCP configuration out; this keeps the account's.
|
|
334
334
|
*/
|
|
335
|
+
/**
|
|
336
|
+
* A model process's failure as a person should read it: one short line. The
|
|
337
|
+
* SDK's error for a CLI that died carries the CLI's stderr, which can be KBs
|
|
338
|
+
* of its minified bundle — internal prompt text included (FOL-107) — so that
|
|
339
|
+
* part goes to the server log, never to an eval result or a trace. An error
|
|
340
|
+
* that is already short (an API error the model answered) is kept as it is.
|
|
341
|
+
*/
|
|
342
|
+
export declare function modelProcessError(err: unknown, where: string): Error;
|
|
335
343
|
export declare function sdkEnv(base: Record<string, string | undefined> | undefined, extra?: Record<string, string>): Record<string, string | undefined>;
|
|
336
344
|
/** The text of a tool result, whichever shape it came in: a string, or a
|
|
337
345
|
* list of content blocks of which only the text ones say anything. */
|
package/dist/src/step-exec.js
CHANGED
|
@@ -1101,7 +1101,7 @@ async function judgeReply(rubric, reply, work, env, signal, model = "haiku", eff
|
|
|
1101
1101
|
}
|
|
1102
1102
|
}
|
|
1103
1103
|
catch (err) {
|
|
1104
|
-
return `FAIL — the judge could not run: ${err
|
|
1104
|
+
return `FAIL — the judge could not run: ${modelProcessError(err, "verify judge").message}`;
|
|
1105
1105
|
}
|
|
1106
1106
|
return texts.join("\n").trim();
|
|
1107
1107
|
}
|
|
@@ -1167,6 +1167,22 @@ function runVerify(agentDir, command, env, data, signal) {
|
|
|
1167
1167
|
* "the only tools I have are the Claude Docs ones". `strictMcpConfig` keeps
|
|
1168
1168
|
* the rest of the on-disk MCP configuration out; this keeps the account's.
|
|
1169
1169
|
*/
|
|
1170
|
+
/**
|
|
1171
|
+
* A model process's failure as a person should read it: one short line. The
|
|
1172
|
+
* SDK's error for a CLI that died carries the CLI's stderr, which can be KBs
|
|
1173
|
+
* of its minified bundle — internal prompt text included (FOL-107) — so that
|
|
1174
|
+
* part goes to the server log, never to an eval result or a trace. An error
|
|
1175
|
+
* that is already short (an API error the model answered) is kept as it is.
|
|
1176
|
+
*/
|
|
1177
|
+
export function modelProcessError(err, where) {
|
|
1178
|
+
const full = err instanceof Error ? err.message : String(err);
|
|
1179
|
+
const at = full.indexOf(" stderr:");
|
|
1180
|
+
if (at < 0 && full.length <= 500)
|
|
1181
|
+
return err instanceof Error ? err : new Error(full);
|
|
1182
|
+
console.error(`[foldrun] ${where}: ${full}`);
|
|
1183
|
+
const head = (at >= 0 ? full.slice(0, at) : full.slice(0, 300)).trim().replace(/[.:]$/, "");
|
|
1184
|
+
return new Error(`${head} — the model process failed; the details are in the server log`);
|
|
1185
|
+
}
|
|
1170
1186
|
export function sdkEnv(base, extra = {}) {
|
|
1171
1187
|
return { ...(base ?? process.env), ...extra, ENABLE_CLAUDEAI_MCP_SERVERS: "false" };
|
|
1172
1188
|
}
|
package/package.json
CHANGED
package/src/evals.ts
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
|
|
34
34
|
import { accountModelEnv, withModelEnv, ModelKeyError } from "./model-env.ts";
|
|
35
35
|
import type { TranslatorSpec } from "./translator.ts";
|
|
36
|
-
import { sdkEnv } from "./step-exec.ts";
|
|
36
|
+
import { sdkEnv, modelProcessError } from "./step-exec.ts";
|
|
37
37
|
import { platformModelEnv } from "./runner.ts";
|
|
38
38
|
import fs from "node:fs";
|
|
39
39
|
import crypto from "node:crypto";
|
|
@@ -621,6 +621,18 @@ function shell(command: string, cwd: string): Promise<{ code: number | null; out
|
|
|
621
621
|
* sentence is seconds; a stalled model must not hold a grade pass. */
|
|
622
622
|
export const JUDGE_TIMEOUT_MS = 120_000;
|
|
623
623
|
|
|
624
|
+
/**
|
|
625
|
+
* The environment a judge's model process starts with: the host's PATH, HOME
|
|
626
|
+
* and temp folder under the model's own variables. An account's provider env
|
|
627
|
+
* is only its URL, key and models, and a CLI started with no HOME dies on
|
|
628
|
+
* uv_os_homedir in a pod whose user has no passwd entry (FOL-107). Never the
|
|
629
|
+
* host's secrets: hostSafeEnv is an allowlist, as for drafts and the
|
|
630
|
+
* assistant's tool loop.
|
|
631
|
+
*/
|
|
632
|
+
export function judgeSdkEnv(env: Record<string, string | undefined>): Record<string, string | undefined> {
|
|
633
|
+
return { ...hostSafeEnv(), ...env };
|
|
634
|
+
}
|
|
635
|
+
|
|
624
636
|
/** One judge call: its words and what it cost (the SDK's result line). */
|
|
625
637
|
export async function judgeCall(
|
|
626
638
|
rubric: string,
|
|
@@ -653,7 +665,7 @@ export async function judgeCall(
|
|
|
653
665
|
allowedTools: [],
|
|
654
666
|
settingSources: [],
|
|
655
667
|
strictMcpConfig: true,
|
|
656
|
-
env,
|
|
668
|
+
env: judgeSdkEnv(env),
|
|
657
669
|
maxTurns: 1,
|
|
658
670
|
abortController: abort,
|
|
659
671
|
},
|
|
@@ -669,7 +681,7 @@ export async function judgeCall(
|
|
|
669
681
|
}
|
|
670
682
|
} catch (err) {
|
|
671
683
|
if (abort.signal.aborted) throw new Error(`the judge took longer than ${JUDGE_TIMEOUT_MS / 1000}s and was stopped`);
|
|
672
|
-
throw err;
|
|
684
|
+
throw modelProcessError(err, "judge");
|
|
673
685
|
} finally {
|
|
674
686
|
clearTimeout(timer);
|
|
675
687
|
}
|
package/src/step-exec.ts
CHANGED
|
@@ -1309,7 +1309,7 @@ async function judgeReply(
|
|
|
1309
1309
|
}
|
|
1310
1310
|
}
|
|
1311
1311
|
} catch (err) {
|
|
1312
|
-
return `FAIL — the judge could not run: ${err
|
|
1312
|
+
return `FAIL — the judge could not run: ${modelProcessError(err, "verify judge").message}`;
|
|
1313
1313
|
}
|
|
1314
1314
|
return texts.join("\n").trim();
|
|
1315
1315
|
}
|
|
@@ -1377,6 +1377,22 @@ function runVerify(
|
|
|
1377
1377
|
* "the only tools I have are the Claude Docs ones". `strictMcpConfig` keeps
|
|
1378
1378
|
* the rest of the on-disk MCP configuration out; this keeps the account's.
|
|
1379
1379
|
*/
|
|
1380
|
+
/**
|
|
1381
|
+
* A model process's failure as a person should read it: one short line. The
|
|
1382
|
+
* SDK's error for a CLI that died carries the CLI's stderr, which can be KBs
|
|
1383
|
+
* of its minified bundle — internal prompt text included (FOL-107) — so that
|
|
1384
|
+
* part goes to the server log, never to an eval result or a trace. An error
|
|
1385
|
+
* that is already short (an API error the model answered) is kept as it is.
|
|
1386
|
+
*/
|
|
1387
|
+
export function modelProcessError(err: unknown, where: string): Error {
|
|
1388
|
+
const full = err instanceof Error ? err.message : String(err);
|
|
1389
|
+
const at = full.indexOf(" stderr:");
|
|
1390
|
+
if (at < 0 && full.length <= 500) return err instanceof Error ? err : new Error(full);
|
|
1391
|
+
console.error(`[foldrun] ${where}: ${full}`);
|
|
1392
|
+
const head = (at >= 0 ? full.slice(0, at) : full.slice(0, 300)).trim().replace(/[.:]$/, "");
|
|
1393
|
+
return new Error(`${head} — the model process failed; the details are in the server log`);
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1380
1396
|
export function sdkEnv(base: Record<string, string | undefined> | undefined, extra: Record<string, string> = {}): Record<string, string | undefined> {
|
|
1381
1397
|
return { ...(base ?? process.env), ...extra, ENABLE_CLAUDEAI_MCP_SERVERS: "false" };
|
|
1382
1398
|
}
|