larkin 0.5.4 → 0.5.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.
Files changed (31) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +7 -1
  3. package/artifacts/release/THIRD_PARTY_NOTICES.txt +1 -100
  4. package/dist/agent/context-prompt.cjs +16 -17
  5. package/dist/agent/context-prompt.mjs +15 -16
  6. package/dist/runtime/pi-state-dir.cjs +105 -0
  7. package/dist/runtime/pi-state-dir.mjs +94 -0
  8. package/dist/runtime/pi-tmux-extension.mjs +137 -0
  9. package/dist/runtime/pi-tmux-injection.mjs +49 -0
  10. package/dist/runtime/pi-tmux.bundle.js +600 -0
  11. package/dist/runtime/pi-tmux.mjs +408 -0
  12. package/dist/runtime/runtime-adapters.mjs +26 -113
  13. package/dist/runtime/runtime-host.cjs +3 -413
  14. package/dist/runtime/runtime-host.mjs +2 -412
  15. package/package.json +2 -8
  16. package/dist/runtime/pi-bash-timeout-extension.mjs +0 -60
  17. package/dist/runtime/pi-bash-timeout-injection.mjs +0 -54
  18. package/dist/runtime/pi-bash-timeout.bundle.js +0 -43
  19. package/dist/runtime/pi-extension-api.mjs +0 -1
  20. package/dist/runtime/pi-subagent-injection.mjs +0 -290
  21. package/dist/runtime/pi-subagent-ledger.cjs +0 -632
  22. package/dist/runtime/pi-subagent-ledger.mjs +0 -594
  23. package/dist/runtime/pi-subagent-record-watchdog-injection.mjs +0 -43
  24. package/dist/runtime/pi-subagent-record-watchdog.bundle.js +0 -183
  25. package/dist/runtime/pi-subagent-record-watchdog.mjs +0 -46
  26. package/dist/runtime/pi-subagents-notification.mjs +0 -175
  27. package/dist/runtime/pi-subagents.bundle.js +0 -9110
  28. package/dist/runtime/pi-supervised-command-extension.mjs +0 -72
  29. package/dist/runtime/pi-supervised-command.bundle.js +0 -4735
  30. package/dist/runtime/pi-supervised-command.mjs +0 -420
  31. package/patches/@tintinweb%2Fpi-subagents@0.14.3.patch +0 -945
@@ -17,7 +17,7 @@ const runtime_readiness_js_1 = require("./runtime-readiness.cjs");
17
17
  const official_lark_cli_js_1 = require("../app/official-lark-cli.cjs");
18
18
  const agent_lark_cli_workspace_js_1 = require("../app/agent-lark-cli-workspace.cjs");
19
19
  const pi_compaction_recovery_js_1 = require("./pi-compaction-recovery.cjs");
20
- const pi_subagent_ledger_js_1 = require("./pi-subagent-ledger.cjs");
20
+ const pi_state_dir_js_1 = require("./pi-state-dir.cjs");
21
21
  class RuntimeSessionResetError extends Error {
22
22
  code;
23
23
  pendingCount;
@@ -41,8 +41,6 @@ class RuntimeSessionRecoveryError extends Error {
41
41
  }
42
42
  exports.RuntimeSessionRecoveryError = RuntimeSessionRecoveryError;
43
43
  const MAX_DELIVERIES = 2048;
44
- const BACKGROUND_COMPLETION_IMMEDIATE_RETRY_LIMIT = 5;
45
- const DEFAULT_SUBAGENT_RECONCILE_INTERVAL_MS = 15_000;
46
44
  const now = () => new Date().toISOString();
47
45
  const isActiveDelivery = (status) => ["pending", "submitting", "accepted"].includes(status);
48
46
  const previousSessionRefFor = (session, reason) => session.sessionId
@@ -310,10 +308,6 @@ function createRuntimeHost(options) {
310
308
  maxAttempts: options.retryPolicy?.maxAttempts ?? 6,
311
309
  stableWindowMs: options.retryPolicy?.stableWindowMs ?? 30_000,
312
310
  };
313
- const subagentReconcileIntervalMs = options.subagentReconcileIntervalMs ?? DEFAULT_SUBAGENT_RECONCILE_INTERVAL_MS;
314
- if (!Number.isFinite(subagentReconcileIntervalMs) || subagentReconcileIntervalMs < 0) {
315
- throw new Error("subagentReconcileIntervalMs must be >= 0");
316
- }
317
311
  const emit = (event) => {
318
312
  if (event.type === "delivery")
319
313
  telemetry?.delivery(event.agentId, event.messageId, event.status);
@@ -325,11 +319,10 @@ function createRuntimeHost(options) {
325
319
  LARKIN_AGENT_ID: config.agentId,
326
320
  ...(generation ? {
327
321
  LARKIN_RUNTIME_OBSERVATION_GENERATION: generation,
328
- [pi_subagent_ledger_js_1.PI_SUBAGENT_SESSION_OWNER_ENV]: generation,
329
322
  } : {}),
330
323
  LARKIN_CONFIG_DIR: process.env.LARKIN_CONFIG_DIR,
331
324
  LARKIN_HOME: process.env.LARKIN_HOME,
332
- LARKIN_STATE_DIR: (0, pi_subagent_ledger_js_1.effectivePiStateDir)(config),
325
+ LARKIN_STATE_DIR: (0, pi_state_dir_js_1.effectivePiStateDir)(config),
333
326
  ...(process.env.HOME ? { HOME: process.env.HOME } : {}),
334
327
  ...(process.env.SHELL ? { SHELL: process.env.SHELL } : {}),
335
328
  ...(process.env.ZDOTDIR ? { ZDOTDIR: process.env.ZDOTDIR } : {}),
@@ -726,12 +719,6 @@ function createRuntimeHost(options) {
726
719
  queueMicrotask(() => { void retryPending(agent); });
727
720
  }
728
721
  queueMicrotask(() => { void scanAndPromoteAcceptedInboxUpdates(agent); });
729
- // A completion queued during this submit has no turn-end if prompt
730
- // rejected/threw before turn-start. Drain now that submitting is clear.
731
- if (!agent.busy && !agent.turnInProgress && agent.backgroundCompletionQueue.length > 0
732
- && !agent.backgroundCompletionRetryTimer) {
733
- scheduleBackgroundCompletionDrain(agent);
734
- }
735
722
  }
736
723
  };
737
724
  const retryPending = async (agent) => {
@@ -808,326 +795,6 @@ function createRuntimeHost(options) {
808
795
  agent.retryAfterSubmit = true;
809
796
  await retryPending(agent);
810
797
  };
811
- const clearBackgroundCompletionRetryTimer = (agent) => {
812
- if (!agent.backgroundCompletionRetryTimer)
813
- return;
814
- clearTimeout(agent.backgroundCompletionRetryTimer);
815
- agent.backgroundCompletionRetryTimer = null;
816
- };
817
- const scheduleBackgroundCompletionDrain = (agent, delayMs = 0) => {
818
- if (agent.stopped)
819
- return;
820
- if (delayMs > 0) {
821
- if (agent.backgroundCompletionRetryTimer)
822
- return;
823
- agent.backgroundCompletionRetryTimer = setTimeout(() => {
824
- agent.backgroundCompletionRetryTimer = null;
825
- if (agent.stopped)
826
- return;
827
- void drainBackgroundCompletionQueue(agent);
828
- }, delayMs);
829
- agent.backgroundCompletionRetryTimer.unref?.();
830
- return;
831
- }
832
- clearBackgroundCompletionRetryTimer(agent);
833
- queueMicrotask(() => { void drainBackgroundCompletionQueue(agent); });
834
- };
835
- const dropBackgroundCompletion = (agent, completionKey) => {
836
- if (!completionKey)
837
- return;
838
- if (agent.backgroundCompletionQueue[0] === completionKey)
839
- agent.backgroundCompletionQueue.shift();
840
- else {
841
- const index = agent.backgroundCompletionQueue.indexOf(completionKey);
842
- if (index >= 0)
843
- agent.backgroundCompletionQueue.splice(index, 1);
844
- }
845
- agent.backgroundCompletionKeys.add(completionKey);
846
- if (agent.backgroundCompletionInFlight === completionKey) {
847
- agent.backgroundCompletionInFlight = null;
848
- agent.backgroundCompletionWakeInputId = null;
849
- }
850
- agent.backgroundCompletionRejectStreak = 0;
851
- clearBackgroundCompletionRetryTimer(agent);
852
- // Leave the durable wake pending so a later restart can requeue it.
853
- };
854
- const scheduleBackgroundCompletionRetry = (agent) => {
855
- const streak = agent.backgroundCompletionRejectStreak;
856
- if (streak < BACKGROUND_COMPLETION_IMMEDIATE_RETRY_LIMIT) {
857
- scheduleBackgroundCompletionDrain(agent);
858
- return;
859
- }
860
- const delayedAttempt = streak - BACKGROUND_COMPLETION_IMMEDIATE_RETRY_LIMIT;
861
- if (delayedAttempt >= retryPolicy.maxAttempts) {
862
- const exhausted = agent.backgroundCompletionQueue[0];
863
- if (exhausted) {
864
- log("background completion wake retries exhausted", exhausted);
865
- dropBackgroundCompletion(agent, exhausted);
866
- }
867
- if (agent.backgroundCompletionQueue.length > 0)
868
- scheduleBackgroundCompletionDrain(agent);
869
- return;
870
- }
871
- const delay = Math.min(retryPolicy.maxDelayMs, retryPolicy.baseDelayMs * 2 ** delayedAttempt);
872
- scheduleBackgroundCompletionDrain(agent, delay);
873
- };
874
- const isPersistentBackgroundWakeFailure = (event) => {
875
- if (!event)
876
- return false;
877
- const category = event.errorCategory;
878
- if (category === "auth" || category === "billing" || category === "quota")
879
- return true;
880
- return category === "provider" && event.retryable === false;
881
- };
882
- const failBackgroundCompletionWake = (agent, event) => {
883
- const completionKey = agent.backgroundCompletionInFlight ?? agent.backgroundCompletionQueue[0];
884
- if (!completionKey)
885
- return;
886
- rearmBackgroundCompletion(agent, completionKey);
887
- if (isPersistentBackgroundWakeFailure(event)) {
888
- log("background completion wake dropped", event?.errorCategory ?? "persistent");
889
- dropBackgroundCompletion(agent, completionKey);
890
- if (agent.backgroundCompletionQueue.length > 0)
891
- scheduleBackgroundCompletionDrain(agent);
892
- return;
893
- }
894
- agent.backgroundCompletionRejectStreak += 1;
895
- scheduleBackgroundCompletionRetry(agent);
896
- };
897
- const rearmBackgroundCompletion = (agent, completionKey = agent.backgroundCompletionInFlight) => {
898
- if (!completionKey)
899
- return;
900
- agent.backgroundCompletionKeys.delete(completionKey);
901
- if (agent.backgroundCompletionInFlight === completionKey) {
902
- agent.backgroundCompletionInFlight = null;
903
- agent.backgroundCompletionWakeInputId = null;
904
- }
905
- if (!agent.backgroundCompletionQueue.includes(completionKey)) {
906
- agent.backgroundCompletionQueue.unshift(completionKey);
907
- }
908
- };
909
- const commitBackgroundCompletion = (agent) => {
910
- const completionKey = agent.backgroundCompletionInFlight;
911
- if (!completionKey)
912
- return;
913
- if (agent.backgroundCompletionQueue[0] === completionKey)
914
- agent.backgroundCompletionQueue.shift();
915
- agent.backgroundCompletionInFlight = null;
916
- agent.backgroundCompletionWakeInputId = null;
917
- agent.backgroundCompletionRejectStreak = 0;
918
- clearBackgroundCompletionRetryTimer(agent);
919
- acknowledgeSubagentWake(agent, completionKey);
920
- };
921
- const wakeOnBackgroundCompletion = async (agent) => {
922
- // Caller already reserved submitting/busy so a concurrent idle drain cannot
923
- // dequeue another head while ensureSession/prompt yields.
924
- try {
925
- const session = await ensureSession(agent);
926
- if (agent.session !== session || agent.stopped)
927
- return { status: "dropped" };
928
- const headKey = agent.backgroundCompletionQueue[0];
929
- const tasks = (0, pi_subagent_ledger_js_1.taskIdsFromCompletionKey)(headKey ?? "")
930
- .map((taskId) => (0, pi_subagent_ledger_js_1.getDispatchedSubagent)(agent.subagentLedger, taskId))
931
- .filter((task) => Boolean(task));
932
- const details = tasks.map((task) => `task ${task.taskId} status=${task.status}`).join("; ");
933
- const wakeReason = details
934
- ? `background subagent completed; ${details}`
935
- : "background subagent completed";
936
- const input = options.promptBuilder.buildRuntimeInput("wake", node_crypto_1.default.randomUUID(), { wakeReason });
937
- const result = await session.prompt(input);
938
- if (agent.session !== session || agent.stopped)
939
- return { status: "dropped" };
940
- if (result.status === "accepted") {
941
- markSessionStable(agent, session);
942
- return { status: "accepted", inputId: input.inputId };
943
- }
944
- agent.busy = false;
945
- return { status: "retry" };
946
- }
947
- catch (error) {
948
- agent.busy = false;
949
- log("background completion wake failed", error instanceof Error ? error.message : String(error));
950
- return { status: "retry" };
951
- }
952
- };
953
- const drainBackgroundCompletionQueue = async (agent) => {
954
- if (agent.stopped || agent.busy || agent.turnInProgress || agent.submitting)
955
- return;
956
- if (agent.backgroundCompletionInFlight || !agent.backgroundCompletionQueue.length)
957
- return;
958
- clearBackgroundCompletionRetryTimer(agent);
959
- const proactive = agent.piProactiveCompaction
960
- && agent.piProactiveCompactionGeneration === agent.generation
961
- && agent.piProactiveCompactionSession === agent.session
962
- ? agent.piProactiveCompaction : null;
963
- if (proactive)
964
- await proactive;
965
- if (agent.adapter.id === "pi" && !agent.busy && !agent.turnInProgress && agent.session) {
966
- const idleGate = proactivelyCompactPiAtIdle(agent, agent.session);
967
- if (idleGate)
968
- await idleGate;
969
- }
970
- if (agent.stopped || agent.busy || agent.turnInProgress || agent.submitting)
971
- return;
972
- if (agent.backgroundCompletionInFlight || !agent.backgroundCompletionQueue.length)
973
- return;
974
- agent.submitting = true;
975
- agent.busy = true;
976
- const completionKey = agent.backgroundCompletionQueue[0];
977
- try {
978
- const outcome = await wakeOnBackgroundCompletion(agent);
979
- if (outcome.status === "accepted") {
980
- agent.backgroundCompletionKeys.add(completionKey);
981
- agent.backgroundCompletionInFlight = completionKey;
982
- agent.backgroundCompletionWakeInputId = outcome.inputId;
983
- // Keep the reject streak until the wake turn actually succeeds. An accepted
984
- // prompt that later terminal-fails must not reset the bounded retry budget.
985
- clearBackgroundCompletionRetryTimer(agent);
986
- }
987
- else if (outcome.status === "dropped") {
988
- if (agent.stopped) {
989
- if (agent.backgroundCompletionQueue[0] === completionKey)
990
- agent.backgroundCompletionQueue.shift();
991
- agent.backgroundCompletionKeys.delete(completionKey);
992
- clearBackgroundCompletionRetryTimer(agent);
993
- }
994
- else {
995
- rearmBackgroundCompletion(agent, completionKey);
996
- agent.busy = false;
997
- }
998
- }
999
- else {
1000
- agent.busy = false;
1001
- agent.backgroundCompletionRejectStreak += 1;
1002
- // Leave the item queued+deduped. Immediate microtask retries cover a
1003
- // brief reject; after that a bounded timer still drains because Pi will
1004
- // not re-emit the same completion.
1005
- scheduleBackgroundCompletionRetry(agent);
1006
- }
1007
- }
1008
- finally {
1009
- agent.submitting = false;
1010
- }
1011
- };
1012
- const persistSubagentLedger = (agent) => {
1013
- (0, pi_subagent_ledger_js_1.writeDispatchedSubagentLedger)((0, pi_subagent_ledger_js_1.ledgerFilePath)((0, pi_subagent_ledger_js_1.effectivePiStateDir)(agent.config)), agent.subagentLedger);
1014
- };
1015
- const dropQueuedBackgroundCompletionFallback = (agent, completionKey) => {
1016
- const keys = new Set([completionKey, ...(0, pi_subagent_ledger_js_1.taskIdsFromCompletionKey)(completionKey)]);
1017
- for (let index = agent.backgroundCompletionQueue.length - 1; index >= 0; index -= 1) {
1018
- const queued = agent.backgroundCompletionQueue[index];
1019
- if (queued && keys.has(queued))
1020
- agent.backgroundCompletionQueue.splice(index, 1);
1021
- }
1022
- for (const key of keys)
1023
- agent.backgroundCompletionKeys.add(key);
1024
- };
1025
- const acknowledgeSubagentWake = (agent, completionKey) => {
1026
- const next = (0, pi_subagent_ledger_js_1.noteDispatchedSubagentWakeAcknowledged)(agent.subagentLedger, { completionKey });
1027
- if (next === agent.subagentLedger)
1028
- return;
1029
- agent.subagentLedger = next;
1030
- persistSubagentLedger(agent);
1031
- for (const taskId of (0, pi_subagent_ledger_js_1.taskIdsFromCompletionKey)(completionKey)) {
1032
- (0, pi_subagent_ledger_js_1.retirePiSubagentRecord)((0, pi_subagent_ledger_js_1.getDispatchedSubagent)(agent.subagentLedger, taskId)?.recordFile);
1033
- }
1034
- };
1035
- const enqueueUndeliveredTerminalWakes = (agent) => {
1036
- for (const key of (0, pi_subagent_ledger_js_1.undeliveredTerminalWakeKeys)(agent.subagentLedger)) {
1037
- agent.backgroundCompletionKeys.delete(key);
1038
- for (const taskId of (0, pi_subagent_ledger_js_1.taskIdsFromCompletionKey)(key))
1039
- agent.backgroundCompletionKeys.delete(taskId);
1040
- noteBackgroundCompletion(agent, key);
1041
- }
1042
- };
1043
- const reconcileAfterSessionSwap = (agent) => {
1044
- reconcileSubagentLedger(agent, { forceMissing: true, missingReason: "pi session gone" });
1045
- enqueueUndeliveredTerminalWakes(agent);
1046
- if (agent.backgroundCompletionQueue.length > 0)
1047
- scheduleBackgroundCompletionDrain(agent);
1048
- };
1049
- const loadSubagentLedger = (config) => {
1050
- return (0, pi_subagent_ledger_js_1.readDispatchedSubagentLedger)((0, pi_subagent_ledger_js_1.ledgerFilePath)((0, pi_subagent_ledger_js_1.effectivePiStateDir)(config)));
1051
- };
1052
- const clearSubagentReconcileTimer = (agent) => {
1053
- if (!agent.subagentReconcileTimer)
1054
- return;
1055
- clearInterval(agent.subagentReconcileTimer);
1056
- agent.subagentReconcileTimer = null;
1057
- };
1058
- const hasActiveDispatchedSubagent = (agent) => agent.subagentLedger.tasks.some((task) => task.status === "dispatched");
1059
- const noteBackgroundCompletion = (agent, completionKey) => {
1060
- const taskIds = (0, pi_subagent_ledger_js_1.taskIdsFromCompletionKey)(completionKey);
1061
- if (agent.backgroundCompletionKeys.has(completionKey))
1062
- return;
1063
- if (taskIds.length > 0 && taskIds.every((taskId) => agent.backgroundCompletionKeys.has(taskId)))
1064
- return;
1065
- agent.backgroundCompletionKeys.add(completionKey);
1066
- for (const taskId of taskIds)
1067
- agent.backgroundCompletionKeys.add(taskId);
1068
- if (!agent.backgroundCompletionQueue.includes(completionKey)) {
1069
- agent.backgroundCompletionQueue.push(completionKey);
1070
- }
1071
- if (!agent.busy && !agent.turnInProgress && !agent.submitting && !agent.backgroundCompletionInFlight) {
1072
- scheduleBackgroundCompletionDrain(agent);
1073
- }
1074
- };
1075
- const recordDispatchedSubagent = (agent, taskId, outputFile) => {
1076
- const recordFile = (0, pi_subagent_ledger_js_1.writeDispatchedSubagentRecordFile)((0, pi_subagent_ledger_js_1.effectivePiStateDir)(agent.config), taskId, agent.piSessionOwner);
1077
- agent.subagentLedger = (0, pi_subagent_ledger_js_1.noteDispatchedSubagent)(agent.subagentLedger, { taskId, outputFile, recordFile });
1078
- persistSubagentLedger(agent);
1079
- armSubagentReconcileTimer(agent);
1080
- };
1081
- const recordTerminalSubagentNotification = (agent, completionKey, statuses) => {
1082
- let next = agent.subagentLedger;
1083
- for (const taskId of (0, pi_subagent_ledger_js_1.taskIdsFromCompletionKey)(completionKey)) {
1084
- const status = statuses?.[taskId];
1085
- next = (0, pi_subagent_ledger_js_1.noteDispatchedSubagentTerminal)(next, {
1086
- taskId,
1087
- status: status && status !== "dispatched" && status !== "orphaned" ? status : "completed",
1088
- wakeKey: completionKey,
1089
- });
1090
- }
1091
- agent.subagentLedger = next;
1092
- persistSubagentLedger(agent);
1093
- if (!hasActiveDispatchedSubagent(agent))
1094
- clearSubagentReconcileTimer(agent);
1095
- };
1096
- const reconcileSubagentLedger = (agent, input = {}) => {
1097
- if (agent.stopped)
1098
- return;
1099
- const result = (0, pi_subagent_ledger_js_1.reconcileDispatchedSubagents)(agent.subagentLedger, {
1100
- probe: options.subagentRecordProbe ?? pi_subagent_ledger_js_1.probePiSubagentRecord,
1101
- forceMissing: input.forceMissing === true,
1102
- missingReason: input.missingReason,
1103
- });
1104
- const previousLedger = agent.subagentLedger;
1105
- agent.subagentLedger = result.ledger;
1106
- if (result.orphaned.length > 0 || result.terminals.length > 0 || result.ledger !== previousLedger) {
1107
- persistSubagentLedger(agent);
1108
- }
1109
- for (const record of [...result.orphaned, ...result.terminals]) {
1110
- noteBackgroundCompletion(agent, record.wakeKey ?? record.taskId);
1111
- }
1112
- if (!hasActiveDispatchedSubagent(agent))
1113
- clearSubagentReconcileTimer(agent);
1114
- else
1115
- armSubagentReconcileTimer(agent);
1116
- };
1117
- const armSubagentReconcileTimer = (agent) => {
1118
- if (agent.stopped || agent.subagentReconcileTimer || subagentReconcileIntervalMs === 0)
1119
- return;
1120
- if (!hasActiveDispatchedSubagent(agent))
1121
- return;
1122
- agent.subagentReconcileTimer = setInterval(() => {
1123
- if (agent.stopped) {
1124
- clearSubagentReconcileTimer(agent);
1125
- return;
1126
- }
1127
- reconcileSubagentLedger(agent);
1128
- }, subagentReconcileIntervalMs);
1129
- agent.subagentReconcileTimer.unref?.();
1130
- };
1131
798
  const scheduleRecreate = (agent, reason) => {
1132
799
  if (agent.stopped || agent.retryTimer || agent.starting || agent.session)
1133
800
  return;
@@ -1149,11 +816,7 @@ function createRuntimeHost(options) {
1149
816
  const proactive = session ? proactivelyCompactPiAtIdle(agent, session) : null;
1150
817
  if (proactive)
1151
818
  await proactive;
1152
- reconcileSubagentLedger(agent, { forceMissing: true, missingReason: "pi session gone" });
1153
- enqueueUndeliveredTerminalWakes(agent);
1154
819
  await retryPending(agent);
1155
- if (agent.backgroundCompletionQueue.length > 0)
1156
- scheduleBackgroundCompletionDrain(agent);
1157
820
  }).catch((error) => {
1158
821
  const readiness = error instanceof runtime_readiness_js_1.RuntimePrerequisiteError ? error.readiness
1159
822
  : (0, runtime_readiness_js_1.classifyRuntimePrerequisite)(agent.adapter.id, error);
@@ -1176,7 +839,6 @@ function createRuntimeHost(options) {
1176
839
  agent.busy = false;
1177
840
  agent.submitting = false;
1178
841
  agent.generation += 1;
1179
- rearmBackgroundCompletion(agent);
1180
842
  agent.recreateReason = reason;
1181
843
  if (agent.stabilityTimer)
1182
844
  clearTimeout(agent.stabilityTimer);
@@ -1186,14 +848,11 @@ function createRuntimeHost(options) {
1186
848
  record.status = "pending";
1187
849
  emitConsumed(agent, persist(agent));
1188
850
  emit({ type: "agent-status", agentId: agent.config.agentId, status: "error", error: reason });
1189
- // Close first so the shutdown sweep can bridge consumed or terminal state
1190
- // before force-missing reconcile treats a plain sidecar as orphaned.
1191
851
  void session.close(`replace after ${reason}`)
1192
852
  .catch((error) => log("runtime close after replacement failed", String(error)))
1193
853
  .finally(() => {
1194
854
  if (agent.stopped)
1195
855
  return;
1196
- reconcileAfterSessionSwap(agent);
1197
856
  scheduleRecreate(agent, reason);
1198
857
  });
1199
858
  };
@@ -1205,7 +864,6 @@ function createRuntimeHost(options) {
1205
864
  agent.busy = false;
1206
865
  agent.submitting = false;
1207
866
  agent.generation += 1;
1208
- rearmBackgroundCompletion(agent);
1209
867
  if (agent.stabilityTimer)
1210
868
  clearTimeout(agent.stabilityTimer);
1211
869
  agent.stabilityTimer = null;
@@ -1220,8 +878,6 @@ function createRuntimeHost(options) {
1220
878
  const recovery = (async () => {
1221
879
  try {
1222
880
  await session.close("runtime configuration error");
1223
- if (!agent.stopped)
1224
- reconcileAfterSessionSwap(agent);
1225
881
  const result = agent.adapter.recoverConfigurationError
1226
882
  ? await agent.adapter.recoverConfigurationError(message)
1227
883
  : { recovered: false, reason: "runtime adapter does not support automatic configuration recovery" };
@@ -1498,16 +1154,6 @@ function createRuntimeHost(options) {
1498
1154
  // closed instead of inheriting a previous turn's chat or reminder.
1499
1155
  agent.stateStore?.clearCurrentInboxSource?.();
1500
1156
  finalizeReminderContexts(agent, "Runtime turn ended without a matching Feishu write");
1501
- if (agent.backgroundCompletionInFlight) {
1502
- if (agent.turnHadFailure)
1503
- failBackgroundCompletionWake(agent);
1504
- else
1505
- commitBackgroundCompletion(agent);
1506
- }
1507
- if (agent.backgroundCompletionQueue.length > 0 && !agent.backgroundCompletionRetryTimer) {
1508
- scheduleBackgroundCompletionDrain(agent);
1509
- }
1510
- reconcileSubagentLedger(agent);
1511
1157
  telemetry?.runtimeEvent(agent.config.agentId, event);
1512
1158
  if (recoveredAuthentication) {
1513
1159
  clearAuthFailure(agent);
@@ -1525,34 +1171,12 @@ function createRuntimeHost(options) {
1525
1171
  void (proactive ?? Promise.resolve("noop")).then(() => retryPending(agent));
1526
1172
  queueMicrotask(() => { void scanAndPromoteAcceptedInboxUpdates(agent); });
1527
1173
  }
1528
- else if (event.type === "runtime-observation") {
1529
- if (event.phase === "background_dispatched" && typeof event.taskId === "string" && event.taskId) {
1530
- recordDispatchedSubagent(agent, event.taskId, typeof event.outputFile === "string" ? event.outputFile : undefined);
1531
- }
1532
- else if (event.phase === "completed" && typeof event.completionKey === "string") {
1533
- recordTerminalSubagentNotification(agent, event.completionKey, event.completionStatuses);
1534
- if (event.handledInTurn === true) {
1535
- acknowledgeSubagentWake(agent, event.completionKey);
1536
- dropQueuedBackgroundCompletionFallback(agent, event.completionKey);
1537
- }
1538
- else {
1539
- noteBackgroundCompletion(agent, event.completionKey);
1540
- }
1541
- }
1542
- }
1543
1174
  else if (event.type === "activity") {
1544
1175
  if (agent.turnInProgress && event.activity !== "internal")
1545
1176
  agent.turnHadAuthenticatedOutput = true;
1546
1177
  emit({ type: "activity", agentId: agent.config.agentId, activity: event.activity, activityKind: event.activity });
1547
1178
  }
1548
1179
  else if (event.type === "input-error") {
1549
- if (agent.backgroundCompletionInFlight
1550
- && (!event.inputId || !agent.backgroundCompletionWakeInputId
1551
- || event.inputId === agent.backgroundCompletionWakeInputId)
1552
- && event.willRetry !== true) {
1553
- agent.turnHadFailure = true;
1554
- failBackgroundCompletionWake(agent, event);
1555
- }
1556
1180
  const record = event.inputId
1557
1181
  ? agent.records.get(event.inputId) ?? [...agent.records.values()].find((candidate) => candidate.input.inputId === event.inputId)
1558
1182
  : undefined;
@@ -1682,7 +1306,6 @@ function createRuntimeHost(options) {
1682
1306
  throw new Error("stale runtime session creation");
1683
1307
  }
1684
1308
  agent.session = session;
1685
- agent.piSessionOwner = sessionEnv[pi_subagent_ledger_js_1.PI_SUBAGENT_SESSION_OWNER_ENV];
1686
1309
  session.subscribe((event) => observe(agent, session, event));
1687
1310
  if (agent.session !== session)
1688
1311
  return session;
@@ -1828,9 +1451,7 @@ function createRuntimeHost(options) {
1828
1451
  ...(agent.previousSession ? { previousSession: agent.previousSession } : {}) });
1829
1452
  }
1830
1453
  emit({ type: "agent-status", agentId, status: "active", readiness });
1831
- agent.piSessionOwner = probeEnv[pi_subagent_ledger_js_1.PI_SUBAGENT_SESSION_OWNER_ENV];
1832
1454
  await oldSession.close("Pi context fallback committed").catch((error) => log("previous Pi session close after fallback failed", String(error)));
1833
- reconcileAfterSessionSwap(agent);
1834
1455
  const proactive = proactivelyCompactPiAtIdle(agent, fresh);
1835
1456
  void (proactive ?? Promise.resolve("noop")).then(() => retryPending(agent));
1836
1457
  return { generationChanged: true, sessionChanged: oldSessionId !== fresh.sessionId, turns: 0,
@@ -1900,10 +1521,6 @@ function createRuntimeHost(options) {
1900
1521
  clearTimeout(previous.retryTimer);
1901
1522
  if (previous.stabilityTimer)
1902
1523
  clearTimeout(previous.stabilityTimer);
1903
- if (previous.backgroundCompletionRetryTimer)
1904
- clearTimeout(previous.backgroundCompletionRetryTimer);
1905
- if (previous.subagentReconcileTimer)
1906
- clearInterval(previous.subagentReconcileTimer);
1907
1524
  const previousFailure = currentAuthFailure(previous);
1908
1525
  const scoped = Boolean(previousFailure
1909
1526
  && (0, runtime_readiness_js_1.authFailureAppliesTo)({
@@ -1915,7 +1532,6 @@ function createRuntimeHost(options) {
1915
1532
  ...previous, config, adapter, session, launchId: node_crypto_1.default.randomUUID(), busy: false, submitting: false,
1916
1533
  starting: null, retryAfterSubmit: false, generation: 0, poller: null, retryTimer: null,
1917
1534
  recreateAttempts: 0, stabilityTimer: null, recreateReason: null, stopped: false,
1918
- backgroundCompletionRetryTimer: null, subagentReconcileTimer: null,
1919
1535
  disabledReason: null, configurationRecovery: null,
1920
1536
  authFailureActive: scoped && previous.authFailureActive,
1921
1537
  authFailureKind: scoped ? previous.authFailureKind : null,
@@ -1937,14 +1553,8 @@ function createRuntimeHost(options) {
1937
1553
  if (!candidate.authFailureActive) {
1938
1554
  emit({ type: "agent-status", agentId: config.agentId, status: "active", readiness: candidate.readiness ?? readiness });
1939
1555
  }
1940
- candidate.piSessionOwner = stageEnv[pi_subagent_ledger_js_1.PI_SUBAGENT_SESSION_OWNER_ENV];
1941
- // Close first so the old session's shutdown sweep can bridge consumed
1942
- // terminals before force-missing reconcile. Commit also clears any
1943
- // inherited backoff timer; reschedule so a queued completion still
1944
- // drains on the new session.
1945
1556
  await previous.session?.close("runtime candidate committed")
1946
1557
  .catch((error) => log("previous runtime close after candidate commit failed", String(error)));
1947
- reconcileAfterSessionSwap(candidate);
1948
1558
  },
1949
1559
  rollback,
1950
1560
  };
@@ -2047,10 +1657,8 @@ function createRuntimeHost(options) {
2047
1657
  ...(agent.authFailureActive ? { error: `${agent.readiness?.reason} ${agent.readiness?.nextAction}` } : {}),
2048
1658
  readiness: agent.authFailureActive ? agent.readiness ?? readiness : readiness,
2049
1659
  });
2050
- agent.piSessionOwner = probeEnv[pi_subagent_ledger_js_1.PI_SUBAGENT_SESSION_OWNER_ENV];
2051
1660
  await oldSession.close("fresh session reset committed")
2052
1661
  .catch((error) => log("previous runtime close after fresh reset failed", String(error)));
2053
- reconcileAfterSessionSwap(agent);
2054
1662
  return { generationChanged: true, sessionChanged: oldSessionId !== fresh.sessionId, turns: 0,
2055
1663
  runtimeReady: true, pendingCount: 0, sessionId: fresh.sessionId };
2056
1664
  },
@@ -2211,10 +1819,8 @@ function createRuntimeHost(options) {
2211
1819
  readiness: agent.authFailureActive ? agent.readiness ?? readiness : readiness,
2212
1820
  });
2213
1821
  durableRollback = null;
2214
- agent.piSessionOwner = probeEnv[pi_subagent_ledger_js_1.PI_SUBAGENT_SESSION_OWNER_ENV];
2215
1822
  await oldSession.close("context-window recovery committed")
2216
1823
  .catch((error) => log("previous runtime close after context-window recovery failed", String(error)));
2217
- reconcileAfterSessionSwap(agent);
2218
1824
  const proactive = proactivelyCompactPiAtIdle(agent, fresh);
2219
1825
  void (proactive ?? Promise.resolve("noop")).then(() => retryPending(agent));
2220
1826
  return { generationChanged: true, sessionChanged: oldSessionId !== fresh.sessionId, turns: 0,
@@ -2300,11 +1906,7 @@ function createRuntimeHost(options) {
2300
1906
  previousSession: loadPersistedPreviousSession(config, stateStore), readiness: null,
2301
1907
  turnInProgress: false, turnHadFailure: false, turnHadAuthenticatedOutput: false, authFailureActive: false,
2302
1908
  authFailureKind: null, authFailureProvider: null,
2303
- promotedInboxUpdateIds: new Set(),
2304
- backgroundCompletionQueue: [], backgroundCompletionKeys: new Set(),
2305
- backgroundCompletionInFlight: null, backgroundCompletionWakeInputId: null,
2306
- backgroundCompletionRejectStreak: 0, backgroundCompletionRetryTimer: null,
2307
- subagentLedger: loadSubagentLedger(config), subagentReconcileTimer: null };
1909
+ promotedInboxUpdateIds: new Set() };
2308
1910
  restoreAuthFailure(agent);
2309
1911
  const startupConsumed = [];
2310
1912
  const startupQuarantined = [];
@@ -2338,8 +1940,6 @@ function createRuntimeHost(options) {
2338
1940
  await ensureSession(agent);
2339
1941
  if (agent.stopped)
2340
1942
  return;
2341
- reconcileSubagentLedger(agent, { forceMissing: true, missingReason: "runtime restarted" });
2342
- enqueueUndeliveredTerminalWakes(agent);
2343
1943
  await recoverStalePiCompaction(agent);
2344
1944
  const startupSession = agent.session;
2345
1945
  const proactive = startupSession ? proactivelyCompactPiAtIdle(agent, startupSession) : null;
@@ -2356,8 +1956,6 @@ function createRuntimeHost(options) {
2356
1956
  const reason = error instanceof Error ? error.message : String(error);
2357
1957
  const transient = error instanceof runtime_readiness_js_1.RuntimePrerequisiteError && error.readiness.state === "unavailable";
2358
1958
  agent.disabledReason = transient ? null : reason;
2359
- reconcileSubagentLedger(agent, { forceMissing: true, missingReason: "runtime restarted" });
2360
- enqueueUndeliveredTerminalWakes(agent);
2361
1959
  if (transient) {
2362
1960
  recoveringCount += 1;
2363
1961
  scheduleRecreate(agent, reason);
@@ -2469,10 +2067,6 @@ function createRuntimeHost(options) {
2469
2067
  clearTimeout(agent.retryTimer);
2470
2068
  if (agent.stabilityTimer)
2471
2069
  clearTimeout(agent.stabilityTimer);
2472
- if (agent.backgroundCompletionRetryTimer)
2473
- clearTimeout(agent.backgroundCompletionRetryTimer);
2474
- if (agent.subagentReconcileTimer)
2475
- clearInterval(agent.subagentReconcileTimer);
2476
2070
  if (agent.busy)
2477
2071
  await agent.session?.cancel(reason);
2478
2072
  await agent.session?.close(reason);
@@ -2485,9 +2079,5 @@ function createRuntimeHost(options) {
2485
2079
  },
2486
2080
  async shutdown(reason) { await Promise.allSettled([...managed.keys()].map((id) => this.stop(id, reason))); },
2487
2081
  subscribe(listener) { listeners.add(listener); return () => listeners.delete(listener); },
2488
- getDispatchedSubagent(agentId, taskId) {
2489
- const agent = managed.get(agentId);
2490
- return agent ? (0, pi_subagent_ledger_js_1.getDispatchedSubagent)(agent.subagentLedger, taskId) : null;
2491
- },
2492
2082
  };
2493
2083
  }