@amaster.ai/employee-runtime-connector 0.1.0-beta.4 → 0.1.0-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.
@@ -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.6";
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,11 +3553,13 @@ 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
- "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.",
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\",\"continuationPolicy\":\"wake_assignee_on_accept\",\"payload\":{\"version\":1,\"prompt\":\"Confirm this result?\",\"acceptLabel\":\"确认\",\"rejectLabel\":\"调整\"}}. Never use interactionType.",
3562
+ "Interactions cannot be updated with PATCH after creation. For direct API calls, include continuationPolicy in the initial POST /api/issues/{issueId}/interactions request and use only the documented POST accept, reject, respond, or cancel resolution endpoint afterward.",
3540
3563
  "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.",
3541
3564
  "For create_interaction request_confirmation, use payload {\"version\":1,\"prompt\":\"Confirm this result?\",\"acceptLabel\":\"确认\",\"rejectLabel\":\"调整\"}. Do not use options arrays for request_confirmation.",
3542
3565
  "For create_interaction request_checkbox_confirmation, use payload {\"version\":1,\"prompt\":\"Select approved items\",\"options\":[{\"id\":\"option_key\",\"label\":\"Option label\"}],\"minSelected\":1,\"maxSelected\":2,\"acceptLabel\":\"确认\",\"rejectLabel\":\"调整\"}.",
@@ -7943,6 +7966,14 @@ function classifyRuntimeActionFailure(err) {
7943
7966
  ...(diagnostics ? { runtimeActionDiagnostics: diagnostics } : {}),
7944
7967
  };
7945
7968
  }
7969
+ if (actionType === "output_channel") {
7970
+ return {
7971
+ errorCode: "runtime_action_validation_failed",
7972
+ errorFamily: "output_contract",
7973
+ ...details,
7974
+ ...(diagnostics ? { runtimeActionDiagnostics: diagnostics } : {}),
7975
+ };
7976
+ }
7946
7977
  if (
7947
7978
  actionType === "create_interaction" &&
7948
7979
  /create_interaction\.[a-z_]+ action requires payload|create_interaction action requires payload|non-canonical fields/i.test(haystack)
@@ -8274,6 +8305,14 @@ async function applyRuntimeActionBridge(config, command, parsed, execution, cwd)
8274
8305
  ...executorActionSources,
8275
8306
  ].filter(Boolean).join("\n\n");
8276
8307
  const envelope = extractRuntimeActionEnvelope(actionText);
8308
+ if (!envelope && executorKind === "pi" && parsed.runtimeActionMarkerInToolOutput === true) {
8309
+ const err = runtimeActionValidationError(
8310
+ "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",
8311
+ );
8312
+ err.runtimeActionType = "output_channel";
8313
+ err.runtimeActionReasonHint = "assistant_message_required";
8314
+ throw err;
8315
+ }
8277
8316
  if (!envelope) return null;
8278
8317
  const rawActions = Array.isArray(envelope.actions) ? envelope.actions.map(asRecord) : [];
8279
8318
  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.6";
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.6",
4
4
  "description": "AMaster Employee runtime connector CLI and daemon",
5
5
  "license": "MIT",
6
6
  "type": "module",