auto-mode 3.1.2 → 3.1.4
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/cli.js +6 -4
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -1
- package/dist/{parse-action-request-qyh3MBGg.js → parse-action-request-DlsgKqiF.js} +85 -15
- package/dist/{start-judge-server-CDYdRR4I.js → start-judge-server-BaeD4mmu.js} +1 -1
- package/dist/start-judge-session-B65PMvQ6.js +1 -0
- package/dist/{start-judge-session-vhUxe9-V.js → start-judge-session-C_k8lacU.js} +17 -12
- package/mods/auto-mode/contract/types.ts +1 -0
- package/mods/auto-mode/hooks/build-prompt-context.ts +15 -2
- package/mods/auto-mode/hooks/types.ts +1 -0
- package/package.json +2 -2
- package/dist/start-judge-session-C0eRJFlg.js +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as pickJudgeLane, E as updateJSONFile, S as CLI_LIMITS, T as resolveXDGDir, _ as readCheckout, a as resolveSessionScopePath, b as loadConfig, c as splitGitCommand, d as loadCheckoutFacts, f as writeActionDiagnostic, g as isUnresolvedWord, h as resolveShellPath, i as classifyAction, l as loadPolicy, m as collectShellCommands, n as readRuntime, o as loadSessionScope, p as toRepositorySlug, s as EMPTY_SESSION_SCOPE, t as parseActionRequest, u as resolveShippedPolicyDir, v as readGitEntry, w as M, x as runCapped, y as DEFAULT_SCOPE_SOURCES } from "./parse-action-request-
|
|
3
|
-
import { a as literal, d as string, i as discriminatedUnion, r as boolean, s as number, u as strictObject } from "./schemas-B80Yxv6m.js";
|
|
2
|
+
import { C as pickJudgeLane, E as updateJSONFile, S as CLI_LIMITS, T as resolveXDGDir, _ as readCheckout, a as resolveSessionScopePath, b as loadConfig, c as splitGitCommand, d as loadCheckoutFacts, f as writeActionDiagnostic, g as isUnresolvedWord, h as resolveShellPath, i as classifyAction, l as loadPolicy, m as collectShellCommands, n as readRuntime, o as loadSessionScope, p as toRepositorySlug, s as EMPTY_SESSION_SCOPE, t as parseActionRequest, u as resolveShippedPolicyDir, v as readGitEntry, w as M, x as runCapped, y as DEFAULT_SCOPE_SOURCES } from "./parse-action-request-DlsgKqiF.js";
|
|
3
|
+
import { a as literal, d as string, i as discriminatedUnion, l as record, p as unknown, r as boolean, s as number, u as strictObject } from "./schemas-B80Yxv6m.js";
|
|
4
4
|
import { createHash, randomUUID } from "node:crypto";
|
|
5
5
|
import { chmod, mkdir, open, readFile, realpath, stat } from "node:fs/promises";
|
|
6
6
|
import { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
@@ -2665,13 +2665,15 @@ function startDetachedProcess(file, args, env) {
|
|
|
2665
2665
|
}
|
|
2666
2666
|
//#endregion
|
|
2667
2667
|
//#region src/judge/judge-server-response-schema.ts
|
|
2668
|
+
const modelUsageSchema = record(string(), unknown());
|
|
2668
2669
|
const judgeServerResponseSchema = discriminatedUnion("kind", [strictObject({
|
|
2669
2670
|
kind: literal("reply"),
|
|
2670
2671
|
text: string(),
|
|
2671
2672
|
model: string(),
|
|
2672
2673
|
safetyStops: number().nullable(),
|
|
2673
2674
|
fallback: boolean(),
|
|
2674
|
-
warm: boolean().nullable()
|
|
2675
|
+
warm: boolean().nullable(),
|
|
2676
|
+
modelUsage: modelUsageSchema.nullable()
|
|
2675
2677
|
}), strictObject({
|
|
2676
2678
|
kind: literal("failure"),
|
|
2677
2679
|
aborted: boolean(),
|
|
@@ -3283,7 +3285,7 @@ async function runJudgeServer(io, socketPath) {
|
|
|
3283
3285
|
io.stderr.write(`auto-mode: judge-server needs a socket path\n\n${USAGE}`);
|
|
3284
3286
|
return 2;
|
|
3285
3287
|
}
|
|
3286
|
-
await (await (await import("./start-judge-server-
|
|
3288
|
+
await (await (await import("./start-judge-server-BaeD4mmu.js")).startJudgeServer({
|
|
3287
3289
|
socketPath,
|
|
3288
3290
|
env: io.runtime.host.env,
|
|
3289
3291
|
idleMs: JUDGE_IDLE_MS
|
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ interface JudgeMessageReply {
|
|
|
20
20
|
readonly safetyStops: number | null;
|
|
21
21
|
readonly fallback: boolean;
|
|
22
22
|
readonly warm: boolean | null;
|
|
23
|
+
readonly modelUsage: Readonly<Record<string, unknown>> | null;
|
|
23
24
|
}
|
|
24
25
|
interface JudgeSession {
|
|
25
26
|
readonly review: (model: string, request: Readonly<ModelRequest>, signal: Readonly<AbortSignal>) => Promise<JudgeMessageReply>;
|
|
@@ -30,6 +31,7 @@ interface JudgeDiagnostics {
|
|
|
30
31
|
readonly status: JudgeStatus;
|
|
31
32
|
readonly failureReason: JudgeFailure | null;
|
|
32
33
|
readonly overturnBasis: OverturnBasis | null;
|
|
34
|
+
readonly overturnReason: string | null;
|
|
33
35
|
readonly model: string;
|
|
34
36
|
readonly answeringModel: string | null;
|
|
35
37
|
readonly safetyStops: number | null;
|
|
@@ -148,6 +150,7 @@ interface UserTask {
|
|
|
148
150
|
}
|
|
149
151
|
interface DirectUserMessage extends UserTask {
|
|
150
152
|
readonly freshness?: 'stale' | undefined;
|
|
153
|
+
readonly position?: 'opening' | undefined;
|
|
151
154
|
}
|
|
152
155
|
interface DelegatedTask {
|
|
153
156
|
readonly text: string;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as loadConfig$1, i as classifyAction$1, n as readRuntime, r as readHostEnvironment, t as parseActionRequest } from "./parse-action-request-
|
|
1
|
+
import { b as loadConfig$1, i as classifyAction$1, n as readRuntime, r as readHostEnvironment, t as parseActionRequest } from "./parse-action-request-DlsgKqiF.js";
|
|
2
2
|
//#region src/index.ts
|
|
3
3
|
function classifyAction(request, config, options = {}) {
|
|
4
4
|
return classifyAction$1(request, config, {
|
|
@@ -3091,7 +3091,7 @@ async function writeActionDiagnostic(payload, entry, host, warnings) {
|
|
|
3091
3091
|
const agentKey = agentID === null ? payload.sessionID : `${payload.sessionID}\0${agentID}`;
|
|
3092
3092
|
const isReviewed = entry.judge !== void 0 || entry.grant !== void 0;
|
|
3093
3093
|
const record = {
|
|
3094
|
-
schemaVersion:
|
|
3094
|
+
schemaVersion: 8,
|
|
3095
3095
|
time: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3096
3096
|
invocationID: entry.invocationID,
|
|
3097
3097
|
sessionHash: toHash(payload.sessionID),
|
|
@@ -3103,8 +3103,8 @@ async function writeActionDiagnostic(payload, entry, host, warnings) {
|
|
|
3103
3103
|
denials: entry.denials ?? null,
|
|
3104
3104
|
escalation: entry.escalation ?? false,
|
|
3105
3105
|
diagnostics: entry.diagnostics ?? null,
|
|
3106
|
-
judge: entry.judge
|
|
3107
|
-
grant: entry.grant
|
|
3106
|
+
judge: entry.judge === void 0 ? null : buildLoggedReview(entry.judge),
|
|
3107
|
+
grant: entry.grant === void 0 ? null : buildLoggedReview(entry.grant),
|
|
3108
3108
|
action: isReviewed ? buildLoggedAction(payload) : null
|
|
3109
3109
|
};
|
|
3110
3110
|
try {
|
|
@@ -3120,6 +3120,17 @@ async function writeActionDiagnostic(payload, entry, host, warnings) {
|
|
|
3120
3120
|
function toHash(value) {
|
|
3121
3121
|
return createHash("sha256").update(value).digest("hex").slice(0, 16);
|
|
3122
3122
|
}
|
|
3123
|
+
function buildLoggedReview(review) {
|
|
3124
|
+
if (review.overturnReason === null) return review;
|
|
3125
|
+
const reason = buildSecretFreeText(review.overturnReason, () => "[secret]");
|
|
3126
|
+
return {
|
|
3127
|
+
...review,
|
|
3128
|
+
overturnReason: findSecret({
|
|
3129
|
+
text: reason,
|
|
3130
|
+
path: null
|
|
3131
|
+
}) === null ? reason : null
|
|
3132
|
+
};
|
|
3133
|
+
}
|
|
3123
3134
|
const LOGGED_INPUT_MAX_CHARS = 2e3;
|
|
3124
3135
|
function buildLoggedAction(payload) {
|
|
3125
3136
|
const redacted = buildSecretFreeValue(payload.toolInput);
|
|
@@ -3149,6 +3160,25 @@ function hasSecret(value) {
|
|
|
3149
3160
|
return false;
|
|
3150
3161
|
}
|
|
3151
3162
|
//#endregion
|
|
3163
|
+
//#region src/diagnostics/write-judge-usage.ts
|
|
3164
|
+
async function writeJudgeUsage(usage, host, warnings) {
|
|
3165
|
+
const path = host.env["AUTO_MODE_DEBUG_PATH"];
|
|
3166
|
+
if (path === void 0 || path === "") return;
|
|
3167
|
+
const line = {
|
|
3168
|
+
time: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3169
|
+
...usage
|
|
3170
|
+
};
|
|
3171
|
+
try {
|
|
3172
|
+
await mkdir(dirname(path), {
|
|
3173
|
+
recursive: true,
|
|
3174
|
+
mode: 448
|
|
3175
|
+
});
|
|
3176
|
+
await appendFile(path, `${JSON.stringify(line)}\n`, { mode: 384 });
|
|
3177
|
+
} catch {
|
|
3178
|
+
warnings.write("auto-mode: judge debug line unavailable\n");
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3181
|
+
//#endregion
|
|
3152
3182
|
//#region src/git/build-repository-context.ts
|
|
3153
3183
|
function buildRepositoryContext(facts) {
|
|
3154
3184
|
if (facts.head === null) return null;
|
|
@@ -3571,18 +3601,24 @@ function buildJudgedVerdict(rule, basis, reply, options) {
|
|
|
3571
3601
|
if (reply === null || reply.kind === "unreadable") return {
|
|
3572
3602
|
verdict: template,
|
|
3573
3603
|
status: "failed",
|
|
3574
|
-
overturnBasis: null
|
|
3604
|
+
overturnBasis: null,
|
|
3605
|
+
overturnReason: null
|
|
3575
3606
|
};
|
|
3576
3607
|
if (reply.kind === "overturn") {
|
|
3577
3608
|
const clearsHardRule = reply.basis === "misread" && options.misreadClears === true;
|
|
3578
|
-
|
|
3609
|
+
const isHeld = rule.tier === "hard" && !clearsHardRule || reply.basis === "misread" && options.overturns === "consent" || reply.basis === "consent" && !options.hasUserMessage;
|
|
3610
|
+
const overturn = {
|
|
3611
|
+
overturnBasis: reply.basis,
|
|
3612
|
+
overturnReason: formatJudgeText(buildSecretFreeText(reply.reason, () => "[secret]"))
|
|
3613
|
+
};
|
|
3614
|
+
return isHeld ? {
|
|
3579
3615
|
verdict: template,
|
|
3580
3616
|
status: "held",
|
|
3581
|
-
|
|
3617
|
+
...overturn
|
|
3582
3618
|
} : {
|
|
3583
3619
|
verdict: { kind: "allow" },
|
|
3584
3620
|
status: "overturned",
|
|
3585
|
-
|
|
3621
|
+
...overturn
|
|
3586
3622
|
};
|
|
3587
3623
|
}
|
|
3588
3624
|
return {
|
|
@@ -3592,7 +3628,8 @@ function buildJudgedVerdict(rule, basis, reply, options) {
|
|
|
3592
3628
|
reason: `The reviewer confirmed the ${rule.name} deny: ${formatJudgeText(reply.reason)}`
|
|
3593
3629
|
},
|
|
3594
3630
|
status: "confirmed",
|
|
3595
|
-
overturnBasis: null
|
|
3631
|
+
overturnBasis: null,
|
|
3632
|
+
overturnReason: null
|
|
3596
3633
|
};
|
|
3597
3634
|
}
|
|
3598
3635
|
function formatJudgeText(text) {
|
|
@@ -3808,7 +3845,7 @@ function sendJudgeMessage(provider, request, transport, signal) {
|
|
|
3808
3845
|
}
|
|
3809
3846
|
async function sendToAgentSDK(provider, request, transport, signal) {
|
|
3810
3847
|
if (transport.session !== void 0) return transport.session.review(provider.model, request, signal);
|
|
3811
|
-
const session = (await import("./start-judge-session-
|
|
3848
|
+
const session = (await import("./start-judge-session-B65PMvQ6.js")).startJudgeSession(transport.env);
|
|
3812
3849
|
try {
|
|
3813
3850
|
return await session.review(provider.model, request, signal);
|
|
3814
3851
|
} finally {
|
|
@@ -3822,7 +3859,8 @@ async function sendToMessagesAPI(provider, request, transport, signal) {
|
|
|
3822
3859
|
model: provider.model,
|
|
3823
3860
|
safetyStops: null,
|
|
3824
3861
|
fallback: false,
|
|
3825
|
-
warm: null
|
|
3862
|
+
warm: null,
|
|
3863
|
+
modelUsage: null
|
|
3826
3864
|
};
|
|
3827
3865
|
}
|
|
3828
3866
|
//#endregion
|
|
@@ -3833,6 +3871,7 @@ async function classifyWithJudge(payload, evidence, judge, options) {
|
|
|
3833
3871
|
let failure = null;
|
|
3834
3872
|
let answered = null;
|
|
3835
3873
|
let replies = evidence.map(() => null);
|
|
3874
|
+
const directMessage = findCurrentDirectUserMessage(payload.decisionContext?.lastDirectUserMessage);
|
|
3836
3875
|
try {
|
|
3837
3876
|
failure = "credential";
|
|
3838
3877
|
const needsKey = pickJudgeLane(judge).credential === "api-key";
|
|
@@ -3840,7 +3879,6 @@ async function classifyWithJudge(payload, evidence, judge, options) {
|
|
|
3840
3879
|
if (needsKey && apiKey === null) throw new Error("no API key for the judge");
|
|
3841
3880
|
failure = "policy";
|
|
3842
3881
|
const system = await loadPolicy({ rulesPath: options.rulesPath }, "judge.md");
|
|
3843
|
-
const directMessage = findCurrentDirectUserMessage(payload.decisionContext?.lastDirectUserMessage);
|
|
3844
3882
|
const user = buildJudgeMessage({
|
|
3845
3883
|
denies: evidence.map((entry) => ({
|
|
3846
3884
|
rule: entry.rule,
|
|
@@ -3872,6 +3910,11 @@ async function classifyWithJudge(payload, evidence, judge, options) {
|
|
|
3872
3910
|
throw error;
|
|
3873
3911
|
});
|
|
3874
3912
|
replies = parseJudgeReplies(answered.text, evidence.map((entry) => entry.rule.name));
|
|
3913
|
+
if (answered.modelUsage !== null) await options.onUsage?.({
|
|
3914
|
+
model: judge.model,
|
|
3915
|
+
answeringModel: answered.model,
|
|
3916
|
+
modelUsage: answered.modelUsage
|
|
3917
|
+
});
|
|
3875
3918
|
failure = null;
|
|
3876
3919
|
} catch {}
|
|
3877
3920
|
const elapsedMs = Math.round(performance.now() - start);
|
|
@@ -3881,7 +3924,8 @@ async function classifyWithJudge(payload, evidence, judge, options) {
|
|
|
3881
3924
|
const verdict = buildJudgedVerdict(entry.rule, entry.basis, reply, {
|
|
3882
3925
|
overturns,
|
|
3883
3926
|
heldReason: entry.containment?.reason,
|
|
3884
|
-
misreadClears: entry.misreadClears
|
|
3927
|
+
misreadClears: entry.misreadClears,
|
|
3928
|
+
hasUserMessage: directMessage !== null
|
|
3885
3929
|
});
|
|
3886
3930
|
return {
|
|
3887
3931
|
...verdict,
|
|
@@ -3889,6 +3933,7 @@ async function classifyWithJudge(payload, evidence, judge, options) {
|
|
|
3889
3933
|
status: verdict.status,
|
|
3890
3934
|
failureReason: failure ?? (reply?.kind === "unreadable" ? "unreadable" : null),
|
|
3891
3935
|
overturnBasis: verdict.overturnBasis,
|
|
3936
|
+
overturnReason: verdict.overturnReason,
|
|
3892
3937
|
model: judge.model,
|
|
3893
3938
|
answeringModel: answered?.model ?? null,
|
|
3894
3939
|
safetyStops: answered?.safetyStops ?? null,
|
|
@@ -5927,6 +5972,28 @@ async function loadTaskScope(request, sources, host, stderr) {
|
|
|
5927
5972
|
});
|
|
5928
5973
|
}
|
|
5929
5974
|
//#endregion
|
|
5975
|
+
//#region src/scope/probe-launcher-spawner.ts
|
|
5976
|
+
async function probeLauncherSpawner(location, readTextFile) {
|
|
5977
|
+
const load = await loadScopeFile(location, readTextFile);
|
|
5978
|
+
return load.kind === "malformed" || load.kind === "scope" && load.scope.replyChannels.length > 0;
|
|
5979
|
+
}
|
|
5980
|
+
//#endregion
|
|
5981
|
+
//#region src/scope/resolve-opening-prompt.ts
|
|
5982
|
+
async function resolveOpeningPrompt(request, runtime) {
|
|
5983
|
+
const context = request.decisionContext;
|
|
5984
|
+
const message = context?.lastDirectUserMessage;
|
|
5985
|
+
if (context === void 0 || message?.position !== "opening") return request;
|
|
5986
|
+
const { position: _, ...unmarked } = message;
|
|
5987
|
+
const isSpawned = await probeLauncherSpawner(runtime.host.env["AUTO_MODE_SCOPE_FILE"], runtime.readTextFile);
|
|
5988
|
+
return {
|
|
5989
|
+
...request,
|
|
5990
|
+
decisionContext: {
|
|
5991
|
+
...context,
|
|
5992
|
+
lastDirectUserMessage: isSpawned ? null : unmarked
|
|
5993
|
+
}
|
|
5994
|
+
};
|
|
5995
|
+
}
|
|
5996
|
+
//#endregion
|
|
5930
5997
|
//#region src/classify-action.ts
|
|
5931
5998
|
async function classifyAction(request, config, options) {
|
|
5932
5999
|
const stderr = options.stderr;
|
|
@@ -5936,7 +6003,8 @@ async function classifyAction(request, config, options) {
|
|
|
5936
6003
|
invocationID,
|
|
5937
6004
|
status: "started"
|
|
5938
6005
|
}, host, stderr);
|
|
5939
|
-
const
|
|
6006
|
+
const resolved = await resolveOpeningPrompt(request, options.runtime);
|
|
6007
|
+
const outcome = options.budget === true ? await classifyWithBudget(resolved, config, options) : await classifyStages(resolved, config, options);
|
|
5940
6008
|
if (options.actionLog === true) await writeActionDiagnostic(request, {
|
|
5941
6009
|
invocationID,
|
|
5942
6010
|
status: outcome.status,
|
|
@@ -6217,7 +6285,8 @@ async function classifyWithGrant(ctx, decided) {
|
|
|
6217
6285
|
const judged = await classifyWithJudge(ctx.request, evidence, judge, {
|
|
6218
6286
|
...ctx.options,
|
|
6219
6287
|
rulesPath: ctx.config.rulesPath,
|
|
6220
|
-
overturns: ctx.config.judgeOverturns ?? "any"
|
|
6288
|
+
overturns: ctx.config.judgeOverturns ?? "any",
|
|
6289
|
+
onUsage: (usage) => writeJudgeUsage(usage, ctx.options.runtime.host, ctx.options.stderr)
|
|
6221
6290
|
});
|
|
6222
6291
|
const granted = grant === null ? null : judged[0] ?? null;
|
|
6223
6292
|
const reviewed = denied === null ? null : judged.at(-1) ?? null;
|
|
@@ -6294,7 +6363,8 @@ const userTaskSchema = strictObject({
|
|
|
6294
6363
|
});
|
|
6295
6364
|
const directUserMessageSchema = strictObject({
|
|
6296
6365
|
...userTaskSchema.shape,
|
|
6297
|
-
freshness: literal("stale").optional()
|
|
6366
|
+
freshness: literal("stale").optional(),
|
|
6367
|
+
position: literal("opening").optional()
|
|
6298
6368
|
});
|
|
6299
6369
|
const delegatedTaskSchema = strictObject({
|
|
6300
6370
|
text: string(),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { d as string, s as number, u as strictObject } from "./schemas-B80Yxv6m.js";
|
|
2
|
-
import { t as startJudgeSession } from "./start-judge-session-
|
|
2
|
+
import { t as startJudgeSession } from "./start-judge-session-C_k8lacU.js";
|
|
3
3
|
import { randomBytes } from "node:crypto";
|
|
4
4
|
import { chmod, mkdir, rename, rm, stat } from "node:fs/promises";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { t as startJudgeSession } from "./start-judge-session-C_k8lacU.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as object, d as string, l as record, s as number } from "./schemas-B80Yxv6m.js";
|
|
1
|
+
import { c as object, d as string, l as record, p as unknown, s as number } from "./schemas-B80Yxv6m.js";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import ut, { delimiter, isAbsolute, join } from "node:path";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
@@ -39277,7 +39277,7 @@ function startJudgeSession(env) {
|
|
|
39277
39277
|
current.reviews += 1;
|
|
39278
39278
|
if (turn.sessionFallback) stop();
|
|
39279
39279
|
else current.cleared = sendClear(current.send, current.stop);
|
|
39280
|
-
return buildReply(turn
|
|
39280
|
+
return buildReply(turn, model, warm);
|
|
39281
39281
|
} catch (error) {
|
|
39282
39282
|
if (signal.aborted) throw new DOMException("Judge review aborted", "AbortError");
|
|
39283
39283
|
throw error;
|
|
@@ -39343,13 +39343,18 @@ function startLiveProcess(model, system, key, env) {
|
|
|
39343
39343
|
waiter.sessionFallback ||= message.scope !== "local";
|
|
39344
39344
|
return;
|
|
39345
39345
|
}
|
|
39346
|
+
if (message.type === "assistant" && message.parent_tool_use_id === null && message.error === void 0) {
|
|
39347
|
+
waiter.replyModel = message.message.model;
|
|
39348
|
+
return;
|
|
39349
|
+
}
|
|
39346
39350
|
if (message.type === "result") {
|
|
39347
39351
|
const done = waiter;
|
|
39348
39352
|
waiter = null;
|
|
39349
39353
|
done.resolve({
|
|
39350
39354
|
result: message,
|
|
39351
39355
|
fallbacks: done.fallbacks,
|
|
39352
|
-
sessionFallback: done.sessionFallback
|
|
39356
|
+
sessionFallback: done.sessionFallback,
|
|
39357
|
+
replyModel: done.replyModel
|
|
39353
39358
|
});
|
|
39354
39359
|
}
|
|
39355
39360
|
};
|
|
@@ -39371,7 +39376,8 @@ function startLiveProcess(model, system, key, env) {
|
|
|
39371
39376
|
resolve,
|
|
39372
39377
|
reject,
|
|
39373
39378
|
fallbacks: 0,
|
|
39374
|
-
sessionFallback: false
|
|
39379
|
+
sessionFallback: false,
|
|
39380
|
+
replyModel: null
|
|
39375
39381
|
};
|
|
39376
39382
|
input.push(text);
|
|
39377
39383
|
})
|
|
@@ -39445,23 +39451,22 @@ async function sendClear(send, stop) {
|
|
|
39445
39451
|
}
|
|
39446
39452
|
}
|
|
39447
39453
|
const MODEL_USAGE = record(string(), object({ outputTokens: number() }));
|
|
39454
|
+
const RAW_MODEL_USAGE = record(string(), unknown());
|
|
39448
39455
|
const SAFETY_STOPS = object({ safety_stops: number() });
|
|
39449
|
-
function buildReply(
|
|
39456
|
+
function buildReply(turn, requested, warm) {
|
|
39457
|
+
const result = turn.result;
|
|
39450
39458
|
if (result.subtype !== "success" || result.is_error) throw new Error(`the judge turn ended in ${result.subtype}`);
|
|
39451
39459
|
const usage = MODEL_USAGE.safeParse(result.modelUsage).data;
|
|
39452
39460
|
const stops = SAFETY_STOPS.safeParse(result).data?.safety_stops;
|
|
39453
39461
|
return {
|
|
39454
39462
|
text: result.result,
|
|
39455
|
-
model:
|
|
39463
|
+
model: turn.replyModel ?? requested,
|
|
39456
39464
|
safetyStops: stops ?? null,
|
|
39457
|
-
fallback: fallbacks > 0 || isFallbackReply(usage, stops),
|
|
39458
|
-
warm
|
|
39465
|
+
fallback: turn.fallbacks > 0 || isFallbackReply(usage, stops),
|
|
39466
|
+
warm,
|
|
39467
|
+
modelUsage: RAW_MODEL_USAGE.safeParse(result.modelUsage).data ?? null
|
|
39459
39468
|
};
|
|
39460
39469
|
}
|
|
39461
|
-
function pickAnsweringModel(usage, requested) {
|
|
39462
|
-
const [top] = Object.entries(usage ?? {}).filter(([, entry]) => entry.outputTokens > 0).toSorted(([, left], [, right]) => right.outputTokens - left.outputTokens);
|
|
39463
|
-
return top === void 0 ? requested : top[0];
|
|
39464
|
-
}
|
|
39465
39470
|
function isFallbackReply(usage, stops) {
|
|
39466
39471
|
if (stops !== void 0) return stops > 0;
|
|
39467
39472
|
const entries = Object.values(usage ?? {});
|
|
@@ -17,6 +17,11 @@ export function buildPromptContext(
|
|
|
17
17
|
originalUserTask: null,
|
|
18
18
|
lastDirectUserMessage: null,
|
|
19
19
|
canCaptureOriginal: input.source === 'startup' || input.source === 'clear',
|
|
20
|
+
|
|
21
|
+
// A launcher can pass the opening prompt on the command line, which
|
|
22
|
+
// Claude Code reports with the origin of a typed prompt. A clear happens
|
|
23
|
+
// only at the prompt of a running session.
|
|
24
|
+
awaitsOpeningPrompt: input.source !== 'clear',
|
|
20
25
|
};
|
|
21
26
|
}
|
|
22
27
|
|
|
@@ -27,21 +32,29 @@ export function buildPromptContext(
|
|
|
27
32
|
originalUserTask: previous?.originalUserTask ?? null,
|
|
28
33
|
lastDirectUserMessage: buildStaleMessage(previous?.lastDirectUserMessage ?? null),
|
|
29
34
|
canCaptureOriginal: previous?.canCaptureOriginal ?? false,
|
|
35
|
+
awaitsOpeningPrompt: previous?.awaitsOpeningPrompt ?? true,
|
|
30
36
|
};
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
const message: UserTask = { text: input.text, origin };
|
|
40
|
+
const isOpeningPrompt = previous?.awaitsOpeningPrompt ?? true;
|
|
34
41
|
|
|
35
42
|
return {
|
|
36
43
|
originalUserTask:
|
|
37
44
|
previous?.originalUserTask ?? (previous?.canCaptureOriginal === true ? message : null),
|
|
38
|
-
lastDirectUserMessage: message,
|
|
45
|
+
lastDirectUserMessage: isOpeningPrompt ? { ...message, position: 'opening' } : message,
|
|
39
46
|
canCaptureOriginal: previous?.canCaptureOriginal ?? false,
|
|
47
|
+
awaitsOpeningPrompt: false,
|
|
40
48
|
};
|
|
41
49
|
}
|
|
42
50
|
|
|
43
51
|
function buildStaleMessage(message: DirectUserMessage | null): DirectUserMessage | null {
|
|
44
52
|
return message === null
|
|
45
53
|
? null
|
|
46
|
-
: {
|
|
54
|
+
: {
|
|
55
|
+
text: message.text,
|
|
56
|
+
origin: message.origin,
|
|
57
|
+
freshness: 'stale',
|
|
58
|
+
...(message.position === undefined ? {} : { position: message.position }),
|
|
59
|
+
};
|
|
47
60
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "auto-mode",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.4",
|
|
4
4
|
"description": "A permission classifier library and Claude Code mod, so agents that are not Claude can run unattended",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"@types/node": "26.6.5",
|
|
89
89
|
"@zgeoff/bun-test-extended": "0.2.1",
|
|
90
90
|
"@zgeoff/format-codemod": "0.3.3",
|
|
91
|
-
"@zgeoff/oxlint-config": "0.7.
|
|
91
|
+
"@zgeoff/oxlint-config": "0.7.1",
|
|
92
92
|
"@zgeoff/skill-gate": "0.2.9",
|
|
93
93
|
"gunshi": "1.0.0-rc.1",
|
|
94
94
|
"knip": "6.42.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { t as startJudgeSession } from "./start-judge-session-vhUxe9-V.js";
|