@amaster.ai/employee-runtime-connector 0.1.0-beta.4 → 0.1.0-beta.5

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.
@@ -585,6 +585,23 @@ function piRuntimeActionText(message) {
585
585
  return text.includes("AMASTER_RUNTIME_ACTIONS") ? text : "";
586
586
  }
587
587
 
588
+ function piEventHasRuntimeActionMarkerInToolOutput(event) {
589
+ const directMessage = asRecord(event.message);
590
+ if (directMessage.role === "toolResult" && piRuntimeActionText(directMessage)) return true;
591
+
592
+ const eventMessages = Array.isArray(event.messages) ? event.messages : [];
593
+ if (eventMessages.some((message) => {
594
+ const record = asRecord(message);
595
+ return record.role === "toolResult" && Boolean(piRuntimeActionText(record));
596
+ })) return true;
597
+
598
+ const toolResults = Array.isArray(event.toolResults) ? event.toolResults : [];
599
+ if (toolResults.some((result) => Boolean(piRuntimeActionText(result)))) return true;
600
+
601
+ if (event.type === "tool_execution_end" && piRuntimeActionText(event.result)) return true;
602
+ return false;
603
+ }
604
+
588
605
  function appendUniqueText(values, text) {
589
606
  const normalized = typeof text === "string" ? text.trim() : "";
590
607
  if (!normalized) return false;
@@ -710,6 +727,7 @@ function parsePiJsonl(stdout) {
710
727
  let terminalEventType = null;
711
728
  let stopReason = null;
712
729
  let hasAssistantOutput = false;
730
+ let runtimeActionMarkerInToolOutput = false;
713
731
  const messages = [];
714
732
  const runtimeActionTexts = [];
715
733
  const usage = { inputTokens: 0, cachedInputTokens: 0, outputTokens: 0 };
@@ -717,6 +735,8 @@ function parsePiJsonl(stdout) {
717
735
  for (const rawLine of String(stdout ?? "").split(/\r?\n/)) {
718
736
  const event = parseJsonLine(rawLine.trim());
719
737
  if (!event) continue;
738
+ runtimeActionMarkerInToolOutput = piEventHasRuntimeActionMarkerInToolOutput(event)
739
+ || runtimeActionMarkerInToolOutput;
720
740
  if (event.type === "session") {
721
741
  sessionId = readString(event.id) ?? sessionId;
722
742
  continue;
@@ -755,6 +775,7 @@ function parsePiJsonl(stdout) {
755
775
  sessionId,
756
776
  summary: messages.at(-1) ?? "",
757
777
  runtimeActionText: runtimeActionTexts.join("\n\n"),
778
+ runtimeActionMarkerInToolOutput,
758
779
  usage,
759
780
  sawTurnEnd,
760
781
  terminalEventType,
@@ -2314,7 +2335,7 @@ import { copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSy
2314
2335
  import { homedir, hostname } from "node:os";
2315
2336
  import { basename, delimiter, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
2316
2337
  import { spawn, spawnSync } from "node:child_process";
2317
- const CONNECTOR_VERSION = "0.1.0-beta.4";
2338
+ const CONNECTOR_VERSION = "0.1.0-beta.5";
2318
2339
  const MAX_INFERRED_ARTIFACT_UPLOADS = 20;
2319
2340
  const MAX_CHECKPOINT_BYTES = 20 * 1024 * 1024;
2320
2341
  const CHECKPOINT_TTL_MS = 24 * 60 * 60 * 1000;
@@ -3532,9 +3553,10 @@ function runtimeActionsInstruction(options = {}) {
3532
3553
  options.canOrchestrateOrganization
3533
3554
  ? "When assigning a newly hired agent's first task in the same action batch, set clientKey on the agent_hire action and set assigneeAgentClientKey or agentClientKey on the create_child_task action to that same key. Do not leave the first task assigned to the current CEO/executing agent unless the CEO should actually do the work."
3534
3555
  : "",
3535
- "Fallback output format: write the marker AMASTER_RUNTIME_ACTIONS, then exactly one fenced json object. Use this literal shape with real action objects: {\"version\":1,\"actions\":[{\"type\":\"add_comment\",\"body\":\"Progress or result summary\"}]}.",
3536
- "The runtime action block must be strict JSON parseable by JSON.parse. Do not use ellipses, placeholders such as [...], comments, trailing commas, single quotes, markdown tables outside quoted strings, or raw double quotes inside string values. Escape quotes and newlines in string values, or generate the block with JSON.stringify / @amaster/runtime-sdk before printing it.",
3537
- "Before final output, validate the runtime action block with JSON.parse. If it would fail, fix the JSON and only then print AMASTER_RUNTIME_ACTIONS.",
3556
+ "Fallback output format: put the marker AMASTER_RUNTIME_ACTIONS in the final assistant message, then exactly one fenced json object. Use this literal shape with real action objects: {\"version\":1,\"actions\":[{\"type\":\"add_comment\",\"body\":\"Progress or result summary\"}]}.",
3557
+ "Never use write, bash, cat, printf, echo, or any other tool to emit the marker or JSON. You may prepare and validate the envelope in a temporary workspace file, but the final assistant message itself must contain the exact marker and JSON; tool output is ignored by the runtime action bridge.",
3558
+ "The runtime action block must be strict JSON parseable by JSON.parse. Do not use ellipses, placeholders such as [...], comments, trailing commas, single quotes, markdown tables outside quoted strings, or raw double quotes inside string values. Escape quotes and newlines in string values, or generate the block with JSON.stringify / @amaster/runtime-sdk before including it in the final assistant message.",
3559
+ "Before final output, validate the runtime action block with JSON.parse. If it would fail, fix the JSON and only then include AMASTER_RUNTIME_ACTIONS in the final assistant message.",
3538
3560
  `Allowed action types: ${allowedActionTypes}.`,
3539
3561
  "For every create_interaction action, set top-level kind to the interaction kind and set payload to a JSON object. Use this complete canonical request_confirmation example: {\"type\":\"create_interaction\",\"kind\":\"request_confirmation\",\"payload\":{\"version\":1,\"prompt\":\"Confirm this result?\",\"acceptLabel\":\"确认\",\"rejectLabel\":\"调整\"}}. Never use interactionType.",
3540
3562
  "For create_interaction ask_user_questions, use payload {\"version\":1,\"title\":\"...\",\"questions\":[{\"id\":\"question_key\",\"prompt\":\"Question text\",\"selectionMode\":\"single\",\"required\":true,\"options\":[{\"id\":\"option_key\",\"label\":\"Option label\"}]}]}. Do not use question/options.value at the top level.",
@@ -7943,6 +7965,14 @@ function classifyRuntimeActionFailure(err) {
7943
7965
  ...(diagnostics ? { runtimeActionDiagnostics: diagnostics } : {}),
7944
7966
  };
7945
7967
  }
7968
+ if (actionType === "output_channel") {
7969
+ return {
7970
+ errorCode: "runtime_action_validation_failed",
7971
+ errorFamily: "output_contract",
7972
+ ...details,
7973
+ ...(diagnostics ? { runtimeActionDiagnostics: diagnostics } : {}),
7974
+ };
7975
+ }
7946
7976
  if (
7947
7977
  actionType === "create_interaction" &&
7948
7978
  /create_interaction\.[a-z_]+ action requires payload|create_interaction action requires payload|non-canonical fields/i.test(haystack)
@@ -8274,6 +8304,14 @@ async function applyRuntimeActionBridge(config, command, parsed, execution, cwd)
8274
8304
  ...executorActionSources,
8275
8305
  ].filter(Boolean).join("\n\n");
8276
8306
  const envelope = extractRuntimeActionEnvelope(actionText);
8307
+ if (!envelope && executorKind === "pi" && parsed.runtimeActionMarkerInToolOutput === true) {
8308
+ const err = runtimeActionValidationError(
8309
+ "AMASTER_RUNTIME_ACTIONS must be emitted in a Pi assistant message; a marker was found only in tool output, and tool output is ignored by the runtime action bridge",
8310
+ );
8311
+ err.runtimeActionType = "output_channel";
8312
+ err.runtimeActionReasonHint = "assistant_message_required";
8313
+ throw err;
8314
+ }
8277
8315
  if (!envelope) return null;
8278
8316
  const rawActions = Array.isArray(envelope.actions) ? envelope.actions.map(asRecord) : [];
8279
8317
  const continuationScope = runtimeActionContinuationScope(command);
@@ -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.0-beta.4";
8
+ const CONNECTOR_VERSION = "0.1.0-beta.5";
9
9
 
10
10
  const CAPABILITIES = [
11
11
  "remote_registration",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amaster.ai/employee-runtime-connector",
3
- "version": "0.1.0-beta.4",
3
+ "version": "0.1.0-beta.5",
4
4
  "description": "AMaster Employee runtime connector CLI and daemon",
5
5
  "license": "MIT",
6
6
  "type": "module",