@amaster.ai/employee-runtime-connector 0.1.1-beta.0 → 0.1.1-beta.1
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/README.md +1 -1
- package/dist/amaster-runtime-daemon.mjs +223 -112
- package/dist/amaster-runtime.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ Pi execution uses three separate evidence layers:
|
|
|
40
40
|
2. a durable, inspectable Runtime Action receipt or finalized Runtime Artifact;
|
|
41
41
|
3. process cleanup disposition.
|
|
42
42
|
|
|
43
|
-
An exact process-kill `EPERM` error emitted only after the first two layers have completed may be isolated as a failed `cleanupDisposition` warning without changing the command's successful business result. Both accepted shapes require `kill` and `EPERM`; generic filesystem/process permission text such as `EPERM: operation not permitted, unlink ...` is a business error. A `runtime_action.status` readback is evidence only when its call/plan ref matches an earlier submit/commit receipt in the same transcript. The diagnostic and durable evidence reference remain in the result. Text-only or action-only-without-assistant-output streams, standalone governed reads, non-effect Runtime Action tools, rejected or pending effects, pre-terminal errors, provider failures, timeout, cancellation, resource limits, any signal, live residue, and uncertain ownership remain failures.
|
|
43
|
+
An exact process-kill `EPERM` error emitted only after the first two layers have completed may be isolated as a failed `cleanupDisposition` warning without changing the command's successful business result. Both accepted shapes require `kill` and `EPERM`; generic filesystem/process permission text such as `EPERM: operation not permitted, unlink ...` is a business error. Durable evidence is limited to a completed Runtime Action, a finalized Runtime Artifact, or an accepted `company_diagnosis_brief` provider receipt whose invocation and returned Diagnosis/document/work-product identities are exact. A `runtime_action.status` readback is evidence only when its call/plan ref matches an earlier submit/commit receipt in the same transcript. The diagnostic and durable evidence reference remain in the result. Text-only or action-only-without-assistant-output streams, standalone governed reads, non-effect Runtime Action tools, rejected or pending effects, pre-terminal errors, provider failures, timeout, cancellation, resource limits, any signal, live residue, and uncertain ownership remain failures.
|
|
44
44
|
|
|
45
45
|
This isolation does not schedule a retry or a second business continuation. Command result delivery and the result outbox remain the sole idempotency boundary.
|
|
46
46
|
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// MirrorX runtime connector daemon bundle.
|
|
3
3
|
|
|
4
4
|
// src/amaster-runtime-daemon.mjs
|
|
5
|
-
import { createHash as
|
|
6
|
-
import { chmodSync as chmodSync6, copyFileSync as copyFileSync3, existsSync as existsSync14, lstatSync as lstatSync7, mkdirSync as mkdirSync9, readFileSync as readFileSync11, readdirSync as readdirSync9, realpathSync as realpathSync5, renameSync as renameSync6, rmSync as rmSync7, statSync as statSync7, symlinkSync as symlinkSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "node:fs";
|
|
7
|
-
import { arch as arch3, homedir as homedir3, hostname as hostname2, platform as platform3 } from "node:os";
|
|
5
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
6
|
+
import { chmodSync as chmodSync6, copyFileSync as copyFileSync3, existsSync as existsSync14, lstatSync as lstatSync7, mkdirSync as mkdirSync9, mkdtempSync, readFileSync as readFileSync11, readdirSync as readdirSync9, realpathSync as realpathSync5, renameSync as renameSync6, rmSync as rmSync7, statSync as statSync7, symlinkSync as symlinkSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "node:fs";
|
|
7
|
+
import { arch as arch3, homedir as homedir3, hostname as hostname2, platform as platform3, tmpdir } from "node:os";
|
|
8
8
|
import { basename as basename6, delimiter as delimiter2, dirname as dirname9, extname as extname2, isAbsolute as isAbsolute8, join as join15, relative as relative9, resolve as resolve12 } from "node:path";
|
|
9
9
|
import { spawn as spawn2, spawnSync as spawnSync6 } from "node:child_process";
|
|
10
10
|
|
|
@@ -1607,7 +1607,7 @@ var MANAGED_PI_PROVIDER_PROTECTED_ENV_NAMES = Object.freeze([
|
|
|
1607
1607
|
function isRecord(value) {
|
|
1608
1608
|
return value && typeof value === "object" && !Array.isArray(value);
|
|
1609
1609
|
}
|
|
1610
|
-
function
|
|
1610
|
+
function readJsonFile(filePath) {
|
|
1611
1611
|
try {
|
|
1612
1612
|
const parsed = JSON.parse(readFileSync2(filePath, "utf8"));
|
|
1613
1613
|
return asRecord(parsed);
|
|
@@ -1679,7 +1679,7 @@ function syncAmasterProviderModels(agentDir, executorEnv) {
|
|
|
1679
1679
|
const apiKey = readString(executorEnv.AMASTER_API_KEY);
|
|
1680
1680
|
if (!apiKey) return false;
|
|
1681
1681
|
const modelsPath = join3(agentDir, "models.json");
|
|
1682
|
-
const config =
|
|
1682
|
+
const config = readJsonFile(modelsPath);
|
|
1683
1683
|
const providers = asRecord(config.providers);
|
|
1684
1684
|
const amaster = { ...asRecord(providers.amaster) };
|
|
1685
1685
|
amaster.apiKey = managedApiKeyConfigValue(executorEnv, apiKey);
|
|
@@ -1707,7 +1707,7 @@ function syncAmasterProviderSettings(agentDir, executorEnv) {
|
|
|
1707
1707
|
if (!apiKey) return false;
|
|
1708
1708
|
const settingsPath = join3(agentDir, "settings.json");
|
|
1709
1709
|
if (!existsSync2(settingsPath)) return false;
|
|
1710
|
-
const settings =
|
|
1710
|
+
const settings = readJsonFile(settingsPath);
|
|
1711
1711
|
const baseUrl = readString(executorEnv.AMASTER_PROVIDER_BASE_URL);
|
|
1712
1712
|
const defaultModel = readString(executorEnv.AMASTER_PROVIDER_DEFAULT_MODEL);
|
|
1713
1713
|
const imageGenBaseUrl = imageGenBaseUrlFromProviderBaseUrl(baseUrl);
|
|
@@ -2264,8 +2264,13 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
2264
2264
|
if (!existsSync3(packagePath) || lstatSync2(packagePath).isSymbolicLink() || !lstatSync2(packagePath).isFile()) {
|
|
2265
2265
|
throw new Error(`pi_managed_mcp_attestation_failed: configured ${MANAGED_WEB_ACCESS_PACKAGE} package is unavailable`);
|
|
2266
2266
|
}
|
|
2267
|
-
|
|
2268
|
-
|
|
2267
|
+
let packageMetadata;
|
|
2268
|
+
try {
|
|
2269
|
+
packageMetadata = JSON.parse(readFileSync3(packagePath, "utf8"));
|
|
2270
|
+
} catch {
|
|
2271
|
+
throw new Error(`pi_managed_mcp_attestation_failed: configured ${MANAGED_WEB_ACCESS_PACKAGE} package metadata is invalid`);
|
|
2272
|
+
}
|
|
2273
|
+
if (packageMetadata.name !== MANAGED_WEB_ACCESS_PACKAGE) {
|
|
2269
2274
|
throw new Error(`pi_managed_mcp_attestation_failed: configured ${MANAGED_WEB_ACCESS_PACKAGE} package identity mismatch`);
|
|
2270
2275
|
}
|
|
2271
2276
|
return {
|
|
@@ -2318,44 +2323,11 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
2318
2323
|
}
|
|
2319
2324
|
}
|
|
2320
2325
|
const browserUse = selectManagedBrowserUse(sourceSettings, npmSource);
|
|
2321
|
-
const webAccess = selectManagedWebAccess(sourceSettings, npmSource);
|
|
2326
|
+
const webAccess = sourceAcquisition ? null : selectManagedWebAccess(sourceSettings, npmSource);
|
|
2322
2327
|
const telemetry = selectManagedTelemetry(sourceSettings, npmSource);
|
|
2323
|
-
if (sourceAcquisition &&
|
|
2328
|
+
if (sourceAcquisition && !browserUse) {
|
|
2324
2329
|
throw new Error("pi_managed_mcp_source_acquisition_packages_missing");
|
|
2325
2330
|
}
|
|
2326
|
-
const sourceProfile = record6(sourceAcquisition?.profile);
|
|
2327
|
-
const sourceAccess = record6(sourceProfile.access);
|
|
2328
|
-
const sourceTransport = record6(sourceProfile.transport);
|
|
2329
|
-
const sourceObservation = sourceAcquisition ? {
|
|
2330
|
-
runId: sourceProfile.runId,
|
|
2331
|
-
retention: sourceProfile.retention
|
|
2332
|
-
} : null;
|
|
2333
|
-
const sourceWebAccessConfig = sourceAcquisition ? {
|
|
2334
|
-
...webAccess.config,
|
|
2335
|
-
fetch: {
|
|
2336
|
-
...record6(webAccess.config.fetch),
|
|
2337
|
-
mode: sourceTransport.webFetchMode,
|
|
2338
|
-
observation: sourceObservation,
|
|
2339
|
-
...!record6(webAccess.config.fetch).provider && !record6(webAccess.config.fetch).summary && typeof sourceSettings.defaultProvider === "string" && typeof sourceSettings.defaultModel === "string" ? { summary: { provider: sourceSettings.defaultProvider, model: sourceSettings.defaultModel } } : {}
|
|
2340
|
-
}
|
|
2341
|
-
} : null;
|
|
2342
|
-
const sourceBrowserConfig = sourceAcquisition ? {
|
|
2343
|
-
...browserUse.config,
|
|
2344
|
-
sessionMode: sourceTransport.browserMode,
|
|
2345
|
-
...sourceAccess.mode === "authenticated" ? { userDataDir: sourceAcquisition.userDataDir } : {},
|
|
2346
|
-
readPolicy: {
|
|
2347
|
-
version: "browser_read_policy_v1",
|
|
2348
|
-
accessMode: sourceAccess.mode,
|
|
2349
|
-
allowedTopLevelLocators: [sourceAccess.exactLocator, ...Array.isArray(sourceAccess.declaredPageLocators) ? sourceAccess.declaredPageLocators : []],
|
|
2350
|
-
allowedTopLevelOrigins: sourceAccess.allowedTopLevelOrigins,
|
|
2351
|
-
subresources: "public_or_same_origin",
|
|
2352
|
-
privateCrossOriginSubresources: "deny",
|
|
2353
|
-
popups: "deny",
|
|
2354
|
-
downloads: "deny",
|
|
2355
|
-
newTargets: "deny",
|
|
2356
|
-
observation: sourceObservation
|
|
2357
|
-
}
|
|
2358
|
-
} : null;
|
|
2359
2331
|
const settings = {
|
|
2360
2332
|
...typeof sourceSettings.defaultProvider === "string" ? { defaultProvider: sourceSettings.defaultProvider } : {},
|
|
2361
2333
|
...typeof sourceSettings.defaultModel === "string" ? { defaultModel: sourceSettings.defaultModel } : {},
|
|
@@ -2363,15 +2335,15 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
2363
2335
|
"npm:pi-mcp-adapter",
|
|
2364
2336
|
...telemetry ? [telemetry.packageSpec] : [],
|
|
2365
2337
|
...webAccess ? [webAccess.packageSpec] : [],
|
|
2366
|
-
|
|
2338
|
+
...!sourceAcquisition && browserUse ? [browserUse.packageSpec] : []
|
|
2367
2339
|
],
|
|
2368
2340
|
...telemetry ? { "pi-telemetry": telemetry.config } : {},
|
|
2369
|
-
...webAccess ? { "pi-web-access":
|
|
2370
|
-
|
|
2341
|
+
...webAccess ? { "pi-web-access": webAccess.config } : {},
|
|
2342
|
+
...!sourceAcquisition && browserUse ? {
|
|
2371
2343
|
plugins: {
|
|
2372
2344
|
[MANAGED_BROWSER_USE_PLUGIN]: browserUse.plugin
|
|
2373
2345
|
},
|
|
2374
|
-
"pi-browser-use":
|
|
2346
|
+
"pi-browser-use": browserUse.config
|
|
2375
2347
|
} : {}
|
|
2376
2348
|
};
|
|
2377
2349
|
writePrivateFile2(join4(agentDir, "settings.json"), `${JSON.stringify(settings, null, 2)}
|
|
@@ -2382,6 +2354,12 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
2382
2354
|
join4(extensionsDir, MANAGED_PI_MCP_ARGS_NORMALIZER_FILENAME),
|
|
2383
2355
|
managedPiMcpArgsNormalizerExtensionSource()
|
|
2384
2356
|
);
|
|
2357
|
+
if (sourceAcquisition && !copyPrivateFile(
|
|
2358
|
+
join4(source, "extensions", "amaster-source-acquisition.js"),
|
|
2359
|
+
join4(extensionsDir, "amaster-source-acquisition.js")
|
|
2360
|
+
)) {
|
|
2361
|
+
throw new Error("pi_managed_mcp_source_acquisition_extension_missing");
|
|
2362
|
+
}
|
|
2385
2363
|
copyPrivateFile(join4(source, "models.json"), join4(agentDir, "models.json"));
|
|
2386
2364
|
const authSource = join4(source, "auth.json");
|
|
2387
2365
|
const protectedValues = [];
|
|
@@ -2523,8 +2501,6 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2523
2501
|
PI_AGENT_MCP_SERVERS_FILE: configPath,
|
|
2524
2502
|
TMPDIR: tmp,
|
|
2525
2503
|
...input.sourceAcquisition ? {
|
|
2526
|
-
PI_WEB_ACCESS_RUNTIME_FETCH_MODE: record6(input.sourceAcquisition.profile).transport?.webFetchMode,
|
|
2527
|
-
PI_WEB_ACCESS_RUNTIME_OBSERVATION: "required",
|
|
2528
2504
|
PI_BROWSER_USE_RUNTIME_READ_POLICY: "required"
|
|
2529
2505
|
} : {}
|
|
2530
2506
|
};
|
|
@@ -4726,6 +4702,7 @@ function governedMcpToolResult(structuredContent) {
|
|
|
4726
4702
|
if (!status) return null;
|
|
4727
4703
|
const invocationId = readString(structuredContent.invocationId);
|
|
4728
4704
|
const providerContent = asRecord(structuredContent.content);
|
|
4705
|
+
const providerReceipt = asRecord(structuredContent.providerReceipt);
|
|
4729
4706
|
const providerStatus = readString(providerContent.status);
|
|
4730
4707
|
const providerResult = asRecord(providerContent.result);
|
|
4731
4708
|
const effectResult = asRecord(providerResult.effectResult);
|
|
@@ -4742,12 +4719,23 @@ function governedMcpToolResult(structuredContent) {
|
|
|
4742
4719
|
...readString(providerResult.planId) ? { planId: readString(providerResult.planId) } : {},
|
|
4743
4720
|
...readString(providerResult.status) ? { resultStatus: readString(providerResult.status) } : {}
|
|
4744
4721
|
} : null;
|
|
4722
|
+
const diagnosisId = readString(providerContent.diagnosisId);
|
|
4723
|
+
const diagnosisRevision = readNumber(providerContent.diagnosisRevision, 0);
|
|
4724
|
+
const documentRevisionId = readString(providerContent.documentRevisionId);
|
|
4725
|
+
const workProductId = readString(providerContent.workProductId);
|
|
4726
|
+
const diagnosisBrief = status === "succeeded" && invocationId && readString(providerReceipt.provider) === "amaster_actions" && readString(providerReceipt.invocationId) === invocationId && readString(providerReceipt.status) === "accepted" && readString(providerReceipt.writeKind) === "company_diagnosis_brief" && diagnosisId && Number.isSafeInteger(diagnosisRevision) && diagnosisRevision > 0 && documentRevisionId && workProductId ? {
|
|
4727
|
+
diagnosisId,
|
|
4728
|
+
diagnosisRevision,
|
|
4729
|
+
documentRevisionId,
|
|
4730
|
+
workProductId
|
|
4731
|
+
} : null;
|
|
4745
4732
|
return {
|
|
4746
4733
|
...invocationId ? { invocationId } : {},
|
|
4747
4734
|
status,
|
|
4748
4735
|
...providerStatus ? { providerStatus } : {},
|
|
4749
4736
|
...artifactIntent ? { artifactIntent } : {},
|
|
4750
|
-
...runtimeAction ? { runtimeAction } : {}
|
|
4737
|
+
...runtimeAction ? { runtimeAction } : {},
|
|
4738
|
+
...diagnosisBrief ? { diagnosisBrief } : {}
|
|
4751
4739
|
};
|
|
4752
4740
|
}
|
|
4753
4741
|
function dedupeGovernedMcpToolResults(results) {
|
|
@@ -4820,10 +4808,23 @@ function finalizedPiRuntimeArtifactEvidence(runtimeArtifacts) {
|
|
|
4820
4808
|
...intentId ? { intentId } : {}
|
|
4821
4809
|
};
|
|
4822
4810
|
}
|
|
4811
|
+
function durablePiDiagnosisBriefEvidence(results) {
|
|
4812
|
+
const result3 = (Array.isArray(results) ? results : []).map(asRecord).find((entry) => readString(entry.status) === "succeeded" && Object.keys(asRecord(entry.diagnosisBrief)).length > 0);
|
|
4813
|
+
if (!result3) return null;
|
|
4814
|
+
const brief = asRecord(result3.diagnosisBrief);
|
|
4815
|
+
return {
|
|
4816
|
+
kind: "company_diagnosis_brief",
|
|
4817
|
+
invocationId: readString(result3.invocationId),
|
|
4818
|
+
diagnosisId: readString(brief.diagnosisId),
|
|
4819
|
+
diagnosisRevision: readNumber(brief.diagnosisRevision, 0),
|
|
4820
|
+
documentRevisionId: readString(brief.documentRevisionId),
|
|
4821
|
+
workProductId: readString(brief.workProductId)
|
|
4822
|
+
};
|
|
4823
|
+
}
|
|
4823
4824
|
function classifyPiTerminalCleanupDisposition(parsed, runtimeArtifacts) {
|
|
4824
4825
|
const diagnostics = Array.isArray(parsed?.cleanupDiagnostics) ? parsed.cleanupDiagnostics.map(asRecord) : [];
|
|
4825
4826
|
if (parsed?.terminalEventType !== "agent_end" || readString(parsed?.stopReason) || parsed?.hasAssistantOutput !== true || diagnostics.length === 0 || diagnostics.some((diagnostic) => readString(diagnostic.phase) !== "post_terminal" || readString(diagnostic.code) !== "pi_terminal_cleanup_permission_denied") || readNumber(parsed?.nonCleanupErrorCount, 0) > 0) return null;
|
|
4826
|
-
const durableEvidence = durablePiRuntimeActionEvidence(parsed?.mcpToolResults) ?? finalizedPiRuntimeArtifactEvidence(runtimeArtifacts);
|
|
4827
|
+
const durableEvidence = durablePiRuntimeActionEvidence(parsed?.mcpToolResults) ?? durablePiDiagnosisBriefEvidence(parsed?.mcpToolResults) ?? finalizedPiRuntimeArtifactEvidence(runtimeArtifacts);
|
|
4827
4828
|
if (!durableEvidence) return null;
|
|
4828
4829
|
return {
|
|
4829
4830
|
status: "failed",
|
|
@@ -6764,7 +6765,7 @@ function within3(candidate, root) {
|
|
|
6764
6765
|
const rel = relative6(root, candidate);
|
|
6765
6766
|
return rel === "" || !rel.startsWith("..") && !isAbsolute6(rel);
|
|
6766
6767
|
}
|
|
6767
|
-
function
|
|
6768
|
+
function readJsonFile2(path, label, fallback = {}) {
|
|
6768
6769
|
if (!existsSync11(path)) return fallback;
|
|
6769
6770
|
const stat = lstatSync6(path);
|
|
6770
6771
|
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
@@ -6815,8 +6816,8 @@ function copyTreeNoLinks(source, target) {
|
|
|
6815
6816
|
chmodSync5(target, 384 | stat.mode & 73);
|
|
6816
6817
|
}
|
|
6817
6818
|
function mergeMcp(seedRoot, overlayRoot, governedConfig) {
|
|
6818
|
-
const seed = record5(
|
|
6819
|
-
const overlay = record5(
|
|
6819
|
+
const seed = record5(readJsonFile2(join12(seedRoot, "mcp.json"), "seed_mcp", { mcpServers: {} }));
|
|
6820
|
+
const overlay = record5(readJsonFile2(join12(overlayRoot, "mcp.json"), "overlay_mcp", { mcpServers: {} }));
|
|
6820
6821
|
assertNoPersistentSecrets(seed, ["seed", "mcp.json"]);
|
|
6821
6822
|
assertNoPersistentSecrets(overlay, ["overlay", "mcp.json"]);
|
|
6822
6823
|
const seedServers = record5(seed.mcpServers);
|
|
@@ -6852,7 +6853,7 @@ function assertEnabledPackagesAvailable(settings, npmRoot) {
|
|
|
6852
6853
|
}
|
|
6853
6854
|
for (const name of requiredNames) {
|
|
6854
6855
|
const metadataPath = join12(npmRoot, "node_modules", ...name.split("/"), "package.json");
|
|
6855
|
-
const metadata =
|
|
6856
|
+
const metadata = readJsonFile2(metadataPath, `package:${name}`, null);
|
|
6856
6857
|
if (!metadata || metadata.name !== name) {
|
|
6857
6858
|
throw new Error(`pi_trusted_runtime_package_unavailable:${name}`);
|
|
6858
6859
|
}
|
|
@@ -6880,8 +6881,8 @@ function materializeTrustedPiRuntimeProfile(input) {
|
|
|
6880
6881
|
}
|
|
6881
6882
|
const mergedJson = {};
|
|
6882
6883
|
for (const entry of JSON_ENTRIES) {
|
|
6883
|
-
const seed =
|
|
6884
|
-
const overlay =
|
|
6884
|
+
const seed = readJsonFile2(join12(seedRoot, entry), `seed_${entry}`, {});
|
|
6885
|
+
const overlay = readJsonFile2(join12(overlayRoot, entry), `overlay_${entry}`, {});
|
|
6885
6886
|
const merged = deepMerge(seed, overlay);
|
|
6886
6887
|
if (entry === "settings.json") {
|
|
6887
6888
|
merged["pi-security"] = {
|
|
@@ -6901,7 +6902,7 @@ function materializeTrustedPiRuntimeProfile(input) {
|
|
|
6901
6902
|
chmodSync5(join12(agentDir, entry), 384);
|
|
6902
6903
|
mergedJson[entry] = merged;
|
|
6903
6904
|
}
|
|
6904
|
-
const governedConfig =
|
|
6905
|
+
const governedConfig = readJsonFile2(input.governedMcpConfigPath, "governed_mcp");
|
|
6905
6906
|
const mcp = mergeMcp(seedRoot, overlayRoot, governedConfig);
|
|
6906
6907
|
writeFileSync8(input.governedMcpConfigPath, `${JSON.stringify(mcp, null, 2)}
|
|
6907
6908
|
`, { mode: 384 });
|
|
@@ -7947,20 +7948,17 @@ async function executeBrowserSessionCommand(command, dependencies = {}) {
|
|
|
7947
7948
|
}
|
|
7948
7949
|
|
|
7949
7950
|
// src/amaster-runtime-daemon/source-acquisition-invocation.mjs
|
|
7951
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
7950
7952
|
var SOURCE_ACQUISITION_PUBLIC_TOOLS = Object.freeze([
|
|
7951
|
-
"
|
|
7952
|
-
"
|
|
7953
|
-
"
|
|
7954
|
-
"
|
|
7955
|
-
"
|
|
7956
|
-
"browser_analyze_screenshot",
|
|
7957
|
-
"browser_wait_for",
|
|
7953
|
+
"source_open",
|
|
7954
|
+
"source_snapshot",
|
|
7955
|
+
"source_screenshot",
|
|
7956
|
+
"source_analyze_screenshot",
|
|
7957
|
+
"source_wait",
|
|
7958
7958
|
"runtime_action.submit",
|
|
7959
7959
|
"runtime_action.status"
|
|
7960
7960
|
]);
|
|
7961
|
-
var SOURCE_ACQUISITION_AUTHENTICATED_TOOLS =
|
|
7962
|
-
SOURCE_ACQUISITION_PUBLIC_TOOLS.filter((tool) => tool !== "web_fetch")
|
|
7963
|
-
);
|
|
7961
|
+
var SOURCE_ACQUISITION_AUTHENTICATED_TOOLS = SOURCE_ACQUISITION_PUBLIC_TOOLS;
|
|
7964
7962
|
function exactToolsFor(profile) {
|
|
7965
7963
|
if (profile?.access?.mode === "public") return SOURCE_ACQUISITION_PUBLIC_TOOLS;
|
|
7966
7964
|
if (profile?.access?.mode === "authenticated") return SOURCE_ACQUISITION_AUTHENTICATED_TOOLS;
|
|
@@ -7982,6 +7980,34 @@ function sourceAcquisitionPiInvocationArgs(profile) {
|
|
|
7982
7980
|
"--no-session"
|
|
7983
7981
|
];
|
|
7984
7982
|
}
|
|
7983
|
+
function serializeSourceAcquisitionProfile(profile) {
|
|
7984
|
+
if (!profile || typeof profile !== "object" || Array.isArray(profile)) return null;
|
|
7985
|
+
const input = Buffer.from(JSON.stringify(profile), "utf8");
|
|
7986
|
+
return {
|
|
7987
|
+
input,
|
|
7988
|
+
sha256: createHash10("sha256").update(input).digest("hex")
|
|
7989
|
+
};
|
|
7990
|
+
}
|
|
7991
|
+
function sourceAcquisitionManagedInputs(options) {
|
|
7992
|
+
return [
|
|
7993
|
+
options.managedInput ? { fd: 3, input: options.managedInput, code: "managed_runtime_assertion" } : null,
|
|
7994
|
+
options.sourceProfileInput ? { fd: 4, input: options.sourceProfileInput, code: "source_acquisition_profile" } : null
|
|
7995
|
+
].filter(Boolean);
|
|
7996
|
+
}
|
|
7997
|
+
function sourceAcquisitionManagedStdio(inputs) {
|
|
7998
|
+
const stdio = ["pipe", "pipe", "pipe"];
|
|
7999
|
+
for (const { fd } of inputs) {
|
|
8000
|
+
while (stdio.length <= fd) stdio.push("ignore");
|
|
8001
|
+
stdio[fd] = "pipe";
|
|
8002
|
+
}
|
|
8003
|
+
return stdio;
|
|
8004
|
+
}
|
|
8005
|
+
function deliverSourceAcquisitionManagedInputs(child, inputs, onError) {
|
|
8006
|
+
for (const { fd, input, code } of inputs) {
|
|
8007
|
+
child.stdio[fd].once("error", (error) => onError(code, error));
|
|
8008
|
+
child.stdio[fd].end(input);
|
|
8009
|
+
}
|
|
8010
|
+
}
|
|
7985
8011
|
function assertSourceAcquisitionRuntimeAuthority({
|
|
7986
8012
|
profile,
|
|
7987
8013
|
executorKind,
|
|
@@ -7995,17 +8021,17 @@ function assertSourceAcquisitionRuntimeAuthority({
|
|
|
7995
8021
|
}
|
|
7996
8022
|
|
|
7997
8023
|
// src/amaster-runtime-daemon.mjs
|
|
7998
|
-
var CONNECTOR_VERSION = "0.1.1-beta.
|
|
8024
|
+
var CONNECTOR_VERSION = "0.1.1-beta.1";
|
|
7999
8025
|
var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
|
|
8000
8026
|
var SOURCE_ACQUISITION_CAPABILITY = "source_acquisition_v1";
|
|
8001
8027
|
var SOURCE_ACQUISITION_PROFILE_VERSION = "source_acquisition_v1";
|
|
8002
8028
|
var SOURCE_ACQUISITION_RETENTION_VERSION = "source_summary_only_v1";
|
|
8003
8029
|
var SOURCE_ACQUISITION_ACTION_VERSION = "complete_source_acquisition_v1";
|
|
8030
|
+
var SOURCE_ACQUISITION_HEADLESS_ADAPTER = "pi_browser_use_headless_v1";
|
|
8031
|
+
var SOURCE_ACQUISITION_DESKTOP_ADAPTER = "browser_skill_desktop_v1";
|
|
8004
8032
|
var SOURCE_ACQUISITION_PACKAGE_VERSIONS = Object.freeze({
|
|
8005
|
-
"@amaster.ai/pi-web-access": "0.1.2-beta.52",
|
|
8006
8033
|
"@amaster.ai/pi-browser-use": "0.1.2-beta.52"
|
|
8007
8034
|
});
|
|
8008
|
-
var SOURCE_ACQUISITION_CONNECTOR_VERSION = "0.1.1-beta.0";
|
|
8009
8035
|
var MAX_CHECKPOINT_BYTES = 20 * 1024 * 1024;
|
|
8010
8036
|
var CHECKPOINT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
8011
8037
|
var AMASTER_PI_PROHIBITED_EXTRA_ARGS = /* @__PURE__ */ new Set(["--no-extensions", "--no-skills", "--no-tools", "--no-session"]);
|
|
@@ -8536,14 +8562,11 @@ function sourceAcquisitionPackageMetadata(packageName2) {
|
|
|
8536
8562
|
if (!existsSync14(packagePath)) return null;
|
|
8537
8563
|
const stat = lstatSync7(packagePath);
|
|
8538
8564
|
if (!stat.isFile() || stat.isSymbolicLink()) return null;
|
|
8539
|
-
const metadata =
|
|
8565
|
+
const metadata = readJsonFile3(packagePath);
|
|
8540
8566
|
return metadata.name === packageName2 && readString(metadata.version) ? metadata : null;
|
|
8541
8567
|
}
|
|
8542
8568
|
function sourceAcquisitionRuntimeReadiness(config) {
|
|
8543
8569
|
const unavailable = (reason) => ({ ready: false, reason });
|
|
8544
|
-
if (CONNECTOR_VERSION !== SOURCE_ACQUISITION_CONNECTOR_VERSION) {
|
|
8545
|
-
return unavailable("source_acquisition_connector_version_mismatch");
|
|
8546
|
-
}
|
|
8547
8570
|
const piExecutor = config.executors.find((executor) => executor.kind === "pi");
|
|
8548
8571
|
if (!piExecutor || !commandExists(piExecutor.command, {
|
|
8549
8572
|
...process.env,
|
|
@@ -8565,9 +8588,16 @@ function sourceAcquisitionRuntimeReadiness(config) {
|
|
|
8565
8588
|
return unavailable("source_acquisition_trusted_runtime_invalid");
|
|
8566
8589
|
}
|
|
8567
8590
|
const packageDigests = {
|
|
8568
|
-
"@amaster.ai/pi-web-access": readString(process.env.AMASTER_SOURCE_ACQUISITION_PI_WEB_ACCESS_DIGEST),
|
|
8569
8591
|
"@amaster.ai/pi-browser-use": readString(process.env.AMASTER_SOURCE_ACQUISITION_PI_BROWSER_USE_DIGEST)
|
|
8570
8592
|
};
|
|
8593
|
+
const extensionDigest = readString(process.env.AMASTER_SOURCE_ACQUISITION_EXTENSION_DIGEST);
|
|
8594
|
+
if (!extensionDigest || !/^[a-f0-9]{64}$/.test(extensionDigest)) {
|
|
8595
|
+
return unavailable("source_acquisition_extension_digest_unavailable");
|
|
8596
|
+
}
|
|
8597
|
+
const adapters = (readString(process.env.AMASTER_SOURCE_ACQUISITION_ADAPTERS) ?? "").split(",").map((value) => value.trim()).filter(Boolean);
|
|
8598
|
+
if (adapters.length === 0 || adapters.some((adapter) => ![SOURCE_ACQUISITION_HEADLESS_ADAPTER, SOURCE_ACQUISITION_DESKTOP_ADAPTER].includes(adapter))) {
|
|
8599
|
+
return unavailable("source_acquisition_adapter_attestation_invalid");
|
|
8600
|
+
}
|
|
8571
8601
|
const connectorDigest = readString(process.env.AMASTER_SOURCE_ACQUISITION_CONNECTOR_DIGEST);
|
|
8572
8602
|
if (!connectorDigest || !/^[a-f0-9]{64}$/.test(connectorDigest)) {
|
|
8573
8603
|
return unavailable("source_acquisition_connector_digest_unavailable");
|
|
@@ -8589,6 +8619,8 @@ function sourceAcquisitionRuntimeReadiness(config) {
|
|
|
8589
8619
|
profileVersion: SOURCE_ACQUISITION_PROFILE_VERSION,
|
|
8590
8620
|
retentionVersion: SOURCE_ACQUISITION_RETENTION_VERSION,
|
|
8591
8621
|
actionVersion: SOURCE_ACQUISITION_ACTION_VERSION,
|
|
8622
|
+
extension: { digest: extensionDigest },
|
|
8623
|
+
adapters,
|
|
8592
8624
|
connector: {
|
|
8593
8625
|
version: CONNECTOR_VERSION,
|
|
8594
8626
|
digest: connectorDigest
|
|
@@ -8703,10 +8735,10 @@ function piAgentSystemDataDir(config) {
|
|
|
8703
8735
|
return configured ? resolve12(expandHomePath(configured)) : null;
|
|
8704
8736
|
}
|
|
8705
8737
|
function readPiAgentLocalPlatformCredential(credentialsDir) {
|
|
8706
|
-
const pointer =
|
|
8738
|
+
const pointer = readJsonFile3(join15(credentialsDir, "latest.json"));
|
|
8707
8739
|
const credentialRef = readString(pointer.credentialRef);
|
|
8708
8740
|
if (!credentialRef || !/^[a-f0-9]{64}$/i.test(credentialRef)) return null;
|
|
8709
|
-
const credential =
|
|
8741
|
+
const credential = readJsonFile3(join15(credentialsDir, `${credentialRef}.json`));
|
|
8710
8742
|
const organizationId = readString(credential.organizationId);
|
|
8711
8743
|
const apiKey = readString(credential.apiKey);
|
|
8712
8744
|
if (credential.version !== 1 || !organizationId || !apiKey) return null;
|
|
@@ -9270,16 +9302,16 @@ function sourceAcquisitionRuntimeProfile(config, command) {
|
|
|
9270
9302
|
const access = asRecord(profile.access);
|
|
9271
9303
|
const transport = asRecord(profile.transport);
|
|
9272
9304
|
const tools = asRecord(profile.tools);
|
|
9273
|
-
if (profile.purpose !== "source_acquisition_v1" || profile.retention !== "source_summary_only_v1" || readString(profile.runId) !== commandRunId(command) || !Array.isArray(tools.exactAllowlist) || tools.exactAllowlist.length === 0 || !["public", "authenticated"].includes(access.mode) || !["isolated", "existing"].includes(transport.browserMode) || ![
|
|
9305
|
+
if (profile.purpose !== "source_acquisition_v1" || profile.retention !== "source_summary_only_v1" || readString(profile.runId) !== commandRunId(command) || !Array.isArray(tools.exactAllowlist) || tools.exactAllowlist.length === 0 || !["public", "authenticated"].includes(access.mode) || !["isolated", "existing"].includes(transport.browserMode) || ![SOURCE_ACQUISITION_HEADLESS_ADAPTER, SOURCE_ACQUISITION_DESKTOP_ADAPTER].includes(transport.adapter)) {
|
|
9274
9306
|
throw new Error("source_acquisition_profile_invalid");
|
|
9275
9307
|
}
|
|
9276
9308
|
if (access.mode === "public") {
|
|
9277
|
-
if (transport.browserMode !== "isolated" || transport.
|
|
9309
|
+
if (transport.browserMode !== "isolated" || transport.adapter !== SOURCE_ACQUISITION_HEADLESS_ADAPTER) {
|
|
9278
9310
|
throw new Error("source_acquisition_profile_invalid");
|
|
9279
9311
|
}
|
|
9280
9312
|
return { profile };
|
|
9281
9313
|
}
|
|
9282
|
-
if (transport.browserMode !== "existing" || transport.
|
|
9314
|
+
if (transport.browserMode !== "existing" || transport.adapter !== SOURCE_ACQUISITION_DESKTOP_ADAPTER) {
|
|
9283
9315
|
throw new Error("source_acquisition_profile_invalid");
|
|
9284
9316
|
}
|
|
9285
9317
|
const companyId = readString(profile.companyId);
|
|
@@ -9288,12 +9320,12 @@ function sourceAcquisitionRuntimeProfile(config, command) {
|
|
|
9288
9320
|
if (!companyId || !bindingId || !/^profile_[a-z0-9]{16,64}$/i.test(localOpaqueRef ?? "")) {
|
|
9289
9321
|
throw new Error("source_acquisition_profile_invalid");
|
|
9290
9322
|
}
|
|
9291
|
-
const profileName2 =
|
|
9323
|
+
const profileName2 = createHash11("sha256").update(`${companyId}\0${bindingId}\0${localOpaqueRef}`).digest("hex");
|
|
9292
9324
|
const stateRoot = resolve12(config.browserSessionStateRoot);
|
|
9293
9325
|
const userDataDir = resolve12(stateRoot, profileName2);
|
|
9294
9326
|
if (!pathWithin2(userDataDir, stateRoot)) throw new Error("source_acquisition_browser_profile_invalid");
|
|
9295
9327
|
const markerPath = join15(userDataDir, ".amaster-browser-session.json");
|
|
9296
|
-
const marker =
|
|
9328
|
+
const marker = readJsonFile3(markerPath);
|
|
9297
9329
|
if (marker.version !== 1 || marker.companyId !== companyId || marker.bindingId !== bindingId || marker.localOpaqueRef !== localOpaqueRef || Object.keys(marker).length !== 4) {
|
|
9298
9330
|
throw new Error("source_acquisition_browser_profile_invalid");
|
|
9299
9331
|
}
|
|
@@ -9309,7 +9341,7 @@ function trustedPiRuntimeSources(config) {
|
|
|
9309
9341
|
policyFile: config.piRuntimeEffectivePolicyFile
|
|
9310
9342
|
};
|
|
9311
9343
|
}
|
|
9312
|
-
function
|
|
9344
|
+
function readJsonFile3(filePath) {
|
|
9313
9345
|
try {
|
|
9314
9346
|
const parsed = JSON.parse(readFileSync11(filePath, "utf8"));
|
|
9315
9347
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
@@ -9554,6 +9586,60 @@ function buildExecutorEnv(config, command, workspace) {
|
|
|
9554
9586
|
AMASTER_EMPLOYEE_COMPANY_ID: companyId
|
|
9555
9587
|
};
|
|
9556
9588
|
}
|
|
9589
|
+
function copyPiModelCallConfig(sourceRoot, targetRoot, fileName, required) {
|
|
9590
|
+
const source = join15(sourceRoot, fileName);
|
|
9591
|
+
if (!existsSync14(source)) {
|
|
9592
|
+
if (required) throw new Error(`pi_model_call_profile_missing: ${fileName}`);
|
|
9593
|
+
return;
|
|
9594
|
+
}
|
|
9595
|
+
const sourceStat = lstatSync7(source);
|
|
9596
|
+
if (!sourceStat.isFile() || sourceStat.isSymbolicLink()) {
|
|
9597
|
+
throw new Error(`pi_model_call_profile_unsafe: ${fileName}`);
|
|
9598
|
+
}
|
|
9599
|
+
const target = join15(targetRoot, fileName);
|
|
9600
|
+
copyFileSync3(source, target);
|
|
9601
|
+
chmodSync6(target, 384);
|
|
9602
|
+
}
|
|
9603
|
+
function preparePiModelCallProfile(commandId, baseEnv) {
|
|
9604
|
+
const sourceRoot = readString(process.env.PI_CODING_AGENT_DIR) ?? readString(process.env.PI_AGENT_HOME) ?? readString(process.env["AMASTER-CLI_CODING_AGENT_DIR"]);
|
|
9605
|
+
if (!sourceRoot) throw new Error("pi_model_call_profile_missing: source Pi home");
|
|
9606
|
+
const sourceStat = lstatSync7(sourceRoot);
|
|
9607
|
+
if (!sourceStat.isDirectory() || sourceStat.isSymbolicLink()) {
|
|
9608
|
+
throw new Error("pi_model_call_profile_unsafe: source Pi home");
|
|
9609
|
+
}
|
|
9610
|
+
const profileRoot = mkdtempSync(join15(tmpdir(), "amaster-pi-model-call-"));
|
|
9611
|
+
const home = join15(profileRoot, "home");
|
|
9612
|
+
const agentDir = join15(profileRoot, "agent");
|
|
9613
|
+
const sessionsDir = join15(profileRoot, "sessions");
|
|
9614
|
+
const tempDir = join15(profileRoot, "tmp");
|
|
9615
|
+
for (const directory of [home, agentDir, sessionsDir, tempDir]) {
|
|
9616
|
+
mkdirSync9(directory, { recursive: true, mode: 448 });
|
|
9617
|
+
}
|
|
9618
|
+
try {
|
|
9619
|
+
copyPiModelCallConfig(sourceRoot, agentDir, "models.json", true);
|
|
9620
|
+
copyPiModelCallConfig(sourceRoot, agentDir, "auth.json", false);
|
|
9621
|
+
return {
|
|
9622
|
+
profileRoot,
|
|
9623
|
+
env: {
|
|
9624
|
+
...baseEnv,
|
|
9625
|
+
HOME: home,
|
|
9626
|
+
PI_AGENT_HOME: agentDir,
|
|
9627
|
+
PI_CODING_AGENT_DIR: agentDir,
|
|
9628
|
+
"AMASTER-CLI_CODING_AGENT_DIR": agentDir,
|
|
9629
|
+
PI_CODING_AGENT_SESSION_DIR: sessionsDir,
|
|
9630
|
+
"AMASTER-CLI_CODING_AGENT_SESSION_DIR": sessionsDir,
|
|
9631
|
+
TMPDIR: tempDir,
|
|
9632
|
+
AMASTER_RUNTIME_COMMAND_ID: commandId
|
|
9633
|
+
}
|
|
9634
|
+
};
|
|
9635
|
+
} catch (error) {
|
|
9636
|
+
rmSync7(profileRoot, { recursive: true, force: true });
|
|
9637
|
+
throw error;
|
|
9638
|
+
}
|
|
9639
|
+
}
|
|
9640
|
+
function cleanupPiModelCallProfile(profile) {
|
|
9641
|
+
if (profile?.profileRoot) rmSync7(profile.profileRoot, { recursive: true, force: true });
|
|
9642
|
+
}
|
|
9557
9643
|
function splitExtraArgs(value) {
|
|
9558
9644
|
return splitList(value).flatMap((entry) => entry.split(/\s+/).filter(Boolean));
|
|
9559
9645
|
}
|
|
@@ -9714,15 +9800,27 @@ async function executeModelCallCommand(config, command, signal) {
|
|
|
9714
9800
|
purpose: readString(payload.purpose) ?? null,
|
|
9715
9801
|
promptBytes: Buffer.byteLength(prompt, "utf8")
|
|
9716
9802
|
});
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
|
|
9721
|
-
|
|
9722
|
-
|
|
9723
|
-
|
|
9724
|
-
|
|
9725
|
-
|
|
9803
|
+
let piModelCallProfile = null;
|
|
9804
|
+
let execution;
|
|
9805
|
+
try {
|
|
9806
|
+
const baseEnv = buildExecutorEnv(config, command, {
|
|
9807
|
+
managed: false,
|
|
9808
|
+
cwd: process.cwd(),
|
|
9809
|
+
sourceWorkspacePath: process.cwd()
|
|
9810
|
+
});
|
|
9811
|
+
piModelCallProfile = executor.kind === "pi" ? preparePiModelCallProfile(command.commandId, baseEnv) : null;
|
|
9812
|
+
execution = await runExecutor(invocation.command, invocation.args, {
|
|
9813
|
+
cwd: process.cwd(),
|
|
9814
|
+
env: piModelCallProfile?.env ?? baseEnv,
|
|
9815
|
+
stdin: invocation.stdin === "prompt" ? prompt : "",
|
|
9816
|
+
timeoutSeconds,
|
|
9817
|
+
maxOutputBytes,
|
|
9818
|
+
executorKind: executor.kind,
|
|
9819
|
+
signal
|
|
9820
|
+
});
|
|
9821
|
+
} finally {
|
|
9822
|
+
cleanupPiModelCallProfile(piModelCallProfile);
|
|
9823
|
+
}
|
|
9726
9824
|
if (execution.stdout) {
|
|
9727
9825
|
await ingestLog(config, command, "stdout", "info", truncateText(execution.stdout, 4e3));
|
|
9728
9826
|
}
|
|
@@ -10330,11 +10428,12 @@ function runExecutor(command, args, options) {
|
|
|
10330
10428
|
const maxRssMb = parsePositiveInteger(options.maxRssMb, 0);
|
|
10331
10429
|
const maxRssBytes = maxRssMb * 1024 * 1024;
|
|
10332
10430
|
const spawnInvocation = managedChildSpawnInvocation(command, args, options.spawnIdentity);
|
|
10431
|
+
const managedInputs = sourceAcquisitionManagedInputs(options);
|
|
10333
10432
|
const child = spawn2(spawnInvocation.command, spawnInvocation.args, {
|
|
10334
10433
|
cwd: options.cwd,
|
|
10335
10434
|
env: options.env,
|
|
10336
10435
|
detached: process.platform !== "win32",
|
|
10337
|
-
stdio:
|
|
10436
|
+
stdio: sourceAcquisitionManagedStdio(managedInputs),
|
|
10338
10437
|
...spawnInvocation.spawnIdentity
|
|
10339
10438
|
});
|
|
10340
10439
|
const processGroupId = processGroupIdForChild(child);
|
|
@@ -10370,13 +10469,10 @@ function runExecutor(command, args, options) {
|
|
|
10370
10469
|
signalExecutorProcess(child, "SIGTERM", processGroupId);
|
|
10371
10470
|
scheduleStopKill();
|
|
10372
10471
|
};
|
|
10373
|
-
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
});
|
|
10378
|
-
child.stdio[3].end(options.managedInput);
|
|
10379
|
-
}
|
|
10472
|
+
deliverSourceAcquisitionManagedInputs(child, managedInputs, (code, error) => {
|
|
10473
|
+
spawnError = `${code}_delivery_failed: ${error.message}`;
|
|
10474
|
+
requestStop(`${code}_delivery_failed`);
|
|
10475
|
+
});
|
|
10380
10476
|
const reapStoppedWorkspaceResidents = () => {
|
|
10381
10477
|
if (settled || !stopReason || stopReason === "completion_cleanup") return;
|
|
10382
10478
|
const residents = listWorkspaceResidentProcesses(options.cwd, processGroupId, {
|
|
@@ -10980,6 +11076,7 @@ async function executeRunExitClosureTurn(config, inputState, options = {}) {
|
|
|
10980
11076
|
executorKind,
|
|
10981
11077
|
...readNumber(storedSpawnIdentity.uid, 0) > 0 ? { spawnIdentity: storedSpawnIdentity } : {},
|
|
10982
11078
|
...readString(executionConfig.managedInput) ? { managedInput: readString(executionConfig.managedInput) } : {},
|
|
11079
|
+
...readString(executionConfig.sourceProfileInput) ? { sourceProfileInput: readString(executionConfig.sourceProfileInput) } : {},
|
|
10983
11080
|
onOutput: (stream, chunk, rawBytes) => {
|
|
10984
11081
|
noteActiveRunOutput(command, stream, chunk, rawBytes);
|
|
10985
11082
|
liveOutputLogger.write(stream, chunk);
|
|
@@ -10995,24 +11092,24 @@ async function executeRunExitClosureTurn(config, inputState, options = {}) {
|
|
|
10995
11092
|
const memoryLimit = asRecord(execution.memoryLimit);
|
|
10996
11093
|
const hasMemoryLimit = readNumber(memoryLimit.rssBytes, 0) > 0;
|
|
10997
11094
|
const parsed = parseExecutorTurnOutput(executorKind, execution, liveOutputLogger, hasOutputFlood);
|
|
11095
|
+
const mcpToolResults = dedupeGovernedMcpToolResults([
|
|
11096
|
+
...Array.isArray(parsed.mcpToolResults) ? parsed.mcpToolResults.map(asRecord) : [],
|
|
11097
|
+
...liveOutputLogger.mcpToolResults().map(asRecord)
|
|
11098
|
+
]);
|
|
10998
11099
|
const outputTelemetry = liveOutputLogger.snapshot({
|
|
10999
11100
|
outputBytes: execution.outputBytes,
|
|
11000
11101
|
floodLimitBytes: Math.max(1, readNumber(executionConfig.maxOutputBytes, config.executorMaxOutputBytes)),
|
|
11001
11102
|
outputTokens: readNumber(parsed.usage?.outputTokens, 0)
|
|
11002
11103
|
});
|
|
11003
11104
|
const completionOutputStopped = executorKind === "pi" && piCompletionOutputStopped(parsed, execution);
|
|
11004
|
-
const cleanupDisposition = executorKind === "pi" && execution.cancelled !== true && !hasOutputFlood && !hasMemoryLimit && execution.timedOut !== true && !execution.spawnError && execution.signal === null ? classifyPiTerminalCleanupDisposition(parsed, []) : null;
|
|
11105
|
+
const cleanupDisposition = executorKind === "pi" && execution.cancelled !== true && !hasOutputFlood && !hasMemoryLimit && execution.timedOut !== true && !execution.spawnError && execution.signal === null ? classifyPiTerminalCleanupDisposition({ ...parsed, mcpToolResults }, []) : null;
|
|
11005
11106
|
const parsedForValidation = cleanupDisposition ? { ...parsed, errorMessage: null } : parsed;
|
|
11006
11107
|
const piInvalidOutputError = executorKind === "pi" ? piOutputValidationError(parsedForValidation, {
|
|
11007
11108
|
allowMissingTurnEnd: completionOutputStopped || Boolean(cleanupDisposition),
|
|
11008
11109
|
allowMissingAssistantOutput: false
|
|
11009
11110
|
}) : null;
|
|
11010
|
-
const parsedError = hasOutputFlood ? "Run-exit closure output exceeded the configured limit" : hasMemoryLimit ? "Run-exit closure exceeded the configured memory limit" : execution.timedOut ? "Run-exit closure timed out" : execution.spawnError ?? piInvalidOutputError ?? parsedForValidation.errorMessage ?? ((execution.exitCode ?? 0) === 0 ? null : `Run-exit closure exited with code ${execution.exitCode ?? "unknown"}`);
|
|
11111
|
+
const parsedError = hasOutputFlood ? "Run-exit closure output exceeded the configured limit" : hasMemoryLimit ? "Run-exit closure exceeded the configured memory limit" : execution.timedOut ? "Run-exit closure timed out" : execution.spawnError ?? piInvalidOutputError ?? parsedForValidation.errorMessage ?? ((execution.exitCode ?? 0) === 0 || cleanupDisposition ? null : `Run-exit closure exited with code ${execution.exitCode ?? "unknown"}`);
|
|
11011
11112
|
const succeeded = execution.cancelled !== true && !hasOutputFlood && !hasMemoryLimit && (execution.exitCode === 0 || completionOutputStopped || Boolean(cleanupDisposition)) && !execution.timedOut && !execution.spawnError && !parsedError;
|
|
11012
|
-
const mcpToolResults = dedupeGovernedMcpToolResults([
|
|
11013
|
-
...Array.isArray(parsed.mcpToolResults) ? parsed.mcpToolResults.map(asRecord) : [],
|
|
11014
|
-
...liveOutputLogger.mcpToolResults().map(asRecord)
|
|
11015
|
-
]);
|
|
11016
11113
|
await ingestLog(config, command, "system", succeeded ? "info" : "error", succeeded ? "Run-exit disposition closure turn completed" : `Run-exit disposition closure turn failed: ${parsedError}`, {
|
|
11017
11114
|
presentationKind: "run_exit_disposition_closure",
|
|
11018
11115
|
closureAttempt: 1,
|
|
@@ -11033,6 +11130,7 @@ async function executeRunExitClosureTurn(config, inputState, options = {}) {
|
|
|
11033
11130
|
timedOut: execution.timedOut,
|
|
11034
11131
|
summary: truncateText(readString(parsed.summary) ?? "", 2e3),
|
|
11035
11132
|
outputTelemetry,
|
|
11133
|
+
cleanupDisposition,
|
|
11036
11134
|
toolResults: mcpToolResults.slice(0, 10).map((result3) => ({
|
|
11037
11135
|
status: readString(result3.status),
|
|
11038
11136
|
toolName: readString(result3.toolName) ?? readString(result3.name) ?? readString(asRecord(result3.runtimeAction).toolName),
|
|
@@ -11955,7 +12053,7 @@ async function materializeIssueAttachments(config, command, workspace) {
|
|
|
11955
12053
|
const body = await runtimeApiBuffer(runtimeAuth, contentPath);
|
|
11956
12054
|
writeFileSync9(targetPath, body);
|
|
11957
12055
|
const attachmentId = readString(attachment.id);
|
|
11958
|
-
const actualSha256 =
|
|
12056
|
+
const actualSha256 = createHash11("sha256").update(body).digest("hex");
|
|
11959
12057
|
const lineageCandidates = lineageCandidatesByAttachmentId.get(attachmentId) ?? [];
|
|
11960
12058
|
const lineage = selectAttachmentLineage(lineageCandidates, actualSha256);
|
|
11961
12059
|
if (lineageCandidates.length > 0 && !lineage) {
|
|
@@ -12047,7 +12145,7 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
12047
12145
|
throw new Error(`artifact_input_manifest_invalid: entry ${index} contentPath does not match attachmentId`);
|
|
12048
12146
|
}
|
|
12049
12147
|
const body = await runtimeApiBuffer(runtimeAuth, contentPath);
|
|
12050
|
-
const actualSha256 =
|
|
12148
|
+
const actualSha256 = createHash11("sha256").update(body).digest("hex");
|
|
12051
12149
|
if (body.byteLength !== byteSize || actualSha256 !== sha256) {
|
|
12052
12150
|
throw new Error(
|
|
12053
12151
|
`artifact_input_integrity_mismatch: workProductId=${workProductId} expectedBytes=${byteSize} actualBytes=${body.byteLength} expectedSha256=${sha256} actualSha256=${actualSha256}`
|
|
@@ -12117,7 +12215,7 @@ function safeCheckpointRelativePath(rawPath) {
|
|
|
12117
12215
|
return normalized;
|
|
12118
12216
|
}
|
|
12119
12217
|
function hashFileSha256(filePath) {
|
|
12120
|
-
return
|
|
12218
|
+
return createHash11("sha256").update(readFileSync11(filePath)).digest("hex");
|
|
12121
12219
|
}
|
|
12122
12220
|
async function materializeIssueCheckpoint(config, command, workspace) {
|
|
12123
12221
|
const checkpointDir = issueCheckpointDir(workspace);
|
|
@@ -12330,6 +12428,7 @@ async function executeRunCommand(config, command) {
|
|
|
12330
12428
|
};
|
|
12331
12429
|
let completionOwnsManagedMcpProfile = false;
|
|
12332
12430
|
const sourceAcquisition = sourceAcquisitionRuntimeProfile(config, command);
|
|
12431
|
+
const sourceProfile = serializeSourceAcquisitionProfile(sourceAcquisition?.profile ?? null);
|
|
12333
12432
|
const trustedPiRuntimeAssertion = commandTrustedPiRuntimeAssertion(command);
|
|
12334
12433
|
assertSourceAcquisitionRuntimeAuthority({
|
|
12335
12434
|
profile: sourceAcquisition,
|
|
@@ -12457,6 +12556,13 @@ async function executeRunCommand(config, command) {
|
|
|
12457
12556
|
inheritedEntries: trustedPiRuntimeProfile.facts.inheritedEntries
|
|
12458
12557
|
});
|
|
12459
12558
|
}
|
|
12559
|
+
if (sourceProfile) {
|
|
12560
|
+
executorEnv = {
|
|
12561
|
+
...executorEnv,
|
|
12562
|
+
AMASTER_SOURCE_ACQUISITION_PROFILE_FD: "4",
|
|
12563
|
+
AMASTER_SOURCE_ACQUISITION_PROFILE_SHA256: sourceProfile.sha256
|
|
12564
|
+
};
|
|
12565
|
+
}
|
|
12460
12566
|
if (executor.kind === "pi" && piResolvedProviderConfig) {
|
|
12461
12567
|
const agentDir = managedMcpProfile ? readString(managedMcpProfile.env.PI_CODING_AGENT_DIR) ?? readString(managedMcpProfile.env.PI_AGENT_HOME) ?? null : piAgentLocalPlatformRunnerEnabled(config) ? readString(executorEnv.PI_AGENT_HOME) ?? readString(executorEnv.PI_CODING_AGENT_DIR) ?? null : readString(executorEnv.PI_CODING_AGENT_DIR) ?? readString(executorEnv.PI_AGENT_HOME) ?? null;
|
|
12462
12568
|
try {
|
|
@@ -12591,6 +12697,7 @@ async function executeRunCommand(config, command) {
|
|
|
12591
12697
|
managedInput: `${JSON.stringify(trustedPiRuntimeAssertion)}
|
|
12592
12698
|
`
|
|
12593
12699
|
} : {},
|
|
12700
|
+
...sourceProfile ? { sourceProfileInput: sourceProfile.input } : {},
|
|
12594
12701
|
onOutput: (stream, chunk, rawBytes) => {
|
|
12595
12702
|
noteActiveRunOutput(command, stream, chunk, rawBytes);
|
|
12596
12703
|
liveOutputLogger.write(stream, chunk);
|
|
@@ -12759,7 +12866,10 @@ async function executeRunCommand(config, command) {
|
|
|
12759
12866
|
const memoryLimitError = hasMemoryLimit ? `${executor.kind === "pi" ? "Pi Agent" : "Executor"} memory limit exceeded: RSS ${readNumber(memoryLimit.rssBytes, 0)} bytes exceeded ${readNumber(memoryLimit.limitBytes, config.executorMaxRssMb * 1024 * 1024)} bytes` : null;
|
|
12760
12867
|
const piUsageDiagnostic = executor.kind === "pi" && !hasOutputFlood && piOutputUsageMetadataMissing(parsed) ? "Pi Agent exited without usage metadata" : null;
|
|
12761
12868
|
const completionOutputStopped = executor.kind === "pi" && piCompletionOutputStopped(parsed, execution);
|
|
12762
|
-
const cleanupDisposition = executor.kind === "pi" && !cancelled && !hasOutputFlood && !hasMemoryLimit && execution.timedOut !== true && !execution.spawnError && execution.signal === null ? classifyPiTerminalCleanupDisposition(
|
|
12869
|
+
const cleanupDisposition = executor.kind === "pi" && !cancelled && !hasOutputFlood && !hasMemoryLimit && execution.timedOut !== true && !execution.spawnError && execution.signal === null ? classifyPiTerminalCleanupDisposition(
|
|
12870
|
+
{ ...parsed, mcpToolResults },
|
|
12871
|
+
runtimeArtifacts
|
|
12872
|
+
) : null;
|
|
12763
12873
|
if (cleanupDisposition) {
|
|
12764
12874
|
await ingestLog(
|
|
12765
12875
|
config,
|
|
@@ -12933,7 +13043,8 @@ async function executeRunCommand(config, command) {
|
|
|
12933
13043
|
maxRssMb: config.executorMaxRssMb,
|
|
12934
13044
|
...piChildIsolation ? { spawnIdentity: piChildIsolation.spawn } : {},
|
|
12935
13045
|
...trustedPiRuntime ? { managedInput: `${JSON.stringify(trustedPiRuntimeAssertion)}
|
|
12936
|
-
` } : {}
|
|
13046
|
+
` } : {},
|
|
13047
|
+
...sourceProfile ? { sourceProfileInput: sourceProfile.input } : {}
|
|
12937
13048
|
}
|
|
12938
13049
|
},
|
|
12939
13050
|
completionRequest: {
|
package/dist/amaster-runtime.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { dirname, join, resolve } from "node:path";
|
|
|
5
5
|
import { homedir, hostname } from "node:os";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
|
|
8
|
-
const CONNECTOR_VERSION = "0.1.1-beta.
|
|
8
|
+
const CONNECTOR_VERSION = "0.1.1-beta.1";
|
|
9
9
|
|
|
10
10
|
const CAPABILITIES = [
|
|
11
11
|
"remote_registration",
|