@amaster.ai/employee-runtime-connector 0.1.1-beta.254 → 0.1.1-beta.256

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.
@@ -27,7 +27,7 @@ var toolNames = /* @__PURE__ */ new Set([
27
27
  "list_goals",
28
28
  "create_issue",
29
29
  "update_issue",
30
- "add_comment"
30
+ "add_issue_comment"
31
31
  ]);
32
32
  function validDelivery(value) {
33
33
  if (!record(value) || !uuid(value.turnId) || !uuid(value.companyId) || !uuid(value.conversationId) || !text(value.token, 64) || !/^[a-f0-9]{64}$/.test(value.token) || !(value.model === null || text(value.model, 200)))
@@ -5508,6 +5508,32 @@ var amasterRuntimeConnectorLogIngestSchema = external_exports.object({
5508
5508
  message: external_exports.string().max(16e3),
5509
5509
  payload: external_exports.record(external_exports.unknown()).default({})
5510
5510
  });
5511
+ var AMASTER_RUNTIME_CONNECTOR_LOG_BATCH_MAX_ENTRIES = 32;
5512
+ var AMASTER_RUNTIME_CONNECTOR_LOG_BATCH_MAX_BYTES = 128 * 1024;
5513
+ var amasterRuntimeConnectorLogIngestBatchSchema = external_exports.object({
5514
+ entries: external_exports.array(amasterRuntimeConnectorLogIngestSchema).min(1).max(AMASTER_RUNTIME_CONNECTOR_LOG_BATCH_MAX_ENTRIES)
5515
+ }).superRefine((value, ctx) => {
5516
+ const commandIds = new Set(value.entries.flatMap((entry) => entry.commandId ? [entry.commandId] : []));
5517
+ if (commandIds.size > 1) {
5518
+ ctx.addIssue({
5519
+ code: external_exports.ZodIssueCode.custom,
5520
+ path: ["entries"],
5521
+ message: "Runtime connector log batch entries must share one commandId"
5522
+ });
5523
+ }
5524
+ const serializedBytes = new TextEncoder().encode(JSON.stringify(value)).byteLength;
5525
+ if (serializedBytes > AMASTER_RUNTIME_CONNECTOR_LOG_BATCH_MAX_BYTES) {
5526
+ ctx.addIssue({
5527
+ code: external_exports.ZodIssueCode.too_big,
5528
+ type: "array",
5529
+ maximum: AMASTER_RUNTIME_CONNECTOR_LOG_BATCH_MAX_BYTES,
5530
+ inclusive: true,
5531
+ exact: false,
5532
+ path: ["entries"],
5533
+ message: "Runtime connector log batch exceeds 128 KiB"
5534
+ });
5535
+ }
5536
+ });
5511
5537
  var amasterRuntimeConnectorCostIngestSchema = external_exports.object({
5512
5538
  commandId: external_exports.string().uuid(),
5513
5539
  idempotencyKey: external_exports.string().trim().regex(/^runtime-command-cost:[0-9a-f-]{36}$/i).optional(),
@@ -30096,7 +30122,7 @@ function runtimeDecompositionRequirementText(context) {
30096
30122
  "Create the complete real direct child graph before doing any substantial source work.",
30097
30123
  "Before browsing, searching, commenting, or doing any source work, call runtime_action_describe for record_work_disposition with dispositionKind create_children and for every child action type you need.",
30098
30124
  "Persist one immutable runtime_action_plan whose first action is record_work_disposition kind create_children and whose remaining actions are exactly the complete child graph referenced by that disposition. Do not append update_parent, add_comment, upsert_document, or any other action after the child graph.",
30099
- "For each record_work_disposition structure child, copy scopeSummary exactly into the bound create_child_task description. The Server compares those normalized strings and rejects a missing or different description with work_disposition_child_scope_mismatch; delegation.objective does not satisfy that binding. Also copy ownerAgentId exactly into the bound create_child_task assigneeAgentId; mentioning an owner in delegation prose or title does not assign the child, and a missing or different explicit assignee is rejected with work_disposition_child_owner_binding_mismatch.",
30125
+ "For each record_work_disposition structure child, copy scopeSummary exactly into the bound create_child_issue description. The Server compares those normalized strings and rejects a missing or different description with work_disposition_child_scope_mismatch; delegation.objective does not satisfy that binding. Also copy ownerAgentId exactly into the bound create_child_issue assigneeAgentId; mentioning an owner in delegation prose or title does not assign the child, and a missing or different explicit assignee is rejected with work_disposition_child_owner_binding_mismatch.",
30100
30126
  "Execute that exact plan with runtime_action_commit.",
30101
30127
  "Once runtime_action_commit succeeds, the committed required child graph is this parent run's durable delegated live disposition.",
30102
30128
  "After runtime_action_commit succeeds, yield and end the parent run immediately. Do not browse, search, research, or execute any delegated child acceptance scope, and do not poll child runs. Child assignment runs are the sole execution path for delegated child scope.",
@@ -33516,7 +33542,7 @@ function assertRequiredTaskAttachmentMaterialized(input, materialized) {
33516
33542
  }
33517
33543
 
33518
33544
  // src/amaster-runtime-daemon.mjs
33519
- var CONNECTOR_VERSION = "0.1.1-beta.254";
33545
+ var CONNECTOR_VERSION = "0.1.1-beta.256";
33520
33546
  var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
33521
33547
  var daemonRequire = createRequire2(import.meta.url);
33522
33548
  var MAX_CHECKPOINT_BYTES = 20 * 1024 * 1024;
@@ -35645,6 +35671,25 @@ function redactProtectedText(value, protectedValues = []) {
35645
35671
  }
35646
35672
  return text3;
35647
35673
  }
35674
+ var RUNTIME_LOG_BATCH_MAX_ENTRIES = 32;
35675
+ var RUNTIME_LOG_BATCH_MAX_BYTES = 128 * 1024;
35676
+ var RUNTIME_LOG_BATCH_FLUSH_MS = 250;
35677
+ function runtimeLogBatchEntries(command, entries) {
35678
+ return entries.map((entry) => ({
35679
+ commandId: command.commandId,
35680
+ runId: commandRunId(command) ?? void 0,
35681
+ stream: entry.stream,
35682
+ level: entry.level,
35683
+ message: truncateText(entry.message),
35684
+ payload: entry.payload ?? {}
35685
+ }));
35686
+ }
35687
+ function runtimeLogBatchEntryBytes(command, entry) {
35688
+ return Buffer.byteLength(JSON.stringify(runtimeLogBatchEntries(command, [entry])[0]));
35689
+ }
35690
+ function runtimeLogBatchBytes(command, entries) {
35691
+ return Buffer.byteLength(JSON.stringify({ entries: runtimeLogBatchEntries(command, entries) }));
35692
+ }
35648
35693
  function createLiveOutputLogger(config, command, executorKind, protectedValues = [], onMcpToolResults = null, options = {}) {
35649
35694
  const buffers = { stdout: "", stderr: "" };
35650
35695
  const displayCounts = { stdout: 0, stderr: 0, system: 0 };
@@ -35667,6 +35712,16 @@ function createLiveOutputLogger(config, command, executorKind, protectedValues =
35667
35712
  let liveLogDeliveryFailed = false;
35668
35713
  let failedLiveLogDeliveryCount = 0;
35669
35714
  let skippedLiveLogDeliveryCount = 0;
35715
+ let logEntriesAttempted = 0;
35716
+ let logEntriesAccepted = 0;
35717
+ let logEntriesInvalidDropped = 0;
35718
+ let logEntriesAmbiguousDropped = 0;
35719
+ let logBatchRequestsAttempted = 0;
35720
+ let logBatchRequestsAccepted = 0;
35721
+ let firstLogDeliveryFailureCategory = null;
35722
+ let pendingBatch = [];
35723
+ let pendingBatchBytes = runtimeLogBatchBytes(command, []);
35724
+ let pendingBatchTimer = null;
35670
35725
  const piToolArgumentTracker = executorKind === "pi" ? createPiToolArgumentAmplificationTracker(options.piToolArgumentGuard) : null;
35671
35726
  const fullTranscriptEnabled = executorKind === "pi" && readString(asRecord(asRecord(command).payload).transcriptDetail) === AMASTER_RUNTIME_TRANSCRIPT_DETAIL_FULL;
35672
35727
  const maxEntriesPerStream = parsePositiveInteger(
@@ -35723,34 +35778,66 @@ function createLiveOutputLogger(config, command, executorKind, protectedValues =
35723
35778
  }
35724
35779
  nonProgressEventCount += 1;
35725
35780
  };
35726
- const deliverLiveLog = async (entry, options2 = {}) => {
35781
+ const deliverLiveLogBatch = async (entries, options2 = {}) => {
35782
+ if (entries.length === 0) return;
35727
35783
  const terminalSummary = options2.terminalSummary === true;
35728
- if (liveLogDeliveryFailed && !terminalSummary) {
35729
- skippedLiveLogDeliveryCount += 1;
35784
+ const bisectRecovery = options2.bisectRecovery === true;
35785
+ if (liveLogDeliveryFailed && !terminalSummary && !bisectRecovery) {
35786
+ skippedLiveLogDeliveryCount += entries.length;
35730
35787
  return;
35731
35788
  }
35732
- let deliveryFailed = false;
35733
- await ingestLog(
35734
- config,
35735
- command,
35736
- entry.stream,
35737
- entry.level,
35738
- truncateText(entry.message),
35739
- entry.payload ?? {},
35740
- {
35741
- timeoutMs: 1e3,
35742
- onError: (message) => {
35743
- deliveryFailed = true;
35744
- process.stderr.write(terminalSummary ? `${message}; terminal live-log summary was not delivered
35789
+ let deliveryError = null;
35790
+ if (!bisectRecovery) logEntriesAttempted += entries.length;
35791
+ logBatchRequestsAttempted += 1;
35792
+ const response = await ingestLogBatch(config, command, entries, {
35793
+ timeoutMs: 1e3,
35794
+ onError: (_message, error) => {
35795
+ deliveryError = error;
35796
+ }
35797
+ });
35798
+ if (response) {
35799
+ logEntriesAccepted += readNumber(response.acceptedCount, entries.length);
35800
+ logBatchRequestsAccepted += 1;
35801
+ return;
35802
+ }
35803
+ if (Number(deliveryError?.httpStatus) === 400) {
35804
+ firstLogDeliveryFailureCategory ??= "invalid";
35805
+ if (entries.length === 1) {
35806
+ logEntriesInvalidDropped += 1;
35807
+ failedLiveLogDeliveryCount += 1;
35808
+ return;
35809
+ }
35810
+ const midpoint = Math.floor(entries.length / 2);
35811
+ const recoveryOptions = { ...options2, bisectRecovery: true };
35812
+ await deliverLiveLogBatch(entries.slice(0, midpoint), recoveryOptions);
35813
+ await deliverLiveLogBatch(entries.slice(midpoint), recoveryOptions);
35814
+ return;
35815
+ }
35816
+ firstLogDeliveryFailureCategory ??= "ambiguous";
35817
+ logEntriesAmbiguousDropped += entries.length;
35818
+ if (!terminalSummary) liveLogDeliveryFailed = true;
35819
+ const message = `AMaster daemon could not determine whether ${entries.length} runtime log entr${entries.length === 1 ? "y was" : "ies were"} accepted`;
35820
+ process.stderr.write(terminalSummary ? `${message}; terminal live-log summary was not delivered
35745
35821
  ` : `${message}; suppressing remaining live logs for this executor turn
35746
35822
  `);
35747
- }
35748
- }
35749
- );
35750
- if (deliveryFailed) {
35751
- liveLogDeliveryFailed = true;
35752
- failedLiveLogDeliveryCount += 1;
35823
+ failedLiveLogDeliveryCount += 1;
35824
+ };
35825
+ const flushPendingBatch = () => {
35826
+ if (pendingBatchTimer) {
35827
+ clearTimeout(pendingBatchTimer);
35828
+ pendingBatchTimer = null;
35753
35829
  }
35830
+ if (pendingBatch.length === 0) return;
35831
+ const entries = pendingBatch;
35832
+ pendingBatch = [];
35833
+ pendingBatchBytes = runtimeLogBatchBytes(command, []);
35834
+ queue = queue.then(() => deliverLiveLogBatch(entries)).catch(() => {
35835
+ });
35836
+ };
35837
+ const schedulePendingBatch = () => {
35838
+ if (pendingBatchTimer) return;
35839
+ pendingBatchTimer = setTimeout(() => flushPendingBatch(), RUNTIME_LOG_BATCH_FLUSH_MS);
35840
+ pendingBatchTimer.unref?.();
35754
35841
  };
35755
35842
  const enqueue = (entry) => {
35756
35843
  const stream = entry.stream === "stderr" || entry.stream === "system" ? entry.stream : "stdout";
@@ -35759,8 +35846,19 @@ function createLiveOutputLogger(config, command, executorKind, protectedValues =
35759
35846
  return;
35760
35847
  }
35761
35848
  displayCounts[stream] = (displayCounts[stream] ?? 0) + 1;
35762
- queue = queue.then(() => deliverLiveLog(entry)).catch(() => {
35763
- });
35849
+ const entryBytes = runtimeLogBatchEntryBytes(command, entry);
35850
+ let candidateBatchBytes = pendingBatchBytes + (pendingBatch.length > 0 ? 1 : 0) + entryBytes;
35851
+ if (pendingBatch.length > 0 && (pendingBatch.length >= RUNTIME_LOG_BATCH_MAX_ENTRIES || candidateBatchBytes > RUNTIME_LOG_BATCH_MAX_BYTES)) {
35852
+ flushPendingBatch();
35853
+ candidateBatchBytes = pendingBatchBytes + entryBytes;
35854
+ }
35855
+ pendingBatch.push(entry);
35856
+ pendingBatchBytes = candidateBatchBytes;
35857
+ if (pendingBatch.length >= RUNTIME_LOG_BATCH_MAX_ENTRIES || pendingBatchBytes >= RUNTIME_LOG_BATCH_MAX_BYTES) {
35858
+ flushPendingBatch();
35859
+ } else {
35860
+ schedulePendingBatch();
35861
+ }
35764
35862
  };
35765
35863
  const shouldSuppressDuplicatePiAgentMessage = (entry) => {
35766
35864
  if (executorKind !== "pi") return false;
@@ -35890,22 +35988,25 @@ function createLiveOutputLogger(config, command, executorKind, protectedValues =
35890
35988
  }
35891
35989
  await observationQueue;
35892
35990
  if (observationError) throw observationError;
35991
+ flushPendingBatch();
35893
35992
  await queue;
35894
35993
  const suppressedSummaries = Object.entries(suppressedCounts).filter(([, count2]) => count2 > 0).map(([stream, count2]) => ({ stream, count: count2 }));
35895
- if (suppressedSummaries.length > 0) {
35994
+ if (suppressedSummaries.length > 0 || liveLogDeliveryFailed) {
35896
35995
  const suppressedCount = suppressedSummaries.reduce((total, summary) => total + summary.count, 0);
35897
- await deliverLiveLog({
35996
+ await deliverLiveLogBatch([{
35898
35997
  stream: "system",
35899
- level: "info",
35900
- message: `Runtime output summarized: ${suppressedCount} event(s) suppressed after ${maxEntriesPerStream} live log entries per stream`,
35998
+ level: liveLogDeliveryFailed ? "warn" : "info",
35999
+ message: liveLogDeliveryFailed ? `Runtime output delivery was incomplete: ${logEntriesAmbiguousDropped} entr${logEntriesAmbiguousDropped === 1 ? "y" : "ies"} had an ambiguous server outcome` : `Runtime output summarized: ${suppressedCount} event(s) suppressed after ${maxEntriesPerStream} live log entries per stream`,
35901
36000
  payload: {
35902
36001
  presentationKind: "output_summary",
35903
36002
  executorKind,
35904
36003
  suppressedCount,
35905
36004
  suppressedByStream: suppressedSummaries,
35906
- maxEntriesPerStream
36005
+ maxEntriesPerStream,
36006
+ deliveryIncomplete: liveLogDeliveryFailed,
36007
+ ambiguousDropped: logEntriesAmbiguousDropped
35907
36008
  }
35908
- }, { terminalSummary: true });
36009
+ }], { terminalSummary: true });
35909
36010
  }
35910
36011
  },
35911
36012
  hasStream(stream) {
@@ -35930,10 +36031,17 @@ function createLiveOutputLogger(config, command, executorKind, protectedValues =
35930
36031
  const normalizedFloodLimitBytes = readNumber(floodLimitBytes, 0);
35931
36032
  return {
35932
36033
  liveLogDelivery: {
35933
- status: liveLogDeliveryFailed ? "partial" : "complete",
36034
+ status: liveLogDeliveryFailed || logEntriesInvalidDropped > 0 ? "partial" : "complete",
35934
36035
  failed: failedLiveLogDeliveryCount,
35935
36036
  skipped: skippedLiveLogDeliveryCount
35936
36037
  },
36038
+ logEntriesAttempted,
36039
+ logEntriesAccepted,
36040
+ logEntriesInvalidDropped,
36041
+ logEntriesAmbiguousDropped,
36042
+ logBatchRequestsAttempted,
36043
+ logBatchRequestsAccepted,
36044
+ ...firstLogDeliveryFailureCategory ? { firstLogDeliveryFailureCategory } : {},
35937
36045
  rawBytesByStream,
35938
36046
  rawOutputBytes,
35939
36047
  retainedBytesByStream,
@@ -36573,6 +36681,15 @@ async function ingestLog(config, command, stream, level, message, payload = {},
36573
36681
  payload
36574
36682
  }, options);
36575
36683
  }
36684
+ async function ingestLogBatch(config, command, entries, options = {}) {
36685
+ const connectorId = requireConnectorId(config);
36686
+ return await bestEffortPostJson(
36687
+ config,
36688
+ `/api/amaster/runtime-connectors/${connectorId}/ingest/logs/batch`,
36689
+ { entries: runtimeLogBatchEntries(command, entries) },
36690
+ options
36691
+ );
36692
+ }
36576
36693
  function parsedUsageCostCents(usage) {
36577
36694
  const costUsd = readNumber(asRecord(usage).costUsd, 0);
36578
36695
  if (!Number.isFinite(costUsd) || costUsd <= 0) return 0;
@@ -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.254";
10
+ const CONNECTOR_VERSION = "0.1.1-beta.256";
11
11
 
12
12
  const CONFIG_KEY_MAP = new Map([
13
13
  ["server_url", "AMASTER_EMPLOYEE_SERVER_URL"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amaster.ai/employee-runtime-connector",
3
- "version": "0.1.1-beta.254",
3
+ "version": "0.1.1-beta.256",
4
4
  "description": "MirrorX runtime connector CLI and daemon",
5
5
  "license": "MIT",
6
6
  "type": "module",