@amaster.ai/employee-runtime-connector 0.1.1-beta.225 → 0.1.1-beta.227
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.
|
@@ -4072,8 +4072,11 @@ var AMASTER_RUNTIME_CONNECTOR_CAPABILITIES = [
|
|
|
4072
4072
|
"runtime_actions_v2",
|
|
4073
4073
|
"continue_task_v1",
|
|
4074
4074
|
"run_exit_live_path_closure_v1",
|
|
4075
|
-
"browser_credential_ref_fill_v1"
|
|
4075
|
+
"browser_credential_ref_fill_v1",
|
|
4076
|
+
"execution_lanes_v1"
|
|
4076
4077
|
];
|
|
4078
|
+
var RUNTIME_EXECUTION_LANES = ["business", "conversation"];
|
|
4079
|
+
var runtimeExecutionLaneSchema = external_exports.enum(RUNTIME_EXECUTION_LANES);
|
|
4077
4080
|
var TERMINAL_BUSINESS_RECONCILIATION_VERSION = "mirrorx.terminal-business-reconciliation/v1";
|
|
4078
4081
|
var terminalBusinessReconciliationAuthoritySnapshotSchema = external_exports.object({
|
|
4079
4082
|
outcomeId: external_exports.string().uuid().nullable(),
|
|
@@ -4311,6 +4314,7 @@ var amasterRuntimeConnectorCreateCommandSchema = external_exports.object({
|
|
|
4311
4314
|
var amasterRuntimeConnectorPollCommandsSchema = external_exports.object({
|
|
4312
4315
|
limit: external_exports.number().int().min(1).max(50).default(1),
|
|
4313
4316
|
maxConcurrentCommands: external_exports.number().int().min(1).max(50).optional(),
|
|
4317
|
+
maxConcurrentBusinessCommands: external_exports.number().int().min(1).max(3).optional(),
|
|
4314
4318
|
leaseId: external_exports.string().trim().min(1).optional(),
|
|
4315
4319
|
leaseSeconds: external_exports.number().int().min(1).max(3600).default(60)
|
|
4316
4320
|
});
|
|
@@ -20307,6 +20311,7 @@ const terminalActionDispositions = new Map([
|
|
|
20307
20311
|
["create_interaction", new Set(["waiting_human", "handoff_existing_live_path"])],
|
|
20308
20312
|
["upsert_external_wait", new Set(["waiting_external"])],
|
|
20309
20313
|
["schedule_monitor", new Set(["scheduled_monitor"])],
|
|
20314
|
+
["continue_task", new Set(["continuation_scheduled"])],
|
|
20310
20315
|
]);
|
|
20311
20316
|
const terminalToolNames = new Set(["runtime_action.submit", "runtime_action.status"]);
|
|
20312
20317
|
|
|
@@ -20330,6 +20335,18 @@ function shouldStopFromReceipt(rawResult) {
|
|
|
20330
20335
|
const disposition = readString(effectResult.runDisposition);
|
|
20331
20336
|
const existingOwner = asRecord(effectResult.existingOwner);
|
|
20332
20337
|
const existingOwnerEpoch = Number(existingOwner.executionEpoch);
|
|
20338
|
+
const continuationCount = Number(effectResult.continuationCount);
|
|
20339
|
+
const maxContinuations = Number(effectResult.maxContinuations);
|
|
20340
|
+
const exactContinuation = disposition === "continuation_scheduled"
|
|
20341
|
+
&& Boolean(readString(effectResult.chainId))
|
|
20342
|
+
&& Boolean(readString(effectResult.continuationIntentId))
|
|
20343
|
+
&& Boolean(readString(effectResult.wakeId))
|
|
20344
|
+
&& Number.isSafeInteger(Number(effectResult.executionEpoch))
|
|
20345
|
+
&& Number(effectResult.executionEpoch) > 0
|
|
20346
|
+
&& Number.isSafeInteger(continuationCount)
|
|
20347
|
+
&& continuationCount > 0
|
|
20348
|
+
&& Number.isSafeInteger(maxContinuations)
|
|
20349
|
+
&& continuationCount <= maxContinuations;
|
|
20333
20350
|
if (!invocationId || !receiptInvocationId || !callId || !receiptCallId) return false;
|
|
20334
20351
|
|
|
20335
20352
|
const exactQueuedWakeHandoff = disposition === "handoff_existing_live_path"
|
|
@@ -20356,7 +20373,8 @@ function shouldStopFromReceipt(rawResult) {
|
|
|
20356
20373
|
&& (disposition !== "waiting_human"
|
|
20357
20374
|
|| Boolean(readString(effectResult.interactionId) && readString(effectResult.epochKey)))
|
|
20358
20375
|
&& (disposition !== "handoff_existing_live_path"
|
|
20359
|
-
|| Boolean(readString(effectResult.epochKey) && exactQueuedWakeHandoff))
|
|
20376
|
+
|| Boolean(readString(effectResult.epochKey) && exactQueuedWakeHandoff))
|
|
20377
|
+
&& (disposition !== "continuation_scheduled" || exactContinuation);
|
|
20360
20378
|
}
|
|
20361
20379
|
|
|
20362
20380
|
export default function mirrorxRunTermination(pi) {
|
|
@@ -23500,6 +23518,39 @@ function resolveRuntimeCostModelIdentity({
|
|
|
23500
23518
|
};
|
|
23501
23519
|
}
|
|
23502
23520
|
|
|
23521
|
+
// src/amaster-runtime-daemon/execution-lanes.mjs
|
|
23522
|
+
function normalizeRuntimeExecutionLane(value) {
|
|
23523
|
+
return value === "conversation" ? "conversation" : "business";
|
|
23524
|
+
}
|
|
23525
|
+
function runtimeExecutionLaneForCapabilities(value, capabilities) {
|
|
23526
|
+
const lane = normalizeRuntimeExecutionLane(value);
|
|
23527
|
+
return lane === "conversation" && !(Array.isArray(capabilities) && capabilities.includes("execution_lanes_v1")) ? "business" : lane;
|
|
23528
|
+
}
|
|
23529
|
+
function localRuntimeCommandLimit(input) {
|
|
23530
|
+
const businessLimit = Number.isInteger(input.businessLimit) && input.businessLimit > 0 ? Math.min(input.businessLimit, 3) : 1;
|
|
23531
|
+
const supportsExecutionLanes = Array.isArray(input.capabilities) && input.capabilities.includes("execution_lanes_v1");
|
|
23532
|
+
return Math.min(4, businessLimit + (supportsExecutionLanes ? 1 : 0));
|
|
23533
|
+
}
|
|
23534
|
+
function selectRuntimeCommandsWithinLaneLimits(input) {
|
|
23535
|
+
const businessLimit = Number.isInteger(input.businessLimit) && input.businessLimit > 0 ? Math.min(input.businessLimit, 3) : 1;
|
|
23536
|
+
const totalLimit = Number.isInteger(input.totalLimit) && input.totalLimit > 0 ? Math.min(input.totalLimit, 4) : 1;
|
|
23537
|
+
const counts = { business: 0, conversation: 0 };
|
|
23538
|
+
for (const lane of Array.isArray(input.activeLanes) ? input.activeLanes : []) {
|
|
23539
|
+
counts[runtimeExecutionLaneForCapabilities(lane, input.capabilities)] += 1;
|
|
23540
|
+
}
|
|
23541
|
+
const selected = [];
|
|
23542
|
+
for (const command of Array.isArray(input.commands) ? input.commands : []) {
|
|
23543
|
+
const lane = runtimeExecutionLaneForCapabilities(command?.executionLane, input.capabilities);
|
|
23544
|
+
const total = counts.business + counts.conversation;
|
|
23545
|
+
if (total >= totalLimit) continue;
|
|
23546
|
+
if (lane === "business" && counts.business >= businessLimit) continue;
|
|
23547
|
+
if (lane === "conversation" && counts.conversation >= 1) continue;
|
|
23548
|
+
selected.push(command);
|
|
23549
|
+
counts[lane] += 1;
|
|
23550
|
+
}
|
|
23551
|
+
return selected;
|
|
23552
|
+
}
|
|
23553
|
+
|
|
23503
23554
|
// src/amaster-runtime-daemon/prompt-compiler.mjs
|
|
23504
23555
|
import { createHash as createHash9 } from "node:crypto";
|
|
23505
23556
|
import { isAbsolute as isAbsolute5 } from "node:path";
|
|
@@ -23770,7 +23821,7 @@ function estimatedTokens(chars) {
|
|
|
23770
23821
|
}
|
|
23771
23822
|
function promptContextMode(input) {
|
|
23772
23823
|
const nativeSession = asRecord(input.nativeSession);
|
|
23773
|
-
if (nativeSession.mode === "governed_action_approval" || readString(input.context?.resumeFromRunId) || isRecoveryWakeReason(input.wakeReason) || CONTINUATION_WAKE_PATTERN.test(input.wakeReason ?? "")) return "continuation";
|
|
23824
|
+
if (nativeSession.mode === "governed_action_approval" || input.wakeReason === "continue_task" || readString(input.context?.resumeFromRunId) || isRecoveryWakeReason(input.wakeReason) || CONTINUATION_WAKE_PATTERN.test(input.wakeReason ?? "")) return "continuation";
|
|
23774
23825
|
if (nativeSession.resume === true || Object.keys(asRecord(input.context?.paperclipContinuationSummary)).length > 0) {
|
|
23775
23826
|
return "warm";
|
|
23776
23827
|
}
|
|
@@ -23800,12 +23851,54 @@ function commentBodies(context) {
|
|
|
23800
23851
|
const comments = Array.isArray(asRecord(context.paperclipWake).comments) ? asRecord(context.paperclipWake).comments : [];
|
|
23801
23852
|
return comments.map((entry) => readString(asRecord(entry).body)).filter(Boolean);
|
|
23802
23853
|
}
|
|
23803
|
-
function continuationText(context) {
|
|
23854
|
+
function continuationText(context, { omitNextAction = false } = {}) {
|
|
23804
23855
|
const summary = asRecord(context.paperclipContinuationSummary);
|
|
23805
|
-
const
|
|
23856
|
+
const rawBody = readString(summary.body);
|
|
23857
|
+
const body = omitNextAction ? rawBody?.replace(/(?:^|\n)##[ \t]+Next Action[ \t]*\n[\s\S]*$/iu, "").trimEnd() : rawBody;
|
|
23806
23858
|
if (!body) return "";
|
|
23807
23859
|
return [readString(summary.title), body].filter(Boolean).join("\n");
|
|
23808
23860
|
}
|
|
23861
|
+
function authoritativeContinuationNextAction(context, input) {
|
|
23862
|
+
if (input.wakeReason !== "continue_task") return null;
|
|
23863
|
+
const nextAction = readString(context.nextAction);
|
|
23864
|
+
const sourceRunId = readString(context.sourceRunId);
|
|
23865
|
+
const continuationChainId = readString(context.continuationChainId);
|
|
23866
|
+
const continuationIntentId = readString(context.continuationIntentId);
|
|
23867
|
+
if (!nextAction || !sourceRunId || !continuationChainId || !continuationIntentId) {
|
|
23868
|
+
throw promptBudgetError(
|
|
23869
|
+
"continuation_next_action_unavailable",
|
|
23870
|
+
"Continue Task wake requires an exact next action and complete continuation lineage"
|
|
23871
|
+
);
|
|
23872
|
+
}
|
|
23873
|
+
const rawCheckpointPaths = context.checkpointPaths;
|
|
23874
|
+
const checkpointPaths = rawCheckpointPaths === void 0 ? [] : Array.isArray(rawCheckpointPaths) ? rawCheckpointPaths.map((entry) => readString(entry)) : null;
|
|
23875
|
+
if (checkpointPaths === null || checkpointPaths.length > 20 || checkpointPaths.some((path) => !path) || new Set(checkpointPaths).size !== checkpointPaths.length) {
|
|
23876
|
+
throw promptBudgetError(
|
|
23877
|
+
"continuation_checkpoint_contract_invalid",
|
|
23878
|
+
"Continue Task wake contains invalid checkpoint path authority"
|
|
23879
|
+
);
|
|
23880
|
+
}
|
|
23881
|
+
return {
|
|
23882
|
+
sourceRef: [
|
|
23883
|
+
`run:${sourceRunId}`,
|
|
23884
|
+
`continuation-chain:${continuationChainId}`,
|
|
23885
|
+
`continuation-intent:${continuationIntentId}`
|
|
23886
|
+
],
|
|
23887
|
+
content: [
|
|
23888
|
+
"The Server persisted this exact instruction when the predecessor Run yielded its execution slot.",
|
|
23889
|
+
"Execute this instruction as the current stage. Do not restart the original task or repeat completed predecessor work unless this instruction explicitly requires it.",
|
|
23890
|
+
"This instruction overrides any generic or inferred Next Action in the Continuation Summary.",
|
|
23891
|
+
...checkpointPaths.length > 0 ? [
|
|
23892
|
+
`The Connector restored these exact predecessor checkpoint files into the current execution workspace: ${JSON.stringify(checkpointPaths)}.`,
|
|
23893
|
+
"Use only these paths as run-local file continuity evidence; other predecessor workspace files were not carried forward."
|
|
23894
|
+
] : [
|
|
23895
|
+
"No predecessor run-local files were declared for carry-forward. Use Server-durable documents, artifacts, work products, or the exact instruction below instead of assuming an old workspace file exists."
|
|
23896
|
+
],
|
|
23897
|
+
"",
|
|
23898
|
+
nextAction
|
|
23899
|
+
].join("\n")
|
|
23900
|
+
};
|
|
23901
|
+
}
|
|
23809
23902
|
var CONTINUATION_SUMMARY_TITLE_ALLOWLIST = /* @__PURE__ */ new Set(["Continuation Summary", "Predecessor Execution Summary"]);
|
|
23810
23903
|
function continuationSectionTitle(context) {
|
|
23811
23904
|
const title = readString(asRecord(context.paperclipContinuationSummary).title);
|
|
@@ -24698,7 +24791,7 @@ function runtimeAuthorizationText(context, mode, {
|
|
|
24698
24791
|
const completionContract = !suppressOrdinaryCompletionContract && completionRole && completionDeliverable ? [
|
|
24699
24792
|
workDisposition.mode === "required" ? "Before the first business mutation, ensure the current required work disposition is recorded. Read-only governed checks may precede it. If no current valid receipt exists, call runtime_action_describe for record_work_disposition and persist exactly one truthful disposition before upsert_document, update_parent, add_comment, create_interaction, publish_delivery_manifest, or any other business mutation. Before ending this run, persist durable progress through Runtime Actions; browser and tool history alone are not durable progress." : "Before ending this run, persist durable progress through Runtime Actions and record one explicit task disposition. Browser and tool history alone are not durable progress.",
|
|
24700
24793
|
firstDocumentCheckpoint,
|
|
24701
|
-
continueTaskEnabled ? "
|
|
24794
|
+
continueTaskEnabled ? "Treat one Run as one bounded, durable checkpoint. Once that checkpoint is persisted and another independent research, build, or revision phase remains, call continue_task immediately with a concrete nextAction and stable idempotencyKey instead of keeping the current Run open, then end the run. If the nextAction depends on files created in this run, include their exact workspace-relative POSIX paths in checkpointPaths; only those files are integrity-checked and carried into the successor workspace. A run-local file omitted from checkpointPaths is not durable continuation state. Do not split an unfinished atomic mutation or claim progress that is not durable. For a future time recheck use schedule_monitor; for an external person or system action use upsert_external_wait. These are mutually exclusive final live paths. Do not call update_parent with status: in_progress." : "If work remains in an ordinary productive run, call update_parent with status: in_progress and a concrete next action so bounded continuation recovery can preserve a live path. Status: todo does not queue a normal continuation from an ordinary productive run. Only a server-issued successful-run handoff recovery may use status: todo, and only according to its exact Recovery Instruction. Otherwise use a supported terminal or waiting disposition."
|
|
24702
24795
|
].filter(Boolean).join(" ") : "";
|
|
24703
24796
|
const businessOutcomeOwnershipContract = businessOutcome.mode === "required" ? evidenceAutoAcceptance ? [
|
|
24704
24797
|
"Evidence-auto Business Outcome closure is owned by the Server terminal reconciler.",
|
|
@@ -25044,6 +25137,7 @@ var COMPANY_INITIALIZATION_PRE_AUTHORITY_SECTIONS = /* @__PURE__ */ new Set([
|
|
|
25044
25137
|
"execution_review_contract",
|
|
25045
25138
|
"governed_business_state",
|
|
25046
25139
|
"continuation_postcondition_gap",
|
|
25140
|
+
"continuation_next_action",
|
|
25047
25141
|
"continuation_summary",
|
|
25048
25142
|
"resolved_dependencies",
|
|
25049
25143
|
"runtime_delivery_readiness",
|
|
@@ -25383,8 +25477,12 @@ function compileCommandPromptWithManifest(input, options = {}) {
|
|
|
25383
25477
|
`issue:${input.issueId ?? "unknown"}`,
|
|
25384
25478
|
...taskCommentIds.map((commentId) => `comment:${commentId}`)
|
|
25385
25479
|
];
|
|
25386
|
-
const
|
|
25387
|
-
const
|
|
25480
|
+
const continuationNextAction = authoritativeContinuationNextAction(context, input);
|
|
25481
|
+
const rawContinuationSummary = continuationText(context);
|
|
25482
|
+
const continuationSummary = continuationText(context, {
|
|
25483
|
+
omitNextAction: Boolean(continuationNextAction)
|
|
25484
|
+
});
|
|
25485
|
+
const includeTask = mode === "cold" || !rawContinuationSummary && !continuationNextAction && asRecord(input.nativeSession).mode !== "governed_action_approval";
|
|
25388
25486
|
const wakeBodies = commentBodies(context);
|
|
25389
25487
|
const hasTaskCommentIds = Array.isArray(context.paperclipTaskMarkdownCommentIds);
|
|
25390
25488
|
const commentsDuplicatedByTask = !hasTaskCommentIds && hasTask && wakeBodies.length > 0 && wakeBodies.every((body) => taskText.includes(body));
|
|
@@ -25436,6 +25534,7 @@ ${resolvedDependencies.details.content}` : resolvedDependencies.details.content
|
|
|
25436
25534
|
const rawSections = [
|
|
25437
25535
|
{ name: "recovery_instruction", title: "Recovery Instruction", priority: 100, sourceRef: `run:${input.runId ?? "unknown"}`, content: completeRecoveryInstruction, truncationReason: completeRecoveryInstruction ? null : "mode_selection" },
|
|
25438
25536
|
{ name: "approval_continuation", title: "Approved Runtime Action Continuation", priority: 99, sourceRef: `run:${input.runId ?? "unknown"}`, content: approvalContinuationText(input), truncationReason: mode === "continuation" ? null : "mode_selection" },
|
|
25537
|
+
...continuationNextAction ? [{ name: "continuation_next_action", title: "Authoritative Continuation Next Action", priority: 100, ...continuationNextAction }] : [],
|
|
25439
25538
|
{ name: "wake_comments", title: wakeDeltaTitle, priority: interactionResolution ? 99 : 95, sourceRef: wakeDeltaSourceRefs, originalContent: wakeDeltaOriginal, content: wakeDeltaContent, truncationReason: commentsSelected ? null : "duplicate_task_context" },
|
|
25440
25539
|
{ name: "task", title: "Task Context", priority: 90, sourceRef: taskSourceRefs, originalContent: [taskText, taskCommentRefGuidance(input, taskText)].filter(Boolean).join("\n"), content: includeTask ? [taskText, taskCommentRefGuidance(input, taskText)].filter(Boolean).join("\n") : "", truncationReason: includeTask ? null : "mode_selection" },
|
|
25441
25540
|
...taskAcceptanceContract ? [{ name: "task_acceptance_contract", title: "Task Acceptance Contract", priority: 100, ...taskAcceptanceContract }] : [],
|
|
@@ -25963,7 +26062,8 @@ var BUILD_SUPPORTED_CAPABILITIES = Object.freeze([
|
|
|
25963
26062
|
"run_cancel",
|
|
25964
26063
|
"run_terminate",
|
|
25965
26064
|
"logs_cost_workspace_status",
|
|
25966
|
-
"browser_credential_ref_fill_v1"
|
|
26065
|
+
"browser_credential_ref_fill_v1",
|
|
26066
|
+
"execution_lanes_v1"
|
|
25967
26067
|
]);
|
|
25968
26068
|
var DYNAMIC_READINESS = Object.freeze({
|
|
25969
26069
|
artifact_template_catalog_v1: {
|
|
@@ -26928,12 +27028,24 @@ var PI_TERMINAL_RUNTIME_ACTION_STATUSES = /* @__PURE__ */ new Set([
|
|
|
26928
27028
|
var PI_TERMINATING_RUNTIME_ACTION_TO_DISPOSITION = /* @__PURE__ */ new Map([
|
|
26929
27029
|
["create_interaction", /* @__PURE__ */ new Set(["waiting_human", "handoff_existing_live_path"])],
|
|
26930
27030
|
["upsert_external_wait", /* @__PURE__ */ new Set(["waiting_external"])],
|
|
26931
|
-
["schedule_monitor", /* @__PURE__ */ new Set(["scheduled_monitor"])]
|
|
27031
|
+
["schedule_monitor", /* @__PURE__ */ new Set(["scheduled_monitor"])],
|
|
27032
|
+
["continue_task", /* @__PURE__ */ new Set(["continuation_scheduled"])]
|
|
26932
27033
|
]);
|
|
26933
27034
|
var PI_TERMINATING_RUNTIME_ACTION_TOOLS = /* @__PURE__ */ new Set([
|
|
26934
27035
|
"runtime_action.submit",
|
|
26935
27036
|
"runtime_action.status"
|
|
26936
27037
|
]);
|
|
27038
|
+
function continuationCheckpointPaths(value) {
|
|
27039
|
+
if (value === void 0) return [];
|
|
27040
|
+
if (!Array.isArray(value) || value.length < 1 || value.length > 20) return null;
|
|
27041
|
+
const paths = value.map((entry) => readString(entry));
|
|
27042
|
+
if (paths.some((entry) => !entry)) return null;
|
|
27043
|
+
if (new Set(paths).size !== paths.length) return null;
|
|
27044
|
+
for (const path of paths) {
|
|
27045
|
+
if (path.includes("\\") || path.startsWith("/") || /^[A-Za-z]:\//.test(path) || path.split("/").some((segment) => !segment || segment === "." || segment === ".." || segment.startsWith(".")) || path.startsWith("input-attachments/") || ["AGENTS.md", "SOUL.md"].includes(path.split("/").at(-1) ?? "")) return null;
|
|
27046
|
+
}
|
|
27047
|
+
return paths;
|
|
27048
|
+
}
|
|
26937
27049
|
function approvedMcpInvocationSucceeded(results, invocationId) {
|
|
26938
27050
|
const approvedInvocationId = readString(invocationId);
|
|
26939
27051
|
return Boolean(approvedInvocationId && (Array.isArray(results) ? results : []).some((rawResult) => {
|
|
@@ -26991,10 +27103,18 @@ function governedMcpToolResult(structuredContent) {
|
|
|
26991
27103
|
const epochKey = readString(effectResult.epochKey);
|
|
26992
27104
|
const existingOwner = asRecord(effectResult.existingOwner);
|
|
26993
27105
|
const existingOwnerEpoch = readNumber(existingOwner.executionEpoch, 0);
|
|
27106
|
+
const continuationChainId = readString(effectResult.chainId);
|
|
27107
|
+
const continuationIntentId = readString(effectResult.continuationIntentId);
|
|
27108
|
+
const continuationWakeId = readString(effectResult.wakeId);
|
|
27109
|
+
const continuationExecutionEpoch = readNumber(effectResult.executionEpoch, 0);
|
|
27110
|
+
const continuationCount = readNumber(effectResult.continuationCount, 0);
|
|
27111
|
+
const maxContinuations = readNumber(effectResult.maxContinuations, 0);
|
|
27112
|
+
const continuationCheckpointPathList = continuationCheckpointPaths(effectResult.checkpointPaths);
|
|
27113
|
+
const exactContinuation = runDisposition === "continuation_scheduled" && continuationChainId && continuationIntentId && continuationWakeId && Number.isSafeInteger(continuationExecutionEpoch) && continuationExecutionEpoch > 0 && Number.isSafeInteger(continuationCount) && continuationCount > 0 && Number.isSafeInteger(maxContinuations) && continuationCount <= maxContinuations && continuationCheckpointPathList !== null;
|
|
26994
27114
|
const exactQueuedWakeHandoff = runDisposition === "handoff_existing_live_path" && readString(existingOwner.kind) === "queued_wake" && Boolean(readString(existingOwner.id)) && ["pending_dispatch", "queued", "deferred_issue_execution"].includes(
|
|
26995
27115
|
readString(existingOwner.status) ?? ""
|
|
26996
27116
|
) && Number.isSafeInteger(existingOwnerEpoch) && existingOwnerEpoch > 0 && readString(existingOwner.nextAction) === "end_current_run";
|
|
26997
|
-
const terminalRunDisposition = status === "succeeded" && providerStatus === "accepted" && PI_TERMINAL_RUNTIME_ACTION_STATUSES.has(runtimeActionResultStatus ?? "") && PI_TERMINATING_RUNTIME_ACTION_TOOLS.has(runtimeActionToolName ?? "") && effectResult.mustEndRun === true && Boolean(expectedDispositions?.has(runDisposition ?? "")) && invocationId && readString(providerReceipt.provider) === "amaster_actions" && readString(providerReceipt.invocationId) === invocationId && readString(providerReceipt.status) === "accepted" && receiptRunId && receiptCommandId && receiptIssueId && runtimeActionCallId && receiptCallId === runtimeActionCallId && (runDisposition !== "waiting_human" || Boolean(interactionId && epochKey)) && (runDisposition !== "handoff_existing_live_path" || Boolean(epochKey && exactQueuedWakeHandoff)) ? {
|
|
27117
|
+
const terminalRunDisposition = status === "succeeded" && providerStatus === "accepted" && PI_TERMINAL_RUNTIME_ACTION_STATUSES.has(runtimeActionResultStatus ?? "") && PI_TERMINATING_RUNTIME_ACTION_TOOLS.has(runtimeActionToolName ?? "") && effectResult.mustEndRun === true && Boolean(expectedDispositions?.has(runDisposition ?? "")) && invocationId && readString(providerReceipt.provider) === "amaster_actions" && readString(providerReceipt.invocationId) === invocationId && readString(providerReceipt.status) === "accepted" && receiptRunId && receiptCommandId && receiptIssueId && runtimeActionCallId && receiptCallId === runtimeActionCallId && (runDisposition !== "waiting_human" || Boolean(interactionId && epochKey)) && (runDisposition !== "handoff_existing_live_path" || Boolean(epochKey && exactQueuedWakeHandoff)) && (runDisposition !== "continuation_scheduled" || Boolean(exactContinuation)) ? {
|
|
26998
27118
|
disposition: runDisposition,
|
|
26999
27119
|
actionType: receiptActionType,
|
|
27000
27120
|
toolName: runtimeActionToolName,
|
|
@@ -27005,6 +27125,17 @@ function governedMcpToolResult(structuredContent) {
|
|
|
27005
27125
|
issueId: receiptIssueId,
|
|
27006
27126
|
...interactionId ? { interactionId } : {},
|
|
27007
27127
|
...epochKey ? { epochKey } : {},
|
|
27128
|
+
...exactContinuation ? {
|
|
27129
|
+
continuation: {
|
|
27130
|
+
chainId: continuationChainId,
|
|
27131
|
+
intentId: continuationIntentId,
|
|
27132
|
+
wakeId: continuationWakeId,
|
|
27133
|
+
executionEpoch: continuationExecutionEpoch,
|
|
27134
|
+
count: continuationCount,
|
|
27135
|
+
max: maxContinuations,
|
|
27136
|
+
...continuationCheckpointPathList.length > 0 ? { checkpointPaths: continuationCheckpointPathList } : {}
|
|
27137
|
+
}
|
|
27138
|
+
} : {},
|
|
27008
27139
|
...exactQueuedWakeHandoff ? {
|
|
27009
27140
|
existingOwner: {
|
|
27010
27141
|
kind: "queued_wake",
|
|
@@ -27073,6 +27204,7 @@ function piTerminatingRunDispositionEvidence(results, expected = {}) {
|
|
|
27073
27204
|
if (!result2) return null;
|
|
27074
27205
|
const disposition = asRecord(result2.terminalRunDisposition);
|
|
27075
27206
|
const existingOwner = asRecord(disposition.existingOwner);
|
|
27207
|
+
const continuation = asRecord(disposition.continuation);
|
|
27076
27208
|
return {
|
|
27077
27209
|
kind: "runtime_action_run_disposition",
|
|
27078
27210
|
disposition: readString(disposition.disposition),
|
|
@@ -27085,6 +27217,17 @@ function piTerminatingRunDispositionEvidence(results, expected = {}) {
|
|
|
27085
27217
|
issueId: expectedIssueId,
|
|
27086
27218
|
...readString(disposition.interactionId) ? { interactionId: readString(disposition.interactionId) } : {},
|
|
27087
27219
|
...readString(disposition.epochKey) ? { epochKey: readString(disposition.epochKey) } : {},
|
|
27220
|
+
...readString(continuation.chainId) && readString(continuation.intentId) && readString(continuation.wakeId) ? {
|
|
27221
|
+
continuation: {
|
|
27222
|
+
chainId: readString(continuation.chainId),
|
|
27223
|
+
intentId: readString(continuation.intentId),
|
|
27224
|
+
wakeId: readString(continuation.wakeId),
|
|
27225
|
+
executionEpoch: readNumber(continuation.executionEpoch, 0),
|
|
27226
|
+
count: readNumber(continuation.count, 0),
|
|
27227
|
+
max: readNumber(continuation.max, 0),
|
|
27228
|
+
...Array.isArray(continuation.checkpointPaths) ? { checkpointPaths: continuation.checkpointPaths.map((entry) => readString(entry)).filter(Boolean) } : {}
|
|
27229
|
+
}
|
|
27230
|
+
} : {},
|
|
27088
27231
|
...readString(existingOwner.kind) === "queued_wake" && readString(existingOwner.id) ? {
|
|
27089
27232
|
existingOwner: {
|
|
27090
27233
|
kind: "queued_wake",
|
|
@@ -27173,7 +27316,8 @@ function classifyPiTerminalCleanupDisposition(parsed, runtimeArtifacts) {
|
|
|
27173
27316
|
diagnostics
|
|
27174
27317
|
};
|
|
27175
27318
|
}
|
|
27176
|
-
function classifyPiTurnLimitResult(parsed) {
|
|
27319
|
+
function classifyPiTurnLimitResult(parsed, options = {}) {
|
|
27320
|
+
if (options.authoritativeTerminalDisposition === true) return null;
|
|
27177
27321
|
const stopReason = readString(parsed?.stopReason);
|
|
27178
27322
|
if (parsed?.sawAgentSettled !== true || !Number.isInteger(parsed?.settledEventIndex) || parsed?.terminalEventType !== "agent_end" || !["toolUse", "tool_use"].includes(stopReason ?? "")) return null;
|
|
27179
27323
|
return {
|
|
@@ -27760,14 +27904,11 @@ function piRuntimeWebEvidence(event) {
|
|
|
27760
27904
|
}
|
|
27761
27905
|
function parsePiJsonl(stdout) {
|
|
27762
27906
|
let sessionId = null;
|
|
27763
|
-
let errorMessage = null;
|
|
27764
27907
|
let streamingText = "";
|
|
27765
27908
|
let sawTurnEnd = false;
|
|
27766
27909
|
let terminalEventType = null;
|
|
27767
27910
|
let stopReason = null;
|
|
27768
27911
|
let hasAssistantOutput = false;
|
|
27769
|
-
let nonCleanupErrorCount = 0;
|
|
27770
|
-
let nonCleanupErrorMessage = null;
|
|
27771
27912
|
let terminalEventIndex = null;
|
|
27772
27913
|
let sawAgentSettled = false;
|
|
27773
27914
|
let settledEventIndex = null;
|
|
@@ -27776,12 +27917,45 @@ function parsePiJsonl(stdout) {
|
|
|
27776
27917
|
const mcpToolResults = [];
|
|
27777
27918
|
const cleanupDiagnostics = [];
|
|
27778
27919
|
const diagnostics = [];
|
|
27920
|
+
const errorEvents = [];
|
|
27921
|
+
let retry = null;
|
|
27922
|
+
let turnStartIndex = -1;
|
|
27923
|
+
let successfulAssistantIndex = -1;
|
|
27779
27924
|
const usage = { inputTokens: 0, cachedInputTokens: 0, outputTokens: 0 };
|
|
27780
27925
|
for (const rawLine of String(stdout ?? "").split(/\r?\n/)) {
|
|
27781
27926
|
const event = parseJsonLine(rawLine.trim());
|
|
27782
27927
|
if (!event) continue;
|
|
27783
27928
|
eventIndex += 1;
|
|
27784
27929
|
mcpToolResults.push(...piMcpToolResults(event));
|
|
27930
|
+
if (event.type === "turn_start") turnStartIndex = eventIndex;
|
|
27931
|
+
if (event.type === "auto_retry_start") {
|
|
27932
|
+
const message = readString(event.errorMessage);
|
|
27933
|
+
const lastError = errorEvents.at(-1);
|
|
27934
|
+
const matched = Number.isSafeInteger(event.attempt) && event.attempt > 0 && (event.attempt === 1 || event.attempt === retry?.attempt + 1) && turnStartIndex >= 0 && lastError?.provider === true && lastError.message === message && lastError.eventIndex === terminalEventIndex && terminalEventType === "agent_end";
|
|
27935
|
+
const priorErrors = retry && event.attempt === retry.attempt + 1 ? retry.errors : [];
|
|
27936
|
+
retry = matched ? {
|
|
27937
|
+
attempt: event.attempt,
|
|
27938
|
+
startIndex: eventIndex,
|
|
27939
|
+
errors: [...priorErrors, ...errorEvents.filter((error) => error.eventIndex >= turnStartIndex && error.provider && error.message === message)]
|
|
27940
|
+
} : null;
|
|
27941
|
+
continue;
|
|
27942
|
+
}
|
|
27943
|
+
if (event.type === "auto_retry_end") {
|
|
27944
|
+
if (event.success === true && retry && event.attempt === retry.attempt && successfulAssistantIndex > retry.startIndex) {
|
|
27945
|
+
for (const error of retry.errors) error.recoveredAt = eventIndex;
|
|
27946
|
+
diagnostics.push({
|
|
27947
|
+
source: "provider",
|
|
27948
|
+
phase: "retry",
|
|
27949
|
+
severity: "info",
|
|
27950
|
+
code: "pi_provider_retry_recovered",
|
|
27951
|
+
attempt: retry.attempt,
|
|
27952
|
+
recoveredErrorEventCount: retry.errors.length,
|
|
27953
|
+
eventIndex
|
|
27954
|
+
});
|
|
27955
|
+
}
|
|
27956
|
+
retry = null;
|
|
27957
|
+
continue;
|
|
27958
|
+
}
|
|
27785
27959
|
if (event.type === "session") {
|
|
27786
27960
|
sessionId = readString(event.sessionId) ?? readString(event.id) ?? sessionId;
|
|
27787
27961
|
continue;
|
|
@@ -27817,9 +27991,12 @@ function parsePiJsonl(stdout) {
|
|
|
27817
27991
|
stopReason = readString(event.stopReason ?? event.stop_reason) ?? piNestedMessageStopReason(event) ?? stopReason;
|
|
27818
27992
|
const terminalError = piStopReasonErrorText(event) ?? piNestedMessageErrorText(event);
|
|
27819
27993
|
if (terminalError) {
|
|
27820
|
-
|
|
27821
|
-
|
|
27822
|
-
|
|
27994
|
+
errorEvents.push({
|
|
27995
|
+
message: terminalError,
|
|
27996
|
+
eventIndex,
|
|
27997
|
+
provider: classifyPiProviderError({ errorMessage: terminalError })?.errorFamily === "transient_upstream"
|
|
27998
|
+
});
|
|
27999
|
+
successfulAssistantIndex = -1;
|
|
27823
28000
|
if (PI_PROVIDER_PROTOCOL_RE.test(terminalError)) {
|
|
27824
28001
|
diagnostics.push({
|
|
27825
28002
|
source: "provider",
|
|
@@ -27831,6 +28008,9 @@ function parsePiJsonl(stdout) {
|
|
|
27831
28008
|
});
|
|
27832
28009
|
}
|
|
27833
28010
|
}
|
|
28011
|
+
if (event.type === "message_end" && asRecord(event.message).role === "assistant" && !terminalError && ["stop", "toolUse"].includes(piMessageStopReason(event.message))) {
|
|
28012
|
+
successfulAssistantIndex = eventIndex;
|
|
28013
|
+
}
|
|
27834
28014
|
hasAssistantOutput = maybeCapturePiMessage(event, messages, usage) || hasAssistantOutput;
|
|
27835
28015
|
continue;
|
|
27836
28016
|
}
|
|
@@ -27850,11 +28030,9 @@ function parsePiJsonl(stdout) {
|
|
|
27850
28030
|
...diagnostic,
|
|
27851
28031
|
eventIndex
|
|
27852
28032
|
});
|
|
27853
|
-
errorMessage = nonCleanupErrorMessage ?? eventError;
|
|
27854
28033
|
} else {
|
|
27855
|
-
|
|
27856
|
-
|
|
27857
|
-
errorMessage = eventError;
|
|
28034
|
+
errorEvents.push({ message: eventError, eventIndex, provider: false });
|
|
28035
|
+
successfulAssistantIndex = -1;
|
|
27858
28036
|
if (PI_PROVIDER_PROTOCOL_RE.test(eventError)) {
|
|
27859
28037
|
diagnostics.push({
|
|
27860
28038
|
source: "provider",
|
|
@@ -27868,6 +28046,9 @@ function parsePiJsonl(stdout) {
|
|
|
27868
28046
|
}
|
|
27869
28047
|
}
|
|
27870
28048
|
}
|
|
28049
|
+
const unresolvedErrors = errorEvents.filter((error) => !(Number.isInteger(error.recoveredAt) && terminalEventIndex > error.recoveredAt && sawAgentSettled && settledEventIndex > terminalEventIndex));
|
|
28050
|
+
const nonCleanupErrorCount = unresolvedErrors.length;
|
|
28051
|
+
const errorMessage = unresolvedErrors.at(-1)?.message ?? cleanupDiagnostics.at(-1)?.message ?? null;
|
|
27871
28052
|
const uniqueMcpToolResults = dedupeGovernedMcpToolResults(mcpToolResults);
|
|
27872
28053
|
return {
|
|
27873
28054
|
sessionId,
|
|
@@ -29862,7 +30043,7 @@ function assertRequiredTaskAttachmentMaterialized(input, materialized) {
|
|
|
29862
30043
|
}
|
|
29863
30044
|
|
|
29864
30045
|
// src/amaster-runtime-daemon.mjs
|
|
29865
|
-
var CONNECTOR_VERSION = "0.1.1-beta.
|
|
30046
|
+
var CONNECTOR_VERSION = "0.1.1-beta.227";
|
|
29866
30047
|
var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
|
|
29867
30048
|
var daemonRequire = createRequire(import.meta.url);
|
|
29868
30049
|
var MAX_CHECKPOINT_BYTES = 20 * 1024 * 1024;
|
|
@@ -29878,7 +30059,7 @@ var activeRunCommands = /* @__PURE__ */ new Map();
|
|
|
29878
30059
|
var pendingResultOutboxRunCommands = /* @__PURE__ */ new Map();
|
|
29879
30060
|
var pendingRunCompletionCommands = /* @__PURE__ */ new Map();
|
|
29880
30061
|
var runCompletionFlights = /* @__PURE__ */ new Map();
|
|
29881
|
-
var
|
|
30062
|
+
var localDispatchCommands = /* @__PURE__ */ new Map();
|
|
29882
30063
|
var workspaceStatusHashCache = /* @__PURE__ */ new Map();
|
|
29883
30064
|
var processGroupRssSampleCache = null;
|
|
29884
30065
|
var lastOrphanReaperRunAtMs = 0;
|
|
@@ -29952,6 +30133,7 @@ function runCompletionStateActiveRunCommands(config) {
|
|
|
29952
30133
|
const command = asRecord(state.command);
|
|
29953
30134
|
return {
|
|
29954
30135
|
commandId: state.commandId,
|
|
30136
|
+
executionLane: normalizeRuntimeExecutionLane(command.executionLane),
|
|
29955
30137
|
...readString(commandRunId(command)) ? { runId: readString(commandRunId(command)) } : {},
|
|
29956
30138
|
...readString(commandIssueId(command)) ? { issueId: readString(commandIssueId(command)) } : {},
|
|
29957
30139
|
...readString(executor.kind) ? { executorKind: readString(executor.kind) } : {},
|
|
@@ -29980,6 +30162,7 @@ function resultOutboxActiveRunCommands(config) {
|
|
|
29980
30162
|
if (!commandId) continue;
|
|
29981
30163
|
entries.push({
|
|
29982
30164
|
commandId,
|
|
30165
|
+
executionLane: normalizeRuntimeExecutionLane(activeRun.executionLane),
|
|
29983
30166
|
...readString(activeRun.runId) ? { runId: readString(activeRun.runId) } : {},
|
|
29984
30167
|
...readString(activeRun.issueId) ? { issueId: readString(activeRun.issueId) } : {},
|
|
29985
30168
|
...readString(activeRun.executorKind) ? { executorKind: readString(activeRun.executorKind) } : {},
|
|
@@ -30384,7 +30567,7 @@ function buildHeartbeatPayload(config, options = {}) {
|
|
|
30384
30567
|
const orphanReaperSummary = asRecord(options.orphanReaper ?? lastOrphanReaperSummary);
|
|
30385
30568
|
const activeRunCommandById = /* @__PURE__ */ new Map();
|
|
30386
30569
|
for (const entry of [
|
|
30387
|
-
...Array.from(
|
|
30570
|
+
...Array.from(localDispatchCommands.values()),
|
|
30388
30571
|
...Array.from(activeRunCommands.values()),
|
|
30389
30572
|
...Array.from(pendingResultOutboxRunCommands.values()),
|
|
30390
30573
|
...Array.from(pendingRunCompletionCommands.values()),
|
|
@@ -30695,7 +30878,14 @@ function activeRunHeartbeatIntervalMs(config) {
|
|
|
30695
30878
|
}
|
|
30696
30879
|
function maxConcurrentCommands(config) {
|
|
30697
30880
|
const configured = Number(config.maxConcurrentCommands);
|
|
30698
|
-
return
|
|
30881
|
+
return localRuntimeCommandLimit({
|
|
30882
|
+
businessLimit: Number.isInteger(configured) && configured > 0 ? configured : 1,
|
|
30883
|
+
capabilities: config.capabilities
|
|
30884
|
+
});
|
|
30885
|
+
}
|
|
30886
|
+
function maxConcurrentBusinessCommands(config) {
|
|
30887
|
+
const configured = Number(config.maxConcurrentCommands);
|
|
30888
|
+
return Number.isInteger(configured) && configured > 0 ? Math.min(configured, 3) : 1;
|
|
30699
30889
|
}
|
|
30700
30890
|
function activeRunCommandCount(config, options = {}) {
|
|
30701
30891
|
const excludeCommandIds = new Set(readStringArray(options.excludeCommandIds));
|
|
@@ -30704,19 +30894,54 @@ function activeRunCommandCount(config, options = {}) {
|
|
|
30704
30894
|
...pendingResultOutboxRunCommands.keys(),
|
|
30705
30895
|
...pendingRunCompletionCommands.keys(),
|
|
30706
30896
|
...runCompletionStateEntries(config).map(({ state }) => state.commandId),
|
|
30707
|
-
...
|
|
30897
|
+
...localDispatchCommands.keys()
|
|
30708
30898
|
].filter((commandId) => !excludeCommandIds.has(commandId)));
|
|
30709
30899
|
return commandIds.size;
|
|
30710
30900
|
}
|
|
30711
30901
|
function availableCommandSlots(config) {
|
|
30712
30902
|
return Math.max(0, maxConcurrentCommands(config) - activeRunCommandCount(config));
|
|
30713
30903
|
}
|
|
30904
|
+
function activeRuntimeExecutionLanes(config) {
|
|
30905
|
+
const laneByCommandId = /* @__PURE__ */ new Map();
|
|
30906
|
+
for (const entry of [
|
|
30907
|
+
...activeRunCommands.values(),
|
|
30908
|
+
...pendingResultOutboxRunCommands.values(),
|
|
30909
|
+
...pendingRunCompletionCommands.values(),
|
|
30910
|
+
...runCompletionStateActiveRunCommands(config),
|
|
30911
|
+
...localDispatchCommands.values()
|
|
30912
|
+
]) {
|
|
30913
|
+
const commandId = readString(entry.commandId);
|
|
30914
|
+
if (!commandId) continue;
|
|
30915
|
+
const lane = runtimeExecutionLaneForCapabilities(entry.executionLane, config.capabilities);
|
|
30916
|
+
if (!laneByCommandId.has(commandId) || lane === "conversation") {
|
|
30917
|
+
laneByCommandId.set(commandId, lane);
|
|
30918
|
+
}
|
|
30919
|
+
}
|
|
30920
|
+
return [...laneByCommandId.values()];
|
|
30921
|
+
}
|
|
30922
|
+
function locallyAdmittedCommands(config, commands) {
|
|
30923
|
+
const admitted = selectRuntimeCommandsWithinLaneLimits({
|
|
30924
|
+
commands,
|
|
30925
|
+
activeLanes: activeRuntimeExecutionLanes(config),
|
|
30926
|
+
businessLimit: Number(config.maxConcurrentCommands),
|
|
30927
|
+
totalLimit: maxConcurrentCommands(config),
|
|
30928
|
+
capabilities: config.capabilities
|
|
30929
|
+
});
|
|
30930
|
+
if (admitted.length !== commands.length) {
|
|
30931
|
+
process.stderr.write(
|
|
30932
|
+
`AMaster daemon deferred ${commands.length - admitted.length} leased command(s) at the local execution-lane guard.
|
|
30933
|
+
`
|
|
30934
|
+
);
|
|
30935
|
+
}
|
|
30936
|
+
return admitted;
|
|
30937
|
+
}
|
|
30714
30938
|
function rememberActiveRunCommand(command, metadata) {
|
|
30715
30939
|
const commandId = readString(command.commandId) ?? readString(command.id);
|
|
30716
30940
|
if (!commandId) return () => {
|
|
30717
30941
|
};
|
|
30718
30942
|
activeRunCommands.set(commandId, {
|
|
30719
30943
|
commandId,
|
|
30944
|
+
executionLane: normalizeRuntimeExecutionLane(command.executionLane),
|
|
30720
30945
|
...readString(commandRunId(command)) ? { runId: readString(commandRunId(command)) } : {},
|
|
30721
30946
|
...readString(commandIssueId(command)) ? { issueId: readString(commandIssueId(command)) } : {},
|
|
30722
30947
|
...metadata.executorKind ? { executorKind: metadata.executorKind } : {},
|
|
@@ -30913,6 +31138,7 @@ async function poll(config) {
|
|
|
30913
31138
|
const body = await postJson(config, `/api/amaster/runtime-connectors/${connectorId}/commands/poll`, {
|
|
30914
31139
|
limit: Math.max(1, limit),
|
|
30915
31140
|
maxConcurrentCommands: maxCommands,
|
|
31141
|
+
maxConcurrentBusinessCommands: maxConcurrentBusinessCommands(config),
|
|
30916
31142
|
leaseId: `amaster-${Date.now()}`,
|
|
30917
31143
|
leaseSeconds: config.leaseSeconds
|
|
30918
31144
|
});
|
|
@@ -32397,7 +32623,7 @@ function walkManagedWorkdirs(root) {
|
|
|
32397
32623
|
}
|
|
32398
32624
|
function activeRuntimeExecutionRefs() {
|
|
32399
32625
|
const activeRunIds = /* @__PURE__ */ new Set();
|
|
32400
|
-
const activeCommandIds = new Set(
|
|
32626
|
+
const activeCommandIds = new Set(localDispatchCommands.keys());
|
|
32401
32627
|
const activeWorkspacePaths = /* @__PURE__ */ new Set();
|
|
32402
32628
|
for (const entry of [
|
|
32403
32629
|
...Array.from(activeRunCommands.values()),
|
|
@@ -32879,6 +33105,7 @@ function pendingRunCompletionSnapshot(config, state) {
|
|
|
32879
33105
|
const execution = asRecord(executor.closureExecution);
|
|
32880
33106
|
return {
|
|
32881
33107
|
commandId: state.commandId,
|
|
33108
|
+
executionLane: normalizeRuntimeExecutionLane(command.executionLane),
|
|
32882
33109
|
...readString(commandRunId(command)) ? { runId: readString(commandRunId(command)) } : {},
|
|
32883
33110
|
...readString(commandIssueId(command)) ? { issueId: readString(commandIssueId(command)) } : {},
|
|
32884
33111
|
...readString(executor.kind) ? { executorKind: readString(executor.kind) } : {},
|
|
@@ -34107,6 +34334,7 @@ function resultOutboxActiveRunSnapshot(command) {
|
|
|
34107
34334
|
if (!current) return null;
|
|
34108
34335
|
return {
|
|
34109
34336
|
commandId,
|
|
34337
|
+
executionLane: normalizeRuntimeExecutionLane(current.executionLane),
|
|
34110
34338
|
...readString(current.runId) ? { runId: readString(current.runId) } : {},
|
|
34111
34339
|
...readString(current.issueId) ? { issueId: readString(current.issueId) } : {},
|
|
34112
34340
|
...readString(current.executorKind) ? { executorKind: readString(current.executorKind) } : {},
|
|
@@ -34639,10 +34867,36 @@ function safeCheckpointRelativePath(rawPath) {
|
|
|
34639
34867
|
function hashFileSha256(filePath) {
|
|
34640
34868
|
return createHash17("sha256").update(readFileSync18(filePath)).digest("hex");
|
|
34641
34869
|
}
|
|
34870
|
+
function expectedContinuationCheckpoint(command) {
|
|
34871
|
+
const payload = asRecord(command.payload);
|
|
34872
|
+
const envelope = asRecord(payload.contextEnvelope);
|
|
34873
|
+
const context = asRecord(asRecord(envelope.runDecisionContext).content);
|
|
34874
|
+
if (readString(context.wakeReason) !== "continue_task") return null;
|
|
34875
|
+
const rawPaths = context.checkpointPaths;
|
|
34876
|
+
if (rawPaths === void 0) return null;
|
|
34877
|
+
if (!Array.isArray(rawPaths) || rawPaths.length < 1 || rawPaths.length > 20) {
|
|
34878
|
+
throw new Error("continuation_checkpoint_contract_invalid: checkpointPaths");
|
|
34879
|
+
}
|
|
34880
|
+
const paths = rawPaths.map((entry) => safeCheckpointRelativePath(readString(entry)));
|
|
34881
|
+
if (paths.some((entry) => !entry) || new Set(paths).size !== paths.length) {
|
|
34882
|
+
throw new Error("continuation_checkpoint_contract_invalid: checkpointPaths");
|
|
34883
|
+
}
|
|
34884
|
+
const sourceRunId = readString(context.sourceRunId);
|
|
34885
|
+
const continuationChainId = readString(context.continuationChainId);
|
|
34886
|
+
const continuationIntentId = readString(context.continuationIntentId);
|
|
34887
|
+
if (!sourceRunId || !continuationChainId || !continuationIntentId) {
|
|
34888
|
+
throw new Error("continuation_checkpoint_contract_invalid: lineage");
|
|
34889
|
+
}
|
|
34890
|
+
return { paths, sourceRunId, continuationChainId, continuationIntentId };
|
|
34891
|
+
}
|
|
34642
34892
|
async function materializeIssueCheckpoint(config, command, workspace) {
|
|
34643
34893
|
const checkpointDir = issueCheckpointDir(workspace);
|
|
34644
34894
|
const manifestPath = join17(checkpointDir, "manifest.json");
|
|
34645
|
-
|
|
34895
|
+
const expectedContinuation = expectedContinuationCheckpoint(command);
|
|
34896
|
+
if (!existsSync17(manifestPath)) {
|
|
34897
|
+
if (expectedContinuation) throw new Error("continuation_checkpoint_unavailable: manifest_missing");
|
|
34898
|
+
return [];
|
|
34899
|
+
}
|
|
34646
34900
|
let manifest;
|
|
34647
34901
|
try {
|
|
34648
34902
|
manifest = asRecord(JSON.parse(readFileSync18(manifestPath, "utf8")));
|
|
@@ -34653,11 +34907,21 @@ async function materializeIssueCheckpoint(config, command, workspace) {
|
|
|
34653
34907
|
const expiresAt = Date.parse(readString(manifest.expiresAt) ?? "");
|
|
34654
34908
|
if (!Number.isFinite(expiresAt) || expiresAt <= Date.now() || readString(manifest.issueId) !== commandIssueId(command)) {
|
|
34655
34909
|
rmSync9(checkpointDir, { recursive: true, force: true });
|
|
34910
|
+
if (expectedContinuation) throw new Error("continuation_checkpoint_unavailable: manifest_expired_or_mismatched");
|
|
34656
34911
|
return [];
|
|
34657
34912
|
}
|
|
34658
34913
|
try {
|
|
34914
|
+
if (readString(manifest.kind) === "continue_task" && !expectedContinuation) {
|
|
34915
|
+
return [];
|
|
34916
|
+
}
|
|
34659
34917
|
const files = Array.isArray(manifest.files) ? manifest.files : [];
|
|
34660
34918
|
if (files.length > 20) throw new Error("issue checkpoint manifest exceeds the limit of 20 files");
|
|
34919
|
+
if (expectedContinuation) {
|
|
34920
|
+
const manifestPaths = files.map((entry) => safeCheckpointRelativePath(readString(asRecord(entry).path)));
|
|
34921
|
+
if (readString(manifest.kind) !== "continue_task" || readString(manifest.sourceRunId) !== expectedContinuation.sourceRunId || readString(manifest.continuationChainId) !== expectedContinuation.continuationChainId || readString(manifest.continuationIntentId) !== expectedContinuation.continuationIntentId || manifestPaths.some((entry) => !entry) || manifestPaths.length !== expectedContinuation.paths.length || manifestPaths.some((entry, index) => entry !== expectedContinuation.paths[index])) {
|
|
34922
|
+
throw new Error("continuation_checkpoint_lineage_mismatch");
|
|
34923
|
+
}
|
|
34924
|
+
}
|
|
34661
34925
|
const filesRoot = realpathSync8(join17(checkpointDir, "files"));
|
|
34662
34926
|
const workspaceRoot = realpathSync8(workspace.cwd);
|
|
34663
34927
|
const validated = [];
|
|
@@ -34686,22 +34950,45 @@ async function materializeIssueCheckpoint(config, command, workspace) {
|
|
|
34686
34950
|
}
|
|
34687
34951
|
totalBytes += expectedByteSize;
|
|
34688
34952
|
if (totalBytes > MAX_CHECKPOINT_BYTES) throw new Error("issue checkpoint exceeds the 20 MB restore limit");
|
|
34689
|
-
validated.push({
|
|
34953
|
+
validated.push({
|
|
34954
|
+
relativePath,
|
|
34955
|
+
source,
|
|
34956
|
+
target,
|
|
34957
|
+
expectedSha256,
|
|
34958
|
+
expectedByteSize
|
|
34959
|
+
});
|
|
34690
34960
|
}
|
|
34691
34961
|
const materialized = [];
|
|
34692
|
-
for (const { relativePath, source, target } of validated) {
|
|
34693
|
-
try {
|
|
34694
|
-
lstatSync11(target);
|
|
34695
|
-
continue;
|
|
34696
|
-
} catch (err) {
|
|
34697
|
-
if (err?.code !== "ENOENT") throw err;
|
|
34698
|
-
}
|
|
34962
|
+
for (const { relativePath, source, target, expectedSha256, expectedByteSize } of validated) {
|
|
34699
34963
|
mkdirSync9(dirname11(target), { recursive: true });
|
|
34700
34964
|
const targetParent = realpathSync8(dirname11(target));
|
|
34701
34965
|
if (!pathWithin3(targetParent, workspaceRoot)) {
|
|
34702
34966
|
throw new Error(`issue checkpoint target escapes its workspace: ${relativePath}`);
|
|
34703
34967
|
}
|
|
34704
|
-
|
|
34968
|
+
let existingTarget = null;
|
|
34969
|
+
try {
|
|
34970
|
+
existingTarget = lstatSync11(target);
|
|
34971
|
+
} catch (err) {
|
|
34972
|
+
if (err?.code !== "ENOENT") throw err;
|
|
34973
|
+
}
|
|
34974
|
+
if (existingTarget && !existingTarget.isFile()) {
|
|
34975
|
+
throw new Error(`issue checkpoint target is not a regular file: ${relativePath}`);
|
|
34976
|
+
}
|
|
34977
|
+
if (existingTarget && existingTarget.size === expectedByteSize && hashFileSha256(target) === expectedSha256) {
|
|
34978
|
+
materialized.push(relativePath);
|
|
34979
|
+
continue;
|
|
34980
|
+
}
|
|
34981
|
+
const temporaryTarget = join17(targetParent, `.${basename8(target)}.checkpoint-${randomUUID()}.tmp`);
|
|
34982
|
+
try {
|
|
34983
|
+
copyFileSync2(source, temporaryTarget);
|
|
34984
|
+
const temporaryStat = lstatSync11(temporaryTarget);
|
|
34985
|
+
if (!temporaryStat.isFile() || temporaryStat.size !== expectedByteSize || hashFileSha256(temporaryTarget) !== expectedSha256) {
|
|
34986
|
+
throw new Error(`issue checkpoint target verification failed: ${relativePath}`);
|
|
34987
|
+
}
|
|
34988
|
+
renameSync10(temporaryTarget, target);
|
|
34989
|
+
} finally {
|
|
34990
|
+
rmSync9(temporaryTarget, { force: true });
|
|
34991
|
+
}
|
|
34705
34992
|
materialized.push(relativePath);
|
|
34706
34993
|
}
|
|
34707
34994
|
if (materialized.length > 0) {
|
|
@@ -34723,48 +35010,112 @@ async function materializeIssueCheckpoint(config, command, workspace) {
|
|
|
34723
35010
|
throw restoreErr;
|
|
34724
35011
|
}
|
|
34725
35012
|
}
|
|
34726
|
-
async function saveIssueCheckpoint(config, command, workspace, candidates) {
|
|
35013
|
+
async function saveIssueCheckpoint(config, command, workspace, candidates, options = {}) {
|
|
34727
35014
|
const checkpointDir = issueCheckpointDir(workspace);
|
|
34728
|
-
const
|
|
34729
|
-
|
|
35015
|
+
const commandKey = readString(command.commandId)?.replace(/[^A-Za-z0-9_-]/g, "-") ?? randomUUID();
|
|
35016
|
+
const stagingDir = `${checkpointDir}.tmp-${commandKey}`;
|
|
35017
|
+
const backupDir = `${checkpointDir}.previous-${commandKey}`;
|
|
35018
|
+
const filesDir = join17(stagingDir, "files");
|
|
35019
|
+
rmSync9(stagingDir, { recursive: true, force: true });
|
|
35020
|
+
rmSync9(backupDir, { recursive: true, force: true });
|
|
34730
35021
|
mkdirSync9(filesDir, { recursive: true });
|
|
34731
|
-
|
|
34732
|
-
|
|
34733
|
-
|
|
34734
|
-
|
|
34735
|
-
const
|
|
34736
|
-
const
|
|
34737
|
-
|
|
34738
|
-
|
|
34739
|
-
|
|
34740
|
-
|
|
34741
|
-
|
|
34742
|
-
|
|
34743
|
-
|
|
34744
|
-
|
|
34745
|
-
|
|
34746
|
-
|
|
34747
|
-
|
|
34748
|
-
|
|
34749
|
-
|
|
34750
|
-
|
|
34751
|
-
|
|
34752
|
-
|
|
34753
|
-
|
|
34754
|
-
|
|
34755
|
-
|
|
34756
|
-
|
|
34757
|
-
|
|
34758
|
-
|
|
34759
|
-
|
|
34760
|
-
|
|
34761
|
-
|
|
34762
|
-
|
|
34763
|
-
|
|
34764
|
-
|
|
35022
|
+
try {
|
|
35023
|
+
const files = [];
|
|
35024
|
+
let totalBytes = 0;
|
|
35025
|
+
const workspaceRoot = realpathSync8(workspace.cwd);
|
|
35026
|
+
const requiredPaths = Array.isArray(options.requiredPaths) ? options.requiredPaths : [];
|
|
35027
|
+
const selectedCandidates = requiredPaths.length > 0 ? requiredPaths.map((requiredPath) => {
|
|
35028
|
+
const normalized = safeCheckpointRelativePath(requiredPath);
|
|
35029
|
+
if (!normalized) {
|
|
35030
|
+
throw new Error(`continuation_checkpoint_file_unavailable: ${requiredPath}`);
|
|
35031
|
+
}
|
|
35032
|
+
const sourceCandidate = resolve16(workspaceRoot, normalized);
|
|
35033
|
+
if (!pathWithin3(sourceCandidate, workspaceRoot)) {
|
|
35034
|
+
throw new Error(`continuation_checkpoint_file_unavailable: ${requiredPath}`);
|
|
35035
|
+
}
|
|
35036
|
+
let sourceStat;
|
|
35037
|
+
try {
|
|
35038
|
+
sourceStat = lstatSync11(sourceCandidate);
|
|
35039
|
+
} catch (err) {
|
|
35040
|
+
if (err?.code === "ENOENT") {
|
|
35041
|
+
throw new Error(`continuation_checkpoint_file_unavailable: ${requiredPath}`);
|
|
35042
|
+
}
|
|
35043
|
+
throw err;
|
|
35044
|
+
}
|
|
35045
|
+
if (!sourceStat.isFile()) {
|
|
35046
|
+
throw new Error(`continuation_checkpoint_file_unavailable: ${requiredPath}`);
|
|
35047
|
+
}
|
|
35048
|
+
const ownedSource = realpathSync8(sourceCandidate);
|
|
35049
|
+
if (!pathWithin3(ownedSource, workspaceRoot)) {
|
|
35050
|
+
throw new Error(`issue checkpoint source escapes its execution workspace: ${normalized}`);
|
|
35051
|
+
}
|
|
35052
|
+
return { rawPath: normalized, filePath: ownedSource };
|
|
35053
|
+
}) : candidates.slice(0, 20);
|
|
35054
|
+
for (const candidate of selectedCandidates) {
|
|
35055
|
+
const relativePath = safeCheckpointRelativePath(candidate.rawPath);
|
|
35056
|
+
const source = readString(candidate.filePath);
|
|
35057
|
+
if (!relativePath || !source || !existsSync17(source) || !statSync11(source).isFile()) {
|
|
35058
|
+
if (requiredPaths.length > 0) throw new Error(`continuation_checkpoint_file_unavailable: ${candidate.rawPath}`);
|
|
35059
|
+
continue;
|
|
35060
|
+
}
|
|
35061
|
+
const ownedSource = realpathSync8(source);
|
|
35062
|
+
if (!pathWithin3(ownedSource, workspaceRoot)) {
|
|
35063
|
+
throw new Error(`issue checkpoint source escapes its execution workspace: ${relativePath}`);
|
|
35064
|
+
}
|
|
35065
|
+
const byteSize = statSync11(ownedSource).size;
|
|
35066
|
+
if (byteSize <= 0 || totalBytes + byteSize > MAX_CHECKPOINT_BYTES) {
|
|
35067
|
+
if (requiredPaths.length > 0) throw new Error(`continuation_checkpoint_file_size_invalid: ${relativePath}`);
|
|
35068
|
+
continue;
|
|
35069
|
+
}
|
|
35070
|
+
const target = resolve16(filesDir, relativePath);
|
|
35071
|
+
if (!pathWithin3(target, filesDir)) continue;
|
|
35072
|
+
mkdirSync9(dirname11(target), { recursive: true });
|
|
35073
|
+
copyFileSync2(ownedSource, target);
|
|
35074
|
+
const storedStat = lstatSync11(target);
|
|
35075
|
+
if (!storedStat.isFile() || storedStat.size !== byteSize) {
|
|
35076
|
+
throw new Error(`issue checkpoint copy verification failed: ${relativePath}`);
|
|
35077
|
+
}
|
|
35078
|
+
totalBytes += byteSize;
|
|
35079
|
+
files.push({ path: relativePath, byteSize, sha256: hashFileSha256(target) });
|
|
35080
|
+
}
|
|
35081
|
+
if (files.length === 0) {
|
|
35082
|
+
rmSync9(stagingDir, { recursive: true, force: true });
|
|
35083
|
+
rmSync9(checkpointDir, { recursive: true, force: true });
|
|
35084
|
+
return null;
|
|
35085
|
+
}
|
|
35086
|
+
const manifest = {
|
|
35087
|
+
version: options.continuation ? 2 : 1,
|
|
35088
|
+
issueId: commandIssueId(command),
|
|
35089
|
+
sourceRunId: commandRunId(command),
|
|
35090
|
+
...options.continuation ? {
|
|
35091
|
+
kind: "continue_task",
|
|
35092
|
+
continuationChainId: options.continuation.chainId,
|
|
35093
|
+
continuationIntentId: options.continuation.intentId
|
|
35094
|
+
} : {},
|
|
35095
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35096
|
+
expiresAt: new Date(Date.now() + CHECKPOINT_TTL_MS).toISOString(),
|
|
35097
|
+
totalBytes,
|
|
35098
|
+
files
|
|
35099
|
+
};
|
|
35100
|
+
writeFileSync11(join17(stagingDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
|
|
34765
35101
|
`);
|
|
34766
|
-
|
|
34767
|
-
|
|
35102
|
+
const replacingExistingCheckpoint = existsSync17(checkpointDir);
|
|
35103
|
+
if (replacingExistingCheckpoint) renameSync10(checkpointDir, backupDir);
|
|
35104
|
+
try {
|
|
35105
|
+
renameSync10(stagingDir, checkpointDir);
|
|
35106
|
+
} catch (err) {
|
|
35107
|
+
if (replacingExistingCheckpoint && existsSync17(backupDir) && !existsSync17(checkpointDir)) {
|
|
35108
|
+
renameSync10(backupDir, checkpointDir);
|
|
35109
|
+
}
|
|
35110
|
+
throw err;
|
|
35111
|
+
}
|
|
35112
|
+
rmSync9(backupDir, { recursive: true, force: true });
|
|
35113
|
+
await ingestLog(config, command, "system", "info", `Saved ${files.length} issue checkpoint file(s) for continuation`, manifest);
|
|
35114
|
+
return manifest;
|
|
35115
|
+
} catch (err) {
|
|
35116
|
+
rmSync9(stagingDir, { recursive: true, force: true });
|
|
35117
|
+
throw err;
|
|
35118
|
+
}
|
|
34768
35119
|
}
|
|
34769
35120
|
function piOutputUsageMetadataMissing(parsed) {
|
|
34770
35121
|
const usage = parsed?.usage ?? {};
|
|
@@ -34837,7 +35188,7 @@ async function executeRunCommand(config, command) {
|
|
|
34837
35188
|
agentInstructionFiles: [...finalAgentInstructionFiles.values()].sort((left, right) => left.path.localeCompare(right.path)),
|
|
34838
35189
|
workspaceProjectInstructionProjection: workspaceProjectInstructionReceipt
|
|
34839
35190
|
});
|
|
34840
|
-
await materializeIssueCheckpoint(config, command, workspace);
|
|
35191
|
+
const materializedCheckpointFiles = await materializeIssueCheckpoint(config, command, workspace);
|
|
34841
35192
|
const requiredArtifactInputs = await materializeRequiredArtifactInputs(config, command, workspace);
|
|
34842
35193
|
let materializedAttachments = requiredArtifactInputs;
|
|
34843
35194
|
try {
|
|
@@ -35347,9 +35698,34 @@ async function executeRunCommand(config, command) {
|
|
|
35347
35698
|
commandId: command.commandId,
|
|
35348
35699
|
issueId: commandIssueId(command)
|
|
35349
35700
|
}) : null;
|
|
35701
|
+
let continuationCheckpoint = null;
|
|
35702
|
+
if (readString(terminalRunDisposition?.disposition) === "continuation_scheduled") {
|
|
35703
|
+
const continuation = asRecord(terminalRunDisposition.continuation);
|
|
35704
|
+
const checkpointPaths = Array.isArray(continuation.checkpointPaths) ? continuation.checkpointPaths.map((entry) => readString(entry)).filter(Boolean) : [];
|
|
35705
|
+
if (checkpointPaths.length > 0) {
|
|
35706
|
+
continuationCheckpoint = await saveIssueCheckpoint(
|
|
35707
|
+
config,
|
|
35708
|
+
command,
|
|
35709
|
+
workspace,
|
|
35710
|
+
workspaceStatus.artifacts.map((artifact) => ({
|
|
35711
|
+
rawPath: artifact.relativePath,
|
|
35712
|
+
filePath: resolve16(cwd, artifact.relativePath)
|
|
35713
|
+
})),
|
|
35714
|
+
{
|
|
35715
|
+
requiredPaths: checkpointPaths,
|
|
35716
|
+
continuation: {
|
|
35717
|
+
chainId: readString(continuation.chainId),
|
|
35718
|
+
intentId: readString(continuation.intentId)
|
|
35719
|
+
}
|
|
35720
|
+
}
|
|
35721
|
+
);
|
|
35722
|
+
} else {
|
|
35723
|
+
await clearIssueCheckpoint(config, command, workspace, "continue_task_without_checkpoint_paths");
|
|
35724
|
+
}
|
|
35725
|
+
}
|
|
35350
35726
|
if (terminalRunDisposition) {
|
|
35351
35727
|
const disposition = readString(terminalRunDisposition.disposition);
|
|
35352
|
-
parsed.summary = disposition === "handoff_existing_live_path" ? "This run handed control to the existing queued live path and ended normally without creating a duplicate interaction." : disposition === "waiting_human" ? "The requested human interaction was persisted; this run ended normally and will resume only under its continuation policy." : disposition === "waiting_external" ? "The external wait was persisted; this run ended normally and will resume only after the recorded condition is satisfied." : "The monitor schedule was persisted; this run ended normally and will resume only at the scheduled check.";
|
|
35728
|
+
parsed.summary = disposition === "handoff_existing_live_path" ? "This run handed control to the existing queued live path and ended normally without creating a duplicate interaction." : disposition === "continuation_scheduled" ? "A bounded continuation was persisted; this run ended normally so another queued command can use the released execution slot." : disposition === "waiting_human" ? "The requested human interaction was persisted; this run ended normally and will resume only under its continuation policy." : disposition === "waiting_external" ? "The external wait was persisted; this run ended normally and will resume only after the recorded condition is satisfied." : "The monitor schedule was persisted; this run ended normally and will resume only at the scheduled check.";
|
|
35353
35729
|
parsed.hasAssistantOutput = true;
|
|
35354
35730
|
await ingestLog(
|
|
35355
35731
|
config,
|
|
@@ -35527,7 +35903,9 @@ async function executeRunCommand(config, command) {
|
|
|
35527
35903
|
);
|
|
35528
35904
|
}
|
|
35529
35905
|
const parsedForValidation = parsed;
|
|
35530
|
-
const piTurnLimitFailure = executor.kind === "pi" && !cancelled && !hasOutputFlood && !hasArgumentAmplification && !hasMemoryLimit && execution.timedOut !== true && !execution.spawnError ? classifyPiTurnLimitResult(parsedForValidation
|
|
35906
|
+
const piTurnLimitFailure = executor.kind === "pi" && !cancelled && !hasOutputFlood && !hasArgumentAmplification && !hasMemoryLimit && execution.timedOut !== true && !execution.spawnError ? classifyPiTurnLimitResult(parsedForValidation, {
|
|
35907
|
+
authoritativeTerminalDisposition: Boolean(terminalRunDisposition)
|
|
35908
|
+
}) : null;
|
|
35531
35909
|
const piInvalidOutputError = executor.kind === "pi" ? piOutputValidationError(parsedForValidation, {
|
|
35532
35910
|
allowMissingTurnEnd: completionOutputStopped,
|
|
35533
35911
|
allowMissingAssistantOutput: execution.completionOutputType === "approval_required",
|
|
@@ -35591,6 +35969,14 @@ async function executeRunCommand(config, command) {
|
|
|
35591
35969
|
...costUsage ? { costUsage } : {},
|
|
35592
35970
|
...terminalTextRepair ? { terminalTextRepair: terminalTextRepair.audit } : {},
|
|
35593
35971
|
...terminalRunDisposition ? { terminalRunDisposition } : {},
|
|
35972
|
+
...continuationCheckpoint ? {
|
|
35973
|
+
continuationCheckpoint: {
|
|
35974
|
+
fileCount: continuationCheckpoint.files.length,
|
|
35975
|
+
totalBytes: continuationCheckpoint.totalBytes,
|
|
35976
|
+
paths: continuationCheckpoint.files.map((file) => file.path)
|
|
35977
|
+
}
|
|
35978
|
+
} : {},
|
|
35979
|
+
...materializedCheckpointFiles.length > 0 ? { materializedCheckpointFiles } : {},
|
|
35594
35980
|
...runtimeArtifacts.length > 0 ? { runtimeArtifacts } : {},
|
|
35595
35981
|
...runtimeDocuments.length > 0 ? { runtimeDocuments } : {},
|
|
35596
35982
|
outputTelemetry,
|
|
@@ -35898,10 +36284,14 @@ async function runOnce(config) {
|
|
|
35898
36284
|
const polled = await postJson(config, `/api/amaster/runtime-connectors/${config.connectorId}/commands/poll`, {
|
|
35899
36285
|
limit: Math.max(1, availableSlots),
|
|
35900
36286
|
maxConcurrentCommands: maxConcurrentCommands(config),
|
|
36287
|
+
maxConcurrentBusinessCommands: maxConcurrentBusinessCommands(config),
|
|
35901
36288
|
leaseId,
|
|
35902
36289
|
leaseSeconds: config.leaseSeconds
|
|
35903
36290
|
});
|
|
35904
|
-
const commands =
|
|
36291
|
+
const commands = locallyAdmittedCommands(
|
|
36292
|
+
config,
|
|
36293
|
+
Array.isArray(polled.commands) ? polled.commands : []
|
|
36294
|
+
);
|
|
35905
36295
|
await Promise.all(commands.map((command) => processCommand(config, command)));
|
|
35906
36296
|
return commands.length;
|
|
35907
36297
|
}
|
|
@@ -35931,13 +36321,23 @@ async function dispatchAvailableCommands(config, options = {}) {
|
|
|
35931
36321
|
const polled = await postJson(config, `/api/amaster/runtime-connectors/${config.connectorId}/commands/poll`, {
|
|
35932
36322
|
limit: Math.max(1, availableSlots),
|
|
35933
36323
|
maxConcurrentCommands: maxConcurrentCommands(config),
|
|
36324
|
+
maxConcurrentBusinessCommands: maxConcurrentBusinessCommands(config),
|
|
35934
36325
|
leaseId,
|
|
35935
36326
|
leaseSeconds: config.leaseSeconds
|
|
35936
36327
|
});
|
|
35937
|
-
const commands =
|
|
36328
|
+
const commands = locallyAdmittedCommands(
|
|
36329
|
+
config,
|
|
36330
|
+
Array.isArray(polled.commands) ? polled.commands : []
|
|
36331
|
+
);
|
|
35938
36332
|
for (const command of commands) {
|
|
35939
36333
|
const commandId = readString(command.commandId) ?? readString(command.id);
|
|
35940
|
-
if (commandId)
|
|
36334
|
+
if (commandId) {
|
|
36335
|
+
localDispatchCommands.set(commandId, {
|
|
36336
|
+
commandId,
|
|
36337
|
+
executionLane: normalizeRuntimeExecutionLane(command.executionLane),
|
|
36338
|
+
phase: "preparing"
|
|
36339
|
+
});
|
|
36340
|
+
}
|
|
35941
36341
|
void processCommand(config, command).catch((err) => {
|
|
35942
36342
|
const idForLog = commandId ?? "unknown";
|
|
35943
36343
|
const message = err instanceof Error ? err.stack || err.message : String(err);
|
|
@@ -35945,7 +36345,7 @@ async function dispatchAvailableCommands(config, options = {}) {
|
|
|
35945
36345
|
${message}
|
|
35946
36346
|
`);
|
|
35947
36347
|
}).finally(() => {
|
|
35948
|
-
if (commandId)
|
|
36348
|
+
if (commandId) localDispatchCommands.delete(commandId);
|
|
35949
36349
|
});
|
|
35950
36350
|
}
|
|
35951
36351
|
return commands.length;
|
package/dist/amaster-runtime.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import { homedir, hostname } from "node:os";
|
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
import { BUILD_SUPPORTED_CAPABILITIES } from "./amaster-runtime-daemon/capability-registry.mjs";
|
|
9
9
|
|
|
10
|
-
const CONNECTOR_VERSION = "0.1.1-beta.
|
|
10
|
+
const CONNECTOR_VERSION = "0.1.1-beta.227";
|
|
11
11
|
|
|
12
12
|
const CONFIG_KEY_MAP = new Map([
|
|
13
13
|
["server_url", "AMASTER_EMPLOYEE_SERVER_URL"],
|