bazilion 0.18.0 → 0.19.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 +607 -96
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +3225 -739
- package/dist/daemon.js.map +1 -1
- package/dist/migrations/0001_init.sql +142 -3
- package/dist/web/client/assets/{ChatPane-CAYS_fIQ.js → ChatPane-DCyGcqdh.js} +1 -1
- package/dist/web/client/assets/ConfirmDialog-C908TxS5.js +1 -0
- package/dist/web/client/assets/{FieldRow-W_54rw5c.js → FieldRow-CELqI-1V.js} +1 -1
- package/dist/web/client/assets/{ProductionTeamPolicyEditor-DNXVX8Lz.js → ProductionTeamPolicyEditor-DnTcWhG8.js} +1 -1
- package/dist/web/client/assets/{ProfileCommunicationEditor-DN0fOzqn.js → ProfileCommunicationEditor-BVIEaW3s.js} +1 -1
- package/dist/web/client/assets/{ResultSourceConversation-DoU4tOWc.js → ResultSourceConversation-4gbZCh_s.js} +1 -1
- package/dist/web/client/assets/{TeamTabs-BmTZRI4T.js → TeamTabs-V17b45X5.js} +1 -1
- package/dist/web/client/assets/{TemplatesTabs-Bs_OXKwx.js → TemplatesTabs-BMK3Qok_.js} +1 -1
- package/dist/web/client/assets/{UnsavedChangesGuard-CPRtFReU.js → UnsavedChangesGuard-BaE-UzyS.js} +1 -1
- package/dist/web/client/assets/{_id-Dbmei5tg.js → _id-BU1l9gP7.js} +1 -1
- package/dist/web/client/assets/{_id-DL4tJFQB.js → _id-BVANQm00.js} +1 -1
- package/dist/web/client/assets/{_id-DR9eFC17.js → _id-Bvh5LyUv.js} +1 -1
- package/dist/web/client/assets/{_id-ybF-pqmr.js → _id-CArZR-IO.js} +1 -1
- package/dist/web/client/assets/{_id-CxAB4TDr.js → _id-tUkSe5li.js} +1 -1
- package/dist/web/client/assets/{activity-oUyy77jD.js → activity-CWCnqjqj.js} +1 -1
- package/dist/web/client/assets/{agents-DkjJp7JP.js → agents-CX4STmGK.js} +1 -1
- package/dist/web/client/assets/{agents-D_TrEqAg.js → agents-CdCnhH06.js} +1 -1
- package/dist/web/client/assets/{approvals-DhOerWdt.js → approvals-CnNpwG78.js} +1 -1
- package/dist/web/client/assets/{attention-DGwiF-Jy.js → attention-CEE-wWrx.js} +1 -1
- package/dist/web/client/assets/chevron-right-CvCEwfSl.js +1 -0
- package/dist/web/client/assets/{config-BJ2ZzHPR.js → config-CSEtI-dq.js} +1 -1
- package/dist/web/client/assets/{inbox-BUElnGep.js → inbox-MYnBtPdF.js} +1 -1
- package/dist/web/client/assets/index-Ct31TjS-.js +52 -0
- package/dist/web/client/assets/{learning-BiTHNwB3.js → learning-BIR5FTgQ.js} +1 -1
- package/dist/web/client/assets/{login-BmcZvAH2.js → login-DIeceuOs.js} +1 -1
- package/dist/web/client/assets/{mcp-Cwk9V82W.js → mcp-CX3kJpGu.js} +1 -1
- package/dist/web/client/assets/{members-CHDNabFh.js → members-DlhSjye1.js} +1 -1
- package/dist/web/client/assets/{memory-Cx_Fpd4e.js → memory-CsDd6b2l.js} +1 -1
- package/dist/web/client/assets/{policy-C0nMdwcG.js → policy-DkWDhG0x.js} +1 -1
- package/dist/web/client/assets/{results-Bz3jASs-.js → results-BHdhNHJJ.js} +1 -1
- package/dist/web/client/assets/review-Dyw47eM1.js +1 -0
- package/dist/web/client/assets/{routes-DsMY_6oy.js → routes-DtYD4WJL.js} +1 -1
- package/dist/web/client/assets/{services-DItA6fJ7.js → services-WUlW7oEo.js} +1 -1
- package/dist/web/client/assets/{skills-DbNV2vgL.js → skills-jNoUfUSZ.js} +1 -1
- package/dist/web/client/assets/styles-DCX6QTqJ.css +2 -0
- package/dist/web/client/assets/{teams-D83scDxw.js → teams-C1kYRrtP.js} +1 -1
- package/dist/web/client/assets/{teams-DAny1ypN.js → teams-D3FaSKE7.js} +1 -1
- package/dist/web/client/assets/{telegram-BOmf9vUh.js → telegram-D86AO6V9.js} +1 -1
- package/dist/web/client/assets/{tokens-DBGH6Bw5.js → tokens-B42KDisP.js} +1 -1
- package/dist/web/client/assets/{triggers-D1_pseI3.js → triggers-yEfWnQ_K.js} +1 -1
- package/dist/web/client/assets/{verifications-CBTo-FyV.js → verifications-DrHQEQFx.js} +2 -2
- package/dist/web/client/assets/{welcome-DAfPOm15.js → welcome-D8IbF_P0.js} +1 -1
- package/dist/web/client/assets/{x-CWY-gUaM.js → x-CXKABZ7C.js} +1 -1
- package/dist/web/server/assets/{_id--zoh1vv7.js → _id-D2bDA1iV.js} +1 -1
- package/dist/web/server/assets/{_id-6p-mDmI8.js → _id-DL-SnSnK.js} +1 -1
- package/dist/web/server/assets/{_id-dUnXL-My2.js → _id-Dab2CVtO2.js} +1 -1
- package/dist/web/server/assets/{_id-DptBl3X8.js → _id-bVispdh-.js} +1 -1
- package/dist/web/server/assets/{_tanstack-start-manifest_v-B3M-dfRO.js → _tanstack-start-manifest_v-BcTOb0oj.js} +84 -85
- package/dist/web/server/assets/{activity-C5jpoEQI.js → activity-CLDAy6rk.js} +1 -1
- package/dist/web/server/assets/{agents-RE6aYOb-.js → agents-CdB2kuNN.js} +1 -1
- package/dist/web/server/assets/{agents-nAOx_H7s.js → agents-DfHcb2H2.js} +1 -1
- package/dist/web/server/assets/{approvals-DhHxIDrL.js → approvals-Bq846WaP.js} +1 -1
- package/dist/web/server/assets/{attention-CBWzWRni.js → attention-Sm-U7s_0.js} +1 -1
- package/dist/web/server/assets/{auth-tB3i6cFd.js → auth-PB5dVyvX.js} +1 -1
- package/dist/web/server/assets/{config-D1k_tTAw.js → config-BNGTBu80.js} +1 -1
- package/dist/web/server/assets/{daemon-client-C7qjQ2iO.js → daemon-client-CWQvck6B.js} +35 -0
- package/dist/web/server/assets/{git-review-Bf5ABFJg.js → git-review-C_h_tezf.js} +1 -1
- package/dist/web/server/assets/{inbox-Dw4pTevh.js → inbox-DJoU-bla.js} +1 -1
- package/dist/web/server/assets/{learning-CF8ZzFVD.js → learning-DVb0I_3Z.js} +1 -1
- package/dist/web/server/assets/{mcp-D5dmBT82.js → mcp-CeZqOiDG.js} +1 -1
- package/dist/web/server/assets/{members-CvwEN9pm.js → members-CcYjuqxB.js} +1 -1
- package/dist/web/server/assets/{memory-CcPK7um7.js → memory-CH2yNT89.js} +1 -1
- package/dist/web/server/assets/{policy-Dh6wd2wN.js → policy-DrRKinMr.js} +1 -1
- package/dist/web/server/assets/{results-BWnu3gXP.js → results-fT2zyiJx.js} +1 -1
- package/dist/web/server/assets/review-CvUPk4HA.js +38 -0
- package/dist/web/server/assets/review-DYcYdUTv.js +859 -0
- package/dist/web/server/assets/review-packets-e36PsTSX.js +172 -0
- package/dist/web/server/assets/{router-Deq94UJQ.js → router-NYhuYQCd.js} +4 -4
- package/dist/web/server/assets/{routes-CVKkvFVv.js → routes-RdppWPiW.js} +1 -1
- package/dist/web/server/assets/{services-CEr61xb5.js → services-Dgu7dcTC.js} +1 -1
- package/dist/web/server/assets/{skills-BImC3LTO.js → skills-DL7UIWa8.js} +1 -1
- package/dist/web/server/assets/{teams-8zEIo08E.js → teams-Cmn7mdx9.js} +1 -1
- package/dist/web/server/assets/{teams-D-yaAWLV.js → teams-DiC-MBg4.js} +1 -1
- package/dist/web/server/assets/{telegram-CGl_LFtJ.js → telegram-CLOFnLjF.js} +1 -1
- package/dist/web/server/assets/{tokens-cB-uf7qm.js → tokens-BVva7GHu.js} +1 -1
- package/dist/web/server/assets/{triggers-CtSj79L0.js → triggers-D4orksJq.js} +1 -1
- package/dist/web/server/assets/{verification-B5QjcpIo.js → verification-C1SHMTX8.js} +1 -1
- package/dist/web/server/assets/{verifications-CUq_6ZqL.js → verifications-C_ycXrPK.js} +1 -1
- package/dist/web/server/assets/{verifications-BfQsfwSE.js → verifications-Ci49n2Km.js} +14 -1
- package/dist/web/server/server.js +75 -39
- package/dist/worker.js +528 -111
- package/dist/worker.js.map +1 -1
- package/package.json +3 -3
- package/dist/web/client/assets/ConfirmDialog-BzIiABOP.js +0 -1
- package/dist/web/client/assets/chevron-right-DSa4xPTs.js +0 -1
- package/dist/web/client/assets/createServerFn-Dzfjt7mA.js +0 -3
- package/dist/web/client/assets/index-Bi-HxcPG.js +0 -50
- package/dist/web/client/assets/review-AK9WGmpv.js +0 -1
- package/dist/web/client/assets/styles-C6br2xxl.css +0 -2
- package/dist/web/server/assets/review-DUe3vHPU.js +0 -393
- package/dist/web/server/assets/review-c_-cFi7H.js +0 -14
package/dist/worker.js
CHANGED
|
@@ -3515,6 +3515,8 @@ function providerBaseUrl(providerName, env) {
|
|
|
3515
3515
|
return env.LLAMACPP_URL ?? LOCAL_PROVIDERS.llamacpp?.baseUrl;
|
|
3516
3516
|
case "vercel-ai-gateway":
|
|
3517
3517
|
return env.AI_GATEWAY_BASE_URL;
|
|
3518
|
+
case "fireworks":
|
|
3519
|
+
return env.FIREWORKS_BASE_URL ?? "https://api.fireworks.ai/inference";
|
|
3518
3520
|
default:
|
|
3519
3521
|
return void 0;
|
|
3520
3522
|
}
|
|
@@ -4046,6 +4048,16 @@ var PROTECTED_REQUIRED_KEYS = new Set(
|
|
|
4046
4048
|
(key) => key !== "images" && key !== "questionEnabled" && key !== "containerNamespace"
|
|
4047
4049
|
)
|
|
4048
4050
|
);
|
|
4051
|
+
var STATIC_REVIEW_KEYS = /* @__PURE__ */ new Set([
|
|
4052
|
+
"kind",
|
|
4053
|
+
"agentId",
|
|
4054
|
+
"message",
|
|
4055
|
+
"turnId",
|
|
4056
|
+
"runtime",
|
|
4057
|
+
"review",
|
|
4058
|
+
"apiKeyRefreshEnabled",
|
|
4059
|
+
"scratch"
|
|
4060
|
+
]);
|
|
4049
4061
|
var VERIFICATION_KEYS = /* @__PURE__ */ new Set([
|
|
4050
4062
|
"kind",
|
|
4051
4063
|
"agentId",
|
|
@@ -4200,6 +4212,27 @@ function parseWorkerInput(value) {
|
|
|
4200
4212
|
requireString(verification.attemptId, "attemptId");
|
|
4201
4213
|
return value;
|
|
4202
4214
|
}
|
|
4215
|
+
if (kind === "packet_review") {
|
|
4216
|
+
assertExactKeys(input, STATIC_REVIEW_KEYS, "static review worker input", STATIC_REVIEW_KEYS);
|
|
4217
|
+
requireString(input.agentId, "agentId");
|
|
4218
|
+
requireString(input.message, "message");
|
|
4219
|
+
requireString(input.turnId, "turnId");
|
|
4220
|
+
assertProtectedProviderRuntime(input.runtime);
|
|
4221
|
+
if (input.apiKeyRefreshEnabled !== true) {
|
|
4222
|
+
throw new Error("worker: static review requires bound API key refresh");
|
|
4223
|
+
}
|
|
4224
|
+
assertMinimalWorkerScratch(input.scratch);
|
|
4225
|
+
const review = objectRecord(input.review, "review metadata");
|
|
4226
|
+
assertExactKeys(
|
|
4227
|
+
review,
|
|
4228
|
+
/* @__PURE__ */ new Set(["packetId", "attemptId"]),
|
|
4229
|
+
"review metadata",
|
|
4230
|
+
/* @__PURE__ */ new Set(["packetId", "attemptId"])
|
|
4231
|
+
);
|
|
4232
|
+
requireString(review.packetId, "packetId");
|
|
4233
|
+
requireString(review.attemptId, "attemptId");
|
|
4234
|
+
return value;
|
|
4235
|
+
}
|
|
4203
4236
|
if (kind === "restricted_review") {
|
|
4204
4237
|
assertExactKeys(input, REVIEW_KEYS, "restricted review worker input", REVIEW_KEYS);
|
|
4205
4238
|
requireString(input.agentId, "agentId");
|
|
@@ -5396,6 +5429,207 @@ function messagingTools(host, fromAgentId) {
|
|
|
5396
5429
|
];
|
|
5397
5430
|
}
|
|
5398
5431
|
|
|
5432
|
+
// ../daemon/src/runtime/tools/review.ts
|
|
5433
|
+
var ReviewCapabilityError = class extends Error {
|
|
5434
|
+
};
|
|
5435
|
+
var SEVERITIES = ["blocker", "major", "minor", "info"];
|
|
5436
|
+
var CONCLUSIONS = ["changes_requested", "commented", "recommended"];
|
|
5437
|
+
function reviewTools(host) {
|
|
5438
|
+
const packetTool = {
|
|
5439
|
+
def: {
|
|
5440
|
+
name: "review_packet",
|
|
5441
|
+
description: "Read the captured revision you are reviewing: its changed paths, whether that revision\u2019s content can still be reproduced from the working tree, the findings recorded so far, and any conclusion already recorded. This is a static review of one captured revision \u2014 it is not the current repository, and nothing here runs code or changes files.",
|
|
5442
|
+
parameters: { type: "object", properties: {}, additionalProperties: false }
|
|
5443
|
+
},
|
|
5444
|
+
async invoke() {
|
|
5445
|
+
return renderBrief(await host.read());
|
|
5446
|
+
}
|
|
5447
|
+
};
|
|
5448
|
+
const pathTool = {
|
|
5449
|
+
def: {
|
|
5450
|
+
name: "review_path",
|
|
5451
|
+
description: "Read one changed path\u2019s patch from the reviewed revision. Only paths listed by review_packet exist in it. If the working tree has moved since the capture, the patch cannot be reproduced and this says so \u2014 a diff of different code is never returned as the reviewed change.",
|
|
5452
|
+
parameters: {
|
|
5453
|
+
type: "object",
|
|
5454
|
+
properties: {
|
|
5455
|
+
path: {
|
|
5456
|
+
type: "string",
|
|
5457
|
+
description: "Repository-relative path, exactly as review_packet listed it."
|
|
5458
|
+
}
|
|
5459
|
+
},
|
|
5460
|
+
required: ["path"],
|
|
5461
|
+
additionalProperties: false
|
|
5462
|
+
}
|
|
5463
|
+
},
|
|
5464
|
+
async invoke(args) {
|
|
5465
|
+
const path = typeof args.path === "string" ? args.path.trim() : "";
|
|
5466
|
+
if (path === "") throw new ReviewCapabilityError("review_path needs a path");
|
|
5467
|
+
return renderContent(await host.path(path));
|
|
5468
|
+
}
|
|
5469
|
+
};
|
|
5470
|
+
const findingTool = {
|
|
5471
|
+
def: {
|
|
5472
|
+
name: "review_finding",
|
|
5473
|
+
description: "Record one finding against the reviewed revision: a path that appears in review_packet, a severity, and what is wrong. The line range is context for a reader, not identity \u2014 do not attach a finding to a line you have not read. A finding is a statement with evidence, never an approval, and a finding that cannot be correlated to this revision is recorded as unverified rather than guessed at.",
|
|
5474
|
+
parameters: {
|
|
5475
|
+
type: "object",
|
|
5476
|
+
properties: {
|
|
5477
|
+
path: { type: "string", description: "Changed path in the reviewed revision." },
|
|
5478
|
+
severity: {
|
|
5479
|
+
type: "string",
|
|
5480
|
+
enum: [...SEVERITIES],
|
|
5481
|
+
description: "blocker | major | minor | info"
|
|
5482
|
+
},
|
|
5483
|
+
note: {
|
|
5484
|
+
type: "string",
|
|
5485
|
+
description: "What is wrong and what it would take to be satisfied. Be specific."
|
|
5486
|
+
},
|
|
5487
|
+
lineStart: {
|
|
5488
|
+
type: "integer",
|
|
5489
|
+
minimum: 1,
|
|
5490
|
+
description: "Optional first line of context."
|
|
5491
|
+
},
|
|
5492
|
+
lineEnd: { type: "integer", minimum: 1, description: "Optional last line of context." }
|
|
5493
|
+
},
|
|
5494
|
+
required: ["path", "severity", "note"],
|
|
5495
|
+
additionalProperties: false
|
|
5496
|
+
}
|
|
5497
|
+
},
|
|
5498
|
+
async invoke(args) {
|
|
5499
|
+
const path = typeof args.path === "string" ? args.path.trim() : "";
|
|
5500
|
+
const note = typeof args.note === "string" ? args.note.trim() : "";
|
|
5501
|
+
const severity = args.severity;
|
|
5502
|
+
if (path === "") throw new ReviewCapabilityError("review_finding needs a path");
|
|
5503
|
+
if (note === "") throw new ReviewCapabilityError("review_finding needs a note");
|
|
5504
|
+
if (!SEVERITIES.includes(severity)) {
|
|
5505
|
+
throw new ReviewCapabilityError(`severity must be one of: ${SEVERITIES.join(", ")}`);
|
|
5506
|
+
}
|
|
5507
|
+
const result = await host.addFinding({
|
|
5508
|
+
path,
|
|
5509
|
+
severity,
|
|
5510
|
+
note,
|
|
5511
|
+
lineStart: readLine(args.lineStart),
|
|
5512
|
+
lineEnd: readLine(args.lineEnd)
|
|
5513
|
+
});
|
|
5514
|
+
return `Finding ${result.findingId} recorded as [${String(severity)}] on ${path} (finding ${result.ordinal}). Nothing was executed and nothing was changed.`;
|
|
5515
|
+
}
|
|
5516
|
+
};
|
|
5517
|
+
const conclusionTool = {
|
|
5518
|
+
def: {
|
|
5519
|
+
name: "review_conclusion",
|
|
5520
|
+
description: "Record your conclusion for this revision and finish. changes_requested | commented | recommended. A conclusion is your statement about this revision: it is not operator acceptance, not a passing test, and not permission to publish, merge or deploy. Unresolved findings stay visible whatever you conclude, so conclude on the evidence you actually have.",
|
|
5521
|
+
parameters: {
|
|
5522
|
+
type: "object",
|
|
5523
|
+
properties: {
|
|
5524
|
+
conclusion: {
|
|
5525
|
+
type: "string",
|
|
5526
|
+
enum: [...CONCLUSIONS],
|
|
5527
|
+
description: "changes_requested | commented | recommended"
|
|
5528
|
+
},
|
|
5529
|
+
note: { type: "string", description: "A short justification, in evidence terms." }
|
|
5530
|
+
},
|
|
5531
|
+
required: ["conclusion"],
|
|
5532
|
+
additionalProperties: false
|
|
5533
|
+
}
|
|
5534
|
+
},
|
|
5535
|
+
async invoke(args) {
|
|
5536
|
+
const conclusion = args.conclusion;
|
|
5537
|
+
if (!CONCLUSIONS.includes(conclusion)) {
|
|
5538
|
+
throw new ReviewCapabilityError(`conclusion must be one of: ${CONCLUSIONS.join(", ")}`);
|
|
5539
|
+
}
|
|
5540
|
+
const result = await host.conclude({
|
|
5541
|
+
conclusion,
|
|
5542
|
+
note: typeof args.note === "string" ? args.note : null
|
|
5543
|
+
});
|
|
5544
|
+
return `Conclusion recorded: ${result.conclusion}. The review is complete; the requester learns the outcome.`;
|
|
5545
|
+
}
|
|
5546
|
+
};
|
|
5547
|
+
return [packetTool, pathTool, findingTool, conclusionTool];
|
|
5548
|
+
}
|
|
5549
|
+
function reviewRequestTool(host) {
|
|
5550
|
+
return {
|
|
5551
|
+
def: {
|
|
5552
|
+
name: "request_review",
|
|
5553
|
+
description: "Ask one existing member of this Team to read the change as it is right now and say what they think of it. The daemon captures the change, so later edits are not covered. Use it when a second pair of eyes is worth more than your own summary; then end your turn and wait \u2014 you will be told what they found. This is a static reading: the reviewer runs nothing and changes nothing, and this is not an approval to publish, merge or deploy.",
|
|
5554
|
+
parameters: {
|
|
5555
|
+
type: "object",
|
|
5556
|
+
properties: {
|
|
5557
|
+
reviewer: {
|
|
5558
|
+
type: "string",
|
|
5559
|
+
description: "The same-Team member who should review \u2014 their name or their agent id. A name that matches nobody comes back with the members you can ask."
|
|
5560
|
+
},
|
|
5561
|
+
summary: {
|
|
5562
|
+
type: "string",
|
|
5563
|
+
description: "What the change is for and what to look at, in your words. It is commentary; it is not evidence."
|
|
5564
|
+
}
|
|
5565
|
+
},
|
|
5566
|
+
required: ["reviewer"],
|
|
5567
|
+
additionalProperties: false
|
|
5568
|
+
}
|
|
5569
|
+
},
|
|
5570
|
+
async invoke(args) {
|
|
5571
|
+
const reviewer = typeof args.reviewer === "string" ? args.reviewer.trim() : "";
|
|
5572
|
+
if (reviewer === "") throw new ReviewCapabilityError("request_review needs a reviewer");
|
|
5573
|
+
const receipt = await host.capture({
|
|
5574
|
+
reviewer,
|
|
5575
|
+
...typeof args.summary === "string" ? { summary: args.summary } : {}
|
|
5576
|
+
});
|
|
5577
|
+
return [
|
|
5578
|
+
`Review packet ${receipt.packetId} is ${receipt.state}, against revision ${receipt.snapshotId}.`,
|
|
5579
|
+
`Reviewer: ${receipt.reviewer}.`,
|
|
5580
|
+
"",
|
|
5581
|
+
"The change is captured as it was at this moment; editing it now does not change what will be",
|
|
5582
|
+
"reviewed. End your turn and wait \u2014 the findings are delivered back to you. A reviewer\u2019s conclusion",
|
|
5583
|
+
"is their statement about this revision, not an approval and not a test result."
|
|
5584
|
+
].join("\n");
|
|
5585
|
+
}
|
|
5586
|
+
};
|
|
5587
|
+
}
|
|
5588
|
+
function readLine(value) {
|
|
5589
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 1 ? value : null;
|
|
5590
|
+
}
|
|
5591
|
+
function renderBrief(brief) {
|
|
5592
|
+
const lines = [
|
|
5593
|
+
`Review packet ${brief.packetId}`,
|
|
5594
|
+
`Change: revision ${brief.snapshot.id} (base ${brief.snapshot.baseOid.slice(0, 12)}${brief.snapshot.complete ? "" : ", INCOMPLETE COVERAGE"})`
|
|
5595
|
+
];
|
|
5596
|
+
if (brief.summary) lines.push(`Requested by the requester: ${brief.summary}`);
|
|
5597
|
+
lines.push(
|
|
5598
|
+
"",
|
|
5599
|
+
`Changed paths (${brief.changes.length}):`,
|
|
5600
|
+
...brief.changes.map(
|
|
5601
|
+
(change) => ` ${change.status.padEnd(9)} ${change.path}${change.previousPath ? ` (was ${change.previousPath})` : ""}`
|
|
5602
|
+
)
|
|
5603
|
+
);
|
|
5604
|
+
lines.push(
|
|
5605
|
+
"",
|
|
5606
|
+
brief.contentAvailable ? "Content: the working tree still matches this revision, so review_path can show a patch." : `Content: NOT reproducible \u2014 ${brief.contentUnavailableReason ?? "the reviewed revision has moved"}. Review from the change list, the requester\u2019s summary and your own reading of the paths; do not describe lines you could not read.`
|
|
5607
|
+
);
|
|
5608
|
+
if (brief.findings.length > 0) {
|
|
5609
|
+
lines.push("", "Findings so far:");
|
|
5610
|
+
for (const finding of brief.findings) {
|
|
5611
|
+
lines.push(
|
|
5612
|
+
` [${finding.severity}] ${finding.path} (${finding.authorKind}) \u2014 ${finding.note}`
|
|
5613
|
+
);
|
|
5614
|
+
}
|
|
5615
|
+
} else {
|
|
5616
|
+
lines.push("", "Findings so far: none.");
|
|
5617
|
+
}
|
|
5618
|
+
if (brief.conclusion) lines.push("", `A conclusion is already recorded: ${brief.conclusion}.`);
|
|
5619
|
+
lines.push(
|
|
5620
|
+
"",
|
|
5621
|
+
"You cannot run commands, change files or publish anything. Record findings with review_finding and finish with review_conclusion."
|
|
5622
|
+
);
|
|
5623
|
+
return lines.join("\n");
|
|
5624
|
+
}
|
|
5625
|
+
function renderContent(content) {
|
|
5626
|
+
if (content.reason) return `No patch for ${content.path}: ${content.reason}`;
|
|
5627
|
+
if (!content.patch) return `No patch for ${content.path}: the change recorded no content.`;
|
|
5628
|
+
return `Patch for ${content.path}${content.truncated ? " (truncated)" : ""}:
|
|
5629
|
+
|
|
5630
|
+
${content.patch}`;
|
|
5631
|
+
}
|
|
5632
|
+
|
|
5399
5633
|
// ../daemon/src/runtime/tools/user-md.ts
|
|
5400
5634
|
function userMdTools(host, teamId) {
|
|
5401
5635
|
return [
|
|
@@ -5451,6 +5685,227 @@ etag: ${etag}`;
|
|
|
5451
5685
|
];
|
|
5452
5686
|
}
|
|
5453
5687
|
|
|
5688
|
+
// ../daemon/src/runtime/tools/verification.ts
|
|
5689
|
+
var VerificationCapabilityError = class extends Error {
|
|
5690
|
+
constructor(message) {
|
|
5691
|
+
super(message);
|
|
5692
|
+
this.name = "VerificationCapabilityError";
|
|
5693
|
+
}
|
|
5694
|
+
};
|
|
5695
|
+
function verificationTools(host) {
|
|
5696
|
+
const attempted = /* @__PURE__ */ new Set();
|
|
5697
|
+
const request = {
|
|
5698
|
+
def: {
|
|
5699
|
+
name: "verification_request",
|
|
5700
|
+
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.",
|
|
5701
|
+
parameters: { type: "object", properties: {}, additionalProperties: false }
|
|
5702
|
+
},
|
|
5703
|
+
async invoke() {
|
|
5704
|
+
return renderBrief2(await host.read());
|
|
5705
|
+
}
|
|
5706
|
+
};
|
|
5707
|
+
const check = {
|
|
5708
|
+
def: {
|
|
5709
|
+
name: "verification_check",
|
|
5710
|
+
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.",
|
|
5711
|
+
parameters: {
|
|
5712
|
+
type: "object",
|
|
5713
|
+
properties: {
|
|
5714
|
+
ordinal: {
|
|
5715
|
+
type: "integer",
|
|
5716
|
+
minimum: 0,
|
|
5717
|
+
description: "Ordinal of a declared check, as listed by verification_request."
|
|
5718
|
+
}
|
|
5719
|
+
},
|
|
5720
|
+
required: ["ordinal"],
|
|
5721
|
+
additionalProperties: false
|
|
5722
|
+
}
|
|
5723
|
+
},
|
|
5724
|
+
async invoke(args, context) {
|
|
5725
|
+
const ordinal = readOrdinal(args);
|
|
5726
|
+
const brief = await host.read();
|
|
5727
|
+
const declared = brief.checks.find((entry) => entry.ordinal === ordinal);
|
|
5728
|
+
if (!declared) {
|
|
5729
|
+
throw new VerificationCapabilityError(
|
|
5730
|
+
`check ${ordinal} was not captured with this request; only ${brief.checks.map((entry) => entry.ordinal).join(", ")} exist`
|
|
5731
|
+
);
|
|
5732
|
+
}
|
|
5733
|
+
if (declared.state !== "not_executed") {
|
|
5734
|
+
throw new VerificationCapabilityError(
|
|
5735
|
+
`check ${ordinal} already reported '${declared.state}' and cannot be run again`
|
|
5736
|
+
);
|
|
5737
|
+
}
|
|
5738
|
+
if (attempted.has(ordinal)) {
|
|
5739
|
+
throw new VerificationCapabilityError(`check ${ordinal} is already running`);
|
|
5740
|
+
}
|
|
5741
|
+
attempted.add(ordinal);
|
|
5742
|
+
try {
|
|
5743
|
+
const run = await host.invoke(ordinal, { toolCallId: context?.toolCallId ?? "" });
|
|
5744
|
+
return renderRun(run);
|
|
5745
|
+
} catch (error) {
|
|
5746
|
+
attempted.delete(ordinal);
|
|
5747
|
+
throw error;
|
|
5748
|
+
}
|
|
5749
|
+
}
|
|
5750
|
+
};
|
|
5751
|
+
return [request, check];
|
|
5752
|
+
}
|
|
5753
|
+
function readOrdinal(args) {
|
|
5754
|
+
const keys2 = Object.keys(args).sort();
|
|
5755
|
+
if (keys2.length !== 1 || keys2[0] !== "ordinal") {
|
|
5756
|
+
throw new VerificationCapabilityError("verification_check takes only a declared ordinal");
|
|
5757
|
+
}
|
|
5758
|
+
const ordinal = args.ordinal;
|
|
5759
|
+
if (!Number.isInteger(ordinal) || ordinal < 0) {
|
|
5760
|
+
throw new VerificationCapabilityError("ordinal must be a non-negative integer");
|
|
5761
|
+
}
|
|
5762
|
+
return ordinal;
|
|
5763
|
+
}
|
|
5764
|
+
function verificationRequestTool(host) {
|
|
5765
|
+
return {
|
|
5766
|
+
def: {
|
|
5767
|
+
name: "request_verification",
|
|
5768
|
+
description: "Hand the current change to one existing member of this Team and ask them to run specific checks against it. The daemon captures the change as it is right now \u2014 you do not capture one yourself \u2014 so later edits are not covered. Use it when a task is finished and an independent check is worth more than your own report; then end your turn and wait. You will be told the outcome. This asks for verification \u2014 it never approves, publishes, merges or deploys anything.",
|
|
5769
|
+
parameters: {
|
|
5770
|
+
type: "object",
|
|
5771
|
+
properties: {
|
|
5772
|
+
specialist: {
|
|
5773
|
+
type: "string",
|
|
5774
|
+
description: "Agent id of the same-Team member who should verify. They must already exist."
|
|
5775
|
+
},
|
|
5776
|
+
checks: {
|
|
5777
|
+
type: "array",
|
|
5778
|
+
maxItems: 8,
|
|
5779
|
+
description: "The exact commands to run against the captured change. Each runs once, as written.",
|
|
5780
|
+
items: {
|
|
5781
|
+
type: "object",
|
|
5782
|
+
properties: {
|
|
5783
|
+
command: {
|
|
5784
|
+
type: "string",
|
|
5785
|
+
description: "Shell command, run in the captured tree."
|
|
5786
|
+
},
|
|
5787
|
+
purpose: { type: "string", description: "What this command establishes." },
|
|
5788
|
+
cwd: {
|
|
5789
|
+
type: "string",
|
|
5790
|
+
description: "Team-relative directory. Defaults to the root."
|
|
5791
|
+
},
|
|
5792
|
+
timeoutSeconds: {
|
|
5793
|
+
type: "integer",
|
|
5794
|
+
minimum: 1,
|
|
5795
|
+
maximum: 300,
|
|
5796
|
+
description: "Timeout. Defaults to 120 seconds."
|
|
5797
|
+
}
|
|
5798
|
+
},
|
|
5799
|
+
required: ["command", "purpose"],
|
|
5800
|
+
additionalProperties: false
|
|
5801
|
+
}
|
|
5802
|
+
},
|
|
5803
|
+
summary: {
|
|
5804
|
+
type: "string",
|
|
5805
|
+
description: "Short acceptance summary: what the change should do, and what to look for."
|
|
5806
|
+
},
|
|
5807
|
+
writablePaths: {
|
|
5808
|
+
type: "array",
|
|
5809
|
+
maxItems: 16,
|
|
5810
|
+
items: { type: "string" },
|
|
5811
|
+
description: "Team-relative paths where checks are expected to write generated output. Advisory: it is recorded and reported, but it does not confine writes."
|
|
5812
|
+
}
|
|
5813
|
+
},
|
|
5814
|
+
required: ["specialist", "checks"],
|
|
5815
|
+
additionalProperties: false
|
|
5816
|
+
}
|
|
5817
|
+
},
|
|
5818
|
+
async invoke(args) {
|
|
5819
|
+
const intent = readIntent(args);
|
|
5820
|
+
const receipt = await host.capture(intent);
|
|
5821
|
+
return renderRequestReceipt(receipt);
|
|
5822
|
+
}
|
|
5823
|
+
};
|
|
5824
|
+
}
|
|
5825
|
+
function readIntent(args) {
|
|
5826
|
+
const specialist = args.specialist;
|
|
5827
|
+
if (typeof specialist !== "string" || specialist.trim() === "") {
|
|
5828
|
+
throw new Error("request_verification needs the id of an existing same-Team specialist");
|
|
5829
|
+
}
|
|
5830
|
+
if (!Array.isArray(args.checks) || args.checks.length === 0) {
|
|
5831
|
+
throw new Error("request_verification needs at least one check");
|
|
5832
|
+
}
|
|
5833
|
+
if (args.checks.length > 8) {
|
|
5834
|
+
throw new Error("request_verification accepts at most eight checks");
|
|
5835
|
+
}
|
|
5836
|
+
const checks = args.checks.map((entry, index) => {
|
|
5837
|
+
const check = entry;
|
|
5838
|
+
if (typeof check?.command !== "string" || check.command.trim() === "") {
|
|
5839
|
+
throw new Error(`check ${index} has no command`);
|
|
5840
|
+
}
|
|
5841
|
+
if (typeof check?.purpose !== "string" || check.purpose.trim() === "") {
|
|
5842
|
+
throw new Error(`check ${index} has no purpose`);
|
|
5843
|
+
}
|
|
5844
|
+
return {
|
|
5845
|
+
command: check.command,
|
|
5846
|
+
purpose: check.purpose,
|
|
5847
|
+
...typeof check.cwd === "string" ? { cwd: check.cwd } : {},
|
|
5848
|
+
...typeof check.timeoutSeconds === "number" ? { timeoutSeconds: check.timeoutSeconds } : {}
|
|
5849
|
+
};
|
|
5850
|
+
});
|
|
5851
|
+
return {
|
|
5852
|
+
specialist: specialist.trim(),
|
|
5853
|
+
checks,
|
|
5854
|
+
...typeof args.summary === "string" ? { summary: args.summary } : {},
|
|
5855
|
+
...Array.isArray(args.writablePaths) ? {
|
|
5856
|
+
writablePaths: args.writablePaths.filter(
|
|
5857
|
+
(path) => typeof path === "string"
|
|
5858
|
+
)
|
|
5859
|
+
} : {}
|
|
5860
|
+
};
|
|
5861
|
+
}
|
|
5862
|
+
function renderRequestReceipt(receipt) {
|
|
5863
|
+
const lines = [
|
|
5864
|
+
`Verification request ${receipt.requestId} is ${receipt.state}, against snapshot ${receipt.snapshotId}.`,
|
|
5865
|
+
`Specialist: ${receipt.specialist}.`,
|
|
5866
|
+
"",
|
|
5867
|
+
"Captured checks:"
|
|
5868
|
+
];
|
|
5869
|
+
for (const check of receipt.checks) {
|
|
5870
|
+
lines.push(` [${check.ordinal}] ${check.command} (cwd ${check.cwd}, ${check.timeoutMs} ms)`);
|
|
5871
|
+
}
|
|
5872
|
+
lines.push(
|
|
5873
|
+
"",
|
|
5874
|
+
"The change is captured as it was at this moment; editing it now does not change what will be",
|
|
5875
|
+
"verified. End your turn and wait \u2014 the outcome is delivered back to you. This request is not an",
|
|
5876
|
+
"approval to publish, merge or deploy, and a passing check is evidence about these commands only."
|
|
5877
|
+
);
|
|
5878
|
+
return lines.join("\n");
|
|
5879
|
+
}
|
|
5880
|
+
function renderBrief2(brief) {
|
|
5881
|
+
const lines = [
|
|
5882
|
+
`Verification request ${brief.requestId}`,
|
|
5883
|
+
`Change: snapshot ${brief.snapshot.id} (base ${brief.snapshot.baseOid.slice(0, 12)}${brief.snapshot.complete ? "" : ", INCOMPLETE COVERAGE"})`,
|
|
5884
|
+
`Environment: image ${brief.environment.image}, shell ${brief.environment.sandbox}${brief.environment.cwd ? `, cwd ${brief.environment.cwd}` : ""}`,
|
|
5885
|
+
`Applicability: ${brief.applicability === "identical" ? "unchanged since capture" : brief.applicability}`
|
|
5886
|
+
];
|
|
5887
|
+
if (brief.summary) lines.push(`Requested by the requester: ${brief.summary}`);
|
|
5888
|
+
if (brief.writablePaths.length > 0) {
|
|
5889
|
+
lines.push(
|
|
5890
|
+
`Declared generated-output paths (where a check is expected to write; this does not confine writes): ${brief.writablePaths.join(", ")}`
|
|
5891
|
+
);
|
|
5892
|
+
}
|
|
5893
|
+
lines.push("", "Captured checks:");
|
|
5894
|
+
for (const entry of brief.checks) {
|
|
5895
|
+
const outcome = entry.state === "not_executed" ? "not run yet" : `${entry.state}${entry.exitCode === null ? "" : ` (exit ${entry.exitCode})`}${entry.commandId ? ` receipt ${entry.commandId}` : ""}`;
|
|
5896
|
+
lines.push(
|
|
5897
|
+
` [${entry.ordinal}] ${entry.command} (cwd ${entry.cwd}, ${entry.timeoutMs} ms, ${entry.purpose}) \u2014 ${outcome}`
|
|
5898
|
+
);
|
|
5899
|
+
}
|
|
5900
|
+
lines.push("", "Run each captured check with verification_check. Report failures as failures.");
|
|
5901
|
+
return lines.join("\n");
|
|
5902
|
+
}
|
|
5903
|
+
function renderRun(run) {
|
|
5904
|
+
const head = `Check ${run.ordinal}: ${run.state}${run.exitCode === null ? "" : ` (exit ${run.exitCode})`}${run.commandId ? ` \u2014 receipt ${run.commandId}` : ""}${run.truncated ? " [output truncated]" : ""}`;
|
|
5905
|
+
return run.output.trim() ? `${head}
|
|
5906
|
+
${run.output}` : head;
|
|
5907
|
+
}
|
|
5908
|
+
|
|
5454
5909
|
// ../daemon/src/runtime/tools/web.ts
|
|
5455
5910
|
import { fetch as undiciFetch2 } from "undici";
|
|
5456
5911
|
|
|
@@ -6127,6 +6582,12 @@ function createBazilionCustomTools(opts) {
|
|
|
6127
6582
|
if (opts.fileSink) {
|
|
6128
6583
|
handlers.push(deliverFileTool(opts.agent.team.path, opts.fileSink, opts.sessionId));
|
|
6129
6584
|
}
|
|
6585
|
+
if (opts.verificationRequestHost) {
|
|
6586
|
+
handlers.push(verificationRequestTool(opts.verificationRequestHost));
|
|
6587
|
+
}
|
|
6588
|
+
if (opts.reviewRequestHost) {
|
|
6589
|
+
handlers.push(reviewRequestTool(opts.reviewRequestHost));
|
|
6590
|
+
}
|
|
6130
6591
|
if (opts.askUser) handlers.push(askUserTool(opts.askUser));
|
|
6131
6592
|
return handlers.map(ourToolToPiTool);
|
|
6132
6593
|
}
|
|
@@ -6140,6 +6601,12 @@ function createProtectedBazilionCustomTools(opts) {
|
|
|
6140
6601
|
...userMdTools(opts.userMdHost, opts.agent.team.id),
|
|
6141
6602
|
deliverFileTool(opts.agent.team.path, opts.fileSink, opts.sessionId)
|
|
6142
6603
|
];
|
|
6604
|
+
if (opts.verificationRequestHost) {
|
|
6605
|
+
handlers.push(verificationRequestTool(opts.verificationRequestHost));
|
|
6606
|
+
}
|
|
6607
|
+
if (opts.reviewRequestHost) {
|
|
6608
|
+
handlers.push(reviewRequestTool(opts.reviewRequestHost));
|
|
6609
|
+
}
|
|
6143
6610
|
if (opts.askUser) handlers.push(askUserTool(opts.askUser));
|
|
6144
6611
|
return handlers.map(ourToolToPiTool);
|
|
6145
6612
|
}
|
|
@@ -6243,7 +6710,9 @@ async function createBazilionSession(opts) {
|
|
|
6243
6710
|
fileSink,
|
|
6244
6711
|
askUser,
|
|
6245
6712
|
sessionId: sessionManager.getSessionId(),
|
|
6246
|
-
env
|
|
6713
|
+
env,
|
|
6714
|
+
verificationRequestHost: opts.verificationRequestHost,
|
|
6715
|
+
reviewRequestHost: opts.reviewRequestHost
|
|
6247
6716
|
});
|
|
6248
6717
|
if (repository) bazilionTools.push(repository.tool);
|
|
6249
6718
|
if (repository && opts.codingHost && shellTools && shellTools.config.sandboxMode === "docker" && !opts.preparedDocker)
|
|
@@ -6365,7 +6834,9 @@ async function createProtectedBazilionSession(opts) {
|
|
|
6365
6834
|
userMdHost: opts.userMdHost,
|
|
6366
6835
|
fileSink: opts.fileSink,
|
|
6367
6836
|
askUser: opts.askUser,
|
|
6368
|
-
sessionId: sessionManager.getSessionId()
|
|
6837
|
+
sessionId: sessionManager.getSessionId(),
|
|
6838
|
+
verificationRequestHost: opts.verificationRequestHost,
|
|
6839
|
+
reviewRequestHost: opts.reviewRequestHost
|
|
6369
6840
|
});
|
|
6370
6841
|
if (repository) bazilionTools.push(repository.tool);
|
|
6371
6842
|
const redactionSecrets = uniqueSecrets(protectedRuntimeSecrets(opts.runtime));
|
|
@@ -6607,111 +7078,6 @@ function explicitConversationFile(directory, target) {
|
|
|
6607
7078
|
return file;
|
|
6608
7079
|
}
|
|
6609
7080
|
|
|
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
|
-
|
|
6715
7081
|
// ../daemon/src/runtime/worker/api-key-refresh.ts
|
|
6716
7082
|
function createIpcApiKeyRefresher(call, context) {
|
|
6717
7083
|
return async (providerName) => {
|
|
@@ -6935,6 +7301,25 @@ function createReviewState(evidenceItems) {
|
|
|
6935
7301
|
tools
|
|
6936
7302
|
};
|
|
6937
7303
|
}
|
|
7304
|
+
function createIpcVerificationRequestHost(ipcCall) {
|
|
7305
|
+
return {
|
|
7306
|
+
capture: (intent) => ipcCall("verificationCapture", intent)
|
|
7307
|
+
};
|
|
7308
|
+
}
|
|
7309
|
+
function createIpcReviewRequestHost(ipcCall) {
|
|
7310
|
+
return {
|
|
7311
|
+
capture: (intent) => ipcCall("reviewPacketCapture", intent)
|
|
7312
|
+
};
|
|
7313
|
+
}
|
|
7314
|
+
function createIpcChangeReviewHost(ipcCall, identity2) {
|
|
7315
|
+
const { packetId, attemptId } = identity2;
|
|
7316
|
+
return {
|
|
7317
|
+
read: () => ipcCall("reviewPacketRead", { packetId, attemptId }),
|
|
7318
|
+
path: (path) => ipcCall("reviewPathRead", { packetId, attemptId, path }),
|
|
7319
|
+
addFinding: (finding) => ipcCall("reviewFindingAdd", { packetId, attemptId, finding }),
|
|
7320
|
+
conclude: (conclusion) => ipcCall("reviewConclusion", { packetId, attemptId, conclusion })
|
|
7321
|
+
};
|
|
7322
|
+
}
|
|
6938
7323
|
function createIpcVerificationHost(ipcCall, identity2) {
|
|
6939
7324
|
return {
|
|
6940
7325
|
// The request identity is bound here from the worker's own input, so a tool call cannot address
|
|
@@ -6944,7 +7329,7 @@ function createIpcVerificationHost(ipcCall, identity2) {
|
|
|
6944
7329
|
};
|
|
6945
7330
|
}
|
|
6946
7331
|
async function createSessionForInput(input, ipcCall) {
|
|
6947
|
-
if (input.kind !== "restricted_review" && input.kind !== "specialist_verification" && !input.repositoryContext)
|
|
7332
|
+
if (input.kind !== "restricted_review" && input.kind !== "specialist_verification" && input.kind !== "packet_review" && !input.repositoryContext)
|
|
6948
7333
|
throw new Error("Coding turn requires daemon-prepared repository context");
|
|
6949
7334
|
if (input.kind === "configured_operator_http") {
|
|
6950
7335
|
const paths = resolvePaths();
|
|
@@ -6979,6 +7364,10 @@ async function createSessionForInput(input, ipcCall) {
|
|
|
6979
7364
|
enabledProviders: new Set(input.enabledProviders),
|
|
6980
7365
|
messagingHost: messagingHost2,
|
|
6981
7366
|
userMdHost: userMdHost2,
|
|
7367
|
+
// The requester's halves of specialist verification and review. Only the configured/browser-enabled
|
|
7368
|
+
// worker kind reaches this builder, and it is an ordinary coding turn.
|
|
7369
|
+
verificationRequestHost: createIpcVerificationRequestHost(ipcCall),
|
|
7370
|
+
reviewRequestHost: createIpcReviewRequestHost(ipcCall),
|
|
6982
7371
|
apiKey: input.apiKey,
|
|
6983
7372
|
refreshApiKey: refreshApiKey2,
|
|
6984
7373
|
browserHost,
|
|
@@ -7014,6 +7403,16 @@ async function createSessionForInput(input, ipcCall) {
|
|
|
7014
7403
|
});
|
|
7015
7404
|
return { handle: handle2 };
|
|
7016
7405
|
}
|
|
7406
|
+
if (input.kind === "packet_review") {
|
|
7407
|
+
const handle2 = await createRestrictedReviewSession({
|
|
7408
|
+
runtime: input.runtime,
|
|
7409
|
+
scratch: input.scratch,
|
|
7410
|
+
systemPrompt: STATIC_REVIEW_SYSTEM_PROMPT,
|
|
7411
|
+
tools: reviewTools(createIpcChangeReviewHost(ipcCall, input.review)).map(ourToolToPiTool),
|
|
7412
|
+
refreshApiKey
|
|
7413
|
+
});
|
|
7414
|
+
return { handle: handle2 };
|
|
7415
|
+
}
|
|
7017
7416
|
if (input.kind === "restricted_review") {
|
|
7018
7417
|
const reviewState = createReviewState(input.review.evidence);
|
|
7019
7418
|
const handle2 = await createRestrictedReviewSession({
|
|
@@ -7050,6 +7449,8 @@ async function createSessionForInput(input, ipcCall) {
|
|
|
7050
7449
|
messagingHost,
|
|
7051
7450
|
userMdHost,
|
|
7052
7451
|
bashApprovalHost,
|
|
7452
|
+
verificationRequestHost: createIpcVerificationRequestHost(ipcCall),
|
|
7453
|
+
reviewRequestHost: createIpcReviewRequestHost(ipcCall),
|
|
7053
7454
|
askUser: input.questionEnabled ? (toolCallId, question) => ipcCall("askUser", { toolCallId, question }) : void 0,
|
|
7054
7455
|
refreshApiKey,
|
|
7055
7456
|
fileSink: async (file, source) => {
|
|
@@ -7090,7 +7491,7 @@ async function main() {
|
|
|
7090
7491
|
session = handle.session;
|
|
7091
7492
|
const consumptionAcks = /* @__PURE__ */ new Set();
|
|
7092
7493
|
const unsubscribe = session.subscribe((piEvent) => {
|
|
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) {
|
|
7494
|
+
if (input.kind !== "restricted_review" && input.kind !== "specialist_verification" && input.kind !== "packet_review" && input.questionEnabled && piEvent.type === "message_end" && piEvent.message.role === "toolResult" && piEvent.message.toolName === "ask_user" && !piEvent.message.isError) {
|
|
7094
7495
|
const message = piEvent.message;
|
|
7095
7496
|
const content = message.content[0];
|
|
7096
7497
|
if (content?.type === "text") {
|
|
@@ -7120,8 +7521,9 @@ async function main() {
|
|
|
7120
7521
|
});
|
|
7121
7522
|
try {
|
|
7122
7523
|
const promptMessage = redactJsonValue(input.message, activeAccessTokens);
|
|
7123
|
-
const
|
|
7124
|
-
const
|
|
7524
|
+
const restricted = input.kind === "restricted_review" || input.kind === "specialist_verification" || input.kind === "packet_review";
|
|
7525
|
+
const sanitizedImages = restricted ? [] : redactJsonValue(input.images ?? [], activeAccessTokens);
|
|
7526
|
+
const promptImages = restricted ? [] : sanitizedImages.map((image) => ({
|
|
7125
7527
|
type: "image",
|
|
7126
7528
|
data: image.data,
|
|
7127
7529
|
mimeType: image.mimeType
|
|
@@ -7164,6 +7566,21 @@ main().catch((error) => {
|
|
|
7164
7566
|
}
|
|
7165
7567
|
process.exit(1);
|
|
7166
7568
|
});
|
|
7569
|
+
var STATIC_REVIEW_SYSTEM_PROMPT = `You are a restricted code reviewer. You review one captured
|
|
7570
|
+
revision and report what you find. Call review_packet to read the revision, review_path to read a patch,
|
|
7571
|
+
review_finding to record a finding, and finish with review_conclusion.
|
|
7572
|
+
|
|
7573
|
+
Boundaries you cannot cross, and must not try to:
|
|
7574
|
+
- You review the *captured revision*, not the current repository. If its content is not reproducible, say
|
|
7575
|
+
so and do not describe lines you could not read: the change list and the requester's summary are what
|
|
7576
|
+
you have.
|
|
7577
|
+
- You have no shell, no editor, no browser and no network tool. You cannot run a test, apply a fix, stage
|
|
7578
|
+
anything, commit, merge or deploy. If something would need running to be sure, say that it needs running.
|
|
7579
|
+
- You cannot publish, and your conclusion is not an approval. It is your statement about this revision.
|
|
7580
|
+
|
|
7581
|
+
Report what you actually found, with the path it concerns. Say when you are unsure, and say when you could
|
|
7582
|
+
not verify something rather than guessing. Do not repeat a finding that is already recorded.
|
|
7583
|
+
`;
|
|
7167
7584
|
var VERIFICATION_SYSTEM_PROMPT = `You are a restricted verification specialist. You verify one
|
|
7168
7585
|
captured change against the checks your requester selected. Call verification_request to read the
|
|
7169
7586
|
request, then verification_check once per declared check, in order.
|