@hachej/boring-agent 0.1.89 → 0.1.91
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/{chunk-GOM3VJOJ.js → chunk-2GBHYJVC.js} +31 -1
- package/dist/{chunk-I7UEASPG.js → chunk-BHH5NH7P.js} +5534 -8253
- package/dist/{chunk-M32FXCIN.js → chunk-CJ2BW2W2.js} +23 -8
- package/dist/{chunk-WZCTVT57.js → chunk-IWBC6SF7.js} +94 -112
- package/dist/chunk-NITBKFG6.js +1246 -0
- package/dist/{chunk-BDYXKHWY.js → chunk-PZC76CIA.js} +7 -1
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +2 -2
- package/dist/{createHarness-CCQLHKUF.js → createHarness-PMYRKDE4.js} +2 -2
- package/dist/errors-BEmw9HMp.d.ts +200 -0
- package/dist/front/index.d.ts +30 -5
- package/dist/front/index.js +230 -44
- package/dist/{harness-VvP0l5Mj.d.ts → harness-Bt_GMNYR.d.ts} +2 -2
- package/dist/{workspaceAgentDispatcher-CKEeNPjW.d.ts → lease-2aXepSBL.d.ts} +254 -59
- package/dist/{protocol-B_OQKfbI.d.ts → middleware-CzW8n7B7.d.ts} +20 -18
- package/dist/piChatEvent-DBO3M5lu.d.ts +367 -0
- package/dist/{piChatSessionService-DPjJ0g71.d.ts → piChatSessionService-BaaVWke7.d.ts} +5 -1
- package/dist/{sandbox-DthfJaOB.d.ts → sandbox-DAD8cWQR.d.ts} +14 -1
- package/dist/server/agent-host/testing/gatewayConformance.d.ts +41 -0
- package/dist/server/agent-host/testing/gatewayConformance.js +465 -0
- package/dist/server/index.d.ts +507 -708
- package/dist/server/index.js +53 -50
- package/dist/server/worker/index.d.ts +9 -7
- package/dist/server/worker/index.js +19 -28
- package/dist/shared/index.d.ts +119 -27
- package/dist/shared/index.js +65 -282
- package/dist/types-jcMapYr9.d.ts +759 -0
- package/docs/ACCESSIBILITY.md +4 -5
- package/docs/API.md +3 -0
- package/docs/AUTHORING.md +68 -0
- package/docs/ERROR_CODES.md +29 -0
- package/docs/README.md +1 -0
- package/docs/RISKS-MULTI-TAB.md +1 -1
- package/docs/runtime-provisioning.md +1 -1
- package/docs/runtime.md +9 -6
- package/package.json +18 -9
- package/dist/chunk-DGRKMMXO.js +0 -8
- package/dist/chunk-XPQEF32D.js +0 -385
- package/dist/piChatEvent-nmOBSNU9.d.ts +0 -367
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-WSQ5QNIY.js";
|
|
4
4
|
import {
|
|
5
5
|
ErrorCode
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2GBHYJVC.js";
|
|
7
7
|
|
|
8
8
|
// src/core/piChatSessionService.ts
|
|
9
9
|
var AgentEffectAdmissionError = class extends Error {
|
|
@@ -17,6 +17,20 @@ var AgentEffectAdmissionError = class extends Error {
|
|
|
17
17
|
details;
|
|
18
18
|
statusCode = 500;
|
|
19
19
|
};
|
|
20
|
+
var observedSynchronousServiceErrors = /* @__PURE__ */ new WeakSet();
|
|
21
|
+
function invokeObservedServiceEffect(effect) {
|
|
22
|
+
try {
|
|
23
|
+
return effect();
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (typeof error === "object" && error !== null || typeof error === "function") {
|
|
26
|
+
observedSynchronousServiceErrors.add(error);
|
|
27
|
+
}
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function isObservedSynchronousServiceError(error) {
|
|
32
|
+
return (typeof error === "object" && error !== null || typeof error === "function") && observedSynchronousServiceErrors.has(error);
|
|
33
|
+
}
|
|
20
34
|
var AGENT_EFFECT_METHODS = {
|
|
21
35
|
createSession: true,
|
|
22
36
|
deleteSession: true,
|
|
@@ -31,34 +45,34 @@ function withAgentEffectAdmission(service, admit) {
|
|
|
31
45
|
...service.listSessions ? { listSessions: (ctx, options) => service.listSessions(ctx, options) } : {},
|
|
32
46
|
async createSession(ctx, init) {
|
|
33
47
|
await admit(ctx);
|
|
34
|
-
return service.createSession(ctx, init);
|
|
48
|
+
return invokeObservedServiceEffect(() => service.createSession(ctx, init));
|
|
35
49
|
},
|
|
36
50
|
async deleteSession(ctx, sessionId) {
|
|
37
51
|
await admit(ctx);
|
|
38
|
-
return service.deleteSession(ctx, sessionId);
|
|
52
|
+
return invokeObservedServiceEffect(() => service.deleteSession(ctx, sessionId));
|
|
39
53
|
},
|
|
40
54
|
...service.readAttachment ? { readAttachment: (ctx, sessionId, messageId, index) => service.readAttachment(ctx, sessionId, messageId, index) } : {},
|
|
41
55
|
readState: (ctx, sessionId) => service.readState(ctx, sessionId),
|
|
42
56
|
subscribe: (ctx, sessionId, cursor, subscriber) => service.subscribe(ctx, sessionId, cursor, subscriber),
|
|
43
57
|
async prompt(ctx, sessionId, payload) {
|
|
44
58
|
await admit(ctx);
|
|
45
|
-
return service.prompt(ctx, sessionId, payload);
|
|
59
|
+
return invokeObservedServiceEffect(() => service.prompt(ctx, sessionId, payload));
|
|
46
60
|
},
|
|
47
61
|
async followUp(ctx, sessionId, payload) {
|
|
48
62
|
await admit(ctx);
|
|
49
|
-
return service.followUp(ctx, sessionId, payload);
|
|
63
|
+
return invokeObservedServiceEffect(() => service.followUp(ctx, sessionId, payload));
|
|
50
64
|
},
|
|
51
65
|
async clearQueue(ctx, sessionId, payload) {
|
|
52
66
|
await admit(ctx);
|
|
53
|
-
return service.clearQueue(ctx, sessionId, payload);
|
|
67
|
+
return invokeObservedServiceEffect(() => service.clearQueue(ctx, sessionId, payload));
|
|
54
68
|
},
|
|
55
69
|
async interrupt(ctx, sessionId, payload) {
|
|
56
70
|
await admit(ctx);
|
|
57
|
-
return service.interrupt(ctx, sessionId, payload);
|
|
71
|
+
return invokeObservedServiceEffect(() => service.interrupt(ctx, sessionId, payload));
|
|
58
72
|
},
|
|
59
73
|
async stop(ctx, sessionId, payload) {
|
|
60
74
|
await admit(ctx);
|
|
61
|
-
return service.stop(ctx, sessionId, payload);
|
|
75
|
+
return invokeObservedServiceEffect(() => service.stop(ctx, sessionId, payload));
|
|
62
76
|
},
|
|
63
77
|
...service.dispose ? { dispose: () => service.dispose() } : {}
|
|
64
78
|
};
|
|
@@ -596,6 +610,7 @@ function createLiveIterator(state, startIndex) {
|
|
|
596
610
|
|
|
597
611
|
export {
|
|
598
612
|
AgentEffectAdmissionError,
|
|
613
|
+
isObservedSynchronousServiceError,
|
|
599
614
|
AGENT_EFFECT_METHODS,
|
|
600
615
|
withAgentEffectAdmission,
|
|
601
616
|
createAgent,
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-AQBXNPMD.js";
|
|
5
5
|
import {
|
|
6
6
|
ErrorCode
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-2GBHYJVC.js";
|
|
8
8
|
|
|
9
9
|
// src/server/harness/pi-coding-agent/createHarness.ts
|
|
10
10
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -20,88 +20,7 @@ import {
|
|
|
20
20
|
getAgentDir as getAgentDir2,
|
|
21
21
|
loadSkills
|
|
22
22
|
} from "@mariozechner/pi-coding-agent";
|
|
23
|
-
|
|
24
|
-
// src/server/logging.ts
|
|
25
|
-
var SENSITIVE_KEYS = new Set([
|
|
26
|
-
"apiKey",
|
|
27
|
-
"api_key",
|
|
28
|
-
"token",
|
|
29
|
-
"secret",
|
|
30
|
-
"password",
|
|
31
|
-
"authorization",
|
|
32
|
-
"cookie",
|
|
33
|
-
"oidcToken",
|
|
34
|
-
"accessToken",
|
|
35
|
-
"refreshToken",
|
|
36
|
-
"ANTHROPIC_API_KEY",
|
|
37
|
-
"OPENAI_API_KEY",
|
|
38
|
-
"VERCEL_OIDC_TOKEN",
|
|
39
|
-
"VERCEL_TEAM_ID"
|
|
40
|
-
].map((key) => key.toLowerCase()));
|
|
41
|
-
function isSensitiveKey(key) {
|
|
42
|
-
return SENSITIVE_KEYS.has(key.toLowerCase());
|
|
43
|
-
}
|
|
44
|
-
function redactValue(key, value, seen) {
|
|
45
|
-
if (key && isSensitiveKey(key) && value != null) return "***";
|
|
46
|
-
if (value == null || typeof value !== "object") return value;
|
|
47
|
-
if (value instanceof Date) return value;
|
|
48
|
-
if (seen.has(value)) return "[Circular]";
|
|
49
|
-
seen.add(value);
|
|
50
|
-
if (Array.isArray(value)) {
|
|
51
|
-
const out2 = value.map((item) => redactValue(void 0, item, seen));
|
|
52
|
-
seen.delete(value);
|
|
53
|
-
return out2;
|
|
54
|
-
}
|
|
55
|
-
const out = {};
|
|
56
|
-
for (const [childKey, childValue] of Object.entries(value)) {
|
|
57
|
-
out[childKey] = redactValue(childKey, childValue, seen);
|
|
58
|
-
}
|
|
59
|
-
seen.delete(value);
|
|
60
|
-
return out;
|
|
61
|
-
}
|
|
62
|
-
function redact(fields) {
|
|
63
|
-
const out = {};
|
|
64
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
65
|
-
for (const [k, v] of Object.entries(fields)) {
|
|
66
|
-
out[k] = redactValue(k, v, seen);
|
|
67
|
-
}
|
|
68
|
-
return out;
|
|
69
|
-
}
|
|
70
|
-
function isVerbose() {
|
|
71
|
-
return typeof process !== "undefined" && process.env?.BORING_AGENT_VERBOSE === "1";
|
|
72
|
-
}
|
|
73
|
-
function createLogger(prefix) {
|
|
74
|
-
function emit(level, msg, fields) {
|
|
75
|
-
const entry = {
|
|
76
|
-
level,
|
|
77
|
-
prefix,
|
|
78
|
-
msg,
|
|
79
|
-
...fields ? redact(fields) : {},
|
|
80
|
-
t: (/* @__PURE__ */ new Date()).toISOString()
|
|
81
|
-
};
|
|
82
|
-
if (level === "error") {
|
|
83
|
-
console.error(JSON.stringify(entry));
|
|
84
|
-
} else if (level === "warn") {
|
|
85
|
-
console.warn(JSON.stringify(entry));
|
|
86
|
-
} else {
|
|
87
|
-
console.log(JSON.stringify(entry));
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return {
|
|
91
|
-
debug(msg, fields) {
|
|
92
|
-
if (isVerbose()) emit("debug", msg, fields);
|
|
93
|
-
},
|
|
94
|
-
info(msg, fields) {
|
|
95
|
-
emit("info", msg, fields);
|
|
96
|
-
},
|
|
97
|
-
warn(msg, fields) {
|
|
98
|
-
emit("warn", msg, fields);
|
|
99
|
-
},
|
|
100
|
-
error(msg, fields) {
|
|
101
|
-
emit("error", msg, fields);
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
23
|
+
import { createLogger } from "@hachej/boring-bash/server";
|
|
105
24
|
|
|
106
25
|
// src/server/harness/pi-coding-agent/tool-adapter.ts
|
|
107
26
|
var BORING_TOOL_ERROR_MARKER = "__boringToolError";
|
|
@@ -399,14 +318,6 @@ import { homedir } from "os";
|
|
|
399
318
|
function getEnv(name) {
|
|
400
319
|
return process.env[name];
|
|
401
320
|
}
|
|
402
|
-
function getEnvSnapshot() {
|
|
403
|
-
return { ...process.env };
|
|
404
|
-
}
|
|
405
|
-
function setEnvDefault(name, value) {
|
|
406
|
-
if (process.env[name] !== void 0) return false;
|
|
407
|
-
process.env[name] = value;
|
|
408
|
-
return true;
|
|
409
|
-
}
|
|
410
321
|
|
|
411
322
|
// src/server/harness/pi-coding-agent/sessions.ts
|
|
412
323
|
import {
|
|
@@ -449,6 +360,7 @@ var PiSessionStore = class {
|
|
|
449
360
|
allowLegacyUnscopedAccess;
|
|
450
361
|
prefixCache = /* @__PURE__ */ new Map();
|
|
451
362
|
listInFlight = /* @__PURE__ */ new Map();
|
|
363
|
+
writerTails = /* @__PURE__ */ new Map();
|
|
452
364
|
constructor(cwd, options) {
|
|
453
365
|
this.cwd = cwd;
|
|
454
366
|
if (typeof options === "string") {
|
|
@@ -462,6 +374,14 @@ var PiSessionStore = class {
|
|
|
462
374
|
getSessionDir() {
|
|
463
375
|
return this.sessionDir;
|
|
464
376
|
}
|
|
377
|
+
/** Reads the Host execution pin from authoritative session metadata. */
|
|
378
|
+
async readRuntimeScopeIdentity(ctx, sessionId) {
|
|
379
|
+
const filepath = await this.resolveSessionFile(sessionId, ctx);
|
|
380
|
+
const entries = parseJsonlPrefixEntries(await readJsonlPrefix(filepath));
|
|
381
|
+
const header = entries.find((entry) => entry.type === "session");
|
|
382
|
+
if (!this.headerBelongsToCtx(header, ctx)) throw new Error(`Session not found: ${sessionId}`);
|
|
383
|
+
return readHeaderRuntimeScopeIdentity(header);
|
|
384
|
+
}
|
|
465
385
|
async list(ctx, options) {
|
|
466
386
|
const normalizedOptions = normalizeListOptions(options);
|
|
467
387
|
const inFlightKey = JSON.stringify([
|
|
@@ -541,7 +461,7 @@ var PiSessionStore = class {
|
|
|
541
461
|
}
|
|
542
462
|
async load(ctx, sessionId) {
|
|
543
463
|
const resolved = await this.resolveSessionTranscript(ctx, sessionId);
|
|
544
|
-
const title =
|
|
464
|
+
const title = newestDurableTitle(resolved.sessionEntries, resolved.linkedEntries) ?? "New session";
|
|
545
465
|
const turnCount = countUserTurns(resolved.transcriptEntries);
|
|
546
466
|
const updatedAtMs = Math.max(resolved.fileStat.mtime.getTime(), resolved.linkedMtimeMs ?? 0);
|
|
547
467
|
return {
|
|
@@ -616,9 +536,53 @@ var PiSessionStore = class {
|
|
|
616
536
|
linkedEntries,
|
|
617
537
|
transcriptEntries,
|
|
618
538
|
fileStat,
|
|
619
|
-
linkedMtimeMs: linked?.mtime.getTime()
|
|
539
|
+
linkedMtimeMs: linked?.mtime.getTime(),
|
|
540
|
+
filepath,
|
|
541
|
+
...linkedPiFile && linked ? { linkedFilepath: linkedPiFile } : {}
|
|
620
542
|
};
|
|
621
543
|
}
|
|
544
|
+
/**
|
|
545
|
+
* Addressed rename capability. Every resolved wrapper/native transcript is
|
|
546
|
+
* appended through the same JSONL path under one process-local writer lock.
|
|
547
|
+
*/
|
|
548
|
+
async rename(ctx, sessionId, title) {
|
|
549
|
+
const trimmed = title.trim();
|
|
550
|
+
if (!trimmed) throw new Error("Session title must not be empty");
|
|
551
|
+
return await this.withWriter(sessionId, async () => {
|
|
552
|
+
const resolved = await this.resolveSessionTranscript(ctx, sessionId);
|
|
553
|
+
const entry = {
|
|
554
|
+
type: "session_info",
|
|
555
|
+
id: randomUUID(),
|
|
556
|
+
parentId: null,
|
|
557
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
558
|
+
name: trimmed
|
|
559
|
+
};
|
|
560
|
+
const line = `${JSON.stringify(entry)}
|
|
561
|
+
`;
|
|
562
|
+
const targets = [resolved.filepath, resolved.linkedFilepath].filter((path) => Boolean(path));
|
|
563
|
+
for (const filepath of targets) {
|
|
564
|
+
await appendFile(filepath, line);
|
|
565
|
+
this.prefixCache.delete(filepath);
|
|
566
|
+
}
|
|
567
|
+
return await this.load(ctx, sessionId);
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
async withWriter(key, action) {
|
|
571
|
+
const previous = this.writerTails.get(key) ?? Promise.resolve();
|
|
572
|
+
let release;
|
|
573
|
+
const current = new Promise((resolve2) => {
|
|
574
|
+
release = resolve2;
|
|
575
|
+
});
|
|
576
|
+
const tail = previous.then(() => current);
|
|
577
|
+
this.writerTails.set(key, tail);
|
|
578
|
+
await previous;
|
|
579
|
+
try {
|
|
580
|
+
return await action();
|
|
581
|
+
} finally {
|
|
582
|
+
release();
|
|
583
|
+
if (this.writerTails.get(key) === tail) this.writerTails.delete(key);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
622
586
|
// Synchronous variant used during session initialization so that no async
|
|
623
587
|
// I/O hop is introduced before createAgentSession (which would break test
|
|
624
588
|
// timing when fake timers are in use). The file is tiny (metadata only).
|
|
@@ -822,7 +786,7 @@ var PiSessionStore = class {
|
|
|
822
786
|
const linkedEntries = linked?.entries.filter(
|
|
823
787
|
(e) => e.type !== "session"
|
|
824
788
|
) ?? [];
|
|
825
|
-
const title =
|
|
789
|
+
const title = newestDurableTitle(sessionEntries, linkedEntries) ?? firstUserMessage(linkedEntries) ?? firstUserMessage(sessionEntries) ?? "New session";
|
|
826
790
|
const turnCount = [...sessionEntries, ...linkedEntries].filter(
|
|
827
791
|
(e) => e.type === "message" && e.message?.role === "user"
|
|
828
792
|
).length;
|
|
@@ -1061,11 +1025,19 @@ function readHeaderSessionCtx(header) {
|
|
|
1061
1025
|
if (!raw || typeof raw !== "object") return {};
|
|
1062
1026
|
return normalizeSessionCtx(raw) ?? {};
|
|
1063
1027
|
}
|
|
1028
|
+
function readHeaderRuntimeScopeIdentity(header) {
|
|
1029
|
+
const raw = header?.boringSessionCtx?.runtimeScopeIdentity;
|
|
1030
|
+
if (raw === void 0) return void 0;
|
|
1031
|
+
if (typeof raw !== "string" || !raw.trim()) throw new Error("Session runtime scope identity is invalid");
|
|
1032
|
+
return raw;
|
|
1033
|
+
}
|
|
1064
1034
|
function normalizeSessionCtx(ctx) {
|
|
1065
|
-
|
|
1035
|
+
const runtimeScopeIdentity = typeof ctx?.runtimeScopeIdentity === "string" && ctx.runtimeScopeIdentity.trim() ? ctx.runtimeScopeIdentity : "";
|
|
1036
|
+
if (!ctx?.workspaceId && !ctx?.userId && !runtimeScopeIdentity) return void 0;
|
|
1066
1037
|
return {
|
|
1067
|
-
...ctx
|
|
1068
|
-
...ctx
|
|
1038
|
+
...ctx?.workspaceId ? { workspaceId: ctx.workspaceId } : {},
|
|
1039
|
+
...ctx?.userId ? { userId: ctx.userId } : {},
|
|
1040
|
+
...runtimeScopeIdentity ? { runtimeScopeIdentity } : {}
|
|
1069
1041
|
};
|
|
1070
1042
|
}
|
|
1071
1043
|
function sameSessionCtx(a, b) {
|
|
@@ -1109,9 +1081,16 @@ function countUserTurns(entries) {
|
|
|
1109
1081
|
(e) => e.type === "message" && e.message?.role === "user"
|
|
1110
1082
|
).length;
|
|
1111
1083
|
}
|
|
1112
|
-
function
|
|
1113
|
-
const
|
|
1114
|
-
|
|
1084
|
+
function newestDurableTitle(wrapperEntries, nativeEntries) {
|
|
1085
|
+
const candidates = [
|
|
1086
|
+
...wrapperEntries.flatMap((entry, offset) => entry.type === "session_info" ? [{ entry, native: 0, offset }] : []),
|
|
1087
|
+
...nativeEntries.flatMap((entry, offset) => entry.type === "session_info" ? [{ entry, native: 1, offset }] : [])
|
|
1088
|
+
];
|
|
1089
|
+
candidates.sort((a, b) => {
|
|
1090
|
+
const timestamp = Date.parse(b.entry.timestamp) - Date.parse(a.entry.timestamp);
|
|
1091
|
+
return timestamp || b.native - a.native || b.offset - a.offset;
|
|
1092
|
+
});
|
|
1093
|
+
return candidates[0]?.entry.name;
|
|
1115
1094
|
}
|
|
1116
1095
|
function firstUserMessage(entries) {
|
|
1117
1096
|
for (const e of entries) {
|
|
@@ -1208,6 +1187,12 @@ function clean(value) {
|
|
|
1208
1187
|
const trimmed = value?.trim();
|
|
1209
1188
|
return trimmed && trimmed.length > 0 ? trimmed : void 0;
|
|
1210
1189
|
}
|
|
1190
|
+
function parseEncodedModelSelection(value) {
|
|
1191
|
+
const encoded = clean(value);
|
|
1192
|
+
if (!encoded) return void 0;
|
|
1193
|
+
const idx = encoded.indexOf(":");
|
|
1194
|
+
return idx > 0 && idx < encoded.length - 1 ? { provider: encoded.slice(0, idx), id: encoded.slice(idx + 1) } : void 0;
|
|
1195
|
+
}
|
|
1211
1196
|
function readPositiveInt(name, fallback) {
|
|
1212
1197
|
const raw = clean(getEnv(name));
|
|
1213
1198
|
if (!raw) return fallback;
|
|
@@ -1371,13 +1356,8 @@ function readPiSettingsDefaultModel() {
|
|
|
1371
1356
|
}
|
|
1372
1357
|
}
|
|
1373
1358
|
function readConfiguredDefaultModel() {
|
|
1374
|
-
const encoded =
|
|
1375
|
-
if (encoded)
|
|
1376
|
-
const idx = encoded.indexOf(":");
|
|
1377
|
-
if (idx > 0 && idx < encoded.length - 1) {
|
|
1378
|
-
return { provider: encoded.slice(0, idx), id: encoded.slice(idx + 1) };
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1359
|
+
const encoded = parseEncodedModelSelection(getEnv("BORING_AGENT_DEFAULT_MODEL"));
|
|
1360
|
+
if (encoded) return encoded;
|
|
1381
1361
|
const explicitProvider = clean(getEnv("BORING_AGENT_DEFAULT_MODEL_PROVIDER"));
|
|
1382
1362
|
const explicitId = clean(getEnv("BORING_AGENT_DEFAULT_MODEL_ID"));
|
|
1383
1363
|
if (explicitProvider && explicitId) {
|
|
@@ -1515,7 +1495,10 @@ function resolveRequestedModel(modelRegistry, input, options = {}) {
|
|
|
1515
1495
|
}
|
|
1516
1496
|
return model;
|
|
1517
1497
|
}
|
|
1518
|
-
function resolveDefaultModel(modelRegistry) {
|
|
1498
|
+
function resolveDefaultModel(modelRegistry, override, strict) {
|
|
1499
|
+
if (override) {
|
|
1500
|
+
return resolveRequestedModel(modelRegistry, { model: override }, { strict });
|
|
1501
|
+
}
|
|
1519
1502
|
const configured = readConfiguredDefaultModel();
|
|
1520
1503
|
if (configured) {
|
|
1521
1504
|
const model = modelRegistry.find(configured.provider, configured.id);
|
|
@@ -1725,7 +1708,7 @@ function createPiCodingAgentHarness(opts) {
|
|
|
1725
1708
|
isNewPiSession = true;
|
|
1726
1709
|
}
|
|
1727
1710
|
const resolvedModel = resolveRequestedModel(modelRegistry, input, { strict: pi.strictModelResolution });
|
|
1728
|
-
const model = resolvedModel ?? resolveDefaultModel(modelRegistry);
|
|
1711
|
+
const model = resolvedModel ?? resolveDefaultModel(modelRegistry, pi.defaultModel, pi.strictModelResolution);
|
|
1729
1712
|
refreshEffectiveResources();
|
|
1730
1713
|
const composedSystemPromptAppend = composeSystemPromptAppend(opts.systemPromptAppend);
|
|
1731
1714
|
const dynamicPromptExtension = opts.systemPromptDynamic ? buildDynamicPromptExtension(opts.systemPromptDynamic) : void 0;
|
|
@@ -1928,9 +1911,8 @@ ${entry.message}`;
|
|
|
1928
1911
|
|
|
1929
1912
|
export {
|
|
1930
1913
|
getEnv,
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
createLogger,
|
|
1914
|
+
PiSessionStore,
|
|
1915
|
+
parseEncodedModelSelection,
|
|
1934
1916
|
registerConfiguredModelProviders,
|
|
1935
1917
|
readConfiguredDefaultModel,
|
|
1936
1918
|
PI_PACKAGE_RESOURCE_FILTERS,
|