bazilion 0.16.0 → 0.18.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/dist/cli.js +672 -87
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +3759 -432
- package/dist/daemon.js.map +1 -1
- package/dist/migrations/0001_init.sql +169 -0
- package/dist/web/client/assets/ChatPane-CAYS_fIQ.js +76 -0
- package/dist/web/client/assets/ConfirmDialog-BzIiABOP.js +1 -0
- package/dist/web/client/assets/{FieldRow-DJ2Gx4Du.js → FieldRow-W_54rw5c.js} +1 -1
- package/dist/web/client/assets/ProductionTeamPolicyEditor-DNXVX8Lz.js +7 -0
- package/dist/web/client/assets/ProfileCommunicationEditor-DN0fOzqn.js +1 -0
- package/dist/web/client/assets/{ResultSourceConversation-CtzJ8QA-.js → ResultSourceConversation-DoU4tOWc.js} +1 -1
- package/dist/web/client/assets/TeamTabs-BmTZRI4T.js +1 -0
- package/dist/web/client/assets/TemplatesTabs-Bs_OXKwx.js +1 -0
- package/dist/web/client/assets/{UnsavedChangesGuard-BCsLw-mU.js → UnsavedChangesGuard-CPRtFReU.js} +1 -1
- package/dist/web/client/assets/{_id-DxopIW-y.js → _id-CxAB4TDr.js} +1 -1
- package/dist/web/client/assets/_id-DL4tJFQB.js +1 -0
- package/dist/web/client/assets/{_id-BEDmIXVf.js → _id-DR9eFC17.js} +1 -1
- package/dist/web/client/assets/{_id-BFM_tn_s.js → _id-Dbmei5tg.js} +1 -1
- package/dist/web/client/assets/{_id-B5Ov7cdO.js → _id-ybF-pqmr.js} +1 -1
- package/dist/web/client/assets/activity-oUyy77jD.js +1 -0
- package/dist/web/client/assets/{agents-CMPOFcs-.js → agents-D_TrEqAg.js} +1 -1
- package/dist/web/client/assets/{agents-O4soKZND.js → agents-DkjJp7JP.js} +1 -1
- package/dist/web/client/assets/{approvals-CwDu_lrA.js → approvals-DhOerWdt.js} +1 -1
- package/dist/web/client/assets/{attention-BY8MMuM_.js → attention-DGwiF-Jy.js} +1 -1
- package/dist/web/client/assets/chevron-right-DSa4xPTs.js +1 -0
- package/dist/web/client/assets/config-BJ2ZzHPR.js +3 -0
- package/dist/web/client/assets/createServerFn-Dzfjt7mA.js +3 -0
- package/dist/web/client/assets/git-review-presentation-CzHQulDk.js +1 -0
- package/dist/web/client/assets/{inbox-CWXql0K3.js → inbox-BUElnGep.js} +1 -1
- package/dist/web/client/assets/index-Bi-HxcPG.js +50 -0
- package/dist/web/client/assets/{learning-DAm4dyyc.js → learning-BiTHNwB3.js} +1 -1
- package/dist/web/client/assets/login-BmcZvAH2.js +1 -0
- package/dist/web/client/assets/{mcp-loLB0wuh.js → mcp-Cwk9V82W.js} +1 -1
- package/dist/web/client/assets/{members-BJ0ikkTl.js → members-CHDNabFh.js} +1 -1
- package/dist/web/client/assets/{memory-Drn9Gv53.js → memory-Cx_Fpd4e.js} +1 -1
- package/dist/web/client/assets/policy-C0nMdwcG.js +1 -0
- package/dist/web/client/assets/{results-9exU6f7m.js → results-Bz3jASs-.js} +1 -1
- package/dist/web/client/assets/review-AK9WGmpv.js +1 -0
- package/dist/web/client/assets/routes-DsMY_6oy.js +1 -0
- package/dist/web/client/assets/{services-BLso1BhA.js → services-DItA6fJ7.js} +1 -1
- package/dist/web/client/assets/{skills-BodqX3OI.js → skills-DbNV2vgL.js} +1 -1
- package/dist/web/client/assets/{styles-d1yjBpud.css → styles-C6br2xxl.css} +1 -1
- package/dist/web/client/assets/{teams-ByQedXZi.js → teams-D83scDxw.js} +1 -1
- package/dist/web/client/assets/{teams-SYsF1bOR.js → teams-DAny1ypN.js} +1 -1
- package/dist/web/client/assets/{telegram-DC9PLFbB.js → telegram-BOmf9vUh.js} +1 -1
- package/dist/web/client/assets/{tokens-DGy8Ijpo.js → tokens-DBGH6Bw5.js} +1 -1
- package/dist/web/client/assets/{triggers-BXpVmHDG.js → triggers-D1_pseI3.js} +1 -1
- package/dist/web/client/assets/verifications-CBTo-FyV.js +2 -0
- package/dist/web/client/assets/welcome-DAfPOm15.js +1 -0
- package/dist/web/client/assets/x-CWY-gUaM.js +1 -0
- package/dist/web/server/assets/{ChatPane-CS5oI7ef.js → ChatPane-DybH39WK.js} +301 -14
- package/dist/web/server/assets/{ResultSourceConversation-BpVWBRYq.js → ResultSourceConversation-BmXTcEOA.js} +1 -1
- package/dist/web/server/assets/{TeamTabs-TCKjCvMA.js → TeamTabs-Dg4v6x0-.js} +8 -0
- package/dist/web/server/assets/{_id-DtIYuJJX.js → _id--onriuvj.js} +1 -1
- package/dist/web/server/assets/{_id-DOnInzLb.js → _id--zoh1vv7.js} +1 -1
- package/dist/web/server/assets/{_id-CeyHEsCZ.js → _id-6p-mDmI8.js} +1 -1
- package/dist/web/server/assets/{_id-5pgKoid8.js → _id-BN1BPEDI.js} +1 -1
- package/dist/web/server/assets/{_id-DFHB9JFQ.js → _id-BYKpT2Tu.js} +1 -1
- package/dist/web/server/assets/{_id-B_-CDHOi2.js → _id-BqWTB8Wl.js} +1 -1
- package/dist/web/server/assets/{_id-BnqodC1c2.js → _id-C_2er0_G.js} +3 -3
- package/dist/web/server/assets/{_id-BG2nkGxa.js → _id-DptBl3X8.js} +1 -1
- package/dist/web/server/assets/{_id-DwZXhLlL.js → _id-EAjRXNbD.js} +2 -2
- package/dist/web/server/assets/{_id-DrB9uR1b.js → _id-dUnXL-My2.js} +1 -1
- package/dist/web/server/assets/{_tanstack-start-manifest_v-D7gKv6m6.js → _tanstack-start-manifest_v-B3M-dfRO.js} +108 -84
- package/dist/web/server/assets/{activity-0VUkStOu.js → activity-C5jpoEQI.js} +1 -1
- package/dist/web/server/assets/{activity-C88qrNqv.js → activity-Cu7zKPGD.js} +1 -1
- package/dist/web/server/assets/{activity-5fWKPDxj.js → activity-Dn50vkQP.js} +2 -2
- package/dist/web/server/assets/{agents-CSXLaM2W.js → agents-RE6aYOb-.js} +1 -1
- package/dist/web/server/assets/{agents-C86K6HvS.js → agents-nAOx_H7s.js} +1 -1
- package/dist/web/server/assets/{approvals-C3MysI6l.js → approvals-DhHxIDrL.js} +1 -1
- package/dist/web/server/assets/{attention-DLeLCKah.js → attention-CBWzWRni.js} +1 -1
- package/dist/web/server/assets/{auth-CDZp9aEk.js → auth-tB3i6cFd.js} +1 -1
- package/dist/web/server/assets/{config-BVTHvljR.js → config-D1k_tTAw.js} +1 -1
- package/dist/web/server/assets/{daemon-client-xWyYKAcx.js → daemon-client-C7qjQ2iO.js} +45 -0
- package/dist/web/server/assets/git-review-BB3M9nYg.js +26 -0
- package/dist/web/server/assets/git-review-Bf5ABFJg.js +179 -0
- package/dist/web/server/assets/git-review-presentation-TJiHJhen.js +81 -0
- package/dist/web/server/assets/{inbox-PQTrjtOw.js → inbox-Dw4pTevh.js} +1 -1
- package/dist/web/server/assets/{learning-K0cmDsZR.js → learning-CF8ZzFVD.js} +1 -1
- package/dist/web/server/assets/{mcp-Rtraochg.js → mcp-D5dmBT82.js} +1 -1
- package/dist/web/server/assets/{members-CD3GiTfF.js → members-Bd0OtiTr.js} +1 -1
- package/dist/web/server/assets/{members-grAKFWgv.js → members-CvwEN9pm.js} +1 -1
- package/dist/web/server/assets/{members-cc5SeEaW.js → members-xSXoYUOd.js} +2 -2
- package/dist/web/server/assets/{memory-egFpBD1g.js → memory-CcPK7um7.js} +1 -1
- package/dist/web/server/assets/{memory-C5i_GxlY.js → memory-UP6AsRkO.js} +2 -2
- package/dist/web/server/assets/{memory-CVqnyUaM.js → memory-lo2vHRNw.js} +1 -1
- package/dist/web/server/assets/{policy-bLKwvnja.js → policy-B62WXIFo.js} +1 -1
- package/dist/web/server/assets/{policy-Dgjb0_gK.js → policy-Bze9Krhg.js} +2 -2
- package/dist/web/server/assets/{policy-ooSBgiDS.js → policy-Dh6wd2wN.js} +1 -1
- package/dist/web/server/assets/{results-N-kP4iFT.js → results-BFqs2iOu.js} +1 -1
- package/dist/web/server/assets/{results-DXdYtHaq.js → results-BWnu3gXP.js} +1 -1
- package/dist/web/server/assets/{results-CfNsFncJ.js → results-CzZk50Fu.js} +3 -3
- package/dist/web/server/assets/review-DUe3vHPU.js +393 -0
- package/dist/web/server/assets/review-c_-cFi7H.js +14 -0
- package/dist/web/server/assets/{router-B6g_s7W3.js → router-Deq94UJQ.js} +41 -27
- package/dist/web/server/assets/{routes-pcRy_Sf8.js → routes-B6x3pEW8.js} +1 -1
- package/dist/web/server/assets/{routes-BqSaZvlu.js → routes-CVKkvFVv.js} +1 -1
- package/dist/web/server/assets/{routes-Dsh8F_7i.js → routes-DsUzzxk4.js} +2 -2
- package/dist/web/server/assets/{services-DlZA8fRL.js → services-CEr61xb5.js} +1 -1
- package/dist/web/server/assets/{skills-i2duvgW-.js → skills-BImC3LTO.js} +1 -1
- package/dist/web/server/assets/{teams-6RYIj1Xm.js → teams-8zEIo08E.js} +1 -1
- package/dist/web/server/assets/{teams-B1AI3NfN.js → teams-D-yaAWLV.js} +1 -1
- package/dist/web/server/assets/{telegram-C4q0YTVn.js → telegram-CGl_LFtJ.js} +1 -1
- package/dist/web/server/assets/{tokens-RFquA2Bx.js → tokens-cB-uf7qm.js} +1 -1
- package/dist/web/server/assets/{triggers-DVD-iE-N.js → triggers-CtSj79L0.js} +1 -1
- package/dist/web/server/assets/verification-B5QjcpIo.js +97 -0
- package/dist/web/server/assets/verifications-BfQsfwSE.js +268 -0
- package/dist/web/server/assets/verifications-CUq_6ZqL.js +26 -0
- package/dist/web/server/server.js +72 -28
- package/dist/worker.js +470 -79
- package/dist/worker.js.map +1 -1
- package/package.json +3 -3
- package/dist/web/client/assets/ChatPane-CQZzxOir.js +0 -76
- package/dist/web/client/assets/ConfirmDialog-MicTTwdy.js +0 -1
- package/dist/web/client/assets/ProductionTeamPolicyEditor-DqUnN_ce.js +0 -7
- package/dist/web/client/assets/ProfileCommunicationEditor-DArXub0b.js +0 -1
- package/dist/web/client/assets/TeamTabs-DbIk5vvT.js +0 -1
- package/dist/web/client/assets/TemplatesTabs-CatJIjGi.js +0 -1
- package/dist/web/client/assets/_id-CrnEVcw8.js +0 -1
- package/dist/web/client/assets/activity-CrG8Bg60.js +0 -1
- package/dist/web/client/assets/chevron-right-Cf6vKeLq.js +0 -1
- package/dist/web/client/assets/config-Cn4iBJFz.js +0 -3
- package/dist/web/client/assets/index-Bq2zrG2_.js +0 -52
- package/dist/web/client/assets/login-BsABI8Ux.js +0 -1
- package/dist/web/client/assets/policy-pQadZyk0.js +0 -1
- package/dist/web/client/assets/routes-jw1PuqiR.js +0 -1
- package/dist/web/client/assets/welcome-BKsnsCxJ.js +0 -1
- package/dist/web/client/assets/x-BK4xNCzS.js +0 -1
package/dist/worker.js
CHANGED
|
@@ -1108,6 +1108,41 @@ function qmdBackend(root, options = {}) {
|
|
|
1108
1108
|
};
|
|
1109
1109
|
}
|
|
1110
1110
|
|
|
1111
|
+
// ../daemon/src/lib/coding-environment/receipt-reference.ts
|
|
1112
|
+
function codingLogReference(content) {
|
|
1113
|
+
const parsed = objectFrom(textContent(content));
|
|
1114
|
+
if (!parsed) return null;
|
|
1115
|
+
return referenceFrom(parsed) ?? referenceFrom(objectFrom(parsed.receipt));
|
|
1116
|
+
}
|
|
1117
|
+
function referenceFrom(value) {
|
|
1118
|
+
if (!value) return null;
|
|
1119
|
+
const commandId = value.id;
|
|
1120
|
+
const teamId = value.teamId;
|
|
1121
|
+
if (typeof commandId !== "string" || commandId.length === 0) return null;
|
|
1122
|
+
if (typeof teamId !== "string" || teamId.length === 0) return null;
|
|
1123
|
+
return { commandId, teamId };
|
|
1124
|
+
}
|
|
1125
|
+
function textContent(content) {
|
|
1126
|
+
if (typeof content === "string") return content;
|
|
1127
|
+
if (!Array.isArray(content)) return "";
|
|
1128
|
+
let out = "";
|
|
1129
|
+
for (const block of content) {
|
|
1130
|
+
if (block && block.type === "text" && typeof block.text === "string") out += block.text;
|
|
1131
|
+
}
|
|
1132
|
+
return out;
|
|
1133
|
+
}
|
|
1134
|
+
function objectFrom(value) {
|
|
1135
|
+
if (typeof value === "string") {
|
|
1136
|
+
try {
|
|
1137
|
+
return objectFrom(JSON.parse(value));
|
|
1138
|
+
} catch {
|
|
1139
|
+
return null;
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
|
|
1143
|
+
return value;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1111
1146
|
// ../daemon/src/runtime/pi/events.ts
|
|
1112
1147
|
function translatePiEvent(e) {
|
|
1113
1148
|
switch (e.type) {
|
|
@@ -1147,6 +1182,22 @@ function translatePiEvent(e) {
|
|
|
1147
1182
|
}
|
|
1148
1183
|
return out;
|
|
1149
1184
|
}
|
|
1185
|
+
case "tool_execution_update": {
|
|
1186
|
+
if (e.toolName !== "coding_command") return [];
|
|
1187
|
+
const progress = e.partialResult?.details?.codingProgress;
|
|
1188
|
+
if (!progress || typeof progress.id !== "string" || typeof progress.commandId !== "string" || typeof progress.output !== "string" || typeof progress.elapsedMs !== "number")
|
|
1189
|
+
return [];
|
|
1190
|
+
return [
|
|
1191
|
+
{
|
|
1192
|
+
type: "coding_progress",
|
|
1193
|
+
id: progress.id,
|
|
1194
|
+
commandId: progress.commandId,
|
|
1195
|
+
output: progress.output,
|
|
1196
|
+
truncated: progress.truncated === true,
|
|
1197
|
+
elapsedMs: Math.max(0, Math.floor(progress.elapsedMs))
|
|
1198
|
+
}
|
|
1199
|
+
];
|
|
1200
|
+
}
|
|
1150
1201
|
case "tool_execution_end": {
|
|
1151
1202
|
if (e.toolName === "ask_user")
|
|
1152
1203
|
return [
|
|
@@ -1254,14 +1305,22 @@ function piMessagesToProviderView(messages, questionResultVisible) {
|
|
|
1254
1305
|
}
|
|
1255
1306
|
case "toolResult": {
|
|
1256
1307
|
const tr = m;
|
|
1257
|
-
if ([
|
|
1258
|
-
|
|
1259
|
-
|
|
1308
|
+
if ([
|
|
1309
|
+
"repository_context",
|
|
1310
|
+
"coding_environment",
|
|
1311
|
+
"coding_command",
|
|
1312
|
+
"coding_receipt",
|
|
1313
|
+
"coding_log",
|
|
1314
|
+
// BAZ-042: a snapshot result names withheld paths, so history must not render it.
|
|
1315
|
+
"source_snapshot"
|
|
1316
|
+
].includes(tr.toolName ?? "")) {
|
|
1317
|
+
const codingLog = codingLogReference(tr.content);
|
|
1260
1318
|
out.push({
|
|
1261
1319
|
role: "tool",
|
|
1262
1320
|
toolCallId: tr.toolCallId,
|
|
1263
1321
|
toolName: tr.toolName,
|
|
1264
|
-
content: "Coding context or command evidence retained privately. Captured transport output follows its communication approval; ask the Agent for the relevant result."
|
|
1322
|
+
content: "Coding context or command evidence retained privately. Captured transport output follows its communication approval; ask the Agent for the relevant result.",
|
|
1323
|
+
...codingLog ? { codingLog } : {}
|
|
1265
1324
|
});
|
|
1266
1325
|
break;
|
|
1267
1326
|
}
|
|
@@ -1298,6 +1357,107 @@ function extractResultReference(value) {
|
|
|
1298
1357
|
return typeof id === "string" && /^[a-f0-9-]{36}$/.test(id) ? { resultId: id } : void 0;
|
|
1299
1358
|
}
|
|
1300
1359
|
|
|
1360
|
+
// ../daemon/src/lib/coding-environment/diagnostics.ts
|
|
1361
|
+
var CODING_OUTPUT_BYTES = 64 * 1024;
|
|
1362
|
+
var CODING_RETAINED_BYTES = 2 * 1024 * 1024;
|
|
1363
|
+
var CODING_LIVE_BYTES = 8 * 1024;
|
|
1364
|
+
function diagnosticTail(value, limit) {
|
|
1365
|
+
const bytes = Buffer.from(value);
|
|
1366
|
+
if (bytes.length <= limit) return { text: value, truncated: false };
|
|
1367
|
+
let offset = bytes.length - limit;
|
|
1368
|
+
while (offset < bytes.length && ((bytes[offset] ?? 0) & 192) === 128) offset++;
|
|
1369
|
+
return { text: bytes.subarray(offset).toString("utf8"), truncated: true };
|
|
1370
|
+
}
|
|
1371
|
+
var CodingDiagnostics = class {
|
|
1372
|
+
decoder = new TextDecoder();
|
|
1373
|
+
secrets;
|
|
1374
|
+
lookbehind;
|
|
1375
|
+
retainBytes;
|
|
1376
|
+
pending = "";
|
|
1377
|
+
text = "";
|
|
1378
|
+
truncated = false;
|
|
1379
|
+
observedBytes = 0;
|
|
1380
|
+
redactions = 0;
|
|
1381
|
+
finished = false;
|
|
1382
|
+
constructor(secrets, retainBytes = CODING_OUTPUT_BYTES) {
|
|
1383
|
+
this.secrets = [...new Set(secrets.filter(Boolean))].sort((a, b) => b.length - a.length);
|
|
1384
|
+
this.lookbehind = Math.max(1, ...this.secrets.map((secret) => secret.length)) - 1;
|
|
1385
|
+
this.retainBytes = retainBytes;
|
|
1386
|
+
}
|
|
1387
|
+
append(bytes) {
|
|
1388
|
+
if (this.finished) throw new Error("Coding diagnostics already finalized");
|
|
1389
|
+
this.observedBytes += bytes.length;
|
|
1390
|
+
for (let offset = 0; offset < bytes.length; offset += 8192) {
|
|
1391
|
+
this.pending += this.decoder.decode(bytes.subarray(offset, offset + 8192), { stream: true });
|
|
1392
|
+
this.flush(false);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
/**
|
|
1396
|
+
* Redacted cumulative tail for a live update. Unlike `finish()` this does not seal
|
|
1397
|
+
* the diagnostics: more output may follow. It deliberately excludes the trailing
|
|
1398
|
+
* lookbehind bytes so a credential split across chunks cannot leak before the next
|
|
1399
|
+
* chunk resolves it.
|
|
1400
|
+
*/
|
|
1401
|
+
preview(limit = CODING_LIVE_BYTES) {
|
|
1402
|
+
return diagnosticTail(this.text, limit);
|
|
1403
|
+
}
|
|
1404
|
+
finish() {
|
|
1405
|
+
if (!this.finished) {
|
|
1406
|
+
this.pending += this.decoder.decode();
|
|
1407
|
+
this.flush(true);
|
|
1408
|
+
this.finished = true;
|
|
1409
|
+
}
|
|
1410
|
+
return {
|
|
1411
|
+
diagnostic: this.text,
|
|
1412
|
+
truncated: this.truncated,
|
|
1413
|
+
observedBytes: this.observedBytes,
|
|
1414
|
+
redacted: this.redactions > 0
|
|
1415
|
+
};
|
|
1416
|
+
}
|
|
1417
|
+
flush(final) {
|
|
1418
|
+
let end = final ? this.pending.length : Math.max(0, this.pending.length - this.lookbehind);
|
|
1419
|
+
const last = this.pending.charCodeAt(end - 1);
|
|
1420
|
+
if (!final && last >= 55296 && last <= 56319) end--;
|
|
1421
|
+
let offset = 0;
|
|
1422
|
+
let safe = "";
|
|
1423
|
+
while (offset < end) {
|
|
1424
|
+
const secret = this.secrets.find((value) => this.pending.startsWith(value, offset));
|
|
1425
|
+
if (secret) {
|
|
1426
|
+
safe += "[redacted]";
|
|
1427
|
+
this.redactions++;
|
|
1428
|
+
offset += secret.length;
|
|
1429
|
+
} else {
|
|
1430
|
+
const code = this.pending.charCodeAt(offset);
|
|
1431
|
+
const char = this.pending[offset] ?? "";
|
|
1432
|
+
safe += code < 32 && code !== 9 && code !== 10 || code >= 127 && code <= 159 ? `\\u${code.toString(16).padStart(4, "0")}` : char;
|
|
1433
|
+
offset++;
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
this.pending = this.pending.slice(offset);
|
|
1437
|
+
const tail = diagnosticTail(this.text + safe, this.retainBytes);
|
|
1438
|
+
this.text = tail.text;
|
|
1439
|
+
this.truncated ||= tail.truncated;
|
|
1440
|
+
}
|
|
1441
|
+
};
|
|
1442
|
+
function codingSecrets(env) {
|
|
1443
|
+
const values = /* @__PURE__ */ new Set();
|
|
1444
|
+
function collect(value, depth = 0) {
|
|
1445
|
+
if (depth > 8) return;
|
|
1446
|
+
if (typeof value === "string" && value.length >= 4) values.add(value);
|
|
1447
|
+
else if (value && typeof value === "object")
|
|
1448
|
+
for (const entry of Object.values(value)) collect(entry, depth + 1);
|
|
1449
|
+
}
|
|
1450
|
+
for (const [key, value] of Object.entries(env)) {
|
|
1451
|
+
if (!value || !/KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|AUTH/i.test(key)) continue;
|
|
1452
|
+
values.add(value);
|
|
1453
|
+
try {
|
|
1454
|
+
collect(JSON.parse(value));
|
|
1455
|
+
} catch {
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
return [...values];
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1301
1461
|
// ../daemon/src/lib/result-source.ts
|
|
1302
1462
|
import { closeSync as closeSync2, constants as constants2, fstatSync as fstatSync2, openSync as openSync2, readSync, realpathSync as realpathSync2 } from "fs";
|
|
1303
1463
|
import { basename as basename2, join as join13 } from "path";
|
|
@@ -1387,67 +1547,6 @@ function validateCodingCommand(input) {
|
|
|
1387
1547
|
};
|
|
1388
1548
|
}
|
|
1389
1549
|
|
|
1390
|
-
// ../daemon/src/lib/coding-environment/diagnostics.ts
|
|
1391
|
-
var CODING_OUTPUT_BYTES = 64 * 1024;
|
|
1392
|
-
function diagnosticTail(value, limit) {
|
|
1393
|
-
const bytes = Buffer.from(value);
|
|
1394
|
-
if (bytes.length <= limit) return { text: value, truncated: false };
|
|
1395
|
-
let offset = bytes.length - limit;
|
|
1396
|
-
while (offset < bytes.length && ((bytes[offset] ?? 0) & 192) === 128) offset++;
|
|
1397
|
-
return { text: bytes.subarray(offset).toString("utf8"), truncated: true };
|
|
1398
|
-
}
|
|
1399
|
-
var CodingDiagnostics = class {
|
|
1400
|
-
decoder = new TextDecoder();
|
|
1401
|
-
secrets;
|
|
1402
|
-
lookbehind;
|
|
1403
|
-
pending = "";
|
|
1404
|
-
text = "";
|
|
1405
|
-
truncated = false;
|
|
1406
|
-
finished = false;
|
|
1407
|
-
constructor(secrets) {
|
|
1408
|
-
this.secrets = [...new Set(secrets.filter(Boolean))].sort((a, b) => b.length - a.length);
|
|
1409
|
-
this.lookbehind = Math.max(1, ...this.secrets.map((secret) => secret.length)) - 1;
|
|
1410
|
-
}
|
|
1411
|
-
append(bytes) {
|
|
1412
|
-
if (this.finished) throw new Error("Coding diagnostics already finalized");
|
|
1413
|
-
for (let offset = 0; offset < bytes.length; offset += 8192) {
|
|
1414
|
-
this.pending += this.decoder.decode(bytes.subarray(offset, offset + 8192), { stream: true });
|
|
1415
|
-
this.flush(false);
|
|
1416
|
-
}
|
|
1417
|
-
}
|
|
1418
|
-
finish() {
|
|
1419
|
-
if (!this.finished) {
|
|
1420
|
-
this.pending += this.decoder.decode();
|
|
1421
|
-
this.flush(true);
|
|
1422
|
-
this.finished = true;
|
|
1423
|
-
}
|
|
1424
|
-
return { diagnostic: this.text, truncated: this.truncated };
|
|
1425
|
-
}
|
|
1426
|
-
flush(final) {
|
|
1427
|
-
let end = final ? this.pending.length : Math.max(0, this.pending.length - this.lookbehind);
|
|
1428
|
-
const last = this.pending.charCodeAt(end - 1);
|
|
1429
|
-
if (!final && last >= 55296 && last <= 56319) end--;
|
|
1430
|
-
let offset = 0;
|
|
1431
|
-
let safe = "";
|
|
1432
|
-
while (offset < end) {
|
|
1433
|
-
const secret = this.secrets.find((value) => this.pending.startsWith(value, offset));
|
|
1434
|
-
if (secret) {
|
|
1435
|
-
safe += "[redacted]";
|
|
1436
|
-
offset += secret.length;
|
|
1437
|
-
} else {
|
|
1438
|
-
const code = this.pending.charCodeAt(offset);
|
|
1439
|
-
const char = this.pending[offset] ?? "";
|
|
1440
|
-
safe += code < 32 && code !== 9 && code !== 10 || code >= 127 && code <= 159 ? `\\u${code.toString(16).padStart(4, "0")}` : char;
|
|
1441
|
-
offset++;
|
|
1442
|
-
}
|
|
1443
|
-
}
|
|
1444
|
-
this.pending = this.pending.slice(offset);
|
|
1445
|
-
const tail = diagnosticTail(this.text + safe, CODING_OUTPUT_BYTES);
|
|
1446
|
-
this.text = tail.text;
|
|
1447
|
-
this.truncated ||= tail.truncated;
|
|
1448
|
-
}
|
|
1449
|
-
};
|
|
1450
|
-
|
|
1451
1550
|
// ../daemon/src/runtime/coding-directory.ts
|
|
1452
1551
|
import { realpathSync as realpathSync4 } from "fs";
|
|
1453
1552
|
import { join as join15 } from "path";
|
|
@@ -2895,6 +2994,7 @@ function runCleanupCommand(dockerPath, args, processEnv) {
|
|
|
2895
2994
|
|
|
2896
2995
|
// ../daemon/src/runtime/pi/coding.ts
|
|
2897
2996
|
function codingTools(input) {
|
|
2997
|
+
const readSecrets = () => typeof input.secrets === "function" ? input.secrets() : input.secrets ?? [];
|
|
2898
2998
|
const hostOperations = input.docker ? null : createLocalBashOperations();
|
|
2899
2999
|
return [
|
|
2900
3000
|
{
|
|
@@ -2935,7 +3035,7 @@ function codingTools(input) {
|
|
|
2935
3035
|
{ additionalProperties: false }
|
|
2936
3036
|
),
|
|
2937
3037
|
executionMode: "sequential",
|
|
2938
|
-
async execute(toolCallId, params, signal) {
|
|
3038
|
+
async execute(toolCallId, params, signal, onUpdate) {
|
|
2939
3039
|
const command = validateCodingCommand(params);
|
|
2940
3040
|
const context = await input.context(command.cwd);
|
|
2941
3041
|
if (context.instructions.state !== "complete")
|
|
@@ -2945,7 +3045,27 @@ function codingTools(input) {
|
|
|
2945
3045
|
toolCallId,
|
|
2946
3046
|
input: command
|
|
2947
3047
|
});
|
|
2948
|
-
const output = new CodingDiagnostics(
|
|
3048
|
+
const output = new CodingDiagnostics(readSecrets());
|
|
3049
|
+
let lastProgressAt = 0;
|
|
3050
|
+
const emitProgress = (force) => {
|
|
3051
|
+
if (!onUpdate) return;
|
|
3052
|
+
const now = Date.now();
|
|
3053
|
+
if (!force && now - lastProgressAt < 400) return;
|
|
3054
|
+
lastProgressAt = now;
|
|
3055
|
+
const preview = output.preview(CODING_LIVE_BYTES);
|
|
3056
|
+
onUpdate({
|
|
3057
|
+
content: [{ type: "text", text: preview.text }],
|
|
3058
|
+
details: {
|
|
3059
|
+
codingProgress: {
|
|
3060
|
+
id: toolCallId,
|
|
3061
|
+
commandId: started.id,
|
|
3062
|
+
output: preview.text,
|
|
3063
|
+
truncated: preview.truncated,
|
|
3064
|
+
elapsedMs: Math.max(0, now - started.startedAt)
|
|
3065
|
+
}
|
|
3066
|
+
}
|
|
3067
|
+
});
|
|
3068
|
+
};
|
|
2949
3069
|
let outcome;
|
|
2950
3070
|
try {
|
|
2951
3071
|
if (input.approval)
|
|
@@ -2966,8 +3086,16 @@ function codingTools(input) {
|
|
|
2966
3086
|
const result = await operations.exec(
|
|
2967
3087
|
command.command,
|
|
2968
3088
|
input.docker ? input.root : cwd.path,
|
|
2969
|
-
{
|
|
3089
|
+
{
|
|
3090
|
+
onData: (bytes) => {
|
|
3091
|
+
output.append(bytes);
|
|
3092
|
+
emitProgress(false);
|
|
3093
|
+
},
|
|
3094
|
+
signal,
|
|
3095
|
+
timeout: command.timeoutSeconds
|
|
3096
|
+
}
|
|
2970
3097
|
);
|
|
3098
|
+
emitProgress(true);
|
|
2971
3099
|
outcome = {
|
|
2972
3100
|
state: result.exitCode === 0 ? "succeeded" : result.exitCode === null ? "interrupted" : "failed",
|
|
2973
3101
|
exitCode: result.exitCode,
|
|
@@ -3012,6 +3140,74 @@ function codingTools(input) {
|
|
|
3012
3140
|
details: { codingEvidence: value }
|
|
3013
3141
|
};
|
|
3014
3142
|
}
|
|
3143
|
+
},
|
|
3144
|
+
{
|
|
3145
|
+
name: "coding_log",
|
|
3146
|
+
label: "Read retained command output",
|
|
3147
|
+
description: "Read a bounded page of retained diagnostic output for a coding receipt, or search it. Producing Agents may read their own logs; a teammate must pass the id of the policy-authorized message that carried coding-receipt:<id>. Output is bounded and may be truncated, expired, deleted or unavailable \u2014 report that state honestly and do not infer completeness from an exit code.",
|
|
3148
|
+
parameters: Type.Object(
|
|
3149
|
+
{
|
|
3150
|
+
id: Type.String({ maxLength: 64 }),
|
|
3151
|
+
messageId: Type.Optional(Type.String({ maxLength: 64 })),
|
|
3152
|
+
search: Type.Optional(Type.String({ minLength: 1, maxLength: 256 })),
|
|
3153
|
+
offset: Type.Optional(Type.Integer({ minimum: 0 })),
|
|
3154
|
+
limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 65536 }))
|
|
3155
|
+
},
|
|
3156
|
+
{ additionalProperties: false }
|
|
3157
|
+
),
|
|
3158
|
+
executionMode: "sequential",
|
|
3159
|
+
async execute(_id, params) {
|
|
3160
|
+
const values = params;
|
|
3161
|
+
if (values.search !== void 0) {
|
|
3162
|
+
const result = await input.host.invoke({
|
|
3163
|
+
action: "log-search",
|
|
3164
|
+
id: values.id,
|
|
3165
|
+
query: values.search,
|
|
3166
|
+
...values.messageId !== void 0 ? { messageId: values.messageId } : {}
|
|
3167
|
+
});
|
|
3168
|
+
return {
|
|
3169
|
+
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
3170
|
+
details: { codingLogSearch: result }
|
|
3171
|
+
};
|
|
3172
|
+
}
|
|
3173
|
+
const value = await input.host.invoke({
|
|
3174
|
+
action: "log",
|
|
3175
|
+
id: values.id,
|
|
3176
|
+
...values.messageId !== void 0 ? { messageId: values.messageId } : {},
|
|
3177
|
+
...values.offset !== void 0 ? { offset: values.offset } : {},
|
|
3178
|
+
...values.limit !== void 0 ? { limit: values.limit } : {}
|
|
3179
|
+
});
|
|
3180
|
+
return {
|
|
3181
|
+
content: [{ type: "text", text: JSON.stringify(value) }],
|
|
3182
|
+
details: { codingLog: value }
|
|
3183
|
+
};
|
|
3184
|
+
}
|
|
3185
|
+
},
|
|
3186
|
+
{
|
|
3187
|
+
name: "source_snapshot",
|
|
3188
|
+
label: "Capture the current source state",
|
|
3189
|
+
description: "Capture a bounded snapshot of the repository source you are about to work from, and quote its reference in your summary. Call this once before you start editing: the reference is how a later change or verification is tied to the version it actually applies to. It is read-only and never changes the repository. The result may be incomplete \u2014 when it is, say so, because an incomplete snapshot cannot support a claim that code is unchanged. Untracked file content is never included unless you name each path.",
|
|
3190
|
+
parameters: Type.Object(
|
|
3191
|
+
{
|
|
3192
|
+
includeUntracked: Type.Optional(
|
|
3193
|
+
Type.Array(Type.String({ maxLength: 4096 }), { maxItems: 1e3 })
|
|
3194
|
+
)
|
|
3195
|
+
},
|
|
3196
|
+
{ additionalProperties: false }
|
|
3197
|
+
),
|
|
3198
|
+
executionMode: "sequential",
|
|
3199
|
+
async execute(toolCallId, params) {
|
|
3200
|
+
const values = params;
|
|
3201
|
+
const value = await input.host.invoke({
|
|
3202
|
+
action: "snapshot",
|
|
3203
|
+
toolCallId,
|
|
3204
|
+
...values.includeUntracked ? { includeUntracked: values.includeUntracked } : {}
|
|
3205
|
+
});
|
|
3206
|
+
return {
|
|
3207
|
+
content: [{ type: "text", text: JSON.stringify(value) }],
|
|
3208
|
+
details: { sourceSnapshot: value }
|
|
3209
|
+
};
|
|
3210
|
+
}
|
|
3015
3211
|
}
|
|
3016
3212
|
];
|
|
3017
3213
|
}
|
|
@@ -3349,6 +3545,20 @@ function fallbackApi(providerName) {
|
|
|
3349
3545
|
return "openai-completions";
|
|
3350
3546
|
}
|
|
3351
3547
|
}
|
|
3548
|
+
var UnknownModelError = class extends Error {
|
|
3549
|
+
providerName;
|
|
3550
|
+
modelId;
|
|
3551
|
+
// Fields are declared explicitly, not as constructor parameter properties:
|
|
3552
|
+
// worker subprocesses run Node's strip-only TypeScript, which rejects them.
|
|
3553
|
+
constructor(providerName, modelId) {
|
|
3554
|
+
super(
|
|
3555
|
+
`Unknown model "${modelId}" for provider "${providerName}": it is not in that provider's catalog, and no endpoint is configured for it. Choose a catalogued model, or configure an endpoint for a custom one.`
|
|
3556
|
+
);
|
|
3557
|
+
this.name = "UnknownModelError";
|
|
3558
|
+
this.providerName = providerName;
|
|
3559
|
+
this.modelId = modelId;
|
|
3560
|
+
}
|
|
3561
|
+
};
|
|
3352
3562
|
function fallbackPiModel(providerName, modelId, baseUrl) {
|
|
3353
3563
|
return {
|
|
3354
3564
|
id: modelId,
|
|
@@ -3420,6 +3630,7 @@ async function createProtectedPiRuntime(options) {
|
|
|
3420
3630
|
function resolvePiModel(runtime, providerName, modelId, baseUrl) {
|
|
3421
3631
|
const known = runtime.getModel(piProviderName(providerName), modelId);
|
|
3422
3632
|
if (known) return baseUrl ? { ...known, baseUrl } : known;
|
|
3633
|
+
if (!baseUrl) throw new UnknownModelError(providerName, modelId);
|
|
3423
3634
|
return fallbackPiModel(providerName, modelId, baseUrl);
|
|
3424
3635
|
}
|
|
3425
3636
|
|
|
@@ -3835,6 +4046,16 @@ var PROTECTED_REQUIRED_KEYS = new Set(
|
|
|
3835
4046
|
(key) => key !== "images" && key !== "questionEnabled" && key !== "containerNamespace"
|
|
3836
4047
|
)
|
|
3837
4048
|
);
|
|
4049
|
+
var VERIFICATION_KEYS = /* @__PURE__ */ new Set([
|
|
4050
|
+
"kind",
|
|
4051
|
+
"agentId",
|
|
4052
|
+
"message",
|
|
4053
|
+
"turnId",
|
|
4054
|
+
"runtime",
|
|
4055
|
+
"verification",
|
|
4056
|
+
"apiKeyRefreshEnabled",
|
|
4057
|
+
"scratch"
|
|
4058
|
+
]);
|
|
3838
4059
|
var REVIEW_KEYS = /* @__PURE__ */ new Set([
|
|
3839
4060
|
"kind",
|
|
3840
4061
|
"agentId",
|
|
@@ -3958,6 +4179,27 @@ function parseWorkerInput(value) {
|
|
|
3958
4179
|
assertMinimalWorkerScratch(input.scratch);
|
|
3959
4180
|
return value;
|
|
3960
4181
|
}
|
|
4182
|
+
if (kind === "specialist_verification") {
|
|
4183
|
+
assertExactKeys(input, VERIFICATION_KEYS, "verification worker input", VERIFICATION_KEYS);
|
|
4184
|
+
requireString(input.agentId, "agentId");
|
|
4185
|
+
requireString(input.message, "message");
|
|
4186
|
+
requireString(input.turnId, "turnId");
|
|
4187
|
+
assertProtectedProviderRuntime(input.runtime);
|
|
4188
|
+
if (input.apiKeyRefreshEnabled !== true) {
|
|
4189
|
+
throw new Error("worker: verification input requires bound API key refresh");
|
|
4190
|
+
}
|
|
4191
|
+
assertMinimalWorkerScratch(input.scratch);
|
|
4192
|
+
const verification = objectRecord(input.verification, "verification metadata");
|
|
4193
|
+
assertExactKeys(
|
|
4194
|
+
verification,
|
|
4195
|
+
/* @__PURE__ */ new Set(["requestId", "attemptId"]),
|
|
4196
|
+
"verification metadata",
|
|
4197
|
+
/* @__PURE__ */ new Set(["requestId", "attemptId"])
|
|
4198
|
+
);
|
|
4199
|
+
requireString(verification.requestId, "requestId");
|
|
4200
|
+
requireString(verification.attemptId, "attemptId");
|
|
4201
|
+
return value;
|
|
4202
|
+
}
|
|
3961
4203
|
if (kind === "restricted_review") {
|
|
3962
4204
|
assertExactKeys(input, REVIEW_KEYS, "restricted review worker input", REVIEW_KEYS);
|
|
3963
4205
|
requireString(input.agentId, "agentId");
|
|
@@ -6006,6 +6248,7 @@ async function createBazilionSession(opts) {
|
|
|
6006
6248
|
if (repository) bazilionTools.push(repository.tool);
|
|
6007
6249
|
if (repository && opts.codingHost && shellTools && shellTools.config.sandboxMode === "docker" && !opts.preparedDocker)
|
|
6008
6250
|
throw new Error("Coding commands require the admitted Docker runtime");
|
|
6251
|
+
const redactionSecrets = uniqueSecrets(codingSecrets(env));
|
|
6009
6252
|
if (repository && opts.codingHost && shellTools)
|
|
6010
6253
|
bazilionTools.push(
|
|
6011
6254
|
...codingTools({
|
|
@@ -6016,7 +6259,7 @@ async function createBazilionSession(opts) {
|
|
|
6016
6259
|
lifecycle: opts.dockerLifecycle,
|
|
6017
6260
|
approval: shellTools.config.approvalMode === "dangerous",
|
|
6018
6261
|
approvalHost: bashApprovalHost,
|
|
6019
|
-
secrets:
|
|
6262
|
+
secrets: () => redactionSecrets
|
|
6020
6263
|
})
|
|
6021
6264
|
);
|
|
6022
6265
|
const customTools = shellTools?.customBash ? [...bazilionTools, shellTools.customBash] : bazilionTools;
|
|
@@ -6038,7 +6281,9 @@ async function createBazilionSession(opts) {
|
|
|
6038
6281
|
session.agent.getApiKey = async (requestedProvider) => {
|
|
6039
6282
|
if (requestedProvider !== piProviderName(providerName)) return void 0;
|
|
6040
6283
|
try {
|
|
6041
|
-
|
|
6284
|
+
const token = await refreshApiKey(providerName);
|
|
6285
|
+
if (token && !redactionSecrets.includes(token)) redactionSecrets.push(token);
|
|
6286
|
+
return token;
|
|
6042
6287
|
} catch {
|
|
6043
6288
|
return void 0;
|
|
6044
6289
|
}
|
|
@@ -6123,6 +6368,7 @@ async function createProtectedBazilionSession(opts) {
|
|
|
6123
6368
|
sessionId: sessionManager.getSessionId()
|
|
6124
6369
|
});
|
|
6125
6370
|
if (repository) bazilionTools.push(repository.tool);
|
|
6371
|
+
const redactionSecrets = uniqueSecrets(protectedRuntimeSecrets(opts.runtime));
|
|
6126
6372
|
if (repository && opts.codingHost)
|
|
6127
6373
|
bazilionTools.push(
|
|
6128
6374
|
...codingTools({
|
|
@@ -6133,7 +6379,7 @@ async function createProtectedBazilionSession(opts) {
|
|
|
6133
6379
|
lifecycle: opts.dockerLifecycle,
|
|
6134
6380
|
approval: true,
|
|
6135
6381
|
approvalHost: opts.bashApprovalHost,
|
|
6136
|
-
secrets:
|
|
6382
|
+
secrets: () => redactionSecrets
|
|
6137
6383
|
})
|
|
6138
6384
|
);
|
|
6139
6385
|
if (!shellTools.customBash) throw new Error("protected Docker bash tool is unavailable");
|
|
@@ -6157,7 +6403,7 @@ async function createProtectedBazilionSession(opts) {
|
|
|
6157
6403
|
installProtectedCredentialBoundary(
|
|
6158
6404
|
session,
|
|
6159
6405
|
opts.runtime.providerName,
|
|
6160
|
-
|
|
6406
|
+
redactionSecrets,
|
|
6161
6407
|
opts.refreshApiKey
|
|
6162
6408
|
);
|
|
6163
6409
|
return sessionHandle(session);
|
|
@@ -6208,11 +6454,14 @@ async function createRestrictedReviewSession(opts) {
|
|
|
6208
6454
|
installProtectedCredentialBoundary(
|
|
6209
6455
|
session,
|
|
6210
6456
|
opts.runtime.providerName,
|
|
6211
|
-
protectedRuntimeSecrets(opts.runtime),
|
|
6457
|
+
uniqueSecrets(protectedRuntimeSecrets(opts.runtime)),
|
|
6212
6458
|
opts.refreshApiKey
|
|
6213
6459
|
);
|
|
6214
6460
|
return sessionHandle(session);
|
|
6215
6461
|
}
|
|
6462
|
+
function uniqueSecrets(values) {
|
|
6463
|
+
return [...new Set(values.filter(Boolean))];
|
|
6464
|
+
}
|
|
6216
6465
|
function materializeProtectedCredentialFile(runtime, scratch) {
|
|
6217
6466
|
const fields = [...runtime.credentialEnv ?? []];
|
|
6218
6467
|
if (runtime.credentialFile) {
|
|
@@ -6237,8 +6486,7 @@ function createInMemorySettingsManager() {
|
|
|
6237
6486
|
}
|
|
6238
6487
|
});
|
|
6239
6488
|
}
|
|
6240
|
-
function installProtectedCredentialBoundary(session, providerName,
|
|
6241
|
-
const activeTokens = [...new Set(initialSecrets.filter(Boolean))];
|
|
6489
|
+
function installProtectedCredentialBoundary(session, providerName, activeTokens, refreshApiKey) {
|
|
6242
6490
|
session.agent.state.messages = redactJsonValue(session.agent.state.messages, activeTokens);
|
|
6243
6491
|
const originalStream = session.agent.streamFunction;
|
|
6244
6492
|
session.agent.streamFunction = async (model, context, options) => {
|
|
@@ -6359,6 +6607,111 @@ function explicitConversationFile(directory, target) {
|
|
|
6359
6607
|
return file;
|
|
6360
6608
|
}
|
|
6361
6609
|
|
|
6610
|
+
// ../daemon/src/runtime/tools/verification.ts
|
|
6611
|
+
var VerificationCapabilityError = class extends Error {
|
|
6612
|
+
constructor(message) {
|
|
6613
|
+
super(message);
|
|
6614
|
+
this.name = "VerificationCapabilityError";
|
|
6615
|
+
}
|
|
6616
|
+
};
|
|
6617
|
+
function verificationTools(host) {
|
|
6618
|
+
const attempted = /* @__PURE__ */ new Set();
|
|
6619
|
+
const request = {
|
|
6620
|
+
def: {
|
|
6621
|
+
name: "verification_request",
|
|
6622
|
+
description: "Read the captured verification request: the exact change under verification, the environment the checks were admitted into, and every declared check with its timeout and any outcome so far. A check you were not asked to run cannot be added here \u2014 a different or additional command needs a new request.",
|
|
6623
|
+
parameters: { type: "object", properties: {}, additionalProperties: false }
|
|
6624
|
+
},
|
|
6625
|
+
async invoke() {
|
|
6626
|
+
return renderBrief(await host.read());
|
|
6627
|
+
}
|
|
6628
|
+
};
|
|
6629
|
+
const check = {
|
|
6630
|
+
def: {
|
|
6631
|
+
name: "verification_check",
|
|
6632
|
+
description: "Invoke exactly one declared check, identified by its ordinal from verification_request. Each check runs at most once: a check that already reported its outcome cannot be run again, and you cannot change its command, cwd, timeout or environment. Report what actually happened, including failures, skips and blockers. A successful exit is evidence about the commands that ran, never proof about later code.",
|
|
6633
|
+
parameters: {
|
|
6634
|
+
type: "object",
|
|
6635
|
+
properties: {
|
|
6636
|
+
ordinal: {
|
|
6637
|
+
type: "integer",
|
|
6638
|
+
minimum: 0,
|
|
6639
|
+
description: "Ordinal of a declared check, as listed by verification_request."
|
|
6640
|
+
}
|
|
6641
|
+
},
|
|
6642
|
+
required: ["ordinal"],
|
|
6643
|
+
additionalProperties: false
|
|
6644
|
+
}
|
|
6645
|
+
},
|
|
6646
|
+
async invoke(args, context) {
|
|
6647
|
+
const ordinal = readOrdinal(args);
|
|
6648
|
+
const brief = await host.read();
|
|
6649
|
+
const declared = brief.checks.find((entry) => entry.ordinal === ordinal);
|
|
6650
|
+
if (!declared) {
|
|
6651
|
+
throw new VerificationCapabilityError(
|
|
6652
|
+
`check ${ordinal} was not captured with this request; only ${brief.checks.map((entry) => entry.ordinal).join(", ")} exist`
|
|
6653
|
+
);
|
|
6654
|
+
}
|
|
6655
|
+
if (declared.state !== "not_executed") {
|
|
6656
|
+
throw new VerificationCapabilityError(
|
|
6657
|
+
`check ${ordinal} already reported '${declared.state}' and cannot be run again`
|
|
6658
|
+
);
|
|
6659
|
+
}
|
|
6660
|
+
if (attempted.has(ordinal)) {
|
|
6661
|
+
throw new VerificationCapabilityError(`check ${ordinal} is already running`);
|
|
6662
|
+
}
|
|
6663
|
+
attempted.add(ordinal);
|
|
6664
|
+
try {
|
|
6665
|
+
const run = await host.invoke(ordinal, { toolCallId: context?.toolCallId ?? "" });
|
|
6666
|
+
return renderRun(run);
|
|
6667
|
+
} catch (error) {
|
|
6668
|
+
attempted.delete(ordinal);
|
|
6669
|
+
throw error;
|
|
6670
|
+
}
|
|
6671
|
+
}
|
|
6672
|
+
};
|
|
6673
|
+
return [request, check];
|
|
6674
|
+
}
|
|
6675
|
+
function readOrdinal(args) {
|
|
6676
|
+
const keys2 = Object.keys(args).sort();
|
|
6677
|
+
if (keys2.length !== 1 || keys2[0] !== "ordinal") {
|
|
6678
|
+
throw new VerificationCapabilityError("verification_check takes only a declared ordinal");
|
|
6679
|
+
}
|
|
6680
|
+
const ordinal = args.ordinal;
|
|
6681
|
+
if (!Number.isInteger(ordinal) || ordinal < 0) {
|
|
6682
|
+
throw new VerificationCapabilityError("ordinal must be a non-negative integer");
|
|
6683
|
+
}
|
|
6684
|
+
return ordinal;
|
|
6685
|
+
}
|
|
6686
|
+
function renderBrief(brief) {
|
|
6687
|
+
const lines = [
|
|
6688
|
+
`Verification request ${brief.requestId}`,
|
|
6689
|
+
`Change: snapshot ${brief.snapshot.id} (base ${brief.snapshot.baseOid.slice(0, 12)}${brief.snapshot.complete ? "" : ", INCOMPLETE COVERAGE"})`,
|
|
6690
|
+
`Environment: image ${brief.environment.image}, shell ${brief.environment.sandbox}${brief.environment.cwd ? `, cwd ${brief.environment.cwd}` : ""}`,
|
|
6691
|
+
`Applicability: ${brief.applicability === "identical" ? "unchanged since capture" : brief.applicability}`
|
|
6692
|
+
];
|
|
6693
|
+
if (brief.summary) lines.push(`Requested by the requester: ${brief.summary}`);
|
|
6694
|
+
if (brief.writablePaths.length > 0) {
|
|
6695
|
+
lines.push(
|
|
6696
|
+
`Declared generated-output paths (where a check is expected to write; this does not confine writes): ${brief.writablePaths.join(", ")}`
|
|
6697
|
+
);
|
|
6698
|
+
}
|
|
6699
|
+
lines.push("", "Captured checks:");
|
|
6700
|
+
for (const entry of brief.checks) {
|
|
6701
|
+
const outcome = entry.state === "not_executed" ? "not run yet" : `${entry.state}${entry.exitCode === null ? "" : ` (exit ${entry.exitCode})`}${entry.commandId ? ` receipt ${entry.commandId}` : ""}`;
|
|
6702
|
+
lines.push(
|
|
6703
|
+
` [${entry.ordinal}] ${entry.command} (cwd ${entry.cwd}, ${entry.timeoutMs} ms, ${entry.purpose}) \u2014 ${outcome}`
|
|
6704
|
+
);
|
|
6705
|
+
}
|
|
6706
|
+
lines.push("", "Run each captured check with verification_check. Report failures as failures.");
|
|
6707
|
+
return lines.join("\n");
|
|
6708
|
+
}
|
|
6709
|
+
function renderRun(run) {
|
|
6710
|
+
const head = `Check ${run.ordinal}: ${run.state}${run.exitCode === null ? "" : ` (exit ${run.exitCode})`}${run.commandId ? ` \u2014 receipt ${run.commandId}` : ""}${run.truncated ? " [output truncated]" : ""}`;
|
|
6711
|
+
return run.output.trim() ? `${head}
|
|
6712
|
+
${run.output}` : head;
|
|
6713
|
+
}
|
|
6714
|
+
|
|
6362
6715
|
// ../daemon/src/runtime/worker/api-key-refresh.ts
|
|
6363
6716
|
function createIpcApiKeyRefresher(call, context) {
|
|
6364
6717
|
return async (providerName) => {
|
|
@@ -6582,8 +6935,16 @@ function createReviewState(evidenceItems) {
|
|
|
6582
6935
|
tools
|
|
6583
6936
|
};
|
|
6584
6937
|
}
|
|
6938
|
+
function createIpcVerificationHost(ipcCall, identity2) {
|
|
6939
|
+
return {
|
|
6940
|
+
// The request identity is bound here from the worker's own input, so a tool call cannot address
|
|
6941
|
+
// another request's attempt: only an ordinal travels.
|
|
6942
|
+
read: () => ipcCall("verificationRead", identity2),
|
|
6943
|
+
invoke: (ordinal) => ipcCall("verificationRun", { ...identity2, ordinal })
|
|
6944
|
+
};
|
|
6945
|
+
}
|
|
6585
6946
|
async function createSessionForInput(input, ipcCall) {
|
|
6586
|
-
if (input.kind !== "restricted_review" && !input.repositoryContext)
|
|
6947
|
+
if (input.kind !== "restricted_review" && input.kind !== "specialist_verification" && !input.repositoryContext)
|
|
6587
6948
|
throw new Error("Coding turn requires daemon-prepared repository context");
|
|
6588
6949
|
if (input.kind === "configured_operator_http") {
|
|
6589
6950
|
const paths = resolvePaths();
|
|
@@ -6641,6 +7002,18 @@ async function createSessionForInput(input, ipcCall) {
|
|
|
6641
7002
|
agentId: input.kind === "protected" ? input.agent.agent.id : input.agentId,
|
|
6642
7003
|
turnId: input.turnId
|
|
6643
7004
|
});
|
|
7005
|
+
if (input.kind === "specialist_verification") {
|
|
7006
|
+
const handle2 = await createRestrictedReviewSession({
|
|
7007
|
+
runtime: input.runtime,
|
|
7008
|
+
scratch: input.scratch,
|
|
7009
|
+
systemPrompt: VERIFICATION_SYSTEM_PROMPT,
|
|
7010
|
+
tools: verificationTools(createIpcVerificationHost(ipcCall, input.verification)).map(
|
|
7011
|
+
ourToolToPiTool
|
|
7012
|
+
),
|
|
7013
|
+
refreshApiKey
|
|
7014
|
+
});
|
|
7015
|
+
return { handle: handle2 };
|
|
7016
|
+
}
|
|
6644
7017
|
if (input.kind === "restricted_review") {
|
|
6645
7018
|
const reviewState = createReviewState(input.review.evidence);
|
|
6646
7019
|
const handle2 = await createRestrictedReviewSession({
|
|
@@ -6717,7 +7090,7 @@ async function main() {
|
|
|
6717
7090
|
session = handle.session;
|
|
6718
7091
|
const consumptionAcks = /* @__PURE__ */ new Set();
|
|
6719
7092
|
const unsubscribe = session.subscribe((piEvent) => {
|
|
6720
|
-
if (input.kind !== "restricted_review" && input.questionEnabled && piEvent.type === "message_end" && piEvent.message.role === "toolResult" && piEvent.message.toolName === "ask_user" && !piEvent.message.isError) {
|
|
7093
|
+
if (input.kind !== "restricted_review" && input.kind !== "specialist_verification" && input.questionEnabled && piEvent.type === "message_end" && piEvent.message.role === "toolResult" && piEvent.message.toolName === "ask_user" && !piEvent.message.isError) {
|
|
6721
7094
|
const message = piEvent.message;
|
|
6722
7095
|
const content = message.content[0];
|
|
6723
7096
|
if (content?.type === "text") {
|
|
@@ -6747,8 +7120,8 @@ async function main() {
|
|
|
6747
7120
|
});
|
|
6748
7121
|
try {
|
|
6749
7122
|
const promptMessage = redactJsonValue(input.message, activeAccessTokens);
|
|
6750
|
-
const sanitizedImages = input.kind === "restricted_review" ? [] : redactJsonValue(input.images ?? [], activeAccessTokens);
|
|
6751
|
-
const promptImages = input.kind === "restricted_review" ? [] : sanitizedImages.map((image) => ({
|
|
7123
|
+
const sanitizedImages = input.kind === "restricted_review" || input.kind === "specialist_verification" ? [] : redactJsonValue(input.images ?? [], activeAccessTokens);
|
|
7124
|
+
const promptImages = input.kind === "restricted_review" || input.kind === "specialist_verification" ? [] : sanitizedImages.map((image) => ({
|
|
6752
7125
|
type: "image",
|
|
6753
7126
|
data: image.data,
|
|
6754
7127
|
mimeType: image.mimeType
|
|
@@ -6791,6 +7164,24 @@ main().catch((error) => {
|
|
|
6791
7164
|
}
|
|
6792
7165
|
process.exit(1);
|
|
6793
7166
|
});
|
|
7167
|
+
var VERIFICATION_SYSTEM_PROMPT = `You are a restricted verification specialist. You verify one
|
|
7168
|
+
captured change against the checks your requester selected. Call verification_request to read the
|
|
7169
|
+
request, then verification_check once per declared check, in order.
|
|
7170
|
+
|
|
7171
|
+
Boundaries you cannot cross, and must not try to:
|
|
7172
|
+
- Only the declared ordinal of a captured check can run, once. You cannot change its command, cwd,
|
|
7173
|
+
timeout or environment, add a check, or retry a check that already reported.
|
|
7174
|
+
- You have no shell, no editor, no browser, no network tool and no deployment credential. A missing
|
|
7175
|
+
toolchain, service or approval is an explicit blocker to report, never something to work around.
|
|
7176
|
+
- Generated output may only be written to the declared writable paths.
|
|
7177
|
+
|
|
7178
|
+
Report what actually happened. A non-zero exit is a failure of that check; say so plainly. An exit
|
|
7179
|
+
code is evidence about the commands that ran, never proof about later code, and never a statement
|
|
7180
|
+
that the change is ready to merge. Distinguish a failure from a check you did not run, and never
|
|
7181
|
+
describe an unrun check as passing.
|
|
7182
|
+
|
|
7183
|
+
Finish with a short summary: the snapshot you verified, each check with its outcome and receipt, and
|
|
7184
|
+
any blocker or limitation that stopped a check. Do not recommend deployment.`;
|
|
6794
7185
|
var REVIEW_SYSTEM_PROMPT = `You are a restricted learning reviewer. Analyze only the supplied
|
|
6795
7186
|
transcript digest and approved-lesson index. You cannot act on the world. Call propose_lesson once
|
|
6796
7187
|
with zero to five proposals, then stop.
|