@akagilnc/pi-workflow-roles 0.1.3718 → 0.1.3733
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/acp-host/description.js +19 -5
- package/dist/acp-host/production-host.js +210 -85
- package/dist/acp-host/seat-profile-soul.js +78 -0
- package/dist/auditor-dossier-tool.js +15 -9
- package/dist/gatekeeper-role.js +13 -10
- package/dist/host-descriptions.js +26 -0
- package/dist/public-cli/inspector-run.js +2 -2
- package/dist/public-cli/instruction-seat-run.js +1 -1
- package/dist/public-cli/main.js +27 -0
- package/dist/public-cli/notary-run.js +2 -2
- package/dist/public-role-summons.js +10 -6
- package/package.json +1 -1
- package/src/acp-host/description.ts +39 -4
- package/src/acp-host/production-host.ts +16 -1
- package/src/acp-host/role-envelope.ts +2 -1
- package/src/acp-host/role-turn-host.ts +47 -23
- package/src/acp-host/seat-profile-soul.ts +97 -0
- package/src/auditor-dossier-tool.ts +26 -14
- package/src/gatekeeper-role.ts +32 -12
- package/src/host-descriptions.ts +26 -0
- package/src/public-cli/inspector-run.ts +3 -3
- package/src/public-cli/instruction-seat-run.ts +2 -2
- package/src/public-cli/notary-run.ts +3 -3
- package/src/public-role-summons.ts +26 -14
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* One ACP host description. Every host-specific value the generic ACP adapter
|
|
3
|
-
* needs — binary location, argv shape, resume verb, binding filename, child env
|
|
4
|
-
* — is data here; the lifecycle in role-turn-host.ts
|
|
3
|
+
* needs — binary location, argv shape, resume verb, binding filename, child env,
|
|
4
|
+
* optional seat-profile soul — is data here; the lifecycle in role-turn-host.ts
|
|
5
|
+
* stays one copy (#732).
|
|
5
6
|
*/
|
|
6
7
|
import { join } from "node:path";
|
|
7
8
|
/** Absolute agent binary for one operator home. */
|
|
8
9
|
export function resolveAcpBinary(description, operatorHome) {
|
|
9
10
|
return join(operatorHome, ...description.binaryFromHome);
|
|
10
11
|
}
|
|
11
|
-
/** Stdio argv:
|
|
12
|
-
|
|
12
|
+
/** Stdio argv: optional profile flag, thinking flag (before the subcommand),
|
|
13
|
+
* prefix, optional model flag pair, suffix. */
|
|
14
|
+
export function acpStdioArgs(description, model, seat) {
|
|
13
15
|
const { prefix, suffix, modelFlag, thinkingFlag } = description.argv;
|
|
14
16
|
const pair = (flag, value) => flag === undefined || value === undefined ? [] : [flag, value];
|
|
15
17
|
return [
|
|
18
|
+
...pair(description.seatProfileSoul?.flag, seat?.profileName),
|
|
19
|
+
...pair(thinkingFlag, model?.thinking),
|
|
16
20
|
...prefix,
|
|
17
21
|
...pair(modelFlag, model?.model),
|
|
18
|
-
...pair(thinkingFlag, model?.thinking),
|
|
19
22
|
...suffix,
|
|
20
23
|
];
|
|
21
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* The modelId the host addresses the seat model by.
|
|
27
|
+
* "argv" hosts address by bare model name; "set_model" hosts address by the
|
|
28
|
+
* `provider:model` modelId the ACP catalog exposes (seat provider after host
|
|
29
|
+
* alias projection, concatenated — never a package provider map).
|
|
30
|
+
*/
|
|
31
|
+
export function acpModelId(modelPassing, model) {
|
|
32
|
+
if (model?.model === undefined)
|
|
33
|
+
return undefined;
|
|
34
|
+
return modelPassing === "set_model" ? `${model.provider}:${model.model}` : model.model;
|
|
35
|
+
}
|
|
@@ -164,7 +164,7 @@ function normalizeReviewComment(raw) {
|
|
|
164
164
|
function createGhApiRunner(options = {}) {
|
|
165
165
|
const spawnImpl = options.spawnImpl ?? spawn;
|
|
166
166
|
return async (args, runOptions = {}) => {
|
|
167
|
-
return await new Promise((
|
|
167
|
+
return await new Promise((resolve20, reject) => {
|
|
168
168
|
const signal = runOptions.signal;
|
|
169
169
|
if (signal?.aborted) {
|
|
170
170
|
reject(signal.reason ?? new Error("aborted"));
|
|
@@ -237,11 +237,11 @@ function createGhApiRunner(options = {}) {
|
|
|
237
237
|
const value = line2.slice(idx + 1).trim();
|
|
238
238
|
headers[name] = value;
|
|
239
239
|
}
|
|
240
|
-
|
|
240
|
+
resolve20({ status, headers, bodyText });
|
|
241
241
|
return;
|
|
242
242
|
}
|
|
243
243
|
if (code === 0) {
|
|
244
|
-
|
|
244
|
+
resolve20({ status: 200, headers: {}, bodyText: stdout });
|
|
245
245
|
return;
|
|
246
246
|
}
|
|
247
247
|
const failure2 = new Error(
|
|
@@ -502,6 +502,19 @@ var init_collector_github = __esm({
|
|
|
502
502
|
}
|
|
503
503
|
});
|
|
504
504
|
|
|
505
|
+
// src/readable-gate-item.ts
|
|
506
|
+
function readableGateItem(value) {
|
|
507
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
508
|
+
}
|
|
509
|
+
function joinReadableGateItems(items, separator = "; ") {
|
|
510
|
+
return items.map(readableGateItem).join(separator);
|
|
511
|
+
}
|
|
512
|
+
var init_readable_gate_item = __esm({
|
|
513
|
+
"src/readable-gate-item.ts"() {
|
|
514
|
+
"use strict";
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
|
|
505
518
|
// src/auditor-dossier-tool.ts
|
|
506
519
|
var auditor_dossier_tool_exports = {};
|
|
507
520
|
__export(auditor_dossier_tool_exports, {
|
|
@@ -512,6 +525,7 @@ __export(auditor_dossier_tool_exports, {
|
|
|
512
525
|
createAuditorDossierTool: () => createAuditorDossierTool,
|
|
513
526
|
gateSubmissionCandidatePath: () => gateSubmissionCandidatePath,
|
|
514
527
|
persistGateSubmissionCandidate: () => persistGateSubmissionCandidate,
|
|
528
|
+
readLatestSubmissionArguments: () => readLatestSubmissionArguments,
|
|
515
529
|
readLatestToolCallLeaf: () => readLatestToolCallLeaf
|
|
516
530
|
});
|
|
517
531
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
@@ -543,16 +557,20 @@ function readLatestToolCallLeaf(context) {
|
|
|
543
557
|
function gateSubmissionCandidatePath(runDirectory) {
|
|
544
558
|
return join(runDirectory, "artifacts", GATE_SUBMISSION_CANDIDATE_FILE);
|
|
545
559
|
}
|
|
546
|
-
function
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
];
|
|
551
|
-
const candidate = input.submissionCandidatePath?.trim();
|
|
552
|
-
if (candidate !== void 0 && candidate.length > 0) {
|
|
553
|
-
lines.push(`\u4EA4\u5377\u5019\u9009\uFF08\u51BB\u7ED3\u5FEB\u7167\uFF09\uFF1A${candidate}`);
|
|
560
|
+
function readLatestSubmissionArguments(context) {
|
|
561
|
+
const leaf = readLatestToolCallLeaf(context);
|
|
562
|
+
if (!isRecord2(leaf) || !isRecord2(leaf.message) || !Array.isArray(leaf.message.content)) {
|
|
563
|
+
return void 0;
|
|
554
564
|
}
|
|
555
|
-
|
|
565
|
+
for (const part of leaf.message.content) {
|
|
566
|
+
if (isRecord2(part) && part.type === "toolCall" && "arguments" in part) {
|
|
567
|
+
return part.arguments;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return void 0;
|
|
571
|
+
}
|
|
572
|
+
function buildGateOfficerReviewInstruction(input) {
|
|
573
|
+
return readableGateItem(input.submission);
|
|
556
574
|
}
|
|
557
575
|
function persistGateSubmissionCandidate(runDirectory, context) {
|
|
558
576
|
const leaf = readLatestToolCallLeaf(context);
|
|
@@ -596,6 +614,7 @@ var AUDITOR_DOSSIER_TOOL_NAME, GATE_SUBMISSION_CANDIDATE_FILE;
|
|
|
596
614
|
var init_auditor_dossier_tool = __esm({
|
|
597
615
|
"src/auditor-dossier-tool.ts"() {
|
|
598
616
|
"use strict";
|
|
617
|
+
init_readable_gate_item();
|
|
599
618
|
AUDITOR_DOSSIER_TOOL_NAME = "ak_get_run_dossier";
|
|
600
619
|
GATE_SUBMISSION_CANDIDATE_FILE = "gate-submission-candidate.json";
|
|
601
620
|
}
|
|
@@ -1208,7 +1227,7 @@ async function spawnEngineDetourOnce(input) {
|
|
|
1208
1227
|
}
|
|
1209
1228
|
const command = input.argv[0];
|
|
1210
1229
|
const args = input.argv.slice(1);
|
|
1211
|
-
return await new Promise((
|
|
1230
|
+
return await new Promise((resolve20, reject) => {
|
|
1212
1231
|
let settled = false;
|
|
1213
1232
|
const signal = input.signal;
|
|
1214
1233
|
const child = spawn2(command, args, {
|
|
@@ -1238,7 +1257,7 @@ async function spawnEngineDetourOnce(input) {
|
|
|
1238
1257
|
if (signal !== void 0) {
|
|
1239
1258
|
signal.removeEventListener("abort", onAbort);
|
|
1240
1259
|
}
|
|
1241
|
-
|
|
1260
|
+
resolve20(result);
|
|
1242
1261
|
};
|
|
1243
1262
|
const onAbort = () => {
|
|
1244
1263
|
fail5(signal !== void 0 ? abortReasonError(signal) : new Error("aborted"));
|
|
@@ -2235,19 +2254,6 @@ var init_reviewer_output = __esm({
|
|
|
2235
2254
|
}
|
|
2236
2255
|
});
|
|
2237
2256
|
|
|
2238
|
-
// src/readable-gate-item.ts
|
|
2239
|
-
function readableGateItem(value) {
|
|
2240
|
-
return typeof value === "string" ? value : JSON.stringify(value);
|
|
2241
|
-
}
|
|
2242
|
-
function joinReadableGateItems(items, separator = "; ") {
|
|
2243
|
-
return items.map(readableGateItem).join(separator);
|
|
2244
|
-
}
|
|
2245
|
-
var init_readable_gate_item = __esm({
|
|
2246
|
-
"src/readable-gate-item.ts"() {
|
|
2247
|
-
"use strict";
|
|
2248
|
-
}
|
|
2249
|
-
});
|
|
2250
|
-
|
|
2251
2257
|
// src/audit-escalation.ts
|
|
2252
2258
|
function buildAuditEscalationResult(decision, deliveredOutput) {
|
|
2253
2259
|
const auditOwned = {
|
|
@@ -8392,6 +8398,7 @@ var init_host_descriptions = __esm({
|
|
|
8392
8398
|
suffix: Object.freeze(["stdio"]),
|
|
8393
8399
|
modelFlag: "--model"
|
|
8394
8400
|
}),
|
|
8401
|
+
modelPassing: "argv",
|
|
8395
8402
|
boundResume: "session/load",
|
|
8396
8403
|
sessionBindingFile: "grok-acp-session.json",
|
|
8397
8404
|
childEnv: Object.freeze({
|
|
@@ -8399,6 +8406,31 @@ var init_host_descriptions = __esm({
|
|
|
8399
8406
|
GROK_MEMORY: "0",
|
|
8400
8407
|
GROK_SUBAGENTS: "0"
|
|
8401
8408
|
})
|
|
8409
|
+
}),
|
|
8410
|
+
/**
|
|
8411
|
+
* Operator home `~/.hermes`, native session/load resume, `acp` subcommand.
|
|
8412
|
+
* Model arrives as an ACP `session/set_model` RPC with modelId `provider:model`
|
|
8413
|
+
* (seat table provider + model concatenated). Reasoning is the global
|
|
8414
|
+
* `--reasoning` flag before `acp`. Soul is the seat profile SOUL.md symlink
|
|
8415
|
+
* (`hermes -p ak-<role> …`); package `souls/<role>.md` is the sole source.
|
|
8416
|
+
*/
|
|
8417
|
+
"hermes": Object.freeze({
|
|
8418
|
+
binaryFromHome: Object.freeze([".local", "bin", "hermes"]),
|
|
8419
|
+
argv: Object.freeze({
|
|
8420
|
+
prefix: Object.freeze(["acp"]),
|
|
8421
|
+
suffix: Object.freeze([]),
|
|
8422
|
+
thinkingFlag: "--reasoning"
|
|
8423
|
+
}),
|
|
8424
|
+
modelPassing: "set_model",
|
|
8425
|
+
boundResume: "session/load",
|
|
8426
|
+
sessionBindingFile: "hermes-acp-session.json",
|
|
8427
|
+
childEnv: Object.freeze({}),
|
|
8428
|
+
seatProfileSoul: Object.freeze({
|
|
8429
|
+
flag: "-p",
|
|
8430
|
+
namePrefix: "ak-",
|
|
8431
|
+
profilesRootFromHome: Object.freeze([".hermes", "profiles"]),
|
|
8432
|
+
soulFileName: "SOUL.md"
|
|
8433
|
+
})
|
|
8402
8434
|
})
|
|
8403
8435
|
});
|
|
8404
8436
|
}
|
|
@@ -11445,12 +11477,12 @@ function createSystemCollectorClock() {
|
|
|
11445
11477
|
return {
|
|
11446
11478
|
wallNow: () => /* @__PURE__ */ new Date(),
|
|
11447
11479
|
monoNow: () => Number(process.hrtime.bigint() - start) / 1e6,
|
|
11448
|
-
sleep: (ms, signal) => new Promise((
|
|
11480
|
+
sleep: (ms, signal) => new Promise((resolve20, reject) => {
|
|
11449
11481
|
if (signal?.aborted) {
|
|
11450
11482
|
reject(signal.reason ?? new Error("aborted"));
|
|
11451
11483
|
return;
|
|
11452
11484
|
}
|
|
11453
|
-
const timer = setTimeout(
|
|
11485
|
+
const timer = setTimeout(resolve20, ms);
|
|
11454
11486
|
const onAbort = () => {
|
|
11455
11487
|
clearTimeout(timer);
|
|
11456
11488
|
reject(signal?.reason ?? new Error("aborted"));
|
|
@@ -14871,10 +14903,10 @@ function presentFailureTerminal(terminal, io) {
|
|
|
14871
14903
|
}
|
|
14872
14904
|
function defaultNavigatorGraceSleep() {
|
|
14873
14905
|
let timer;
|
|
14874
|
-
const sleep = ((ms) => new Promise((
|
|
14906
|
+
const sleep = ((ms) => new Promise((resolve20) => {
|
|
14875
14907
|
timer = setTimeout(() => {
|
|
14876
14908
|
timer = void 0;
|
|
14877
|
-
|
|
14909
|
+
resolve20();
|
|
14878
14910
|
}, ms);
|
|
14879
14911
|
}));
|
|
14880
14912
|
sleep.cancel = () => {
|
|
@@ -14886,7 +14918,7 @@ function defaultNavigatorGraceSleep() {
|
|
|
14886
14918
|
return sleep;
|
|
14887
14919
|
}
|
|
14888
14920
|
function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep = defaultNavigatorGraceSleep()) {
|
|
14889
|
-
return new Promise((
|
|
14921
|
+
return new Promise((resolve20, reject) => {
|
|
14890
14922
|
let settled = false;
|
|
14891
14923
|
const finish = (action) => {
|
|
14892
14924
|
if (settled) return;
|
|
@@ -14895,11 +14927,11 @@ function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep
|
|
|
14895
14927
|
action();
|
|
14896
14928
|
};
|
|
14897
14929
|
void work.then(
|
|
14898
|
-
(value) => finish(() =>
|
|
14930
|
+
(value) => finish(() => resolve20({ status: "done", value })),
|
|
14899
14931
|
(error) => finish(() => reject(error))
|
|
14900
14932
|
);
|
|
14901
14933
|
void sleep(graceMs).then(() => {
|
|
14902
|
-
finish(() =>
|
|
14934
|
+
finish(() => resolve20({ status: "timeout" }));
|
|
14903
14935
|
});
|
|
14904
14936
|
});
|
|
14905
14937
|
}
|
|
@@ -16929,8 +16961,11 @@ async function summonPublicRole(options) {
|
|
|
16929
16961
|
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
16930
16962
|
// #753: reask rides the existing notary same-ticket resume summons.instruction.
|
|
16931
16963
|
...options.reviewReask === void 0 ? {} : { reviewReask: options.reviewReask },
|
|
16932
|
-
// #
|
|
16933
|
-
...options.gateReviewInstruction === void 0 ? {} : { gateReviewInstruction: options.gateReviewInstruction }
|
|
16964
|
+
// #786: verbatim submission body on same-parent resume (not conclusion re-ask).
|
|
16965
|
+
...options.gateReviewInstruction === void 0 ? {} : { gateReviewInstruction: options.gateReviewInstruction },
|
|
16966
|
+
// Offline test injects — same faces as public CLI env (production leaves unset).
|
|
16967
|
+
...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
|
|
16968
|
+
...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
|
|
16934
16969
|
};
|
|
16935
16970
|
const captured = options.io === void 0 ? createCapturingIo() : void 0;
|
|
16936
16971
|
const io = options.io ?? captured.io;
|
|
@@ -17027,11 +17062,10 @@ async function summonGateOfficer(options) {
|
|
|
17027
17062
|
home = homeFromRunDirectory2(options.sourceRunDirectory);
|
|
17028
17063
|
}
|
|
17029
17064
|
let gateReviewInstruction;
|
|
17030
|
-
if (options.reask === void 0) {
|
|
17065
|
+
if (options.reask === void 0 && options.submission !== void 0) {
|
|
17031
17066
|
const { buildGateOfficerReviewInstruction: buildGateOfficerReviewInstruction2 } = await Promise.resolve().then(() => (init_auditor_dossier_tool(), auditor_dossier_tool_exports));
|
|
17032
17067
|
gateReviewInstruction = buildGateOfficerReviewInstruction2({
|
|
17033
|
-
|
|
17034
|
-
...options.submissionCandidatePath === void 0 ? {} : { submissionCandidatePath: options.submissionCandidatePath }
|
|
17068
|
+
submission: options.submission
|
|
17035
17069
|
});
|
|
17036
17070
|
}
|
|
17037
17071
|
const common = {
|
|
@@ -17041,7 +17075,9 @@ async function summonGateOfficer(options) {
|
|
|
17041
17075
|
...options.io === void 0 ? {} : { io: options.io },
|
|
17042
17076
|
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
17043
17077
|
...options.reask === void 0 ? {} : { reviewReask: options.reask },
|
|
17044
|
-
...gateReviewInstruction === void 0 ? {} : { gateReviewInstruction }
|
|
17078
|
+
...gateReviewInstruction === void 0 ? {} : { gateReviewInstruction },
|
|
17079
|
+
...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
|
|
17080
|
+
...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
|
|
17045
17081
|
};
|
|
17046
17082
|
if (options.officer === "notary") {
|
|
17047
17083
|
return summonPublicRole({
|
|
@@ -18670,13 +18706,11 @@ async function projectGatekeeperRun(options) {
|
|
|
18670
18706
|
}
|
|
18671
18707
|
};
|
|
18672
18708
|
}
|
|
18673
|
-
|
|
18674
|
-
|
|
18675
|
-
options.context
|
|
18676
|
-
);
|
|
18709
|
+
persistGateSubmissionCandidate(runDirectory, options.context);
|
|
18710
|
+
const submission = readLatestSubmissionArguments(options.context);
|
|
18677
18711
|
let summoned;
|
|
18678
18712
|
try {
|
|
18679
|
-
const summon = options.summonOfficer ?? (async (nextOfficer, sourceRunDirectory, officerSignal, reask) => {
|
|
18713
|
+
const summon = options.summonOfficer ?? (async (nextOfficer, sourceRunDirectory, officerSignal, reask, nextSubmission) => {
|
|
18680
18714
|
const { summonGateOfficer: summonGateOfficer2 } = await Promise.resolve().then(() => (init_public_role_summons(), public_role_summons_exports));
|
|
18681
18715
|
return summonGateOfficer2({
|
|
18682
18716
|
officer: nextOfficer,
|
|
@@ -18684,10 +18718,20 @@ async function projectGatekeeperRun(options) {
|
|
|
18684
18718
|
cwd: options.context.cwd ?? process.cwd(),
|
|
18685
18719
|
...officerSignal === void 0 ? {} : { signal: officerSignal },
|
|
18686
18720
|
...reask === void 0 ? {} : { reask },
|
|
18687
|
-
...
|
|
18721
|
+
...nextSubmission === void 0 ? {} : { submission: nextSubmission },
|
|
18722
|
+
...options.home === void 0 ? {} : { home: options.home },
|
|
18723
|
+
...options.packageRoot === void 0 ? {} : { packageRoot: options.packageRoot },
|
|
18724
|
+
...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
|
|
18725
|
+
...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
|
|
18688
18726
|
});
|
|
18689
18727
|
});
|
|
18690
|
-
summoned = await summon(
|
|
18728
|
+
summoned = await summon(
|
|
18729
|
+
officer,
|
|
18730
|
+
runDirectory,
|
|
18731
|
+
options.signal,
|
|
18732
|
+
options.reask,
|
|
18733
|
+
submission
|
|
18734
|
+
);
|
|
18691
18735
|
} catch (error) {
|
|
18692
18736
|
return {
|
|
18693
18737
|
officer,
|
|
@@ -24137,7 +24181,7 @@ import { mkdtemp as mkdtemp3, rm as rm3 } from "node:fs/promises";
|
|
|
24137
24181
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
24138
24182
|
import { join as join32 } from "node:path";
|
|
24139
24183
|
async function runCommand(command, args, options = {}) {
|
|
24140
|
-
return await new Promise((
|
|
24184
|
+
return await new Promise((resolve20, reject) => {
|
|
24141
24185
|
const child = spawn4(command, args, { ...options.cwd === void 0 ? {} : { cwd: options.cwd }, stdio: ["ignore", "pipe", "pipe"], signal: options.signal });
|
|
24142
24186
|
let stdout = "", stderr = "";
|
|
24143
24187
|
child.stdout.setEncoding("utf8").on("data", (chunk) => {
|
|
@@ -24157,7 +24201,7 @@ async function runCommand(command, args, options = {}) {
|
|
|
24157
24201
|
const actual = code ?? 1;
|
|
24158
24202
|
if ((options.allowedCodes ?? [0]).includes(actual)) {
|
|
24159
24203
|
settled = true;
|
|
24160
|
-
|
|
24204
|
+
resolve20({ stdout, stderr, code: actual });
|
|
24161
24205
|
} else fail5(void 0, code, signal);
|
|
24162
24206
|
});
|
|
24163
24207
|
});
|
|
@@ -24621,16 +24665,21 @@ import { join as join33 } from "node:path";
|
|
|
24621
24665
|
function resolveAcpBinary(description, operatorHome) {
|
|
24622
24666
|
return join33(operatorHome, ...description.binaryFromHome);
|
|
24623
24667
|
}
|
|
24624
|
-
function acpStdioArgs(description, model) {
|
|
24668
|
+
function acpStdioArgs(description, model, seat) {
|
|
24625
24669
|
const { prefix, suffix, modelFlag, thinkingFlag } = description.argv;
|
|
24626
24670
|
const pair = (flag, value) => flag === void 0 || value === void 0 ? [] : [flag, value];
|
|
24627
24671
|
return [
|
|
24672
|
+
...pair(description.seatProfileSoul?.flag, seat?.profileName),
|
|
24673
|
+
...pair(thinkingFlag, model?.thinking),
|
|
24628
24674
|
...prefix,
|
|
24629
24675
|
...pair(modelFlag, model?.model),
|
|
24630
|
-
...pair(thinkingFlag, model?.thinking),
|
|
24631
24676
|
...suffix
|
|
24632
24677
|
];
|
|
24633
24678
|
}
|
|
24679
|
+
function acpModelId(modelPassing, model) {
|
|
24680
|
+
if (model?.model === void 0) return void 0;
|
|
24681
|
+
return modelPassing === "set_model" ? `${model.provider}:${model.model}` : model.model;
|
|
24682
|
+
}
|
|
24634
24683
|
|
|
24635
24684
|
// src/acp-host/role-envelope.ts
|
|
24636
24685
|
init_gatekeeper_pass_envelope();
|
|
@@ -24732,8 +24781,8 @@ function connectAcpStdio(options) {
|
|
|
24732
24781
|
request(method, params) {
|
|
24733
24782
|
if (closed) return Promise.reject(terminalError ?? acpError("acp-connection-closed", "ACP connection is closed"));
|
|
24734
24783
|
const id = ++nextId;
|
|
24735
|
-
return new Promise((
|
|
24736
|
-
pending.set(id, { resolve:
|
|
24784
|
+
return new Promise((resolve20, reject) => {
|
|
24785
|
+
pending.set(id, { resolve: resolve20, reject });
|
|
24737
24786
|
child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}
|
|
24738
24787
|
`, (error) => {
|
|
24739
24788
|
if (error === null || error === void 0) return;
|
|
@@ -24757,7 +24806,7 @@ function connectAcpStdio(options) {
|
|
|
24757
24806
|
settleClosed(acpError("acp-connection-closed", "ACP connection is closed"));
|
|
24758
24807
|
child.stdin.end();
|
|
24759
24808
|
child.kill("SIGTERM");
|
|
24760
|
-
await new Promise((
|
|
24809
|
+
await new Promise((resolve20) => child.once("close", () => resolve20()));
|
|
24761
24810
|
}
|
|
24762
24811
|
});
|
|
24763
24812
|
}
|
|
@@ -24768,6 +24817,7 @@ function createAcpRoleTurnHost(config) {
|
|
|
24768
24817
|
const execution = serial.then(async () => {
|
|
24769
24818
|
const continuation = request.continuation;
|
|
24770
24819
|
const prepared = await config.prepare(request);
|
|
24820
|
+
const systemPromptOverride = renderAcpSystemPromptOverride(prepared.systemPrompt);
|
|
24771
24821
|
let connection;
|
|
24772
24822
|
let sessionId;
|
|
24773
24823
|
let accepted = false;
|
|
@@ -24783,40 +24833,47 @@ function createAcpRoleTurnHost(config) {
|
|
|
24783
24833
|
const initializeMeta = initialized._meta;
|
|
24784
24834
|
const modelState = initializeMeta?.modelState;
|
|
24785
24835
|
const availableModels = Array.isArray(modelState?.availableModels) ? modelState.availableModels : void 0;
|
|
24786
|
-
if (request.model !== void 0 && availableModels !== void 0 && !availableModels.some((entry) => typeof entry === "object" && entry !== null && entry.modelId === request.model
|
|
24836
|
+
if (request.model !== void 0 && availableModels !== void 0 && !availableModels.some((entry) => typeof entry === "object" && entry !== null && entry.modelId === acpModelId(config.modelPassing, request.model))) {
|
|
24787
24837
|
return failure("activation", "AcpHostModelMismatch", "host-model-mismatch", {
|
|
24788
24838
|
provider: request.model.provider,
|
|
24789
24839
|
model: request.model.model
|
|
24790
24840
|
});
|
|
24791
24841
|
}
|
|
24792
24842
|
const priorNativePaths = continuation.kind === "resume" ? request.hostTransition?.priorNativePaths : void 0;
|
|
24843
|
+
const loadConnection = connection;
|
|
24844
|
+
const sessionBindParams = {
|
|
24845
|
+
cwd: request.cwd,
|
|
24846
|
+
mcpServers: prepared.mcpServers,
|
|
24847
|
+
_meta: { systemPromptOverride, yoloMode: false }
|
|
24848
|
+
};
|
|
24849
|
+
const loadSession = async (bindSessionId) => {
|
|
24850
|
+
const loaded = await loadConnection.request("session/load", {
|
|
24851
|
+
sessionId: bindSessionId,
|
|
24852
|
+
...sessionBindParams
|
|
24853
|
+
});
|
|
24854
|
+
return typeof loaded.sessionId === "string" && loaded.sessionId !== "" ? loaded.sessionId : bindSessionId;
|
|
24855
|
+
};
|
|
24793
24856
|
if (continuation.kind === "resume" && config.boundResume === "session/load") {
|
|
24794
24857
|
const boundSessionId = await config.sessionIdentity.load(request.principal);
|
|
24795
24858
|
if (boundSessionId !== void 0 && boundSessionId !== "") {
|
|
24796
|
-
|
|
24797
|
-
sessionId: boundSessionId,
|
|
24798
|
-
cwd: request.cwd,
|
|
24799
|
-
mcpServers: prepared.mcpServers,
|
|
24800
|
-
_meta: { systemPromptOverride: renderAcpSystemPromptOverride(prepared.systemPrompt), yoloMode: false }
|
|
24801
|
-
});
|
|
24802
|
-
sessionId = typeof loaded.sessionId === "string" && loaded.sessionId !== "" ? loaded.sessionId : boundSessionId;
|
|
24859
|
+
sessionId = await loadSession(boundSessionId);
|
|
24803
24860
|
}
|
|
24804
24861
|
}
|
|
24805
24862
|
if (sessionId === void 0) {
|
|
24806
|
-
const session = await connection.request(
|
|
24807
|
-
"session/new",
|
|
24808
|
-
{
|
|
24809
|
-
cwd: request.cwd,
|
|
24810
|
-
mcpServers: prepared.mcpServers,
|
|
24811
|
-
_meta: { systemPromptOverride: renderAcpSystemPromptOverride(prepared.systemPrompt), yoloMode: false }
|
|
24812
|
-
}
|
|
24813
|
-
);
|
|
24863
|
+
const session = await connection.request("session/new", sessionBindParams);
|
|
24814
24864
|
sessionId = typeof session.sessionId === "string" ? session.sessionId : void 0;
|
|
24815
24865
|
if (sessionId === void 0 || sessionId === "") {
|
|
24816
24866
|
return failure("session", "AcpSessionFailure", "session-id-missing");
|
|
24817
24867
|
}
|
|
24818
24868
|
await config.sessionIdentity.bind(request.principal, sessionId);
|
|
24819
24869
|
}
|
|
24870
|
+
if (config.modelPassing === "set_model" && request.model !== void 0 && sessionId !== void 0) {
|
|
24871
|
+
await connection.request("session/set_model", {
|
|
24872
|
+
sessionId,
|
|
24873
|
+
modelId: acpModelId(config.modelPassing, request.model)
|
|
24874
|
+
});
|
|
24875
|
+
sessionId = await loadSession(sessionId);
|
|
24876
|
+
}
|
|
24820
24877
|
let prompt = priorNativePaths !== void 0 && priorNativePaths.length > 0 ? `${prepared.prompt}
|
|
24821
24878
|
${priorNativePaths.join("\n")}` : prepared.prompt;
|
|
24822
24879
|
const abortSignal = request.signal === void 0 ? prepared.abortSignal : prepared.abortSignal === void 0 ? request.signal : AbortSignal.any([prepared.abortSignal, request.signal]);
|
|
@@ -24827,7 +24884,7 @@ ${priorNativePaths.join("\n")}` : prepared.prompt;
|
|
|
24827
24884
|
}
|
|
24828
24885
|
const promptRequest = activeConnection.request("session/prompt", params);
|
|
24829
24886
|
if (abortSignal === void 0) return promptRequest;
|
|
24830
|
-
return new Promise((
|
|
24887
|
+
return new Promise((resolve20, reject) => {
|
|
24831
24888
|
let settled = false;
|
|
24832
24889
|
const onAbort = () => {
|
|
24833
24890
|
if (settled) return;
|
|
@@ -24842,7 +24899,7 @@ ${priorNativePaths.join("\n")}` : prepared.prompt;
|
|
|
24842
24899
|
if (settled) return;
|
|
24843
24900
|
settled = true;
|
|
24844
24901
|
abortSignal.removeEventListener("abort", onAbort);
|
|
24845
|
-
|
|
24902
|
+
resolve20(value);
|
|
24846
24903
|
},
|
|
24847
24904
|
(error) => {
|
|
24848
24905
|
if (settled) return;
|
|
@@ -24856,12 +24913,9 @@ ${priorNativePaths.join("\n")}` : prepared.prompt;
|
|
|
24856
24913
|
for (let attempt = 0; attempt < 8; attempt += 1) {
|
|
24857
24914
|
let result;
|
|
24858
24915
|
try {
|
|
24859
|
-
const promptParts = [
|
|
24860
|
-
{ type: "text", text: prompt }
|
|
24861
|
-
];
|
|
24862
24916
|
result = await promptOrAbort({
|
|
24863
24917
|
sessionId,
|
|
24864
|
-
prompt:
|
|
24918
|
+
prompt: [{ type: "text", text: prompt }]
|
|
24865
24919
|
});
|
|
24866
24920
|
} catch (error) {
|
|
24867
24921
|
if (typeof error === "object" && error !== null && error.code === "host-aborted") {
|
|
@@ -24966,11 +25020,11 @@ function projectAcpActivationFlags(request) {
|
|
|
24966
25020
|
return flags;
|
|
24967
25021
|
}
|
|
24968
25022
|
async function listen(server, path) {
|
|
24969
|
-
await new Promise((
|
|
25023
|
+
await new Promise((resolve20, reject) => {
|
|
24970
25024
|
server.once("error", reject);
|
|
24971
25025
|
server.listen(path, () => {
|
|
24972
25026
|
server.off("error", reject);
|
|
24973
|
-
|
|
25027
|
+
resolve20();
|
|
24974
25028
|
});
|
|
24975
25029
|
});
|
|
24976
25030
|
}
|
|
@@ -25361,8 +25415,8 @@ async function prepareAcpRoleEnvelope(options) {
|
|
|
25361
25415
|
try {
|
|
25362
25416
|
const closeAll = server.closeAllConnections;
|
|
25363
25417
|
if (typeof closeAll === "function") closeAll.call(server);
|
|
25364
|
-
await new Promise((
|
|
25365
|
-
server.close((error) => error ? reject(error) :
|
|
25418
|
+
await new Promise((resolve20, reject) => {
|
|
25419
|
+
server.close((error) => error ? reject(error) : resolve20());
|
|
25366
25420
|
});
|
|
25367
25421
|
} catch (error) {
|
|
25368
25422
|
cleanupFailures.push(error);
|
|
@@ -25470,11 +25524,70 @@ async function prepareAcpRoleEnvelope(options) {
|
|
|
25470
25524
|
}
|
|
25471
25525
|
}
|
|
25472
25526
|
|
|
25527
|
+
// src/acp-host/seat-profile-soul.ts
|
|
25528
|
+
import { constants as constants3 } from "node:fs";
|
|
25529
|
+
import { access as access4, copyFile, lstat as lstat6, mkdir as mkdir6, readlink, symlink, unlink as unlink4 } from "node:fs/promises";
|
|
25530
|
+
import { dirname as dirname18, join as join35, relative as relative3, resolve as resolve19 } from "node:path";
|
|
25531
|
+
function seatProfileName(spec, role) {
|
|
25532
|
+
return `${spec.namePrefix}${role}`;
|
|
25533
|
+
}
|
|
25534
|
+
function packageRoleSoulPath(packageRoot, role) {
|
|
25535
|
+
return join35(packageRoot, "souls", `${role}.md`);
|
|
25536
|
+
}
|
|
25537
|
+
async function pathExists(path) {
|
|
25538
|
+
try {
|
|
25539
|
+
await access4(path, constants3.F_OK);
|
|
25540
|
+
return true;
|
|
25541
|
+
} catch {
|
|
25542
|
+
return false;
|
|
25543
|
+
}
|
|
25544
|
+
}
|
|
25545
|
+
async function ensureSeatProfileSoul(options) {
|
|
25546
|
+
const { spec, operatorHome, packageRoot, role } = options;
|
|
25547
|
+
const profileName = seatProfileName(spec, role);
|
|
25548
|
+
const soulTarget = resolve19(packageRoleSoulPath(packageRoot, role));
|
|
25549
|
+
if (!await pathExists(soulTarget)) {
|
|
25550
|
+
throw new Error(`packaged role soul missing: ${soulTarget}`);
|
|
25551
|
+
}
|
|
25552
|
+
const profilesRoot = join35(operatorHome, ...spec.profilesRootFromHome);
|
|
25553
|
+
const profileDir = join35(profilesRoot, profileName);
|
|
25554
|
+
const hostRoot = dirname18(profilesRoot);
|
|
25555
|
+
const soulPath = join35(profileDir, spec.soulFileName);
|
|
25556
|
+
if (!await pathExists(profileDir)) {
|
|
25557
|
+
await mkdir6(profileDir, { recursive: true });
|
|
25558
|
+
for (const name of ["auth.json", ".env", "config.yaml"]) {
|
|
25559
|
+
const source = join35(hostRoot, name);
|
|
25560
|
+
if (!await pathExists(source)) continue;
|
|
25561
|
+
await copyFile(source, join35(profileDir, name));
|
|
25562
|
+
}
|
|
25563
|
+
} else {
|
|
25564
|
+
await mkdir6(profileDir, { recursive: true });
|
|
25565
|
+
}
|
|
25566
|
+
const desiredLink = relative3(profileDir, soulTarget);
|
|
25567
|
+
let current;
|
|
25568
|
+
try {
|
|
25569
|
+
const st = await lstat6(soulPath);
|
|
25570
|
+
if (st.isSymbolicLink()) {
|
|
25571
|
+
current = await readlink(soulPath);
|
|
25572
|
+
}
|
|
25573
|
+
} catch {
|
|
25574
|
+
current = void 0;
|
|
25575
|
+
}
|
|
25576
|
+
if (current === desiredLink || current === soulTarget) {
|
|
25577
|
+
return profileName;
|
|
25578
|
+
}
|
|
25579
|
+
if (await pathExists(soulPath) || current !== void 0) {
|
|
25580
|
+
await unlink4(soulPath);
|
|
25581
|
+
}
|
|
25582
|
+
await symlink(desiredLink, soulPath);
|
|
25583
|
+
return profileName;
|
|
25584
|
+
}
|
|
25585
|
+
|
|
25473
25586
|
// src/acp-host/session-identity.ts
|
|
25474
|
-
import { mkdir as
|
|
25475
|
-
import { dirname as
|
|
25587
|
+
import { mkdir as mkdir7, readFile as readFile19, rename, writeFile as writeFile9 } from "node:fs/promises";
|
|
25588
|
+
import { dirname as dirname19, join as join36 } from "node:path";
|
|
25476
25589
|
function createAcpSessionIdentityAuthority(authority, sessionBindingFile) {
|
|
25477
|
-
const bindingPath = (principal) =>
|
|
25590
|
+
const bindingPath = (principal) => join36(authority.decode(principal).sessionDirectory, sessionBindingFile);
|
|
25478
25591
|
return {
|
|
25479
25592
|
resolveSessionFile(principal) {
|
|
25480
25593
|
return authority.decode(principal).sessionFile;
|
|
@@ -25493,7 +25606,7 @@ function createAcpSessionIdentityAuthority(authority, sessionBindingFile) {
|
|
|
25493
25606
|
},
|
|
25494
25607
|
async bind(principal, sessionId) {
|
|
25495
25608
|
const target = bindingPath(principal);
|
|
25496
|
-
await
|
|
25609
|
+
await mkdir7(dirname19(target), { recursive: true });
|
|
25497
25610
|
const temporary = `${target}.${process.pid}.tmp`;
|
|
25498
25611
|
await writeFile9(temporary, `${JSON.stringify({ sessionId })}
|
|
25499
25612
|
`, { encoding: "utf8", mode: 384 });
|
|
@@ -25580,11 +25693,23 @@ function createProductionAcpRoleTurnHost(options) {
|
|
|
25580
25693
|
return createComposedAcpRoleTurnHost({
|
|
25581
25694
|
sessionIdentity: createAcpSessionIdentityAuthority(principalAuthority, description.sessionBindingFile),
|
|
25582
25695
|
boundResume: description.boundResume,
|
|
25696
|
+
modelPassing: description.modelPassing,
|
|
25583
25697
|
roleRuntimeDependencies: createAcpRoleRuntimeDependencies(packageRoot),
|
|
25584
25698
|
async connect(request) {
|
|
25699
|
+
const seatProfile = description.seatProfileSoul;
|
|
25700
|
+
const profileName = seatProfile === void 0 ? void 0 : await ensureSeatProfileSoul({
|
|
25701
|
+
spec: seatProfile,
|
|
25702
|
+
operatorHome: request.home,
|
|
25703
|
+
packageRoot,
|
|
25704
|
+
role: request.activation.role
|
|
25705
|
+
});
|
|
25585
25706
|
return connectAcpStdio({
|
|
25586
25707
|
binary: resolveAcpBinary(description, request.home),
|
|
25587
|
-
args: acpStdioArgs(
|
|
25708
|
+
args: acpStdioArgs(
|
|
25709
|
+
description,
|
|
25710
|
+
request.model,
|
|
25711
|
+
profileName === void 0 ? void 0 : { profileName }
|
|
25712
|
+
),
|
|
25588
25713
|
cwd: request.cwd,
|
|
25589
25714
|
env
|
|
25590
25715
|
});
|