@amaster.ai/employee-runtime-connector 0.1.1-beta.21 → 0.1.1-beta.23
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 +15 -1
- package/dist/amaster-runtime-daemon.mjs +429 -117
- package/dist/amaster-runtime.mjs +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ For production images, install an exact version and invoke the package bin:
|
|
|
13
13
|
```sh
|
|
14
14
|
npm install --omit=dev --prefix /opt/pi-cli-runtime @amaster.ai/employee-runtime-connector@0.1.0
|
|
15
15
|
/opt/pi-cli-runtime/node_modules/.bin/amaster-runtime setup https://employee.example.com \
|
|
16
|
-
--capabilities remote_registration,heartbeat,executor_discovery,workspace_binding,run_wakeup,model_call,run_cancel,run_terminate,logs_cost_workspace_status
|
|
16
|
+
--capabilities remote_registration,heartbeat,executor_discovery,workspace_binding,run_wakeup,model_call,model_call_output_contract_v1,run_cancel,run_terminate,logs_cost_workspace_status
|
|
17
17
|
/opt/pi-cli-runtime/node_modules/.bin/amaster-runtime daemon start --foreground
|
|
18
18
|
```
|
|
19
19
|
|
|
@@ -32,6 +32,20 @@ The source of truth lives under this package's `src/` directory. The package bui
|
|
|
32
32
|
|
|
33
33
|
Runtime code belongs in the container image. Persist only connector state, the result outbox, and workspaces under the configured state directory.
|
|
34
34
|
|
|
35
|
+
## Contracted Pi model calls
|
|
36
|
+
|
|
37
|
+
Pi `model_call` commands with `model_call_output_contract_v1` keep provider and
|
|
38
|
+
model selection paired with the output ceiling. Command target fields have the
|
|
39
|
+
highest precedence, followed by `AMASTER_PI_PROVIDER` / `AMASTER_PI_MODEL`, then
|
|
40
|
+
the Pi profile's `defaultProvider` / `defaultModel`. Each selected precedence
|
|
41
|
+
layer must be a complete provider/model pair: a partial command or runtime
|
|
42
|
+
override fails closed instead of silently falling through to a lower-precedence
|
|
43
|
+
default. The daemon copies only the normalized default pair into the isolated
|
|
44
|
+
one-shot profile, validates that the resolved model exists, applies
|
|
45
|
+
`maxOutputTokens` to that exact model, and records the resolved target and source
|
|
46
|
+
in command-result diagnostics. Missing or unknown targets also fail closed
|
|
47
|
+
before Pi is spawned.
|
|
48
|
+
|
|
35
49
|
## Pi tool-argument transport guard
|
|
36
50
|
|
|
37
51
|
`AMASTER_PI_TOOL_ARGUMENT_GUARD_MODE` defaults to `shadow`; supported values are
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// MirrorX runtime connector daemon bundle.
|
|
3
3
|
|
|
4
4
|
// src/amaster-runtime-daemon.mjs
|
|
5
|
-
import { createHash as
|
|
5
|
+
import { createHash as createHash15 } from "node:crypto";
|
|
6
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 statSync8, symlinkSync as symlinkSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "node:fs";
|
|
7
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 delimiter3, dirname as dirname9, extname as extname2, isAbsolute as isAbsolute8, join as join15, relative as relative9, resolve as resolve12 } from "node:path";
|
|
@@ -2005,6 +2005,73 @@ function syncAmasterProviderFiles(agentDir, executorEnv) {
|
|
|
2005
2005
|
settingsSynced: syncAmasterProviderSettings(agentDir, executorEnv)
|
|
2006
2006
|
};
|
|
2007
2007
|
}
|
|
2008
|
+
function normalizePiModelId(modelId) {
|
|
2009
|
+
return readString(modelId)?.replace(/:(?:off|minimal|low|medium|high|xhigh|max)$/i, "") ?? null;
|
|
2010
|
+
}
|
|
2011
|
+
function assertPiModelConfigured(agentDir, provider, model) {
|
|
2012
|
+
const modelsPath = join3(agentDir, "models.json");
|
|
2013
|
+
const config = readJsonFile(modelsPath);
|
|
2014
|
+
const providers = asRecord(config.providers);
|
|
2015
|
+
const providerConfig = asRecord(providers[provider]);
|
|
2016
|
+
const configuredModels = Array.isArray(providerConfig.models) ? providerConfig.models : [];
|
|
2017
|
+
const configuredModelExists = configuredModels.some((entry) => readString(asRecord(entry).id) === model);
|
|
2018
|
+
const existingOverrides = asRecord(providerConfig.modelOverrides);
|
|
2019
|
+
if (!configuredModelExists && !(model in existingOverrides)) {
|
|
2020
|
+
throw new Error(`pi_model_call_model_missing: ${provider}/${model}`);
|
|
2021
|
+
}
|
|
2022
|
+
return { modelsPath, config, providers, providerConfig, existingOverrides };
|
|
2023
|
+
}
|
|
2024
|
+
function resolvePiModelCallTarget(agentDir, providerId, modelId, explicitSource = "command") {
|
|
2025
|
+
const explicitProvider = readString(providerId);
|
|
2026
|
+
const explicitModel = normalizePiModelId(modelId);
|
|
2027
|
+
if (Boolean(explicitProvider) !== Boolean(explicitModel)) {
|
|
2028
|
+
throw new Error("pi_model_call_target_partial");
|
|
2029
|
+
}
|
|
2030
|
+
let provider = explicitProvider;
|
|
2031
|
+
let model = explicitModel;
|
|
2032
|
+
let source = explicitSource;
|
|
2033
|
+
if (!provider || !model) {
|
|
2034
|
+
const settings = readJsonFile(join3(agentDir, "settings.json"));
|
|
2035
|
+
const defaultProvider = readString(settings.defaultProvider);
|
|
2036
|
+
const defaultModel = normalizePiModelId(settings.defaultModel);
|
|
2037
|
+
if (Boolean(defaultProvider) !== Boolean(defaultModel)) {
|
|
2038
|
+
throw new Error("pi_model_call_default_partial");
|
|
2039
|
+
}
|
|
2040
|
+
if (!defaultProvider || !defaultModel) {
|
|
2041
|
+
throw new Error("pi_model_call_default_missing");
|
|
2042
|
+
}
|
|
2043
|
+
provider = defaultProvider;
|
|
2044
|
+
model = defaultModel;
|
|
2045
|
+
source = "pi_settings_default";
|
|
2046
|
+
}
|
|
2047
|
+
assertPiModelConfigured(agentDir, provider, model);
|
|
2048
|
+
return { provider, model, source };
|
|
2049
|
+
}
|
|
2050
|
+
function applyModelCallOutputContract(agentDir, providerId, modelId, maxOutputTokens) {
|
|
2051
|
+
const provider = readString(providerId);
|
|
2052
|
+
const model = normalizePiModelId(modelId);
|
|
2053
|
+
const tokenLimit = Number(maxOutputTokens);
|
|
2054
|
+
if (!provider || !model || !Number.isSafeInteger(tokenLimit) || tokenLimit <= 0) {
|
|
2055
|
+
throw new Error("pi_model_call_output_contract_invalid");
|
|
2056
|
+
}
|
|
2057
|
+
const { modelsPath, config, providers, providerConfig, existingOverrides } = assertPiModelConfigured(agentDir, provider, model);
|
|
2058
|
+
writeJsonFileAtomic(modelsPath, {
|
|
2059
|
+
...config,
|
|
2060
|
+
providers: {
|
|
2061
|
+
...providers,
|
|
2062
|
+
[provider]: {
|
|
2063
|
+
...providerConfig,
|
|
2064
|
+
modelOverrides: {
|
|
2065
|
+
...existingOverrides,
|
|
2066
|
+
[model]: {
|
|
2067
|
+
...asRecord(existingOverrides[model]),
|
|
2068
|
+
maxTokens: tokenLimit
|
|
2069
|
+
}
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
});
|
|
2074
|
+
}
|
|
2008
2075
|
|
|
2009
2076
|
// src/amaster-runtime-daemon/pi-mcp-args-normalizer.mjs
|
|
2010
2077
|
function isJsonObject(value) {
|
|
@@ -2734,11 +2801,11 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
2734
2801
|
if (!Number.isFinite(value)) throw new Error("pi_managed_mcp_attestation_failed: invalid attestation clock");
|
|
2735
2802
|
return value;
|
|
2736
2803
|
}
|
|
2737
|
-
function
|
|
2804
|
+
function sha2562(value) {
|
|
2738
2805
|
return createHash3("sha256").update(value).digest("hex");
|
|
2739
2806
|
}
|
|
2740
2807
|
function adapterServerConfigHash(definition) {
|
|
2741
|
-
return
|
|
2808
|
+
return sha2562(stablePiJson({
|
|
2742
2809
|
command: definition.command,
|
|
2743
2810
|
args: definition.args,
|
|
2744
2811
|
env: definition.env,
|
|
@@ -3278,17 +3345,17 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
3278
3345
|
if (receipt.status !== "attested" || receipt.mode !== "probe" || receipt.proxyMode !== input.proxyMode || receipt.proxyPresent !== expectedProxyPresent || receipt.effectiveSetHash !== input.effectiveSetHash || receipt.attestorSourceSha256 !== input.attestorSourceSha256 || receipt.configSha256 !== input.configSha256 || receipt.cacheSha256 !== input.cacheSha256) {
|
|
3279
3346
|
throw new Error("pi_managed_mcp_effective_tools_failed: probe receipt mismatch");
|
|
3280
3347
|
}
|
|
3281
|
-
if (
|
|
3348
|
+
if (sha2562(readFileSync3(input.configPath)) !== input.configSha256) {
|
|
3282
3349
|
throw new Error("pi_managed_mcp_effective_tools_failed: config drifted during probe");
|
|
3283
3350
|
}
|
|
3284
|
-
if (
|
|
3351
|
+
if (sha2562(readFileSync3(input.cachePath)) !== input.cacheSha256) {
|
|
3285
3352
|
throw new Error("pi_managed_mcp_effective_tools_failed: cache drifted during probe");
|
|
3286
3353
|
}
|
|
3287
3354
|
return {
|
|
3288
3355
|
effectiveToolProxyMode: receipt.proxyMode,
|
|
3289
3356
|
effectiveToolProxyPresent: receipt.proxyPresent,
|
|
3290
3357
|
effectiveToolSetHash: receipt.effectiveSetHash,
|
|
3291
|
-
effectiveToolProbeDigest:
|
|
3358
|
+
effectiveToolProbeDigest: sha2562(stablePiJson(receipt)),
|
|
3292
3359
|
effectiveToolProbeAt: receipt.attestedAt,
|
|
3293
3360
|
effectiveToolBindings: receipt.effectiveToolBindings
|
|
3294
3361
|
};
|
|
@@ -3370,8 +3437,8 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
3370
3437
|
};
|
|
3371
3438
|
writePrivateFile2(cachePath, `${JSON.stringify(cache, null, 2)}
|
|
3372
3439
|
`);
|
|
3373
|
-
const cacheSha256 =
|
|
3374
|
-
const attestorSourceSha256 =
|
|
3440
|
+
const cacheSha256 = sha2562(readFileSync3(cachePath));
|
|
3441
|
+
const attestorSourceSha256 = sha2562(managedPiEffectiveToolsAttestorExtensionSource());
|
|
3375
3442
|
const manifestPath = join4(piCodingAgentDir, "effective-tools-manifest.json");
|
|
3376
3443
|
const receiptPath = join4(tmp, "effective-tools-receipt.json");
|
|
3377
3444
|
const manifest = {
|
|
@@ -3389,7 +3456,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
3389
3456
|
}))),
|
|
3390
3457
|
proxyMode: mcpToolMode === MANAGED_PI_HYBRID_MCP_TOOL_MODE ? "required" : "forbidden",
|
|
3391
3458
|
attestorSourceSha256,
|
|
3392
|
-
configSha256:
|
|
3459
|
+
configSha256: sha2562(readFileSync3(configPath)),
|
|
3393
3460
|
cacheSha256
|
|
3394
3461
|
};
|
|
3395
3462
|
writePrivateFile2(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
@@ -3400,7 +3467,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
3400
3467
|
receiptPath,
|
|
3401
3468
|
cacheSha256,
|
|
3402
3469
|
configPath,
|
|
3403
|
-
configSha256:
|
|
3470
|
+
configSha256: sha2562(readFileSync3(configPath)),
|
|
3404
3471
|
attestorSourceSha256,
|
|
3405
3472
|
effectiveSetHash: manifest.effectiveSetHash,
|
|
3406
3473
|
proxyMode: manifest.proxyMode
|
|
@@ -3563,7 +3630,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
3563
3630
|
sessionId: gateway.sessionId,
|
|
3564
3631
|
sourcePiHome,
|
|
3565
3632
|
piCodingAgentDir,
|
|
3566
|
-
configSha256:
|
|
3633
|
+
configSha256: sha2562(readFileSync3(configPath))
|
|
3567
3634
|
};
|
|
3568
3635
|
return {
|
|
3569
3636
|
profileRoot,
|
|
@@ -4364,24 +4431,6 @@ function continuationText(context) {
|
|
|
4364
4431
|
if (!body) return "";
|
|
4365
4432
|
return [readString(summary.title), body].filter(Boolean).join("\n");
|
|
4366
4433
|
}
|
|
4367
|
-
function onDemandRefs(input) {
|
|
4368
|
-
const context = asRecord(input.context);
|
|
4369
|
-
const issue = asRecord(context.paperclipIssue);
|
|
4370
|
-
const wake = asRecord(context.paperclipWake);
|
|
4371
|
-
const refs = [
|
|
4372
|
-
readString(issue.id) ? `issue:${readString(issue.id)}` : null,
|
|
4373
|
-
...commentRefs(context).map((id) => `comment:${id}`),
|
|
4374
|
-
...(Array.isArray(context.childIssueSummaries) ? context.childIssueSummaries : []).map((entry) => readString(asRecord(entry).id)).filter(Boolean).map((id) => `child_issue:${id}`),
|
|
4375
|
-
...(Array.isArray(wake.workProducts) ? wake.workProducts : []).map((entry) => readString(asRecord(entry).id)).filter(Boolean).map((id) => `work_product:${id}`)
|
|
4376
|
-
];
|
|
4377
|
-
const unique = [...new Set(refs.filter(Boolean))];
|
|
4378
|
-
if (unique.length === 0) return "";
|
|
4379
|
-
return [
|
|
4380
|
-
"Large context objects are intentionally omitted from this prompt.",
|
|
4381
|
-
"Use managed typed read tools when more detail is required; preserve returned source and freshness metadata.",
|
|
4382
|
-
...unique.map((ref) => `- ${ref}`)
|
|
4383
|
-
].join("\n");
|
|
4384
|
-
}
|
|
4385
4434
|
function governedReadSection(context) {
|
|
4386
4435
|
const reads = Array.isArray(context.governedReadResults) ? context.governedReadResults : [];
|
|
4387
4436
|
if (reads.length === 0) return { content: "", provenance: [] };
|
|
@@ -4791,6 +4840,7 @@ function fixedRules(input, includeIssueLine) {
|
|
|
4791
4840
|
"Before changing the task status to done, audit every explicit requirement in the task against the final evidence. A successful tool or document write proves delivery, not acceptance: inspect the delivered content for required sections, diagrams, tables, and factual constraints.",
|
|
4792
4841
|
"Do not leave stale in-progress wording such as \u201Ccurrent run\u201D in a terminal deliverable; rewrite it to the final observed state. Do not list finalization itself as remaining or next work in a terminal deliverable.",
|
|
4793
4842
|
serverOwnedBusinessOutcomeReview ? "If any requirement is missing or cannot be verified, do not mark done or request final completion or Business Outcome review. Keep the issue in_progress with the exact gap and next owner. An intermediate review remains available only for an exact document revision that must be approved before execution can continue: use create_interaction with kind request_confirmation, payload.resolutionMode review, and purposeCode review_document_revision; never use that interaction as final completion or Outcome acceptance." : "If anything is missing, do not mark done. `update_parent` cannot write `in_review` or `blocked`. Human review: create_interaction kind request_confirmation with payload.resolutionMode review. Required platform/provider/external action needs a typed interaction or first-class blocker; otherwise keep todo with the gap and owner.",
|
|
4843
|
+
"A create_interaction result with status=pending or mustEndRun=true establishes human attention and is the final mutation of this run. End the run immediately: do not publish a Delivery Manifest, update a document or task, or submit any other mutation. Continue only in the new run created after the interaction is resolved.",
|
|
4794
4844
|
DEADLINE_POSTURE_GUARD,
|
|
4795
4845
|
"Do not install operating-system or user-global packages, and do not use host package managers such as brew, apt, yum, or global pip/npm installs. Use tools already available or workspace-local dependencies or virtual environments. If a required renderer or evaluator is unavailable, keep the source artifact, record the exact verification gap, and do not mutate the host.",
|
|
4796
4846
|
`- command id: ${input.commandId}`,
|
|
@@ -5127,30 +5177,26 @@ function overflowDependencyRefsText(overflowRefs) {
|
|
|
5127
5177
|
...overflowRefs.map((ref) => `- issue ${JSON.stringify(ref.selector)}, key ${JSON.stringify(ref.key)}`)
|
|
5128
5178
|
].join("\n");
|
|
5129
5179
|
}
|
|
5130
|
-
function taskCommentRefGuidance(input) {
|
|
5180
|
+
function taskCommentRefGuidance(input, taskText) {
|
|
5131
5181
|
if (!input.hasGovernedMcp || !readString(input.issueId)) return "";
|
|
5182
|
+
if (!/\[comment body (?:omitted|truncated)[^\]]*comment:[^\s\]]+\]/i.test(taskText)) return "";
|
|
5132
5183
|
const call = readIssueEvidenceCommentCallText(input.issueId, "<id>", input);
|
|
5133
5184
|
return `References like comment:<id> above mark truncated comment bodies. Fetch the full text before relying on them \u2014 ${call} (replace <id> with the referenced comment id).`;
|
|
5134
5185
|
}
|
|
5135
|
-
function
|
|
5186
|
+
function piMcpUsageText(input) {
|
|
5136
5187
|
if (!input.hasGovernedMcp || input.executorKind !== "pi" || !managedPiMcpProxyAvailable(input) || isRecoveryWakeReason(input.wakeReason)) return "";
|
|
5137
|
-
const hybrid = input.managedMcpToolMode === "hybrid";
|
|
5138
5188
|
const proxy = (tool, args) => JSON.stringify({
|
|
5139
5189
|
server: "amaster",
|
|
5140
5190
|
tool,
|
|
5141
5191
|
args: JSON.stringify(args)
|
|
5142
5192
|
});
|
|
5143
5193
|
return [
|
|
5144
|
-
|
|
5194
|
+
"This run uses the outer `mcp` proxy for Governed MCP calls. Emit actual tool calls; `args` is the stringified inner canonical object. Pi validates this string schema before extension hooks, so never send object-valued `args`.",
|
|
5195
|
+
"Before the first write, describe that exact canonical action and use the returned schema; do not infer write arguments from this example.",
|
|
5145
5196
|
"Keep review payload strings short. Reference the exact document key and revision in `target`; do not duplicate the reviewed document body in `prompt` or `detailsMarkdown`.",
|
|
5146
5197
|
"payload.supersedesInteractionId is invalid. provenance.supersedesInteractionId is only for replacing a currently pending governed interaction; after changes_requested or rejected resolution, do not send a supersession id.",
|
|
5147
5198
|
"update_parent.comment creates a separate persistent issue comment. Omit it when add_comment already recorded the message.",
|
|
5148
|
-
|
|
5149
|
-
`- submit: ${proxy("runtime_action.submit", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-progress", action: { type: "update_parent", status: "in_progress" } })}`,
|
|
5150
|
-
`- submit intermediate document review interaction: ${proxy("runtime_action.submit", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-review", action: { type: "create_interaction", kind: "request_confirmation", continuationPolicy: "wake_assignee_on_accept", provenance: { purposeCode: "review_document_revision", requirementRefs: ["acceptance:document_review"], attentionOwner: { kind: "board", id: "board" }, epochKey: "document_revision:22222222-2222-4222-8222-222222222222" }, payload: { version: 1, resolutionMode: "review", prompt: "Review `plan` revision 1.", target: { type: "issue_document", issueId: "11111111-1111-4111-8111-111111111111", documentId: "33333333-3333-4333-8333-333333333333", key: "plan", revisionId: "22222222-2222-4222-8222-222222222222", revisionNumber: 1 } } } })}`,
|
|
5151
|
-
`- plan: ${proxy("runtime_action.plan", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-plan", actions: [{ type: "update_parent", status: "in_progress" }] })}`,
|
|
5152
|
-
`- commit the returned plan revision: ${proxy("runtime_action.commit", { schemaVersion: "runtime-action-v1", planId: "11111111-1111-4111-8111-111111111111", revision: "plan-revision-1" })}`,
|
|
5153
|
-
...!hybrid ? [`- read document: ${proxy("amaster.read_issue_document", { issueId: "AM-123", key: "plan" })}`] : []
|
|
5199
|
+
`- minimal envelope example: ${proxy("runtime_action.describe", { schemaVersion: "runtime-action-v1", actionType: "update_parent" })}`
|
|
5154
5200
|
].join("\n");
|
|
5155
5201
|
}
|
|
5156
5202
|
function piDirectTypedToolsText(input) {
|
|
@@ -5161,9 +5207,8 @@ function piDirectTypedToolsText(input) {
|
|
|
5161
5207
|
return "Direct typed governed tools are unavailable because the run catalog snapshot is empty. Do not guess a proxy or tool name.";
|
|
5162
5208
|
}
|
|
5163
5209
|
return [
|
|
5164
|
-
input.managedMcpToolMode === "hybrid" ? "
|
|
5165
|
-
|
|
5166
|
-
input.managedMcpToolMode === "hybrid" ? "For a canonical tool not listed above, use the single managed `mcp` proxy only after exact describe. Never infer an alias, use REST, or bypass the governed Gateway." : "A tool not listed above is unavailable in this run. Do not infer a namespace or fall back to REST/bare MCP."
|
|
5210
|
+
input.managedMcpToolMode === "hybrid" ? "Use the attested direct typed tools already present in the provider tool definitions with object arguments; do not duplicate them through the `mcp` proxy." : "Use only the attested direct typed tools already present in the provider tool definitions. Call their exact names with object arguments; do not call the `mcp` proxy and do not stringify an inner argument envelope.",
|
|
5211
|
+
input.managedMcpToolMode === "hybrid" ? "For a canonical tool absent from those definitions, first use the direct typed `runtime_action_describe`, then call the single managed `mcp` proxy with stringified inner `args`. Never infer an alias, use REST, or bypass the governed Gateway." : "A tool absent from the provider tool definitions is unavailable in this run. Do not infer a namespace or fall back to REST/bare MCP."
|
|
5167
5212
|
].join("\n");
|
|
5168
5213
|
}
|
|
5169
5214
|
function sectionText(section) {
|
|
@@ -5217,7 +5262,7 @@ var CONTEXT_AVAILABILITY_SECTION_TITLES = Object.freeze({
|
|
|
5217
5262
|
runtime_decomposition_requirement: "Required Task Decomposition",
|
|
5218
5263
|
task_context_authority: "Task Context Authority",
|
|
5219
5264
|
verified_company_context: "Verified Company Context",
|
|
5220
|
-
|
|
5265
|
+
pi_mcp_usage: "Pi Governed MCP Usage",
|
|
5221
5266
|
governed_reads: "Governed External Reads",
|
|
5222
5267
|
optional_task_wiki_context: "Optional Company Wiki Context",
|
|
5223
5268
|
agent_instructions: "Agent Instructions",
|
|
@@ -5249,14 +5294,6 @@ function projectModelContextAvailability(manifestSections) {
|
|
|
5249
5294
|
);
|
|
5250
5295
|
coveredSections.push(...budgetOmissions);
|
|
5251
5296
|
}
|
|
5252
|
-
const rawSnapshot = bySection.get("raw_snapshot");
|
|
5253
|
-
const onDemandRefs2 = bySection.get("on_demand_refs");
|
|
5254
|
-
if (rawSnapshot?.omitted === true && rawSnapshot.truncationReason === "on_demand_large_object" && Number(rawSnapshot.originalChars ?? 0) > 0 && (!onDemandRefs2 || onDemandRefs2.omitted === true)) {
|
|
5255
|
-
lines.push(
|
|
5256
|
-
"Additional raw run context was intentionally not inlined and no managed on-demand reference was provided. Do not assume that omitted details are absent."
|
|
5257
|
-
);
|
|
5258
|
-
coveredSections.push("raw_snapshot");
|
|
5259
|
-
}
|
|
5260
5297
|
return {
|
|
5261
5298
|
content: lines.join("\n"),
|
|
5262
5299
|
coveredSections: [...new Set(coveredSections)]
|
|
@@ -5347,8 +5384,8 @@ function compileCommandPromptWithManifest(input, options = {}) {
|
|
|
5347
5384
|
${resolvedDependencies.details.content}` : ""
|
|
5348
5385
|
].filter(Boolean).join("\n\n") : "";
|
|
5349
5386
|
const piDirectTypedTools = piDirectTypedToolsText(input);
|
|
5350
|
-
const
|
|
5351
|
-
resolvedDependencies.required.content ?
|
|
5387
|
+
const piMcpUsage = [
|
|
5388
|
+
input.managedMcpToolMode === "proxy_only" && !resolvedDependencies.required.content ? piMcpUsageText(input) : "",
|
|
5352
5389
|
piDirectTypedTools
|
|
5353
5390
|
].filter(Boolean).join("\n");
|
|
5354
5391
|
const deliveryReadinessContent = runtimeDeliveryReadinessText(context, input);
|
|
@@ -5358,7 +5395,7 @@ ${resolvedDependencies.details.content}` : ""
|
|
|
5358
5395
|
{ name: "recovery_instruction", title: "Recovery Instruction", priority: 100, sourceRef: `run:${input.runId ?? "unknown"}`, content: completeRecoveryInstruction, truncationReason: completeRecoveryInstruction ? null : "mode_selection" },
|
|
5359
5396
|
{ name: "approval_continuation", title: "Approved Runtime Action Continuation", priority: 99, sourceRef: `run:${input.runId ?? "unknown"}`, content: approvalContinuationText(input), truncationReason: mode === "continuation" ? null : "mode_selection" },
|
|
5360
5397
|
{ name: "wake_comments", title: wakeDeltaTitle, priority: interactionResolution ? 99 : 95, sourceRef: wakeDeltaSourceRefs, originalContent: wakeDeltaOriginal, content: wakeDeltaContent, truncationReason: commentsSelected ? null : "duplicate_task_context" },
|
|
5361
|
-
{ name: "task", title: "Task Context", priority: 90, sourceRef: `issue:${input.issueId ?? "unknown"}`, originalContent: [taskText, taskCommentRefGuidance(input)].filter(Boolean).join("\n"), content: includeTask ? [taskText, taskCommentRefGuidance(input)].filter(Boolean).join("\n") : "", truncationReason: includeTask ? null : "mode_selection" },
|
|
5398
|
+
{ name: "task", title: "Task Context", priority: 90, sourceRef: `issue:${input.issueId ?? "unknown"}`, originalContent: [taskText, taskCommentRefGuidance(input, taskText)].filter(Boolean).join("\n"), content: includeTask ? [taskText, taskCommentRefGuidance(input, taskText)].filter(Boolean).join("\n") : "", truncationReason: includeTask ? null : "mode_selection" },
|
|
5362
5399
|
...governedBusinessState ? [{ name: "governed_business_state", title: "Governed Business State", priority: 99, ...governedBusinessState }] : [],
|
|
5363
5400
|
{ name: "continuation_summary", title: "Continuation Summary", priority: 97, sourceRef: readString(asRecord(context.paperclipContinuationSummary).key) ?? `issue:${input.issueId ?? "unknown"}`, observedAt: readString(asRecord(context.paperclipContinuationSummary).updatedAt), originalContent: continuationSummary, content: mode === "cold" ? "" : continuationSummary, truncationReason: mode === "cold" ? "mode_selection" : null },
|
|
5364
5401
|
...resolvedDependencyContent ? [{
|
|
@@ -5375,18 +5412,18 @@ ${resolvedDependencies.details.content}` : ""
|
|
|
5375
5412
|
{ name: "runtime_decomposition_requirement", title: "Required Task Decomposition", priority: 98, sourceRef: `issue:${input.issueId ?? "unknown"}`, content: runtimeDecompositionRequirementText(context) },
|
|
5376
5413
|
...taskContextAuthority ? [{ name: "task_context_authority", title: "Task Context Authority", priority: 98, ...taskContextAuthority }] : [],
|
|
5377
5414
|
...verifiedCompanyContext.content ? [{ name: "verified_company_context", title: "Verified Company Context", priority: 96, sourceRef: verifiedCompanyContext.sourceRef, observedAt: verifiedCompanyContext.observedAt, freshness: { kind: "run_snapshot" }, content: verifiedCompanyContext.content }] : [],
|
|
5378
|
-
...
|
|
5379
|
-
name: "
|
|
5380
|
-
title:
|
|
5415
|
+
...piMcpUsage ? [{
|
|
5416
|
+
name: "pi_mcp_usage",
|
|
5417
|
+
title: "Pi Governed MCP Usage",
|
|
5381
5418
|
priority: 96,
|
|
5382
5419
|
sourceRef: "amaster_governed_mcp_proxy_contract",
|
|
5383
|
-
content:
|
|
5420
|
+
content: piMcpUsage
|
|
5384
5421
|
}] : [],
|
|
5385
5422
|
{ name: "governed_reads", title: "Governed External Reads", priority: 88, sourceRef: governedReads.provenance.map((entry) => entry.sourceRef), observedAt: governedReads.provenance.map((entry) => entry.observedAt), freshness: governedReads.provenance.map((entry) => entry.freshness), scope: governedReads.provenance.map((entry) => entry.scope), content: governedReads.content },
|
|
5386
5423
|
...optionalTaskWikiContext ? [optionalTaskWikiContext] : [],
|
|
5387
5424
|
{ name: "agent_instructions", title: "Agent Instructions", priority: 100, sourceRef: "agent_instructions_bundle", content: readString(input.agentInstructions) ?? "" },
|
|
5388
5425
|
{ name: "attachments", title: "Materialized Inputs", priority: 80, sourceRef: "materialized_attachments", content: readString(input.attachmentsText) ?? "" },
|
|
5389
|
-
{ name: "on_demand_refs", title: "On-demand Context References", priority: 70, sourceRef: `issue:${input.issueId ?? "unknown"}`, content:
|
|
5426
|
+
{ name: "on_demand_refs", title: "On-demand Context References", priority: 70, sourceRef: `issue:${input.issueId ?? "unknown"}`, content: overflowDependencyRefsText(resolvedDependencies.overflowRefs) },
|
|
5390
5427
|
{ name: "raw_snapshot", title: "Raw Context Snapshot", priority: 0, sourceRef: `run:${input.runId ?? "unknown"}`, originalChars: jsonCharLength(context), content: "", truncationReason: "on_demand_large_object" }
|
|
5391
5428
|
];
|
|
5392
5429
|
const seenContent = /* @__PURE__ */ new Set();
|
|
@@ -5492,10 +5529,7 @@ function renderAgentInstructionsBundle(bundle, delivery) {
|
|
|
5492
5529
|
].join("\n");
|
|
5493
5530
|
}
|
|
5494
5531
|
if (resolvedDelivery.mode === "executor_auto_load") {
|
|
5495
|
-
return
|
|
5496
|
-
materialized,
|
|
5497
|
-
"This executor has already loaded ./AGENTS.md through its project-instruction channel. Follow it for the whole run; do not read it again merely to initialize. Read sibling instruction files only when ./AGENTS.md references them or the current task requires them."
|
|
5498
|
-
].join("\n");
|
|
5532
|
+
return "";
|
|
5499
5533
|
}
|
|
5500
5534
|
return [
|
|
5501
5535
|
materialized,
|
|
@@ -5512,6 +5546,187 @@ function agentInstructionDeliveryAudit(bundle, delivery) {
|
|
|
5512
5546
|
};
|
|
5513
5547
|
}
|
|
5514
5548
|
|
|
5549
|
+
// src/amaster-runtime-daemon/agent-instruction-system-kernel-shadow.mjs
|
|
5550
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
5551
|
+
var SHADOW_VERSION = 1;
|
|
5552
|
+
var TARGET_CHARS = 16e3;
|
|
5553
|
+
var USER_RESPONSE_START = "<user-facing-response>";
|
|
5554
|
+
var USER_RESPONSE_END = "</user-facing-response>";
|
|
5555
|
+
var RUNTIME_HEADING = "# AMaster Runtime Contract";
|
|
5556
|
+
var RUNTIME_KERNEL_SECTIONS = /* @__PURE__ */ new Set([
|
|
5557
|
+
"Narrow recovery and terminalization",
|
|
5558
|
+
"Secrets and Safety",
|
|
5559
|
+
"Execution continuity"
|
|
5560
|
+
]);
|
|
5561
|
+
var ROLE_KERNEL_SECTIONS = /* @__PURE__ */ new Set([
|
|
5562
|
+
"How you think",
|
|
5563
|
+
"What you do",
|
|
5564
|
+
"What you do not do",
|
|
5565
|
+
"When you finish"
|
|
5566
|
+
]);
|
|
5567
|
+
function sha256(value) {
|
|
5568
|
+
return createHash5("sha256").update(value, "utf8").digest("hex");
|
|
5569
|
+
}
|
|
5570
|
+
function normalizedText(value) {
|
|
5571
|
+
return typeof value === "string" ? value.trim() : "";
|
|
5572
|
+
}
|
|
5573
|
+
function sectionAudit(scope, section, disposition) {
|
|
5574
|
+
return {
|
|
5575
|
+
scope,
|
|
5576
|
+
heading: section.heading,
|
|
5577
|
+
disposition,
|
|
5578
|
+
chars: section.content.length,
|
|
5579
|
+
sha256: sha256(section.content)
|
|
5580
|
+
};
|
|
5581
|
+
}
|
|
5582
|
+
function splitH2Sections(content, scope) {
|
|
5583
|
+
const matches = [...content.matchAll(/^## (.+)$/gm)];
|
|
5584
|
+
const sections = [];
|
|
5585
|
+
const preambleEnd = matches[0]?.index ?? content.length;
|
|
5586
|
+
const preamble = content.slice(0, preambleEnd).trim();
|
|
5587
|
+
if (preamble) {
|
|
5588
|
+
sections.push({
|
|
5589
|
+
scope,
|
|
5590
|
+
heading: `${scope}_preamble`,
|
|
5591
|
+
content: preamble
|
|
5592
|
+
});
|
|
5593
|
+
}
|
|
5594
|
+
for (let index = 0; index < matches.length; index += 1) {
|
|
5595
|
+
const match = matches[index];
|
|
5596
|
+
const start = match.index;
|
|
5597
|
+
const end = matches[index + 1]?.index ?? content.length;
|
|
5598
|
+
const sectionContent = content.slice(start, end).trim();
|
|
5599
|
+
if (!sectionContent) continue;
|
|
5600
|
+
sections.push({
|
|
5601
|
+
scope,
|
|
5602
|
+
heading: match[1].trim(),
|
|
5603
|
+
content: sectionContent
|
|
5604
|
+
});
|
|
5605
|
+
}
|
|
5606
|
+
return sections;
|
|
5607
|
+
}
|
|
5608
|
+
function extractUserResponseContract(content) {
|
|
5609
|
+
const start = content.indexOf(USER_RESPONSE_START);
|
|
5610
|
+
if (start === -1) return null;
|
|
5611
|
+
const end = content.indexOf(USER_RESPONSE_END, start);
|
|
5612
|
+
if (end === -1) return null;
|
|
5613
|
+
const contentEnd = end + USER_RESPONSE_END.length;
|
|
5614
|
+
return {
|
|
5615
|
+
start,
|
|
5616
|
+
end: contentEnd,
|
|
5617
|
+
content: content.slice(start, contentEnd).trim()
|
|
5618
|
+
};
|
|
5619
|
+
}
|
|
5620
|
+
function splitManagedLayout(content) {
|
|
5621
|
+
const userResponse = extractUserResponseContract(content);
|
|
5622
|
+
const runtimeStart = content.indexOf(RUNTIME_HEADING);
|
|
5623
|
+
if (!userResponse || runtimeStart === -1 || runtimeStart < userResponse.end) return null;
|
|
5624
|
+
const afterRuntime = content.slice(runtimeStart);
|
|
5625
|
+
const parts = afterRuntime.split(/^---$/gm);
|
|
5626
|
+
if (parts.length < 2) return null;
|
|
5627
|
+
const rolePartIndex = parts.findIndex((part, index) => index > 0 && /^## (?:How you think|What you do|What you do not do|When you finish)$/m.test(part));
|
|
5628
|
+
if (rolePartIndex === -1) return null;
|
|
5629
|
+
const runtime = parts[0].trim();
|
|
5630
|
+
const role = parts.slice(rolePartIndex).join("\n---\n").trim();
|
|
5631
|
+
if (!runtime.startsWith(RUNTIME_HEADING) || !role) return null;
|
|
5632
|
+
return { userResponse: userResponse.content, runtime, role };
|
|
5633
|
+
}
|
|
5634
|
+
function kernelProjection(content) {
|
|
5635
|
+
const layout = splitManagedLayout(content);
|
|
5636
|
+
if (!layout) return null;
|
|
5637
|
+
const selected = [{
|
|
5638
|
+
scope: "response",
|
|
5639
|
+
heading: "User-Facing Response Contract",
|
|
5640
|
+
content: layout.userResponse
|
|
5641
|
+
}];
|
|
5642
|
+
const onDemand = [];
|
|
5643
|
+
for (const section of splitH2Sections(layout.runtime, "runtime")) {
|
|
5644
|
+
if (section.heading === "runtime_preamble" || RUNTIME_KERNEL_SECTIONS.has(section.heading)) {
|
|
5645
|
+
selected.push(section);
|
|
5646
|
+
} else {
|
|
5647
|
+
onDemand.push(section);
|
|
5648
|
+
}
|
|
5649
|
+
}
|
|
5650
|
+
for (const section of splitH2Sections(layout.role, "role")) {
|
|
5651
|
+
if (section.heading === "role_preamble" || ROLE_KERNEL_SECTIONS.has(section.heading)) {
|
|
5652
|
+
selected.push(section);
|
|
5653
|
+
} else {
|
|
5654
|
+
onDemand.push(section);
|
|
5655
|
+
}
|
|
5656
|
+
}
|
|
5657
|
+
return {
|
|
5658
|
+
candidate: selected.map((section) => section.content).join("\n\n---\n\n"),
|
|
5659
|
+
selected,
|
|
5660
|
+
onDemand
|
|
5661
|
+
};
|
|
5662
|
+
}
|
|
5663
|
+
function buildAgentInstructionSystemKernelShadow(bundle) {
|
|
5664
|
+
const bundleMode = normalizedText(bundle?.mode).toLowerCase();
|
|
5665
|
+
const source = normalizedText(bundle?.files?.["AGENTS.md"]);
|
|
5666
|
+
const base = {
|
|
5667
|
+
version: SHADOW_VERSION,
|
|
5668
|
+
mode: "shadow_only",
|
|
5669
|
+
activation: "disabled",
|
|
5670
|
+
targetChars: TARGET_CHARS,
|
|
5671
|
+
bundleMode: bundleMode || "unknown",
|
|
5672
|
+
sourceFile: source ? "AGENTS.md" : null
|
|
5673
|
+
};
|
|
5674
|
+
if (!source) {
|
|
5675
|
+
return {
|
|
5676
|
+
candidate: "",
|
|
5677
|
+
audit: {
|
|
5678
|
+
...base,
|
|
5679
|
+
status: "not_applicable",
|
|
5680
|
+
reason: "agents_entry_not_supplied"
|
|
5681
|
+
}
|
|
5682
|
+
};
|
|
5683
|
+
}
|
|
5684
|
+
if (bundleMode !== "managed") {
|
|
5685
|
+
return {
|
|
5686
|
+
candidate: "",
|
|
5687
|
+
audit: {
|
|
5688
|
+
...base,
|
|
5689
|
+
status: "not_applicable",
|
|
5690
|
+
reason: bundleMode === "external" ? "external_instructions_are_user_owned" : "managed_bundle_not_attested",
|
|
5691
|
+
sourceChars: source.length,
|
|
5692
|
+
sourceSha256: sha256(source)
|
|
5693
|
+
}
|
|
5694
|
+
};
|
|
5695
|
+
}
|
|
5696
|
+
const projection = kernelProjection(source);
|
|
5697
|
+
if (!projection) {
|
|
5698
|
+
return {
|
|
5699
|
+
candidate: "",
|
|
5700
|
+
audit: {
|
|
5701
|
+
...base,
|
|
5702
|
+
status: "unavailable",
|
|
5703
|
+
reason: "managed_layout_not_recognized",
|
|
5704
|
+
sourceChars: source.length,
|
|
5705
|
+
sourceSha256: sha256(source)
|
|
5706
|
+
}
|
|
5707
|
+
};
|
|
5708
|
+
}
|
|
5709
|
+
const candidateChars = projection.candidate.length;
|
|
5710
|
+
const reductionChars = source.length - candidateChars;
|
|
5711
|
+
return {
|
|
5712
|
+
candidate: projection.candidate,
|
|
5713
|
+
audit: {
|
|
5714
|
+
...base,
|
|
5715
|
+
status: "candidate_ready",
|
|
5716
|
+
reason: "managed_sections_classified",
|
|
5717
|
+
sourceChars: source.length,
|
|
5718
|
+
sourceSha256: sha256(source),
|
|
5719
|
+
candidateChars,
|
|
5720
|
+
candidateSha256: sha256(projection.candidate),
|
|
5721
|
+
reductionChars,
|
|
5722
|
+
reductionRatio: source.length > 0 ? Number((reductionChars / source.length).toFixed(4)) : 0,
|
|
5723
|
+
withinTarget: candidateChars <= TARGET_CHARS,
|
|
5724
|
+
selectedSections: projection.selected.map((section) => sectionAudit(section.scope, section, "kernel_candidate")),
|
|
5725
|
+
onDemandSections: projection.onDemand.map((section) => sectionAudit(section.scope, section, "on_demand_candidate"))
|
|
5726
|
+
}
|
|
5727
|
+
};
|
|
5728
|
+
}
|
|
5729
|
+
|
|
5515
5730
|
// src/amaster-runtime-daemon/config-state.mjs
|
|
5516
5731
|
import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync5, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
5517
5732
|
import { homedir as homedir2, hostname } from "node:os";
|
|
@@ -5597,6 +5812,7 @@ var CAPABILITIES = [
|
|
|
5597
5812
|
"run_wakeup",
|
|
5598
5813
|
"runtime_actions_v2",
|
|
5599
5814
|
"model_call",
|
|
5815
|
+
"model_call_output_contract_v1",
|
|
5600
5816
|
"run_cancel",
|
|
5601
5817
|
"run_terminate",
|
|
5602
5818
|
"logs_cost_workspace_status"
|
|
@@ -6434,9 +6650,9 @@ function governedMcpToolResult(structuredContent) {
|
|
|
6434
6650
|
const intentId = readString(effectResult.artifactIntentId);
|
|
6435
6651
|
const manifestId = readString(effectResult.manifestId);
|
|
6436
6652
|
const sourceRelativePath = readString(effectResult.sourceRelativePath);
|
|
6437
|
-
const
|
|
6653
|
+
const sha2562 = readString(effectResult.sha256);
|
|
6438
6654
|
const byteSize = readNumber(effectResult.byteSize, 0);
|
|
6439
|
-
const artifactIntent = providerStatus === "pending_reconcile" && intentId && manifestId && sourceRelativePath && /^[a-f0-9]{64}$/.test(
|
|
6655
|
+
const artifactIntent = providerStatus === "pending_reconcile" && intentId && manifestId && sourceRelativePath && /^[a-f0-9]{64}$/.test(sha2562 ?? "") && Number.isSafeInteger(byteSize) && byteSize > 0 ? { intentId, manifestId, sourceRelativePath, sha256: sha2562, byteSize } : null;
|
|
6440
6656
|
const workspaceDocumentEffect = asRecord(effectResult.workspaceDocumentIntent);
|
|
6441
6657
|
const workspaceDocumentCallId = readString(workspaceDocumentEffect.callId);
|
|
6442
6658
|
const workspaceDocumentManifestId = readString(workspaceDocumentEffect.manifestId);
|
|
@@ -7391,7 +7607,7 @@ var postJsonWithRetry = postRuntimeConnectorJsonWithRetry;
|
|
|
7391
7607
|
var bestEffortPostJson = bestEffortPostRuntimeConnectorJson;
|
|
7392
7608
|
|
|
7393
7609
|
// src/amaster-runtime-daemon/runtime-artifact-upload.mjs
|
|
7394
|
-
import { createHash as
|
|
7610
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
7395
7611
|
import { closeSync, constants, fstatSync, lstatSync as lstatSync3, openSync, readFileSync as readFileSync6, realpathSync as realpathSync3 } from "node:fs";
|
|
7396
7612
|
import { isAbsolute as isAbsolute3, relative as relative3, resolve as resolve3 } from "node:path";
|
|
7397
7613
|
var SHA256_PATTERN = /^[a-f0-9]{64}$/;
|
|
@@ -7481,7 +7697,7 @@ function prepareRuntimeArtifactUploads(cwd, mcpToolResults) {
|
|
|
7481
7697
|
`Runtime Artifact ${intentId}`,
|
|
7482
7698
|
{ expectedByteSize }
|
|
7483
7699
|
);
|
|
7484
|
-
const actualSha256 =
|
|
7700
|
+
const actualSha256 = createHash6("sha256").update(body).digest("hex");
|
|
7485
7701
|
if (body.length !== expectedByteSize || actualSha256 !== expectedSha256) {
|
|
7486
7702
|
throw new Error(`Runtime Artifact ${intentId} bytes do not match the governed ownership manifest`);
|
|
7487
7703
|
}
|
|
@@ -7498,7 +7714,7 @@ function prepareRuntimeArtifactUploads(cwd, mcpToolResults) {
|
|
|
7498
7714
|
}
|
|
7499
7715
|
|
|
7500
7716
|
// src/amaster-runtime-daemon/runtime-document-upload.mjs
|
|
7501
|
-
import { createHash as
|
|
7717
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
7502
7718
|
|
|
7503
7719
|
// src/amaster-runtime-daemon/workspace-sensitive-path.mjs
|
|
7504
7720
|
var SENSITIVE_PATH_SEGMENTS = /* @__PURE__ */ new Set([
|
|
@@ -7573,7 +7789,7 @@ function prepareRuntimeDocumentUploads(cwd, mcpToolResults) {
|
|
|
7573
7789
|
maxByteSize: MAX_WORKSPACE_DOCUMENT_BYTES
|
|
7574
7790
|
}
|
|
7575
7791
|
);
|
|
7576
|
-
const actualSha256 =
|
|
7792
|
+
const actualSha256 = createHash7("sha256").update(body).digest("hex");
|
|
7577
7793
|
if (body.length !== expectedByteSize || actualSha256 !== expectedSha256) {
|
|
7578
7794
|
throw new Error(`Runtime Document ${callId} bytes do not match the governed ownership manifest`);
|
|
7579
7795
|
}
|
|
@@ -7647,9 +7863,9 @@ function createRuntimeArtifactIngestQueue({ ingest, onError }) {
|
|
|
7647
7863
|
let queue = Promise.resolve();
|
|
7648
7864
|
const artifactIdentity = (intent) => {
|
|
7649
7865
|
const sourceRelativePath = readString(asRecord(intent).sourceRelativePath);
|
|
7650
|
-
const
|
|
7866
|
+
const sha2562 = readString(asRecord(intent).sha256);
|
|
7651
7867
|
const byteSize = asRecord(intent).byteSize;
|
|
7652
|
-
return sourceRelativePath &&
|
|
7868
|
+
return sourceRelativePath && sha2562 && Number.isSafeInteger(byteSize) && byteSize > 0 ? `${sourceRelativePath}\0${sha2562}\0${byteSize}` : null;
|
|
7653
7869
|
};
|
|
7654
7870
|
const retainReceipts = (receipts) => {
|
|
7655
7871
|
artifacts.push(...receipts);
|
|
@@ -7699,7 +7915,7 @@ function createRuntimeArtifactIngestQueue({ ingest, onError }) {
|
|
|
7699
7915
|
}
|
|
7700
7916
|
|
|
7701
7917
|
// src/amaster-runtime-daemon/workspace-guard.mjs
|
|
7702
|
-
import { createHash as
|
|
7918
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
7703
7919
|
import { existsSync as existsSync7, mkdirSync as mkdirSync6, realpathSync as realpathSync4, statSync as statSync4 } from "node:fs";
|
|
7704
7920
|
import { basename as basename4, join as join8, isAbsolute as isAbsolute4, relative as relative4, resolve as resolve4 } from "node:path";
|
|
7705
7921
|
|
|
@@ -7825,7 +8041,7 @@ function resolveWorkspaceCwd(config, command) {
|
|
|
7825
8041
|
return cwd;
|
|
7826
8042
|
}
|
|
7827
8043
|
function shortHash(value, length = 12) {
|
|
7828
|
-
return
|
|
8044
|
+
return createHash8("sha256").update(String(value)).digest("hex").slice(0, length);
|
|
7829
8045
|
}
|
|
7830
8046
|
function safeSegment(value, fallback) {
|
|
7831
8047
|
const raw = String(value ?? "").trim();
|
|
@@ -8269,7 +8485,7 @@ function summarizeAmasterRuntimeVersionDrift(input = {}) {
|
|
|
8269
8485
|
}
|
|
8270
8486
|
|
|
8271
8487
|
// src/amaster-runtime-daemon/pi-child-isolation.mjs
|
|
8272
|
-
import { createHash as
|
|
8488
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
8273
8489
|
import {
|
|
8274
8490
|
chmodSync as chmodSync3,
|
|
8275
8491
|
chownSync as chownSync2,
|
|
@@ -8280,7 +8496,7 @@ import {
|
|
|
8280
8496
|
import { resolve as resolve7, sep } from "node:path";
|
|
8281
8497
|
var defaultFs = { chmodSync: chmodSync3, chownSync: chownSync2, lchownSync, lstatSync: lstatSync4, readdirSync: readdirSync6 };
|
|
8282
8498
|
function defaultHashRunId(runId) {
|
|
8283
|
-
return Number.parseInt(
|
|
8499
|
+
return Number.parseInt(createHash9("sha256").update(runId).digest("hex").slice(0, 8), 16);
|
|
8284
8500
|
}
|
|
8285
8501
|
function positiveInteger(value, label) {
|
|
8286
8502
|
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
@@ -8404,7 +8620,7 @@ function preparePiChildIsolation(input) {
|
|
|
8404
8620
|
}
|
|
8405
8621
|
|
|
8406
8622
|
// src/amaster-runtime-daemon/pi-company-memory.mjs
|
|
8407
|
-
import { createHash as
|
|
8623
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
8408
8624
|
import {
|
|
8409
8625
|
chmodSync as chmodSync4,
|
|
8410
8626
|
chownSync as chownSync3,
|
|
@@ -8490,7 +8706,7 @@ function safeCompanyPiHomeSegment(companyId) {
|
|
|
8490
8706
|
const raw = requiredString3(companyId, "companyId");
|
|
8491
8707
|
if (/^[A-Za-z0-9][A-Za-z0-9._-]{0,119}$/.test(raw)) return raw;
|
|
8492
8708
|
const normalized = raw.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^[._-]+|[._-]+$/g, "").slice(0, 80);
|
|
8493
|
-
const hash =
|
|
8709
|
+
const hash = createHash10("sha256").update(raw).digest("hex").slice(0, 12);
|
|
8494
8710
|
return normalized ? `${normalized}-${hash}` : `company-${hash}`;
|
|
8495
8711
|
}
|
|
8496
8712
|
function ensureMemoryRoot(root, fs) {
|
|
@@ -8529,7 +8745,7 @@ function allocateCompanyGid(root, companyId, input, fs) {
|
|
|
8529
8745
|
if (groups[companyId]) return groups[companyId];
|
|
8530
8746
|
const used = new Set(Object.values(groups));
|
|
8531
8747
|
const initialOffset = Number.parseInt(
|
|
8532
|
-
|
|
8748
|
+
createHash10("sha256").update(companyId).digest("hex").slice(0, 12),
|
|
8533
8749
|
16
|
|
8534
8750
|
) % gidSpan;
|
|
8535
8751
|
let gid = null;
|
|
@@ -8631,7 +8847,7 @@ function prepareCompanyPiMemory(input, fs = defaultFs2) {
|
|
|
8631
8847
|
}
|
|
8632
8848
|
|
|
8633
8849
|
// src/amaster-runtime-daemon/pi-trusted-runtime-profile.mjs
|
|
8634
|
-
import { createHash as
|
|
8850
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
8635
8851
|
import {
|
|
8636
8852
|
chmodSync as chmodSync5,
|
|
8637
8853
|
copyFileSync as copyFileSync2,
|
|
@@ -8671,7 +8887,7 @@ function sha256File(path, label) {
|
|
|
8671
8887
|
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
8672
8888
|
throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
|
|
8673
8889
|
}
|
|
8674
|
-
return
|
|
8890
|
+
return createHash11("sha256").update(readFileSync9(path)).digest("hex");
|
|
8675
8891
|
}
|
|
8676
8892
|
function verifyDeclaredFiles(manifest, root, label, ignoredPaths = [], enforceComplete = true) {
|
|
8677
8893
|
if (!Array.isArray(manifest.files) || manifest.files.length === 0) {
|
|
@@ -8939,12 +9155,12 @@ function materializeTrustedPiRuntimeProfile(input) {
|
|
|
8939
9155
|
// bundle skills were enabled. Absent profile => main skills only.
|
|
8940
9156
|
...skillProfile ? {
|
|
8941
9157
|
skillProfile,
|
|
8942
|
-
enabledSkillsDigest:
|
|
9158
|
+
enabledSkillsDigest: createHash11("sha256").update(JSON.stringify(enabledSkills)).digest("hex")
|
|
8943
9159
|
} : {}
|
|
8944
9160
|
};
|
|
8945
9161
|
return {
|
|
8946
9162
|
facts,
|
|
8947
|
-
attestationId:
|
|
9163
|
+
attestationId: createHash11("sha256").update(JSON.stringify(facts)).digest("hex")
|
|
8948
9164
|
};
|
|
8949
9165
|
}
|
|
8950
9166
|
function assertAuditArgsRedacted(value) {
|
|
@@ -9140,7 +9356,7 @@ function verifyTrustedPiRuntimeAssertion(input) {
|
|
|
9140
9356
|
if (hasSourceAssertion) {
|
|
9141
9357
|
const exactTools = Array.isArray(record7(sourceProfile.tools).exactAllowlist) ? record7(sourceProfile.tools).exactAllowlist : [];
|
|
9142
9358
|
const exactActions = Array.isArray(record7(sourceProfile.actions).exactAllowlist) ? record7(sourceProfile.actions).exactAllowlist : [];
|
|
9143
|
-
const profileHash =
|
|
9359
|
+
const profileHash = createHash11("sha256").update(JSON.stringify(sourceProfile)).digest("hex");
|
|
9144
9360
|
if (assertion.unknownToolMode !== "deny" || maxCalls !== 0 || sourceAssertion.profileVersion !== sourceProfile.purpose || sourceAssertion.profileHash !== profileHash || sourceAssertion.retentionVersion !== sourceProfile.retention || JSON.stringify(sourceAssertion.exactTools) !== JSON.stringify(exactTools) || JSON.stringify(sourceAssertion.exactActions) !== JSON.stringify(exactActions) || sourceAssertion.sourceId !== sourceProfile.sourceId || sourceAssertion.sourceRevisionId !== sourceProfile.sourceRevisionId || sourceAssertion.sourceRevision !== sourceProfile.sourceRevision || sourceAssertion.attemptId !== sourceProfile.attemptId || sourceAssertion.epoch !== sourceProfile.epoch) {
|
|
9145
9361
|
throw new Error("pi_trusted_runtime_assertion_binding_mismatch:sourceAcquisition");
|
|
9146
9362
|
}
|
|
@@ -9169,7 +9385,7 @@ function verifyTrustedPiRuntimeAssertion(input) {
|
|
|
9169
9385
|
|
|
9170
9386
|
// src/amaster-runtime-daemon/workspace-status.mjs
|
|
9171
9387
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
9172
|
-
import { createHash as
|
|
9388
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
9173
9389
|
import { existsSync as existsSync12, readdirSync as readdirSync8, readFileSync as readFileSync10, statSync as statSync7 } from "node:fs";
|
|
9174
9390
|
import { basename as basename5, extname, isAbsolute as isAbsolute7, join as join13, relative as relative7, resolve as resolve10 } from "node:path";
|
|
9175
9391
|
var WORKSPACE_RUNTIME_SERVICES_FILENAME = ".amaster-runtime-services.json";
|
|
@@ -9240,7 +9456,7 @@ function sanitizeTrackedChange(line) {
|
|
|
9240
9456
|
return isSafeRelativePath(path) ? line : null;
|
|
9241
9457
|
}
|
|
9242
9458
|
function sha256File2(filePath) {
|
|
9243
|
-
return
|
|
9459
|
+
return createHash12("sha256").update(readFileSync10(filePath)).digest("hex");
|
|
9244
9460
|
}
|
|
9245
9461
|
function artifactHashCacheKey(relativePath, stat) {
|
|
9246
9462
|
return `${relativePath}\0${stat.size}\0${stat.mtimeMs}`;
|
|
@@ -9441,7 +9657,7 @@ function readWorkspaceStatus(cwd, opts = {}) {
|
|
|
9441
9657
|
}
|
|
9442
9658
|
|
|
9443
9659
|
// src/amaster-runtime-daemon/pi-browser-session-adapter.mjs
|
|
9444
|
-
import { createHash as
|
|
9660
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
9445
9661
|
import { spawn, spawnSync as spawnSync5 } from "node:child_process";
|
|
9446
9662
|
import { existsSync as existsSync13 } from "node:fs";
|
|
9447
9663
|
import {
|
|
@@ -9564,7 +9780,7 @@ function fail(code) {
|
|
|
9564
9780
|
throw Object.assign(new Error(code), { code });
|
|
9565
9781
|
}
|
|
9566
9782
|
function profileName(identity2) {
|
|
9567
|
-
return
|
|
9783
|
+
return createHash13("sha256").update(`${identity2.companyId}\0${identity2.bindingId}\0${identity2.localOpaqueRef}`).digest("hex");
|
|
9568
9784
|
}
|
|
9569
9785
|
function expectedMarker(identity2) {
|
|
9570
9786
|
return {
|
|
@@ -9963,7 +10179,7 @@ async function executeBrowserSessionCommand(command, dependencies = {}) {
|
|
|
9963
10179
|
}
|
|
9964
10180
|
|
|
9965
10181
|
// src/amaster-runtime-daemon/source-acquisition-invocation.mjs
|
|
9966
|
-
import { createHash as
|
|
10182
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
9967
10183
|
var SOURCE_ACQUISITION_PUBLIC_TOOLS = Object.freeze([
|
|
9968
10184
|
"source_open",
|
|
9969
10185
|
"source_snapshot",
|
|
@@ -10000,7 +10216,7 @@ function serializeSourceAcquisitionProfile(profile) {
|
|
|
10000
10216
|
const input = Buffer.from(JSON.stringify(profile), "utf8");
|
|
10001
10217
|
return {
|
|
10002
10218
|
input,
|
|
10003
|
-
sha256:
|
|
10219
|
+
sha256: createHash14("sha256").update(input).digest("hex")
|
|
10004
10220
|
};
|
|
10005
10221
|
}
|
|
10006
10222
|
function sourceAcquisitionManagedInputs(options) {
|
|
@@ -10036,7 +10252,7 @@ function assertSourceAcquisitionRuntimeAuthority({
|
|
|
10036
10252
|
}
|
|
10037
10253
|
|
|
10038
10254
|
// src/amaster-runtime-daemon.mjs
|
|
10039
|
-
var CONNECTOR_VERSION = "0.1.1-beta.
|
|
10255
|
+
var CONNECTOR_VERSION = "0.1.1-beta.23";
|
|
10040
10256
|
var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
|
|
10041
10257
|
var SOURCE_ACQUISITION_CAPABILITY = "source_acquisition_v1";
|
|
10042
10258
|
var SOURCE_ACQUISITION_PROFILE_VERSION = "source_acquisition_v1";
|
|
@@ -11370,7 +11586,7 @@ function sourceAcquisitionRuntimeProfile(config, command) {
|
|
|
11370
11586
|
if (!companyId || !bindingId || !/^profile_[a-z0-9]{16,64}$/i.test(localOpaqueRef ?? "")) {
|
|
11371
11587
|
throw new Error("source_acquisition_profile_invalid");
|
|
11372
11588
|
}
|
|
11373
|
-
const profileName2 =
|
|
11589
|
+
const profileName2 = createHash15("sha256").update(`${companyId}\0${bindingId}\0${localOpaqueRef}`).digest("hex");
|
|
11374
11590
|
const stateRoot = resolve12(config.browserSessionStateRoot);
|
|
11375
11591
|
const userDataDir = resolve12(stateRoot, profileName2);
|
|
11376
11592
|
if (!pathWithin2(userDataDir, stateRoot)) throw new Error("source_acquisition_browser_profile_invalid");
|
|
@@ -11541,6 +11757,7 @@ function buildCommandPrompt(command, workspace, materializedAttachments = [], op
|
|
|
11541
11757
|
suppliedFiles: agentInstructionFileNames(agentInstructionsBundle)
|
|
11542
11758
|
});
|
|
11543
11759
|
const agentInstructions = renderAgentInstructionsBundle(agentInstructionsBundle, agentInstructionDelivery);
|
|
11760
|
+
const agentInstructionSystemKernelShadow = buildAgentInstructionSystemKernelShadow(agentInstructionsBundle);
|
|
11544
11761
|
const runtimeAuth = commandRuntimeAuth(command);
|
|
11545
11762
|
const hasGovernedMcp = Object.keys(asRecord(runtimeAuth.governedMcp)).length > 0;
|
|
11546
11763
|
const attachmentsText = materializedAttachments.length > 0 ? [
|
|
@@ -11597,7 +11814,8 @@ function buildCommandPrompt(command, workspace, materializedAttachments = [], op
|
|
|
11597
11814
|
agentInstructionDelivery: agentInstructionDeliveryAudit(
|
|
11598
11815
|
agentInstructionsBundle,
|
|
11599
11816
|
agentInstructionDelivery
|
|
11600
|
-
)
|
|
11817
|
+
),
|
|
11818
|
+
agentInstructionSystemKernelShadow: agentInstructionSystemKernelShadow.audit
|
|
11601
11819
|
}
|
|
11602
11820
|
};
|
|
11603
11821
|
}
|
|
@@ -11668,7 +11886,30 @@ function copyPiModelCallConfig(sourceRoot, targetRoot, fileName, required) {
|
|
|
11668
11886
|
copyFileSync3(source, target);
|
|
11669
11887
|
chmodSync6(target, 384);
|
|
11670
11888
|
}
|
|
11671
|
-
function
|
|
11889
|
+
function copyPiModelCallDefaults(sourceRoot, targetRoot) {
|
|
11890
|
+
const source = join15(sourceRoot, "settings.json");
|
|
11891
|
+
if (!existsSync14(source)) return;
|
|
11892
|
+
const sourceStat = lstatSync7(source);
|
|
11893
|
+
if (!sourceStat.isFile() || sourceStat.isSymbolicLink()) {
|
|
11894
|
+
throw new Error("pi_model_call_profile_unsafe: settings.json");
|
|
11895
|
+
}
|
|
11896
|
+
let settings;
|
|
11897
|
+
try {
|
|
11898
|
+
settings = asRecord(JSON.parse(readFileSync11(source, "utf8")));
|
|
11899
|
+
} catch {
|
|
11900
|
+
throw new Error("pi_model_call_profile_invalid: settings.json");
|
|
11901
|
+
}
|
|
11902
|
+
const defaultProvider = readString(settings.defaultProvider);
|
|
11903
|
+
const defaultModel = normalizePiModelId(settings.defaultModel);
|
|
11904
|
+
const target = join15(targetRoot, "settings.json");
|
|
11905
|
+
writeFileSync9(target, `${JSON.stringify({
|
|
11906
|
+
...defaultProvider ? { defaultProvider } : {},
|
|
11907
|
+
...defaultModel ? { defaultModel } : {}
|
|
11908
|
+
}, null, 2)}
|
|
11909
|
+
`, { mode: 384 });
|
|
11910
|
+
chmodSync6(target, 384);
|
|
11911
|
+
}
|
|
11912
|
+
function preparePiModelCallProfile(commandId, baseEnv, options = {}) {
|
|
11672
11913
|
const sourceRoot = readString(process.env.PI_CODING_AGENT_DIR) ?? readString(process.env.PI_AGENT_HOME) ?? readString(process.env["AMASTER-CLI_CODING_AGENT_DIR"]);
|
|
11673
11914
|
if (!sourceRoot) throw new Error("pi_model_call_profile_missing: source Pi home");
|
|
11674
11915
|
const sourceStat = lstatSync7(sourceRoot);
|
|
@@ -11686,6 +11927,7 @@ function preparePiModelCallProfile(commandId, baseEnv) {
|
|
|
11686
11927
|
try {
|
|
11687
11928
|
copyPiModelCallConfig(sourceRoot, agentDir, "models.json", true);
|
|
11688
11929
|
copyPiModelCallConfig(sourceRoot, agentDir, "auth.json", false);
|
|
11930
|
+
if (options.includeDefaults === true) copyPiModelCallDefaults(sourceRoot, agentDir);
|
|
11689
11931
|
return {
|
|
11690
11932
|
profileRoot,
|
|
11691
11933
|
env: {
|
|
@@ -11721,6 +11963,16 @@ function sanitizePiExtraArgs(value) {
|
|
|
11721
11963
|
function nativeSessionResumeEnabled(session) {
|
|
11722
11964
|
return process.env.AMASTER_RUNTIME_ENABLE_NATIVE_SESSION_RESUME === "true" || readString(session.mode) === "governed_action_approval" && session.required === true;
|
|
11723
11965
|
}
|
|
11966
|
+
function modelCallResponseContract(payload) {
|
|
11967
|
+
if (payload.responseContract === void 0) return null;
|
|
11968
|
+
const contract = asRecord(payload.responseContract);
|
|
11969
|
+
const maxOutputTokens = Number(contract.maxOutputTokens);
|
|
11970
|
+
const maxSemanticBytes = Number(contract.maxSemanticBytes);
|
|
11971
|
+
if (readString(contract.format) !== "json" || readString(contract.thinking) !== "off" || !Number.isSafeInteger(maxOutputTokens) || maxOutputTokens < 1 || maxOutputTokens > 131072 || !Number.isSafeInteger(maxSemanticBytes) || maxSemanticBytes < 1024 || maxSemanticBytes > 256 * 1024) {
|
|
11972
|
+
throw new Error("model_call_response_contract_invalid");
|
|
11973
|
+
}
|
|
11974
|
+
return { format: "json", thinking: "off", maxOutputTokens, maxSemanticBytes };
|
|
11975
|
+
}
|
|
11724
11976
|
function resolveNativeSessionRequest(command, workspace) {
|
|
11725
11977
|
const payload = asRecord(command.payload);
|
|
11726
11978
|
const session = asRecord(payload.nativeSession);
|
|
@@ -11754,17 +12006,22 @@ function resolveNativeSessionRequest(command, workspace) {
|
|
|
11754
12006
|
...enabled && requested && sessionId && requestedCwd && !cwdMatched ? { skippedReason: "native_session_cwd_mismatch" } : {}
|
|
11755
12007
|
};
|
|
11756
12008
|
}
|
|
11757
|
-
function buildExecutorInvocation(executor, command = {}, workspace = null) {
|
|
12009
|
+
function buildExecutorInvocation(executor, command = {}, workspace = null, options = {}) {
|
|
11758
12010
|
const payload = asRecord(command.payload);
|
|
11759
12011
|
if (command.commandType === "model_call") {
|
|
11760
12012
|
if (executor.kind === "pi") {
|
|
11761
12013
|
const args = ["--mode", "json"];
|
|
11762
|
-
const
|
|
11763
|
-
const
|
|
12014
|
+
const responseContract = options.responseContract ?? null;
|
|
12015
|
+
const modelTarget = asRecord(options.modelTarget);
|
|
12016
|
+
const provider = readString(modelTarget.provider) ?? readString(payload.provider) ?? readString(process.env.AMASTER_PI_PROVIDER);
|
|
12017
|
+
const configuredModel = readString(modelTarget.model) ?? readString(payload.model) ?? readString(process.env.AMASTER_PI_MODEL);
|
|
12018
|
+
const model = responseContract ? normalizePiModelId(configuredModel) : configuredModel;
|
|
11764
12019
|
if (provider) args.push("--provider", provider);
|
|
11765
12020
|
if (model) args.push("--model", model);
|
|
12021
|
+
if (responseContract?.thinking) args.push("--thinking", responseContract.thinking);
|
|
11766
12022
|
args.push(...sanitizePiExtraArgs(process.env.AMASTER_PI_EXTRA_ARGS));
|
|
11767
12023
|
args.push("--no-extensions", "--no-skills", "--no-session", "--no-tools");
|
|
12024
|
+
if (responseContract) args.push("--no-context-files");
|
|
11768
12025
|
args.push("-p");
|
|
11769
12026
|
return { command: executor.command, args, stdin: "prompt" };
|
|
11770
12027
|
}
|
|
@@ -11852,7 +12109,7 @@ async function executeModelCallCommand(config, command, signal) {
|
|
|
11852
12109
|
if (!prompt) {
|
|
11853
12110
|
throw new Error("model_call command requires a prompt");
|
|
11854
12111
|
}
|
|
11855
|
-
const
|
|
12112
|
+
const responseContract = modelCallResponseContract(payload);
|
|
11856
12113
|
const timeoutSeconds = Math.max(1, Math.min(
|
|
11857
12114
|
config.executorTimeoutSeconds,
|
|
11858
12115
|
readNumber(payload.timeoutSeconds, Math.min(config.executorTimeoutSeconds, 60))
|
|
@@ -11861,14 +12118,9 @@ async function executeModelCallCommand(config, command, signal) {
|
|
|
11861
12118
|
config.executorMaxOutputBytes,
|
|
11862
12119
|
readNumber(payload.maxOutputBytes, 512 * 1024)
|
|
11863
12120
|
));
|
|
11864
|
-
await ackCommand(config, command, "spawned");
|
|
11865
|
-
await ingestLog(config, command, "system", "info", `Starting ${executor.kind} runtime model call`, {
|
|
11866
|
-
executorKind: executor.kind,
|
|
11867
|
-
args: invocation.args,
|
|
11868
|
-
purpose: readString(payload.purpose) ?? null,
|
|
11869
|
-
promptBytes: Buffer.byteLength(prompt, "utf8")
|
|
11870
|
-
});
|
|
11871
12121
|
let piModelCallProfile = null;
|
|
12122
|
+
let modelTarget = null;
|
|
12123
|
+
let invocation = null;
|
|
11872
12124
|
let execution;
|
|
11873
12125
|
try {
|
|
11874
12126
|
const baseEnv = buildExecutorEnv(config, command, {
|
|
@@ -11876,7 +12128,16 @@ async function executeModelCallCommand(config, command, signal) {
|
|
|
11876
12128
|
cwd: process.cwd(),
|
|
11877
12129
|
sourceWorkspacePath: process.cwd()
|
|
11878
12130
|
});
|
|
11879
|
-
|
|
12131
|
+
const commandProvider = readString(payload.provider);
|
|
12132
|
+
const commandModel = readString(payload.model);
|
|
12133
|
+
const commandTargetRequested = Boolean(commandProvider || commandModel);
|
|
12134
|
+
const envProvider = readString(process.env.AMASTER_PI_PROVIDER);
|
|
12135
|
+
const envModel = readString(process.env.AMASTER_PI_MODEL);
|
|
12136
|
+
const envTargetRequested = Boolean(envProvider || envModel);
|
|
12137
|
+
const configuredTarget = commandTargetRequested ? { provider: commandProvider, model: commandModel, source: "command" } : { provider: envProvider, model: envModel, source: "runtime_env" };
|
|
12138
|
+
piModelCallProfile = executor.kind === "pi" ? preparePiModelCallProfile(command.commandId, baseEnv, {
|
|
12139
|
+
includeDefaults: Boolean(responseContract && !commandTargetRequested && !envTargetRequested)
|
|
12140
|
+
}) : null;
|
|
11880
12141
|
if (piModelCallProfile) {
|
|
11881
12142
|
await syncPiExecutorProviderConfig(
|
|
11882
12143
|
config,
|
|
@@ -11884,7 +12145,29 @@ async function executeModelCallCommand(config, command, signal) {
|
|
|
11884
12145
|
piModelCallProfile.env.PI_CODING_AGENT_DIR,
|
|
11885
12146
|
resolvePiExecutorProviderConfig(config, command, baseEnv)
|
|
11886
12147
|
);
|
|
12148
|
+
if (responseContract) {
|
|
12149
|
+
modelTarget = resolvePiModelCallTarget(
|
|
12150
|
+
piModelCallProfile.env.PI_CODING_AGENT_DIR,
|
|
12151
|
+
configuredTarget.provider,
|
|
12152
|
+
configuredTarget.model,
|
|
12153
|
+
configuredTarget.source
|
|
12154
|
+
);
|
|
12155
|
+
applyModelCallOutputContract(
|
|
12156
|
+
piModelCallProfile.env.PI_CODING_AGENT_DIR,
|
|
12157
|
+
modelTarget.provider,
|
|
12158
|
+
modelTarget.model,
|
|
12159
|
+
responseContract.maxOutputTokens
|
|
12160
|
+
);
|
|
12161
|
+
}
|
|
11887
12162
|
}
|
|
12163
|
+
invocation = buildExecutorInvocation(executor, command, null, { responseContract, modelTarget });
|
|
12164
|
+
await ackCommand(config, command, "spawned");
|
|
12165
|
+
await ingestLog(config, command, "system", "info", `Starting ${executor.kind} runtime model call`, {
|
|
12166
|
+
executorKind: executor.kind,
|
|
12167
|
+
args: invocation.args,
|
|
12168
|
+
purpose: readString(payload.purpose) ?? null,
|
|
12169
|
+
promptBytes: Buffer.byteLength(prompt, "utf8")
|
|
12170
|
+
});
|
|
11888
12171
|
execution = await runExecutor(invocation.command, invocation.args, {
|
|
11889
12172
|
cwd: process.cwd(),
|
|
11890
12173
|
env: piModelCallProfile?.env ?? baseEnv,
|
|
@@ -11907,9 +12190,13 @@ async function executeModelCallCommand(config, command, signal) {
|
|
|
11907
12190
|
const hasOutputFlood = Boolean(readString(outputFlood.stream) && readNumber(outputFlood.bytes, 0) > 0);
|
|
11908
12191
|
const timedOut = execution.timedOut === true;
|
|
11909
12192
|
const parsed = hasOutputFlood ? { summary: "", usage: null, errorMessage: null, messages: [] } : executor.kind === "pi" ? parsePiJsonl(execution.stdout) : parseGenericOutput(execution.stdout, execution.stderr);
|
|
11910
|
-
const
|
|
11911
|
-
const
|
|
11912
|
-
const
|
|
12193
|
+
const rawSummary = parsed.summary || parsed.finalMessage || parsed.messages?.join("\n\n") || "";
|
|
12194
|
+
const semanticBytes = Buffer.byteLength(rawSummary, "utf8");
|
|
12195
|
+
const semanticOutputExceeded = Boolean(responseContract && semanticBytes > responseContract.maxSemanticBytes);
|
|
12196
|
+
const summary = semanticOutputExceeded ? "" : responseContract ? rawSummary : truncateText(rawSummary, 8e3);
|
|
12197
|
+
const hasTerminalCompletion = !responseContract || executor.kind !== "pi" || Boolean(parsed.terminalEventType);
|
|
12198
|
+
const succeeded = !hasOutputFlood && !timedOut && !semanticOutputExceeded && !execution.spawnError && execution.exitCode === 0 && hasTerminalCompletion && !parsed.errorMessage && Boolean(summary);
|
|
12199
|
+
const error = timedOut ? `Runtime model call timed out after ${timeoutSeconds}s` : execution.spawnError ?? parsed.errorMessage ?? (hasOutputFlood ? `Runtime model call output flood: ${readString(outputFlood.stream)} exceeded ${readNumber(outputFlood.limitBytes, 0)} bytes` : semanticOutputExceeded ? `Runtime model call semantic output exceeded ${responseContract.maxSemanticBytes} bytes` : !hasTerminalCompletion ? "Runtime model call exited without a terminal provider response" : succeeded ? null : `Runtime model call exited with code ${execution.exitCode ?? "unknown"}`);
|
|
11913
12200
|
await completeCommand(config, command, succeeded ? "succeeded" : "failed", {
|
|
11914
12201
|
callType: "model_call",
|
|
11915
12202
|
executorKind: executor.kind,
|
|
@@ -11920,7 +12207,26 @@ async function executeModelCallCommand(config, command, signal) {
|
|
|
11920
12207
|
timedOut,
|
|
11921
12208
|
summary,
|
|
11922
12209
|
usage: parsed.usage,
|
|
11923
|
-
|
|
12210
|
+
...responseContract ? {
|
|
12211
|
+
driver: "pi_cli_json_v1",
|
|
12212
|
+
responseContract,
|
|
12213
|
+
...modelTarget ? {
|
|
12214
|
+
provider: modelTarget.provider,
|
|
12215
|
+
model: modelTarget.model,
|
|
12216
|
+
modelTargetSource: modelTarget.source
|
|
12217
|
+
} : {},
|
|
12218
|
+
stopReason: parsed.stopReason ?? null,
|
|
12219
|
+
terminalEventType: parsed.terminalEventType ?? null,
|
|
12220
|
+
semanticBytes,
|
|
12221
|
+
outputBytes: Object.values(execution.outputBytes).reduce((total, bytes) => total + bytes, 0),
|
|
12222
|
+
outputBytesByStream: execution.outputBytes,
|
|
12223
|
+
retainedOutputBytes: Object.values(execution.retainedOutputBytes).reduce((total, bytes) => total + bytes, 0),
|
|
12224
|
+
retainedOutputBytesByStream: execution.retainedOutputBytes
|
|
12225
|
+
} : {},
|
|
12226
|
+
// Contracted model calls persist semantic output and metadata only. Pi's
|
|
12227
|
+
// JSONL stdout may contain provider reasoning/event content, so retaining
|
|
12228
|
+
// even a bounded tail would violate the response-contract data boundary.
|
|
12229
|
+
stdout: responseContract ? "" : truncateText(execution.stdout, 8e3),
|
|
11924
12230
|
stderr: truncateText(filterExecutionStderrForResult(executor.kind, execution.stderr), 8e3),
|
|
11925
12231
|
...hasOutputFlood ? {
|
|
11926
12232
|
errorCode: "model_call_output_flood",
|
|
@@ -11930,6 +12236,12 @@ async function executeModelCallCommand(config, command, signal) {
|
|
|
11930
12236
|
bytes: readNumber(outputFlood.bytes, 0),
|
|
11931
12237
|
limitBytes: readNumber(outputFlood.limitBytes, maxOutputBytes)
|
|
11932
12238
|
}
|
|
12239
|
+
} : semanticOutputExceeded ? {
|
|
12240
|
+
errorCode: "model_call_semantic_output_exceeded",
|
|
12241
|
+
errorFamily: "validation"
|
|
12242
|
+
} : responseContract && !hasTerminalCompletion ? {
|
|
12243
|
+
errorCode: "model_call_terminal_event_missing",
|
|
12244
|
+
errorFamily: "provider_protocol"
|
|
11933
12245
|
} : {}
|
|
11934
12246
|
}, error ?? void 0);
|
|
11935
12247
|
}
|
|
@@ -14202,7 +14514,7 @@ async function materializeIssueAttachments(config, command, workspace) {
|
|
|
14202
14514
|
const body = await runtimeApiBuffer(runtimeAuth, contentPath);
|
|
14203
14515
|
writeFileSync9(targetPath, body);
|
|
14204
14516
|
const attachmentId = readString(attachment.id);
|
|
14205
|
-
const actualSha256 =
|
|
14517
|
+
const actualSha256 = createHash15("sha256").update(body).digest("hex");
|
|
14206
14518
|
const lineageCandidates = lineageCandidatesByAttachmentId.get(attachmentId) ?? [];
|
|
14207
14519
|
const lineage = selectAttachmentLineage(lineageCandidates, actualSha256);
|
|
14208
14520
|
if (lineageCandidates.length > 0 && !lineage) {
|
|
@@ -14283,10 +14595,10 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
14283
14595
|
const entry = asRecord(rawEntry);
|
|
14284
14596
|
const workProductId = readString(entry.workProductId);
|
|
14285
14597
|
const attachmentId = readString(entry.attachmentId);
|
|
14286
|
-
const
|
|
14598
|
+
const sha2562 = readString(entry.sha256);
|
|
14287
14599
|
const contentPath = readString(entry.contentPath);
|
|
14288
14600
|
const byteSize = readNumber(entry.byteSize, null);
|
|
14289
|
-
if (!workProductId || !attachmentId || !/^[a-f0-9]{64}$/i.test(
|
|
14601
|
+
if (!workProductId || !attachmentId || !/^[a-f0-9]{64}$/i.test(sha2562 ?? "") || !contentPath || byteSize === null) {
|
|
14290
14602
|
throw new Error(`artifact_input_manifest_invalid: entry ${index} is incomplete`);
|
|
14291
14603
|
}
|
|
14292
14604
|
const expectedContentPath = `/api/attachments/${attachmentId}/content`;
|
|
@@ -14294,10 +14606,10 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
14294
14606
|
throw new Error(`artifact_input_manifest_invalid: entry ${index} contentPath does not match attachmentId`);
|
|
14295
14607
|
}
|
|
14296
14608
|
const body = await runtimeApiBuffer(runtimeAuth, contentPath);
|
|
14297
|
-
const actualSha256 =
|
|
14298
|
-
if (body.byteLength !== byteSize || actualSha256 !==
|
|
14609
|
+
const actualSha256 = createHash15("sha256").update(body).digest("hex");
|
|
14610
|
+
if (body.byteLength !== byteSize || actualSha256 !== sha2562) {
|
|
14299
14611
|
throw new Error(
|
|
14300
|
-
`artifact_input_integrity_mismatch: workProductId=${workProductId} expectedBytes=${byteSize} actualBytes=${body.byteLength} expectedSha256=${
|
|
14612
|
+
`artifact_input_integrity_mismatch: workProductId=${workProductId} expectedBytes=${byteSize} actualBytes=${body.byteLength} expectedSha256=${sha2562} actualSha256=${actualSha256}`
|
|
14301
14613
|
);
|
|
14302
14614
|
}
|
|
14303
14615
|
const sourceDir = safeArtifactInputSourceDir(entry, index);
|
|
@@ -14327,7 +14639,7 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
14327
14639
|
relativePath,
|
|
14328
14640
|
contentType: readString(entry.contentType),
|
|
14329
14641
|
byteSize: body.byteLength,
|
|
14330
|
-
sha256,
|
|
14642
|
+
sha256: sha2562,
|
|
14331
14643
|
contentPath
|
|
14332
14644
|
});
|
|
14333
14645
|
}
|
|
@@ -14364,7 +14676,7 @@ function safeCheckpointRelativePath(rawPath) {
|
|
|
14364
14676
|
return normalized;
|
|
14365
14677
|
}
|
|
14366
14678
|
function hashFileSha256(filePath) {
|
|
14367
|
-
return
|
|
14679
|
+
return createHash15("sha256").update(readFileSync11(filePath)).digest("hex");
|
|
14368
14680
|
}
|
|
14369
14681
|
async function materializeIssueCheckpoint(config, command, workspace) {
|
|
14370
14682
|
const checkpointDir = issueCheckpointDir(workspace);
|
package/dist/amaster-runtime.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { basename, dirname, join, resolve } from "node:path";
|
|
|
6
6
|
import { homedir, hostname } from "node:os";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
|
|
9
|
-
const CONNECTOR_VERSION = "0.1.1-beta.
|
|
9
|
+
const CONNECTOR_VERSION = "0.1.1-beta.23";
|
|
10
10
|
|
|
11
11
|
const CAPABILITIES = [
|
|
12
12
|
"remote_registration",
|
|
@@ -16,6 +16,7 @@ const CAPABILITIES = [
|
|
|
16
16
|
"run_wakeup",
|
|
17
17
|
"runtime_actions_v2",
|
|
18
18
|
"model_call",
|
|
19
|
+
"model_call_output_contract_v1",
|
|
19
20
|
"run_cancel",
|
|
20
21
|
"run_terminate",
|
|
21
22
|
"logs_cost_workspace_status",
|