@slock-ai/daemon 0.57.3 → 0.57.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.
@@ -1058,6 +1058,143 @@ function shortMessageId(value) {
1058
1058
  return value.slice(0, 8);
1059
1059
  }
1060
1060
 
1061
+ // ../shared/src/externalAgentIntegration.ts
1062
+ import { z as z2 } from "zod";
1063
+ var EXTERNAL_AGENT_COMMS_PROTOCOL_VERSION = "agent-comms-core.v1";
1064
+ var EXTERNAL_AGENT_PROOF_SCHEMA_VERSION = "agent-proof.v1";
1065
+ var EXTERNAL_RUNTIME_INTEGRATION_MANIFEST_SCHEMA = "slock-external-runtime-integration.v1";
1066
+ var EXTERNAL_AGENT_WAKE_EVENT_SCHEMA = "slock-external-agent-wake-event.v1";
1067
+ var externalAgentCommsModeValues = ["spawn-core", "attach-core", "import-core"];
1068
+ var externalAgentIntegrationPatternValues = ["external-harness-plugin", "integrated-runtime"];
1069
+ var externalAgentIsolationValues = ["profile-scoped", "session-scoped"];
1070
+ var externalAgentWakeAdapterKindValues = ["claude-code-channels", "hermes-in-process"];
1071
+ var externalAgentWakeProofLevelValues = [
1072
+ "server_delivered",
1073
+ "harness_accepted",
1074
+ "wake_injected"
1075
+ ];
1076
+ var externalAgentProofLevelValues = [
1077
+ ...externalAgentWakeProofLevelValues,
1078
+ "model_seen"
1079
+ ];
1080
+ var externalAgentCommsLifecycleStateValues = [
1081
+ "unbound",
1082
+ "bound_stopped",
1083
+ "starting",
1084
+ "connected_replaying",
1085
+ "listening_idle",
1086
+ "handoff_pending",
1087
+ "degraded_backoff",
1088
+ "stopping",
1089
+ "stopped",
1090
+ "auth_revoked"
1091
+ ];
1092
+ var externalAgentLifecycleSourceValues = ["server_core", "comms_core", "wake_adapter", "server"];
1093
+ var externalAgentLifecycleProvenanceValues = [
1094
+ "slock_core",
1095
+ "adapter_observed",
1096
+ "agent_reported"
1097
+ ];
1098
+ var externalAgentAdapterFailureValues = [
1099
+ "no_session",
1100
+ "busy",
1101
+ "injection_failed",
1102
+ "protocol_mismatch",
1103
+ "auth_revoked"
1104
+ ];
1105
+ var externalAgentServerApiModeValues = ["interim-agent-api-events", "agent-inbox-protocol"];
1106
+ var nonEmptyStringSchema = z2.string().min(1);
1107
+ var isoTimestampSchema = z2.string().refine((value) => !Number.isNaN(Date.parse(value)), {
1108
+ message: "must be a parseable timestamp"
1109
+ });
1110
+ var externalRuntimeIntegrationManifestSchema = z2.object({
1111
+ schema: z2.literal(EXTERNAL_RUNTIME_INTEGRATION_MANIFEST_SCHEMA),
1112
+ runtimeId: nonEmptyStringSchema,
1113
+ integrationPattern: z2.enum(externalAgentIntegrationPatternValues),
1114
+ commsMode: z2.enum(externalAgentCommsModeValues),
1115
+ commsProtocolVersion: z2.literal(EXTERNAL_AGENT_COMMS_PROTOCOL_VERSION),
1116
+ proofSchemaVersion: z2.literal(EXTERNAL_AGENT_PROOF_SCHEMA_VERSION),
1117
+ minSlockCliVersion: nonEmptyStringSchema,
1118
+ multiplex: z2.boolean(),
1119
+ agentIsolation: z2.enum(externalAgentIsolationValues),
1120
+ bridgeLifecycle: z2.object({
1121
+ explicitStartOnly: z2.literal(true),
1122
+ oneShotCommandsBridgeIndependent: z2.literal(true),
1123
+ requiresBridgeFailureCodes: z2.array(z2.enum(["BRIDGE_NOT_RUNNING", "NO_CORE_SESSION"])).min(1),
1124
+ autoStartDefault: z2.literal(false)
1125
+ }).strict(),
1126
+ serverApi: z2.object({
1127
+ mode: z2.enum(externalAgentServerApiModeValues),
1128
+ deliveryOnly: z2.boolean(),
1129
+ cursorAuthority: z2.literal("model_seen_only")
1130
+ }).strict(),
1131
+ wakeAdapter: z2.object({
1132
+ kind: z2.enum(externalAgentWakeAdapterKindValues),
1133
+ protocol: nonEmptyStringSchema,
1134
+ requiresInteractiveSession: z2.boolean().optional()
1135
+ }).strict()
1136
+ }).strict().superRefine((value, ctx) => {
1137
+ if (!value.bridgeLifecycle.requiresBridgeFailureCodes.includes("BRIDGE_NOT_RUNNING")) {
1138
+ ctx.addIssue({
1139
+ code: "custom",
1140
+ path: ["bridgeLifecycle", "requiresBridgeFailureCodes"],
1141
+ message: "bridge-dependent surfaces must include BRIDGE_NOT_RUNNING"
1142
+ });
1143
+ }
1144
+ if (!value.bridgeLifecycle.requiresBridgeFailureCodes.includes("NO_CORE_SESSION")) {
1145
+ ctx.addIssue({
1146
+ code: "custom",
1147
+ path: ["bridgeLifecycle", "requiresBridgeFailureCodes"],
1148
+ message: "bridge-dependent surfaces must include NO_CORE_SESSION"
1149
+ });
1150
+ }
1151
+ if (value.serverApi.mode === "interim-agent-api-events" && value.serverApi.deliveryOnly !== true) {
1152
+ ctx.addIssue({
1153
+ code: "custom",
1154
+ path: ["serverApi", "deliveryOnly"],
1155
+ message: "interim agent-api events mode must be delivery-only"
1156
+ });
1157
+ }
1158
+ });
1159
+ var externalAgentWakeEventBaseSchema = z2.object({
1160
+ schema: z2.literal(EXTERNAL_AGENT_WAKE_EVENT_SCHEMA),
1161
+ eventId: nonEmptyStringSchema,
1162
+ attemptId: nonEmptyStringSchema,
1163
+ messageId: nonEmptyStringSchema,
1164
+ agentId: nonEmptyStringSchema,
1165
+ profile: nonEmptyStringSchema,
1166
+ coreSessionId: nonEmptyStringSchema,
1167
+ adapterInstance: nonEmptyStringSchema,
1168
+ runtimeSession: nonEmptyStringSchema.nullable(),
1169
+ occurredAt: isoTimestampSchema,
1170
+ lifecycleState: z2.enum(externalAgentCommsLifecycleStateValues),
1171
+ authority: z2.object({
1172
+ source: z2.enum(externalAgentLifecycleSourceValues),
1173
+ provenance: z2.enum(externalAgentLifecycleProvenanceValues)
1174
+ }).strict()
1175
+ }).strict();
1176
+ var externalAgentProofEventEnvelopeSchema = externalAgentWakeEventBaseSchema.extend({
1177
+ kind: z2.literal("proof"),
1178
+ proofLevel: z2.enum(externalAgentWakeProofLevelValues),
1179
+ outcome: z2.literal("ok"),
1180
+ failureMeta: z2.undefined().optional(),
1181
+ reason: z2.string().optional()
1182
+ });
1183
+ var externalAgentFailedWakeEventEnvelopeSchema = externalAgentWakeEventBaseSchema.extend({
1184
+ kind: z2.literal("wake_attempt"),
1185
+ proofLevel: z2.undefined().optional(),
1186
+ outcome: z2.literal("failed"),
1187
+ failureMeta: z2.object({
1188
+ failureClass: z2.enum(externalAgentAdapterFailureValues),
1189
+ retryAfterMs: z2.number().int().positive().optional()
1190
+ }).strict(),
1191
+ reason: nonEmptyStringSchema
1192
+ });
1193
+ var externalAgentWakeEventEnvelopeSchema = z2.discriminatedUnion("kind", [
1194
+ externalAgentProofEventEnvelopeSchema,
1195
+ externalAgentFailedWakeEventEnvelopeSchema
1196
+ ]);
1197
+
1061
1198
  // ../shared/src/translationLanguages.ts
1062
1199
  var SUPPORTED_TRANSLATION_LANGUAGE_CODES = [
1063
1200
  "en",
@@ -1164,6 +1301,7 @@ var RUNTIME_MODELS = {
1164
1301
  { id: "claude-opus-4-8", label: "Claude Opus 4.8" },
1165
1302
  { id: "claude-opus-4-7", label: "Claude Opus 4.7" },
1166
1303
  { id: "claude-opus-4-6", label: "Claude Opus 4.6" },
1304
+ { id: "fable", label: "Claude Fable" },
1167
1305
  { id: "sonnet", label: "Claude Sonnet" },
1168
1306
  { id: "claude-sonnet-4-6", label: "Claude Sonnet 4.6" },
1169
1307
  { id: "haiku", label: "Claude Haiku" },
@@ -6513,6 +6651,7 @@ import {
6513
6651
  VERSION as PI_SDK_VERSION
6514
6652
  } from "@earendil-works/pi-coding-agent";
6515
6653
  var PI_SESSION_DIR = ".pi-sessions";
6654
+ var PI_SDK_COMPACTION_ENABLED = true;
6516
6655
  var PI_PROVIDER_LABELS = {
6517
6656
  google: "Google",
6518
6657
  openai: "OpenAI",
@@ -6711,7 +6850,7 @@ async function createPiAgentSessionForContext(ctx, sessionId) {
6711
6850
  if (launchRuntimeFields.model && launchRuntimeFields.model !== "default" && !model) {
6712
6851
  throw new Error(`Pi model not found: ${launchRuntimeFields.model}`);
6713
6852
  }
6714
- const settingsManager = SettingsManager.inMemory({ compaction: { enabled: false } });
6853
+ const settingsManager = SettingsManager.inMemory({ compaction: { enabled: PI_SDK_COMPACTION_ENABLED } });
6715
6854
  const resourceLoader = new DefaultResourceLoader({
6716
6855
  cwd: ctx.workingDirectory,
6717
6856
  agentDir,
@@ -8843,6 +8982,7 @@ var AgentProcessManager = class _AgentProcessManager {
8843
8982
  maxConcurrentAgentStarts;
8844
8983
  agentStartIntervalMs;
8845
8984
  startingInboxes = /* @__PURE__ */ new Map();
8985
+ pendingStartRebinds = /* @__PURE__ */ new Map();
8846
8986
  /** Cached configs for agents whose process exited normally — enables auto-restart on next message */
8847
8987
  idleAgentConfigs = /* @__PURE__ */ new Map();
8848
8988
  slockCliPath;
@@ -9488,6 +9628,92 @@ var AgentProcessManager = class _AgentProcessManager {
9488
9628
  ...attrs
9489
9629
  };
9490
9630
  }
9631
+ recordStartRebind(agentId, start, reason, previousLaunchId, nextLaunchId, sessionId) {
9632
+ this.recordDaemonTrace("daemon.agent.start.rebound", {
9633
+ ...this.startQueueTraceAttrs(
9634
+ agentId,
9635
+ start.config,
9636
+ start.wakeMessage,
9637
+ start.unreadSummary,
9638
+ start.resumePrompt,
9639
+ start.launchId,
9640
+ start.wakeMessageTransient ?? false
9641
+ ),
9642
+ reason,
9643
+ previous_launch_id_present: Boolean(previousLaunchId),
9644
+ next_launch_id_present: Boolean(nextLaunchId),
9645
+ session_id_present: Boolean(sessionId)
9646
+ });
9647
+ }
9648
+ sameWakeMessage(left, right) {
9649
+ if (!left || !right) return left === right;
9650
+ if (left.message_id && right.message_id) return left.message_id === right.message_id;
9651
+ return left === right;
9652
+ }
9653
+ rebindQueuedStart(agentId, start, reason) {
9654
+ const item = this.queuedAgentStarts.get(agentId);
9655
+ if (!item) {
9656
+ return false;
9657
+ }
9658
+ const previousLaunchId = item.launchId || null;
9659
+ const nextLaunchId = start.launchId || previousLaunchId;
9660
+ const previousWakeMessage = item.wakeMessage;
9661
+ if (previousWakeMessage && start.wakeMessage && !this.sameWakeMessage(previousWakeMessage, start.wakeMessage)) {
9662
+ const pending = this.startingInboxes.get(agentId) || [];
9663
+ pending.push(previousWakeMessage);
9664
+ this.startingInboxes.set(agentId, pending);
9665
+ }
9666
+ item.config = start.config;
9667
+ item.unreadSummary = start.unreadSummary;
9668
+ item.resumePrompt = start.resumePrompt;
9669
+ item.launchId = nextLaunchId || void 0;
9670
+ if (start.wakeMessage) {
9671
+ item.wakeMessage = start.wakeMessage;
9672
+ item.wakeMessageTransient = start.wakeMessageTransient;
9673
+ }
9674
+ this.recordStartRebind(
9675
+ agentId,
9676
+ { ...start, launchId: nextLaunchId || void 0 },
9677
+ reason,
9678
+ previousLaunchId,
9679
+ nextLaunchId,
9680
+ null
9681
+ );
9682
+ return true;
9683
+ }
9684
+ rebindRunningStart(agentId, start, reason) {
9685
+ const ap = this.agents.get(agentId);
9686
+ if (!ap) {
9687
+ this.pendingStartRebinds.set(agentId, start);
9688
+ return false;
9689
+ }
9690
+ const previousLaunchId = ap.launchId;
9691
+ const nextLaunchId = start.launchId || ap.launchId || null;
9692
+ const nextSessionId = ap.sessionId || start.config.sessionId || null;
9693
+ ap.launchId = nextLaunchId;
9694
+ ap.sessionId = nextSessionId;
9695
+ ap.config = {
9696
+ ...start.config,
9697
+ sessionId: nextSessionId
9698
+ };
9699
+ this.idleAgentConfigs.set(agentId, {
9700
+ config: { ...stripManagedRunnerCredential(ap.config), sessionId: nextSessionId },
9701
+ sessionId: nextSessionId,
9702
+ launchId: nextLaunchId
9703
+ });
9704
+ this.recordStartRebind(agentId, start, reason, previousLaunchId, nextLaunchId, nextSessionId);
9705
+ this.sendAgentStatus(agentId, "active", nextLaunchId);
9706
+ if (nextSessionId) {
9707
+ this.sendToServer({ type: "agent:session", agentId, sessionId: nextSessionId, launchId: nextLaunchId || void 0 });
9708
+ }
9709
+ if (start.wakeMessage) {
9710
+ const accepted = this.deliverMessage(agentId, start.wakeMessage, { transient: start.wakeMessageTransient === true });
9711
+ if (accepted instanceof Promise) {
9712
+ accepted.catch((err) => logger.error(`[Agent ${agentId}] Failed to deliver wake message after start rebind`, err));
9713
+ }
9714
+ }
9715
+ return true;
9716
+ }
9491
9717
  async startAgent(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient = false) {
9492
9718
  this.recordDaemonTrace("daemon.agent.start.requested", this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient));
9493
9719
  if (this.agents.has(agentId)) {
@@ -9495,7 +9721,8 @@ var AgentProcessManager = class _AgentProcessManager {
9495
9721
  ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
9496
9722
  reason: "already_running"
9497
9723
  });
9498
- logger.info(`[Agent ${agentId}] Start ignored (already running)`);
9724
+ this.rebindRunningStart(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient }, "already_running");
9725
+ logger.info(`[Agent ${agentId}] Start rebound (already running)`);
9499
9726
  return;
9500
9727
  }
9501
9728
  if (this.agentsStarting.has(agentId)) {
@@ -9503,7 +9730,8 @@ var AgentProcessManager = class _AgentProcessManager {
9503
9730
  ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
9504
9731
  reason: "already_starting"
9505
9732
  });
9506
- logger.info(`[Agent ${agentId}] Start ignored (startup in progress)`);
9733
+ this.pendingStartRebinds.set(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient });
9734
+ logger.info(`[Agent ${agentId}] Start rebind deferred (startup in progress)`);
9507
9735
  return;
9508
9736
  }
9509
9737
  if (this.queuedAgentStarts.has(agentId)) {
@@ -9511,7 +9739,8 @@ var AgentProcessManager = class _AgentProcessManager {
9511
9739
  ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
9512
9740
  reason: "already_queued"
9513
9741
  });
9514
- logger.info(`[Agent ${agentId}] Start ignored (startup already queued)`);
9742
+ this.rebindQueuedStart(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient }, "already_queued");
9743
+ logger.info(`[Agent ${agentId}] Queued start rebound (startup already queued)`);
9515
9744
  return;
9516
9745
  }
9517
9746
  return new Promise((resolve, reject) => {
@@ -9570,6 +9799,11 @@ var AgentProcessManager = class _AgentProcessManager {
9570
9799
  ...this.startQueueTraceAttrs(item.agentId, item.config, item.wakeMessage, item.unreadSummary, item.resumePrompt, item.launchId, item.wakeMessageTransient),
9571
9800
  reason: "already_running_or_starting"
9572
9801
  });
9802
+ if (this.agents.has(item.agentId)) {
9803
+ this.rebindRunningStart(item.agentId, item, "already_running_or_starting");
9804
+ } else {
9805
+ this.pendingStartRebinds.set(item.agentId, item);
9806
+ }
9573
9807
  logger.info(`[Agent ${item.agentId}] Queued start skipped (already running or starting)`);
9574
9808
  item.resolve();
9575
9809
  this.pumpAgentStartQueue();
@@ -9656,7 +9890,8 @@ var AgentProcessManager = class _AgentProcessManager {
9656
9890
  ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
9657
9891
  reason: "already_running"
9658
9892
  });
9659
- logger.info(`[Agent ${agentId}] Start ignored (already running)`);
9893
+ this.rebindRunningStart(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient }, "already_running");
9894
+ logger.info(`[Agent ${agentId}] Start rebound (already running)`);
9660
9895
  return;
9661
9896
  }
9662
9897
  if (this.agentsStarting.has(agentId)) {
@@ -9664,7 +9899,8 @@ var AgentProcessManager = class _AgentProcessManager {
9664
9899
  ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
9665
9900
  reason: "already_starting"
9666
9901
  });
9667
- logger.info(`[Agent ${agentId}] Start ignored (startup in progress)`);
9902
+ this.pendingStartRebinds.set(agentId, { config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient });
9903
+ logger.info(`[Agent ${agentId}] Start rebind deferred (startup in progress)`);
9668
9904
  return;
9669
9905
  }
9670
9906
  this.agentsStarting.add(agentId);
@@ -9792,7 +10028,12 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9792
10028
  nativeStandingPrompt: Boolean(driver.supportsNativeStandingPrompt)
9793
10029
  });
9794
10030
  const effectiveConfig = await this.buildSpawnConfig(agentId, runtimeConfig);
9795
- const canDeferEmptyStart = driver.deferSpawnUntilMessage === true && !wakeMessage && !runtimeConfig.runtimeProfileControl && (!unreadSummary || Object.keys(unreadSummary).length === 0);
10031
+ const pendingStartRebind = this.pendingStartRebinds.get(agentId);
10032
+ if (pendingStartRebind) {
10033
+ this.pendingStartRebinds.delete(agentId);
10034
+ }
10035
+ const effectiveLaunchId = pendingStartRebind?.launchId || launchId || null;
10036
+ const canDeferEmptyStart = driver.deferSpawnUntilMessage === true && !wakeMessage && !pendingStartRebind?.wakeMessage && !runtimeConfig.runtimeProfileControl && (!unreadSummary || Object.keys(unreadSummary).length === 0);
9796
10037
  if (canDeferEmptyStart) {
9797
10038
  const pendingMessages = this.startingInboxes.get(agentId) || [];
9798
10039
  this.startingInboxes.delete(agentId);
@@ -9800,12 +10041,12 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9800
10041
  this.idleAgentConfigs.set(agentId, {
9801
10042
  config: effectiveConfig,
9802
10043
  sessionId: effectiveConfig.sessionId || null,
9803
- launchId: launchId || null
10044
+ launchId: effectiveLaunchId
9804
10045
  });
9805
- this.sendAgentStatus(agentId, "active", launchId || null);
10046
+ this.sendAgentStatus(agentId, "active", effectiveLaunchId);
9806
10047
  this.broadcastActivity(agentId, "online", "Process idle");
9807
10048
  this.recordDaemonTrace("daemon.agent.spawn.deferred", {
9808
- ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
10049
+ ...this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, effectiveLaunchId || void 0, wakeMessageTransient),
9809
10050
  pending_messages_count: pendingMessages.length,
9810
10051
  reason: "defer_until_concrete_message"
9811
10052
  });
@@ -9823,7 +10064,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9823
10064
  workingDirectory: agentDataDir,
9824
10065
  slockCliPath: this.slockCliPath,
9825
10066
  daemonApiKey: this.daemonApiKey,
9826
- launchId: launchId || null,
10067
+ launchId: effectiveLaunchId,
9827
10068
  agentCredentialProxyInboxCoordinator: this.createAgentProxyInboxCoordinator(agentId),
9828
10069
  cliTransportTraceDir: this.cliTransportTraceDir
9829
10070
  };
@@ -9834,7 +10075,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9834
10075
  inbox: wakeMessageDeliveredAsInboxUpdate && wakeMessage ? [wakeMessage, ...startingInboxMessages] : startingInboxMessages,
9835
10076
  config: runtimeConfig,
9836
10077
  sessionId: runtimeConfig.sessionId || null,
9837
- launchId: launchId || null,
10078
+ launchId: effectiveLaunchId,
9838
10079
  startupWakeMessage: wakeMessage,
9839
10080
  startupUnreadSummary: unreadSummary,
9840
10081
  startupResumePrompt: resumePrompt,
@@ -9870,8 +10111,11 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9870
10111
  this.idleAgentConfigs.set(agentId, {
9871
10112
  config: { ...effectiveConfig, sessionId: effectiveConfig.sessionId || null },
9872
10113
  sessionId: effectiveConfig.sessionId || null,
9873
- launchId: launchId || null
10114
+ launchId: effectiveLaunchId
9874
10115
  });
10116
+ if (pendingStartRebind) {
10117
+ this.recordStartRebind(agentId, pendingStartRebind, "startup_registered", launchId || null, effectiveLaunchId, agentProcess.sessionId);
10118
+ }
9875
10119
  this.startRuntimeTrace(agentId, agentProcess, "spawn", wakeMessage ? [wakeMessage] : void 0, runtimeInputTraceAttrs);
9876
10120
  this.agentsStarting.delete(agentId);
9877
10121
  if (runtimeConfig.runtimeProfileControl) {
@@ -10106,16 +10350,26 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10106
10350
  throw new Error(`Runtime session failed to start: ${startResult.reason}${startResult.error ? ` (${startResult.error})` : ""}`);
10107
10351
  }
10108
10352
  this.recordDaemonTrace("daemon.agent.spawn.created", {
10109
- ...this.startQueueTraceAttrs(agentId, effectiveConfig, wakeMessage, unreadSummary, resumePrompt, launchId, wakeMessageTransient),
10353
+ ...this.startQueueTraceAttrs(agentId, effectiveConfig, wakeMessage, unreadSummary, resumePrompt, agentProcess.launchId || void 0, wakeMessageTransient),
10110
10354
  detached: false,
10111
10355
  new_session: false,
10112
10356
  process_pid_present: typeof runtime.pid === "number"
10113
10357
  });
10114
- this.sendAgentStatus(agentId, "active", launchId || null);
10358
+ this.sendAgentStatus(agentId, "active", agentProcess.launchId);
10359
+ if (pendingStartRebind && agentProcess.sessionId) {
10360
+ this.sendToServer({ type: "agent:session", agentId, sessionId: agentProcess.sessionId, launchId: agentProcess.launchId || void 0 });
10361
+ }
10362
+ if (pendingStartRebind?.wakeMessage) {
10363
+ const accepted = this.deliverMessage(agentId, pendingStartRebind.wakeMessage, { transient: pendingStartRebind.wakeMessageTransient === true });
10364
+ if (accepted instanceof Promise) {
10365
+ accepted.catch((err) => logger.error(`[Agent ${agentId}] Failed to deliver wake message after startup rebind`, err));
10366
+ }
10367
+ }
10115
10368
  this.broadcastActivity(agentId, "working", "Starting\u2026");
10116
10369
  this.startRuntimeStartupTimeout(agentId, agentProcess);
10117
10370
  } catch (err) {
10118
10371
  this.agentsStarting.delete(agentId);
10372
+ this.pendingStartRebinds.delete(agentId);
10119
10373
  this.cleanupFailedRuntimeStart(agentId, agentProcess, err);
10120
10374
  throw err;
10121
10375
  }
@@ -10384,6 +10638,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10384
10638
  }
10385
10639
  async stopAgent(agentId, { wait = false, silent = false } = {}) {
10386
10640
  this.cancelQueuedAgentStart(agentId, "stop requested");
10641
+ this.pendingStartRebinds.delete(agentId);
10387
10642
  this.idleAgentConfigs.delete(agentId);
10388
10643
  const ap = this.agents.get(agentId);
10389
10644
  if (!ap) {