@amaster.ai/employee-runtime-connector 0.1.1-beta.4 → 0.1.1-beta.6
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.
|
@@ -2096,15 +2096,28 @@ export default function amasterEffectiveToolsAttestor(pi) {
|
|
|
2096
2096
|
}
|
|
2097
2097
|
|
|
2098
2098
|
const allTools = pi.getAllTools();
|
|
2099
|
+
if (allTools.some((tool) => typeof tool.name !== "string" || !tool.name)) {
|
|
2100
|
+
throw new Error("registered tool identity mismatch");
|
|
2101
|
+
}
|
|
2102
|
+
const activeToolNames = pi.getActiveTools();
|
|
2103
|
+
if (activeToolNames.some((name) => typeof name !== "string" || !name)) {
|
|
2104
|
+
throw new Error("active tool identity mismatch");
|
|
2105
|
+
}
|
|
2106
|
+
activeToolNames.sort();
|
|
2107
|
+
const activeToolNameSet = new Set(activeToolNames);
|
|
2099
2108
|
const proxyPresent = allTools.some((tool) => tool.name === "mcp");
|
|
2109
|
+
const nonCatalogTools = activeToolNames.filter((name) => !expectedByName.has(name));
|
|
2100
2110
|
const adapterTools = allTools.filter((tool) => sourceIsMcpAdapter(tool.sourceInfo));
|
|
2101
|
-
const directTools = adapterTools.filter((tool) => tool.name !== "mcp").map((tool) => ({
|
|
2111
|
+
const directTools = adapterTools.filter((tool) => tool.name !== "mcp" && activeToolNameSet.has(tool.name)).map((tool) => ({
|
|
2102
2112
|
name: tool.name,
|
|
2103
2113
|
schemaHash: schemaHash(tool.parameters),
|
|
2104
2114
|
}));
|
|
2105
2115
|
const actualByName = new Map(directTools.map((entry) => [entry.name, entry]));
|
|
2106
|
-
const missing = [...expectedByName.keys()].filter((name) => !actualByName.has(name)).sort();
|
|
2107
|
-
const unexpected =
|
|
2116
|
+
const missing = [...expectedByName.keys()].filter((name) => !actualByName.has(name) || !activeToolNameSet.has(name)).sort();
|
|
2117
|
+
const unexpected = adapterTools
|
|
2118
|
+
.map((tool) => tool.name)
|
|
2119
|
+
.filter((name) => name !== "mcp" && !expectedByName.has(name))
|
|
2120
|
+
.sort();
|
|
2108
2121
|
const schemaMismatches = [...expectedByName.entries()].flatMap(([name, expected]) => {
|
|
2109
2122
|
const actual = actualByName.get(name);
|
|
2110
2123
|
return actual && actual.schemaHash !== expected.effectiveSchemaHash
|
|
@@ -2112,8 +2125,8 @@ export default function amasterEffectiveToolsAttestor(pi) {
|
|
|
2112
2125
|
: [];
|
|
2113
2126
|
});
|
|
2114
2127
|
const effectiveSetHash = toolSetHash(directTools);
|
|
2115
|
-
if (proxyPresent || missing.length > 0 || unexpected.length > 0 || schemaMismatches.length > 0) {
|
|
2116
|
-
throw new Error("effective tool surface mismatch: proxy=" + proxyPresent + " missing=" + missing.join(",") + " unexpected=" + unexpected.join(",") + " schemas=" + schemaMismatches.map((entry) => entry.name).join(","));
|
|
2128
|
+
if (proxyPresent || nonCatalogTools.length > 0 || missing.length > 0 || unexpected.length > 0 || schemaMismatches.length > 0) {
|
|
2129
|
+
throw new Error("effective tool surface mismatch: proxy=" + proxyPresent + " nonCatalog=" + nonCatalogTools.join(",") + " missing=" + missing.join(",") + " unexpected=" + unexpected.join(",") + " schemas=" + schemaMismatches.map((entry) => entry.name).join(","));
|
|
2117
2130
|
}
|
|
2118
2131
|
if (effectiveSetHash !== manifest.effectiveSetHash) throw new Error("effective tool set hash mismatch");
|
|
2119
2132
|
receipt = {
|
|
@@ -2168,6 +2181,18 @@ var MANAGED_PI_MCP_TOOL_MODE = "proxy_only";
|
|
|
2168
2181
|
var MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE = "direct_typed";
|
|
2169
2182
|
var MANAGED_PI_MCP_ARGS_NORMALIZATION = "json_string_control_characters_v1";
|
|
2170
2183
|
var MANAGED_PI_MCP_ARGS_NORMALIZER_FILENAME = "amaster-mcp-args-normalizer.js";
|
|
2184
|
+
function applyManagedPiToolAllowlist(args, profile) {
|
|
2185
|
+
const toolAllowlist = Array.isArray(profile?.toolAllowlist) ? profile.toolAllowlist.filter((name) => typeof name === "string" && name) : [];
|
|
2186
|
+
if (toolAllowlist.length === 0) return [...args];
|
|
2187
|
+
const printArgIndex = Math.max(args.lastIndexOf("-p"), args.lastIndexOf("--print"));
|
|
2188
|
+
if (printArgIndex < 0) throw new Error("pi_managed_mcp_invocation_invalid: print mode argument missing");
|
|
2189
|
+
return [
|
|
2190
|
+
...args.slice(0, printArgIndex),
|
|
2191
|
+
"--tools",
|
|
2192
|
+
toolAllowlist.join(","),
|
|
2193
|
+
...args.slice(printArgIndex)
|
|
2194
|
+
];
|
|
2195
|
+
}
|
|
2171
2196
|
function createManagedPiMcpProfileApi(options = {}) {
|
|
2172
2197
|
const spawnSyncImpl = typeof options.spawnSync === "function" ? options.spawnSync : spawnSync2;
|
|
2173
2198
|
const nowImpl = typeof options.now === "function" ? options.now : Date.now;
|
|
@@ -2264,6 +2289,12 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
2264
2289
|
]);
|
|
2265
2290
|
const FORBIDDEN_ARGV = /* @__PURE__ */ new Set([
|
|
2266
2291
|
"--no-tools",
|
|
2292
|
+
"--no-builtin-tools",
|
|
2293
|
+
"-nbt",
|
|
2294
|
+
"--tools",
|
|
2295
|
+
"-t",
|
|
2296
|
+
"--exclude-tools",
|
|
2297
|
+
"-xt",
|
|
2267
2298
|
"--no-extensions",
|
|
2268
2299
|
"--no-skills",
|
|
2269
2300
|
"--no-session",
|
|
@@ -2550,7 +2581,7 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
2550
2581
|
if (!ALLOWED_COMMAND_ENV2.has(name)) throw new Error(`pi_managed_mcp_env_injection_blocked: ${name}`);
|
|
2551
2582
|
}
|
|
2552
2583
|
const args = Array.isArray(input.extraArgs) ? input.extraArgs.map(String) : [];
|
|
2553
|
-
if (args.some((arg) => FORBIDDEN_ARGV.has(arg) || arg.startsWith("--session=") || arg.startsWith("--fork=") || arg.startsWith("--session-dir=") || arg.startsWith("--extension=") || arg.startsWith("--package=") || arg.startsWith("--settings="))) {
|
|
2584
|
+
if (args.some((arg) => FORBIDDEN_ARGV.has(arg) || arg.startsWith("--tools=") || arg.startsWith("--exclude-tools=") || arg.startsWith("--session=") || arg.startsWith("--fork=") || arg.startsWith("--session-dir=") || arg.startsWith("--extension=") || arg.startsWith("--package=") || arg.startsWith("--settings="))) {
|
|
2554
2585
|
throw new Error("pi_managed_mcp_config_override_blocked: Pi config/tool/session argv is forbidden for governed runs");
|
|
2555
2586
|
}
|
|
2556
2587
|
}
|
|
@@ -3063,6 +3094,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
3063
3094
|
configPath,
|
|
3064
3095
|
markerPath,
|
|
3065
3096
|
env,
|
|
3097
|
+
toolAllowlist: directCatalog ? [...directToolNames] : null,
|
|
3066
3098
|
protectedValues: [.../* @__PURE__ */ new Set([
|
|
3067
3099
|
sessionToken,
|
|
3068
3100
|
...seededRuntime.protectedValues,
|
|
@@ -3912,7 +3944,7 @@ function fixedRules(input, includeIssueLine) {
|
|
|
3912
3944
|
"Use only the declared workspace; make concrete progress and report concisely.",
|
|
3913
3945
|
"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.",
|
|
3914
3946
|
"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.",
|
|
3915
|
-
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
|
|
3947
|
+
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.",
|
|
3916
3948
|
DEADLINE_POSTURE_GUARD,
|
|
3917
3949
|
"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.",
|
|
3918
3950
|
`- command id: ${input.commandId}`,
|
|
@@ -3971,9 +4003,13 @@ function recoveryInstructionText(input) {
|
|
|
3971
4003
|
if (input.wakeReason === "source_scoped_recovery_action") {
|
|
3972
4004
|
const wake = asRecord(context.paperclipWake);
|
|
3973
4005
|
const unresolvedBlockerIssueIds = Array.isArray(wake.unresolvedBlockerIssueIds) ? wake.unresolvedBlockerIssueIds.map(readString).filter(Boolean) : [];
|
|
3974
|
-
const blockedDisposition = unresolvedBlockerIssueIds.length > 0 ?
|
|
3975
|
-
"-
|
|
3976
|
-
|
|
4006
|
+
const blockedDisposition = unresolvedBlockerIssueIds.length > 0 ? [
|
|
4007
|
+
"- `update_parent` cannot write `blocked`; the existing first-class blocker path is authoritative and must not be replaced by `in_progress`;",
|
|
4008
|
+
`- name the exact blocker and wait condition from: ${unresolvedBlockerIssueIds.join(", ")}; continuation/todo can wait behind that blocker when source work remains;`
|
|
4009
|
+
].join("\n") : [
|
|
4010
|
+
"- `update_parent` cannot write `blocked`; do not use `in_progress` to represent a wait;",
|
|
4011
|
+
"- when a specific human, platform, provider, or external action is required before work can continue, create a typed interaction that names the exact owner and unblock action;",
|
|
4012
|
+
"- otherwise, if source work remains on this issue, choose continuation/todo and then execute the Runtime Action Continuation Option rendered below so the control plane can queue a normal-model continuation;"
|
|
3977
4013
|
].join("\n");
|
|
3978
4014
|
return [
|
|
3979
4015
|
"This is a status-only source recovery. Do not repeat the original source work or create or revise deliverables.",
|
|
@@ -5781,6 +5817,14 @@ function piMessageText(message) {
|
|
|
5781
5817
|
return readString(block.text) ?? readString(block.content) ?? "";
|
|
5782
5818
|
}).filter(Boolean).join("\n").trim();
|
|
5783
5819
|
}
|
|
5820
|
+
function piMessageHasToolCall(message) {
|
|
5821
|
+
const content = asRecord(message).content;
|
|
5822
|
+
if (!Array.isArray(content)) return false;
|
|
5823
|
+
return content.some((entry) => {
|
|
5824
|
+
const block = asRecord(entry);
|
|
5825
|
+
return block.type === "toolCall" && Boolean(readString(block.name));
|
|
5826
|
+
});
|
|
5827
|
+
}
|
|
5784
5828
|
function appendUniqueText(values, text) {
|
|
5785
5829
|
const normalized = typeof text === "string" ? text.trim() : "";
|
|
5786
5830
|
if (!normalized) return false;
|
|
@@ -5868,7 +5912,7 @@ function maybeCapturePiMessage(event, messages, usage) {
|
|
|
5868
5912
|
const message = asRecord(event.message);
|
|
5869
5913
|
if (message.role === "assistant") {
|
|
5870
5914
|
const text = piMessageText(message);
|
|
5871
|
-
capturedAssistantOutput = capturePiAssistantText(text, messages) || capturedAssistantOutput;
|
|
5915
|
+
capturedAssistantOutput = capturePiAssistantText(text, messages) || piMessageHasToolCall(message) || capturedAssistantOutput;
|
|
5872
5916
|
assignPiUsage(usage, piMessageUsage(message));
|
|
5873
5917
|
}
|
|
5874
5918
|
const eventMessages = Array.isArray(event.messages) ? event.messages : [];
|
|
@@ -5878,7 +5922,7 @@ function maybeCapturePiMessage(event, messages, usage) {
|
|
|
5878
5922
|
continue;
|
|
5879
5923
|
}
|
|
5880
5924
|
const text = piMessageText(eventMessage);
|
|
5881
|
-
capturedAssistantOutput = capturePiAssistantText(text, messages) || capturedAssistantOutput;
|
|
5925
|
+
capturedAssistantOutput = capturePiAssistantText(text, messages) || piMessageHasToolCall(eventMessage) || capturedAssistantOutput;
|
|
5882
5926
|
assignPiUsage(usage, piMessageUsage(eventMessage));
|
|
5883
5927
|
}
|
|
5884
5928
|
return capturedAssistantOutput;
|
|
@@ -8695,7 +8739,7 @@ function assertSourceAcquisitionRuntimeAuthority({
|
|
|
8695
8739
|
}
|
|
8696
8740
|
|
|
8697
8741
|
// src/amaster-runtime-daemon.mjs
|
|
8698
|
-
var CONNECTOR_VERSION = "0.1.1-beta.
|
|
8742
|
+
var CONNECTOR_VERSION = "0.1.1-beta.6";
|
|
8699
8743
|
var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
|
|
8700
8744
|
var SOURCE_ACQUISITION_CAPABILITY = "source_acquisition_v1";
|
|
8701
8745
|
var SOURCE_ACQUISITION_PROFILE_VERSION = "source_acquisition_v1";
|
|
@@ -10478,6 +10522,14 @@ async function executeModelCallCommand(config, command, signal) {
|
|
|
10478
10522
|
sourceWorkspacePath: process.cwd()
|
|
10479
10523
|
});
|
|
10480
10524
|
piModelCallProfile = executor.kind === "pi" ? preparePiModelCallProfile(command.commandId, baseEnv) : null;
|
|
10525
|
+
if (piModelCallProfile) {
|
|
10526
|
+
await syncPiExecutorProviderConfig(
|
|
10527
|
+
config,
|
|
10528
|
+
command,
|
|
10529
|
+
piModelCallProfile.env.PI_CODING_AGENT_DIR,
|
|
10530
|
+
resolvePiExecutorProviderConfig(config, command, baseEnv)
|
|
10531
|
+
);
|
|
10532
|
+
}
|
|
10481
10533
|
execution = await runExecutor(invocation.command, invocation.args, {
|
|
10482
10534
|
cwd: process.cwd(),
|
|
10483
10535
|
env: piModelCallProfile?.env ?? baseEnv,
|
|
@@ -13162,6 +13214,7 @@ async function executeRunCommand(config, command) {
|
|
|
13162
13214
|
}
|
|
13163
13215
|
if (managedMcpProfile) {
|
|
13164
13216
|
executorEnv = managedMcpProfile.env;
|
|
13217
|
+
if (executor.kind === "pi") invocation.args = applyManagedPiToolAllowlist(invocation.args, managedMcpProfile);
|
|
13165
13218
|
await ingestLog(config, command, "system", "info", `Attested isolated ${executor.kind} managed MCP profile`, {
|
|
13166
13219
|
presentationKind: "managed_mcp_attestation",
|
|
13167
13220
|
...managedMcpProfile.attestation
|
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.6";
|
|
9
9
|
|
|
10
10
|
const CAPABILITIES = [
|
|
11
11
|
"remote_registration",
|