@botiverse/raft-daemon 0.72.8 → 0.72.12

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.
@@ -4032,6 +4032,55 @@ var CANONICAL_MESSAGE_MANIFEST = Object.freeze({
4032
4032
  excludedClientOnly: EXCLUDED_CLIENT_ONLY_MESSAGE_FIELDS
4033
4033
  });
4034
4034
 
4035
+ // ../shared/src/canonicalMessageV2.ts
4036
+ var CANONICAL_MESSAGE_V2_SCHEMA_VERSION = 5;
4037
+ var CANONICAL_MESSAGE_V2_ENVELOPE_KIND = "normalized-message-v2";
4038
+ var CANONICAL_REACTION_PREVIEW_LIMIT = 3;
4039
+ var CANONICAL_REACTION_LIMIT = 30;
4040
+ var CANONICAL_MESSAGE_V2_MANIFEST = Object.freeze({
4041
+ schemaVersion: CANONICAL_MESSAGE_V2_SCHEMA_VERSION,
4042
+ envelopeKind: CANONICAL_MESSAGE_V2_ENVELOPE_KIND,
4043
+ legacyIngressManifestVersion: CANONICAL_MESSAGE_MANIFEST_VERSION,
4044
+ soleApplyEligible: true,
4045
+ reactions: Object.freeze({
4046
+ mergePolicy: "present-overwrite",
4047
+ maxItems: CANONICAL_REACTION_LIMIT,
4048
+ fields: Object.freeze(["count", "emoji", "previewK"]),
4049
+ previewFields: Object.freeze(["displayName", "id"]),
4050
+ previewLimit: CANONICAL_REACTION_PREVIEW_LIMIT,
4051
+ legacyCompatibilityPreviewPolicy: "empty-without-room-common-provenance",
4052
+ deterministicOrder: "emoji-code-unit/actor-id-code-unit"
4053
+ }),
4054
+ viewerOverlayFields: Object.freeze(["reactions.reactedByMe"]),
4055
+ readCacheRelations: Object.freeze(["Message.ReactionActors"]),
4056
+ forbiddenCanonicalPaths: Object.freeze([
4057
+ "reactions[].reactorIds",
4058
+ "reactions[].reactorNames"
4059
+ ])
4060
+ });
4061
+
4062
+ // ../shared/src/discussionGraph.ts
4063
+ var DISCUSSION_RELATION_REGISTRY = Object.freeze({
4064
+ messageReactionActors: Object.freeze({
4065
+ rootKind: "message",
4066
+ relation: "reaction-actors",
4067
+ backing: "read-cache",
4068
+ consistency: "read-page",
4069
+ provenance: Object.freeze({ count: "shared-parent-fold", previewK: "shared-parent-fold" }),
4070
+ invalidation: "parent-scope-epoch",
4071
+ allowedCommands: Object.freeze(["set-interaction"])
4072
+ }),
4073
+ messageReplies: Object.freeze({
4074
+ rootKind: "message",
4075
+ relation: "replies",
4076
+ backing: "sync-scope",
4077
+ consistency: "sync-scope-window",
4078
+ provenance: Object.freeze({ replyCount: "shared-parent-fold" }),
4079
+ invalidation: "own-scope-rebaseline",
4080
+ allowedCommands: Object.freeze(["reply"])
4081
+ })
4082
+ });
4083
+
4035
4084
  // ../shared/src/index.ts
4036
4085
  var COMPUTER_CAPABILITY_SUPERVISOR_MUTATIONS = "computer:supervisor-mutations-v1";
4037
4086
  var RUNTIME_CONFIG_VERSION = 1;
@@ -4558,7 +4607,7 @@ var TRIAL_DURATION_DAYS = (TRIAL_END_DATE.getTime() - TRIAL_START_DATE.getTime()
4558
4607
 
4559
4608
  // src/agentProcessManager.ts
4560
4609
  import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync6, readdirSync as readdirSync4, statSync, writeFileSync as writeFileSync4 } from "fs";
4561
- import { mkdir, writeFile, access, readdir as readdir2, stat as stat2, readFile, rm as rm2, lstat, realpath, open } from "fs/promises";
4610
+ import { readdir as readdir2, stat as stat2, readFile, rm as rm2, lstat, realpath, open } from "fs/promises";
4562
4611
  import { createHash as createHash3, randomUUID as randomUUID6 } from "crypto";
4563
4612
  import path14 from "path";
4564
4613
  import { gzipSync } from "zlib";
@@ -4566,8 +4615,9 @@ import os6 from "os";
4566
4615
 
4567
4616
  // src/proxy.ts
4568
4617
  import { HttpsProxyAgent } from "https-proxy-agent";
4569
- import { ProxyAgent } from "undici";
4618
+ import { Agent, ProxyAgent } from "undici";
4570
4619
  var fetchDispatcherCache = /* @__PURE__ */ new Map();
4620
+ var isolatedFetchDispatcherCache = /* @__PURE__ */ new Map();
4571
4621
  function getFetchPreResponseTimeoutMs(env) {
4572
4622
  const parsed = Number.parseInt(env.SLOCK_DAEMON_FETCH_PRE_RESPONSE_TIMEOUT_MS || "", 10);
4573
4623
  return Number.isFinite(parsed) && parsed > 0 ? parsed : 3e4;
@@ -4632,32 +4682,60 @@ function resolveProxyUrl(targetUrl, env) {
4632
4682
  if (shouldBypassProxy(targetUrl, env)) return void 0;
4633
4683
  return proxyUrl;
4634
4684
  }
4685
+ function createProxyDispatcher(proxyUrl, timeoutMs) {
4686
+ return new ProxyAgent({
4687
+ uri: proxyUrl,
4688
+ connect: { timeout: timeoutMs },
4689
+ requestTls: { timeout: timeoutMs },
4690
+ headersTimeout: timeoutMs
4691
+ });
4692
+ }
4693
+ function closeDispatcherBestEffort(dispatcher) {
4694
+ void Promise.resolve().then(() => dispatcher.close()).catch(() => dispatcher.destroy?.(new Error("evicted"))).catch(() => {
4695
+ });
4696
+ }
4635
4697
  function buildFetchDispatcher(targetUrl, env) {
4636
4698
  const proxyUrl = resolveProxyUrl(targetUrl, env);
4637
4699
  if (!proxyUrl) return void 0;
4638
4700
  const cached = fetchDispatcherCache.get(proxyUrl);
4639
4701
  if (cached) return cached;
4640
4702
  const timeoutMs = getFetchPreResponseTimeoutMs(env);
4641
- const dispatcher = new ProxyAgent({
4642
- uri: proxyUrl,
4643
- // All three are pre-response and body-agnostic (see getFetchPreResponseTimeoutMs):
4644
- // headersTimeout = headers-hang leg; requestTls.timeout = CONNECT-tunnel
4645
- // establish leg; connect.timeout = socket to the proxy itself (defensive).
4703
+ const dispatcher = createProxyDispatcher(proxyUrl, timeoutMs);
4704
+ fetchDispatcherCache.set(proxyUrl, dispatcher);
4705
+ return dispatcher;
4706
+ }
4707
+ function getIsolatedDispatcherCacheKey(targetUrl, isolationKey, env) {
4708
+ const proxyUrl = resolveProxyUrl(targetUrl, env);
4709
+ const routeKey = proxyUrl ? `proxy:${proxyUrl}` : `direct:${new URL(targetUrl).origin}`;
4710
+ return { cacheKey: `${isolationKey}\0${routeKey}`, proxyUrl };
4711
+ }
4712
+ function buildIsolatedFetchDispatcher(targetUrl, isolationKey, env) {
4713
+ const { cacheKey, proxyUrl } = getIsolatedDispatcherCacheKey(targetUrl, isolationKey, env);
4714
+ const cached = isolatedFetchDispatcherCache.get(cacheKey);
4715
+ if (cached) return cached;
4716
+ const timeoutMs = getFetchPreResponseTimeoutMs(env);
4717
+ const dispatcher = proxyUrl ? createProxyDispatcher(proxyUrl, timeoutMs) : new Agent({
4646
4718
  connect: { timeout: timeoutMs },
4647
- requestTls: { timeout: timeoutMs },
4648
4719
  headersTimeout: timeoutMs
4649
4720
  });
4650
- fetchDispatcherCache.set(proxyUrl, dispatcher);
4721
+ isolatedFetchDispatcherCache.set(cacheKey, dispatcher);
4651
4722
  return dispatcher;
4652
4723
  }
4724
+ function evictIsolatedFetchDispatcher(targetUrl, isolationKey, env) {
4725
+ const { cacheKey } = getIsolatedDispatcherCacheKey(targetUrl, isolationKey, env);
4726
+ const cached = isolatedFetchDispatcherCache.get(cacheKey);
4727
+ if (!cached) return false;
4728
+ isolatedFetchDispatcherCache.delete(cacheKey);
4729
+ closeDispatcherBestEffort(cached);
4730
+ return true;
4731
+ }
4653
4732
  function evictFetchDispatcher(targetUrl, env) {
4654
4733
  const proxyUrl = resolveProxyUrl(targetUrl, env);
4655
4734
  if (!proxyUrl) return false;
4656
4735
  const cached = fetchDispatcherCache.get(proxyUrl);
4657
4736
  if (!cached) return false;
4658
4737
  fetchDispatcherCache.delete(proxyUrl);
4659
- void Promise.resolve().then(() => cached.close()).catch(() => cached.destroy?.(new Error("evicted"))).catch(() => {
4660
- });
4738
+ closeDispatcherBestEffort(cached);
4661
4739
  return true;
4662
4740
  }
4663
4741
 
@@ -4666,11 +4744,17 @@ function withDaemonFetchProxy(input, init = {}, env = process.env) {
4666
4744
  const dispatcher = buildFetchDispatcher(input.toString(), env);
4667
4745
  return dispatcher ? { ...init, dispatcher } : init;
4668
4746
  }
4669
- async function daemonFetch(input, init, env = process.env) {
4747
+ async function daemonFetch(input, init, env = process.env, options = {}) {
4748
+ const targetUrl = input.toString();
4749
+ const fetchInit = options.isolationKey ? { ...init, dispatcher: buildIsolatedFetchDispatcher(targetUrl, options.isolationKey, env) } : withDaemonFetchProxy(input, init, env);
4670
4750
  try {
4671
- return await fetch(input, withDaemonFetchProxy(input, init, env));
4751
+ return await fetch(input, fetchInit);
4672
4752
  } catch (err) {
4673
- evictFetchDispatcher(input.toString(), env);
4753
+ if (options.isolationKey) {
4754
+ evictIsolatedFetchDispatcher(targetUrl, options.isolationKey, env);
4755
+ } else {
4756
+ evictFetchDispatcher(targetUrl, env);
4757
+ }
4674
4758
  throw err;
4675
4759
  }
4676
4760
  }
@@ -6499,6 +6583,7 @@ var HOP_BY_HOP_REQUEST_HEADERS = /* @__PURE__ */ new Set([
6499
6583
  var LOCAL_HELD_CONTEXT_LIMIT = 3;
6500
6584
  var AGENT_CREDENTIAL_PROXY_HOST = "127.0.0.1";
6501
6585
  var AGENT_CREDENTIAL_PROXY_BIND_MAX_ATTEMPTS = 3;
6586
+ var AGENT_CREDENTIAL_PROXY_FETCH_ISOLATION_KEY = "agent-credential-proxy";
6502
6587
  function createProxyRequestHandler() {
6503
6588
  return (req, res) => {
6504
6589
  void handleProxyRequest(req, res);
@@ -6653,11 +6738,16 @@ async function handleProxyRequest(req, res) {
6653
6738
  headers.set("content-type", "application/json");
6654
6739
  headers.delete("content-length");
6655
6740
  }
6656
- const upstream = await daemonFetch(target, {
6657
- method,
6658
- headers,
6659
- body
6660
- });
6741
+ const upstream = await daemonFetch(
6742
+ target,
6743
+ {
6744
+ method,
6745
+ headers,
6746
+ body
6747
+ },
6748
+ process.env,
6749
+ { isolationKey: AGENT_CREDENTIAL_PROXY_FETCH_ISOLATION_KEY }
6750
+ );
6661
6751
  if (upstream.status >= 500) {
6662
6752
  const transportError = transportNormalizedErrorForHttpStatus(target, upstream.status, registration.launchId);
6663
6753
  logger.warn(
@@ -11731,7 +11821,11 @@ function buildBuiltInAgentDir(workingDirectory) {
11731
11821
  async function buildPiSpawnEnv(ctx) {
11732
11822
  return (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
11733
11823
  }
11734
- function seedBuiltInAuthStorage(authStorage, runtimeConfig) {
11824
+ function seedPiSessionAuthStorage(authStorage, runtimeConfig) {
11825
+ if (runtimeConfig.runtime === "pi" && runtimeConfig.provider?.kind === "pi-builtin") {
11826
+ authStorage.setRuntimeApiKey(runtimeConfig.provider.providerId, runtimeConfig.provider.apiKey);
11827
+ return;
11828
+ }
11735
11829
  if (runtimeConfig.runtime !== "builtin") return;
11736
11830
  if (runtimeConfig.provider.kind === "preset") {
11737
11831
  authStorage.setRuntimeApiKey(runtimeConfig.provider.providerId, runtimeConfig.provider.apiKey);
@@ -11744,11 +11838,12 @@ function seedBuiltInAuthStorage(authStorage, runtimeConfig) {
11744
11838
  }
11745
11839
  }
11746
11840
  function buildPiSessionCreateEnvPatch(runtimeConfig, envVars) {
11747
- if (runtimeConfig.runtime !== "builtin" || !envVars) return envVars;
11748
- const providerApiKeyEnvNames = /* @__PURE__ */ new Set([
11841
+ if (!envVars) return null;
11842
+ const providerApiKeyEnvNames = runtimeConfig.runtime === "builtin" ? /* @__PURE__ */ new Set([
11749
11843
  ...Object.values(BUILTIN_RUNTIME_PROVIDER_ENV_KEYS),
11750
11844
  ...Object.values(BUILTIN_RUNTIME_GATEWAY_PROVIDER_ENV_KEYS)
11751
- ]);
11845
+ ]) : runtimeConfig.runtime === "pi" && runtimeConfig.provider?.kind === "pi-builtin" ? /* @__PURE__ */ new Set([PI_BUILTIN_PROVIDER_ENV_KEYS[runtimeConfig.provider.providerId]]) : /* @__PURE__ */ new Set();
11846
+ if (providerApiKeyEnvNames.size === 0) return envVars;
11752
11847
  const filtered = Object.fromEntries(
11753
11848
  Object.entries(envVars).filter(([key]) => !providerApiKeyEnvNames.has(key))
11754
11849
  );
@@ -12106,7 +12201,7 @@ async function createPiAgentSessionForContext(ctx, sessionId, opts = {}) {
12106
12201
  const agentDir = opts.agentDir ?? spawnEnv.PI_CODING_AGENT_DIR ?? getAgentDir();
12107
12202
  mkdirSync3(agentDir, { recursive: true });
12108
12203
  const authStorage = AuthStorage.create(path12.join(agentDir, "auth.json"));
12109
- seedBuiltInAuthStorage(authStorage, runtimeConfig);
12204
+ seedPiSessionAuthStorage(authStorage, runtimeConfig);
12110
12205
  const settingsManager = SettingsManager.create(ctx.workingDirectory, agentDir);
12111
12206
  const providerEnvScope = opts.isolateHostProviderEnv ? BUILTIN_BLOCKED_HOST_PROVIDER_ENV_KEYS : void 0;
12112
12207
  const sessionCreateEnvPatch = buildPiSessionCreateEnvPatch(runtimeConfig, launchRuntimeFields.envVars);
@@ -12229,22 +12324,17 @@ async function createPiAgentSessionForContext(ctx, sessionId, opts = {}) {
12229
12324
  throw error;
12230
12325
  }
12231
12326
  }
12327
+ var piPromptsInFlight = 0;
12232
12328
  var PiSdkRuntimeSession = class {
12233
- constructor(ctx, setCurrentSessionId, sessionFactory = createPiAgentSessionForContext, opts = {}) {
12329
+ constructor(ctx, setCurrentSessionId, sessionFactory = createPiAgentSessionForContext) {
12234
12330
  this.ctx = ctx;
12235
12331
  this.setCurrentSessionId = setCurrentSessionId;
12236
12332
  this.sessionFactory = sessionFactory;
12237
12333
  this.mappingState = createPiSdkEventMappingState(ctx.config.sessionId || null);
12238
- const runtimeConfig = hydrateRuntimeConfig(ctx.config);
12239
- const launchRuntimeFields = runtimeConfigToLaunchFields(runtimeConfig);
12240
- this.sdkCallEnvPatch = buildPiSessionCreateEnvPatch(runtimeConfig, launchRuntimeFields.envVars);
12241
- this.sdkCallEnvRemoveFirst = opts.isolateHostProviderEnv ? BUILTIN_BLOCKED_HOST_PROVIDER_ENV_KEYS : void 0;
12242
12334
  }
12243
12335
  descriptor = PI_RUNTIME_SESSION_DESCRIPTOR;
12244
12336
  events = new EventEmitter2();
12245
12337
  mappingState;
12246
- sdkCallEnvPatch;
12247
- sdkCallEnvRemoveFirst;
12248
12338
  session = null;
12249
12339
  unsubscribe = null;
12250
12340
  started = false;
@@ -12377,10 +12467,41 @@ var PiSdkRuntimeSession = class {
12377
12467
  return !this.didClose && this.session === session && !session.isStreaming;
12378
12468
  }
12379
12469
  deferSdkCall(invoke) {
12470
+ const queuedAt = currentTimeMs();
12380
12471
  setImmediate(() => {
12381
12472
  if (this.didClose) return;
12473
+ const span = this.ctx.tracer?.startSpan("daemon.pi.prompt", {
12474
+ surface: "daemon",
12475
+ kind: "internal",
12476
+ attrs: {
12477
+ agentId: this.ctx.agentId,
12478
+ launchId: this.ctx.launchId || void 0,
12479
+ runtime: this.ctx.config.runtime
12480
+ }
12481
+ });
12482
+ const startedAt = currentTimeMs();
12483
+ piPromptsInFlight += 1;
12484
+ span?.addEvent("daemon.pi.prompt.start", {
12485
+ agentId: this.ctx.agentId,
12486
+ queued_ms: startedAt - queuedAt,
12487
+ prompts_in_flight: piPromptsInFlight
12488
+ });
12489
+ let settled = false;
12490
+ const settle = (status) => {
12491
+ if (settled) return;
12492
+ settled = true;
12493
+ piPromptsInFlight -= 1;
12494
+ span?.end(status, {
12495
+ attrs: {
12496
+ queued_ms: startedAt - queuedAt,
12497
+ duration_ms: currentTimeMs() - startedAt,
12498
+ prompts_in_flight_after: piPromptsInFlight
12499
+ }
12500
+ });
12501
+ };
12382
12502
  try {
12383
- void withProcessEnvPatch(this.sdkCallEnvPatch, invoke, { removeFirst: this.sdkCallEnvRemoveFirst }).catch((error) => {
12503
+ void invoke().then(() => settle("ok")).catch((error) => {
12504
+ settle("error");
12384
12505
  if (this.didClose) return;
12385
12506
  this.events.emit("runtime_event", {
12386
12507
  kind: "error",
@@ -12388,6 +12509,7 @@ var PiSdkRuntimeSession = class {
12388
12509
  });
12389
12510
  });
12390
12511
  } catch (error) {
12512
+ settle("error");
12391
12513
  if (this.didClose) return;
12392
12514
  this.events.emit("runtime_event", {
12393
12515
  kind: "error",
@@ -12513,7 +12635,7 @@ var BuiltInDriver = class extends PiDriver {
12513
12635
  exposeLaunchTraceEvidence: true,
12514
12636
  exposeLaunchEnvToTools: false,
12515
12637
  isolateHostProviderEnv: true
12516
- }), { isolateHostProviderEnv: true });
12638
+ }));
12517
12639
  }
12518
12640
  buildSystemPrompt(config, _agentId) {
12519
12641
  return buildCliTransportSystemPrompt(config, {
@@ -12778,8 +12900,27 @@ async function reapOrphanProcesses(pids, logger2, recordTrace) {
12778
12900
  }
12779
12901
 
12780
12902
  // src/workspaces.ts
12781
- import { readdir, rm, stat } from "fs/promises";
12903
+ import { access, mkdir, readdir, rm, stat, writeFile } from "fs/promises";
12782
12904
  import path13 from "path";
12905
+ async function initializeAgentWorkspace(workspacePath, initialMemoryMd, seedFiles) {
12906
+ await mkdir(workspacePath, { recursive: true });
12907
+ const memoryMdPath = path13.join(workspacePath, "MEMORY.md");
12908
+ try {
12909
+ await access(memoryMdPath);
12910
+ } catch {
12911
+ await writeFile(memoryMdPath, initialMemoryMd);
12912
+ }
12913
+ await mkdir(path13.join(workspacePath, "notes"), { recursive: true });
12914
+ for (const { relativePath, content } of seedFiles) {
12915
+ const fullPath = path13.join(workspacePath, relativePath);
12916
+ try {
12917
+ await access(fullPath);
12918
+ } catch {
12919
+ await mkdir(path13.dirname(fullPath), { recursive: true });
12920
+ await writeFile(fullPath, content);
12921
+ }
12922
+ }
12923
+ }
12783
12924
  function isValidWorkspaceDirectoryName(directoryName) {
12784
12925
  return !directoryName.includes("/") && !directoryName.includes("\\") && !directoryName.includes("..");
12785
12926
  }
@@ -17395,29 +17536,12 @@ var AgentProcessManager = class _AgentProcessManager {
17395
17536
  const originalLaunchId = launchId || null;
17396
17537
  try {
17397
17538
  const agentDataDir = path14.join(this.dataDir, agentId);
17398
- await mkdir(agentDataDir, { recursive: true });
17399
17539
  const initialRuntimeConfig = withLocalRuntimeContext(config, agentId, agentDataDir);
17400
- const memoryMdPath = path14.join(agentDataDir, "MEMORY.md");
17401
- try {
17402
- await access(memoryMdPath);
17403
- } catch {
17404
- const initialMemoryMd = buildInitialMemoryMd(initialRuntimeConfig);
17405
- await writeFile(memoryMdPath, initialMemoryMd);
17406
- }
17407
- const notesDir = path14.join(agentDataDir, "notes");
17408
- await mkdir(notesDir, { recursive: true });
17409
- if (getOnboardingSeedMode(config) === FIRST_CINDY_SEED_MODE) {
17410
- const seedFiles = buildOnboardingSeedFiles();
17411
- for (const { relativePath, content } of seedFiles) {
17412
- const fullPath = path14.join(agentDataDir, relativePath);
17413
- try {
17414
- await access(fullPath);
17415
- } catch {
17416
- await mkdir(path14.dirname(fullPath), { recursive: true });
17417
- await writeFile(fullPath, content);
17418
- }
17419
- }
17420
- }
17540
+ await initializeAgentWorkspace(
17541
+ agentDataDir,
17542
+ buildInitialMemoryMd(initialRuntimeConfig),
17543
+ getOnboardingSeedMode(config) === FIRST_CINDY_SEED_MODE ? buildOnboardingSeedFiles() : []
17544
+ );
17421
17545
  pendingStartRebind = this.lifecycleRecords.getPendingStartRebind(agentId);
17422
17546
  if (pendingStartRebind) {
17423
17547
  this.lifecycleRecords.deletePendingStartRebind(agentId);
@@ -18189,36 +18313,26 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
18189
18313
  async buildSpawnConfig(agentId, config) {
18190
18314
  const baseConfig = config.serverUrl === this.serverUrl ? config : { ...config, serverUrl: this.serverUrl };
18191
18315
  const runnerConfig = await this.ensureManagedRunnerCredential(agentId, baseConfig);
18192
- if (!this.defaultAgentEnvVarsProvider) {
18193
- return runnerConfig;
18194
- }
18195
- try {
18196
- const defaultEnvVars = await this.defaultAgentEnvVarsProvider({
18197
- runtime: runnerConfig.runtime,
18198
- model: runnerConfig.model,
18199
- envVars: runnerConfig.envVars
18200
- });
18201
- if (!defaultEnvVars || Object.keys(defaultEnvVars).length === 0) {
18202
- return runnerConfig;
18203
- }
18204
- const mergedEnvVars = {
18205
- ...defaultEnvVars,
18206
- ...runnerConfig.envVars ?? {}
18207
- };
18208
- if (this.sameEnvVars(mergedEnvVars, runnerConfig.envVars)) {
18209
- return runnerConfig;
18316
+ let effectiveConfig = runnerConfig;
18317
+ if (this.defaultAgentEnvVarsProvider) {
18318
+ try {
18319
+ const defaultEnvVars = await this.defaultAgentEnvVarsProvider({
18320
+ runtime: runnerConfig.runtime,
18321
+ model: runnerConfig.model,
18322
+ envVars: runnerConfig.envVars
18323
+ });
18324
+ const mergedEnvVars = { ...defaultEnvVars ?? {}, ...runnerConfig.envVars ?? {} };
18325
+ if (!this.sameEnvVars(mergedEnvVars, runnerConfig.envVars)) {
18326
+ effectiveConfig = { ...runnerConfig, envVars: mergedEnvVars };
18327
+ }
18328
+ } catch (error) {
18329
+ const reason = error instanceof Error ? error.message : String(error);
18330
+ logger.warn(
18331
+ `[Agent ${agentId}] Failed to resolve default runtime env vars \u2014 continuing without machine-level defaults (${reason})`
18332
+ );
18210
18333
  }
18211
- return {
18212
- ...runnerConfig,
18213
- envVars: mergedEnvVars
18214
- };
18215
- } catch (error) {
18216
- const reason = error instanceof Error ? error.message : String(error);
18217
- logger.warn(
18218
- `[Agent ${agentId}] Failed to resolve default runtime env vars \u2014 continuing without machine-level defaults (${reason})`
18219
- );
18220
- return runnerConfig;
18221
18334
  }
18335
+ return effectiveConfig;
18222
18336
  }
18223
18337
  async requestManagedRunnerCredentialOnce(agentId, config) {
18224
18338
  const url = new URL(`/internal/computer/runners/${encodeURIComponent(agentId)}/credentials`, this.serverUrl);
@@ -24580,6 +24694,17 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
24580
24694
  },
24581
24695
  endAttrs: ["outcome", "models_count", "default_model_present", "verified_as", "error_class"]
24582
24696
  },
24697
+ // task #510: per-prompt span. `prompts_in_flight` is the cross-agent concurrency
24698
+ // observable — under the old process-env-patch lock it could never exceed 1
24699
+ // (every Pi prompt serialized process-wide); > 1 proves the queue is gone.
24700
+ // `queued_ms` is the queued -> prompt-start wait that users experienced as the
24701
+ // 60-165s stall.
24702
+ "daemon.pi.prompt": {
24703
+ spanAttrs: ["agentId", "launchId", "runtime", "queued_ms", "duration_ms", "prompts_in_flight_after"],
24704
+ eventAttrs: {
24705
+ "daemon.pi.prompt.start": ["agentId", "queued_ms", "prompts_in_flight"]
24706
+ }
24707
+ },
24583
24708
  "daemon.pi.session.create": {
24584
24709
  spanAttrs: ["agentId", "launchId", "runtime", "model", "session_id_present", "requested_model"],
24585
24710
  eventAttrs: {
@@ -24780,7 +24905,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
24780
24905
  }
24781
24906
  async function runBundledSlockCli(argv) {
24782
24907
  process.argv = [process.execPath, "slock", ...argv];
24783
- await import("./dist-54TOXXOV.js");
24908
+ await import("./dist-ME3NQ5JP.js");
24784
24909
  }
24785
24910
  function detectRuntimes(tracer = noopTracer) {
24786
24911
  const ids = [];
@@ -26149,9 +26274,9 @@ var DaemonCore = class {
26149
26274
  });
26150
26275
  }
26151
26276
  emitReadyIfConnected() {
26152
- if (this.connection.connected) this.emitReady();
26277
+ if (this.connection.connected) void this.emitReady();
26153
26278
  }
26154
- emitReady() {
26279
+ async emitReady() {
26155
26280
  const { ids: runtimes, versions: runtimeVersions, diagnostics: runtimeDiagnostics = {} } = this.runtimeDetector();
26156
26281
  const runtimeInfo = runtimes.map((id) => runtimeVersions[id] ? `${id} (${runtimeVersions[id]})` : id);
26157
26282
  logger.info(`[Daemon] Detected runtimes: ${runtimeInfo.join(", ") || "none"}`);
@@ -26161,6 +26286,15 @@ var DaemonCore = class {
26161
26286
  const runningAgentIds = this.agentManager.getRunningAgentIds();
26162
26287
  const idleAgentSessions = this.agentManager.getIdleAgentSessionIds();
26163
26288
  const runtimeProfileReports = this.agentManager.getAgentRuntimeProfileReports();
26289
+ let lifecycleAcks = this.options.getComputerLifecycleAcks?.() ?? [];
26290
+ if (this.options.getComputerLifecycleReadyAcks) {
26291
+ try {
26292
+ lifecycleAcks = await this.options.getComputerLifecycleReadyAcks();
26293
+ } catch (error) {
26294
+ logger.warn(`[Daemon] Computer lifecycle attestation skipped: ${error instanceof Error ? error.message : String(error)}`);
26295
+ lifecycleAcks = [];
26296
+ }
26297
+ }
26164
26298
  this.connection.send({
26165
26299
  type: "ready",
26166
26300
  capabilities: [
@@ -26177,7 +26311,7 @@ var DaemonCore = class {
26177
26311
  daemonVersion: this.daemonVersion,
26178
26312
  ...this.computerVersion ? { computerVersion: this.computerVersion } : {},
26179
26313
  migrationTransport: this.getMigrationTransportReady(),
26180
- ...this.options.getComputerLifecycleAcks ? { lifecycleAcks: this.options.getComputerLifecycleAcks() } : {}
26314
+ ...this.options.getComputerLifecycleAcks || this.options.getComputerLifecycleReadyAcks ? { lifecycleAcks } : {}
26181
26315
  });
26182
26316
  this.recordDaemonTrace("daemon.ready.sent", {
26183
26317
  runtimes_count: runtimes.length,
@@ -26198,20 +26332,25 @@ var DaemonCore = class {
26198
26332
  logger.warn(`[Daemon] opencli wrapper refresh skipped: ${err instanceof Error ? err.message : String(err)}`);
26199
26333
  }
26200
26334
  }
26201
- this.emitReady();
26335
+ void this.emitReady();
26202
26336
  const runningAgentIds = this.agentManager.getRunningAgentIds();
26203
26337
  const idleAgentSessions = this.agentManager.getIdleAgentSessionIds();
26204
26338
  const runtimeProfileReports = this.agentManager.getAgentRuntimeProfileReports();
26205
26339
  if (this.options.onComputerUpgradeReconcile) {
26206
26340
  void Promise.resolve().then(
26207
- () => this.options.onComputerUpgradeReconcile((done) => {
26208
- this.connection.send({ type: "computer:upgrade:done", ...done });
26209
- this.recordDaemonTrace("daemon.computer_upgrade.reconciled", {
26210
- request_id: done.requestId,
26211
- ok: done.ok,
26212
- ...done.newVersion ? { new_version: done.newVersion } : {}
26213
- });
26214
- })
26341
+ () => this.options.onComputerUpgradeReconcile(
26342
+ (done) => {
26343
+ this.connection.send({ type: "computer:upgrade:done", ...done });
26344
+ this.recordDaemonTrace("daemon.computer_upgrade.reconciled", {
26345
+ request_id: done.requestId,
26346
+ ok: done.ok,
26347
+ ...done.newVersion ? { new_version: done.newVersion } : {}
26348
+ });
26349
+ },
26350
+ (progress) => {
26351
+ this.connection.send({ type: "computer:upgrade:progress", ...progress });
26352
+ }
26353
+ )
26215
26354
  ).catch((err) => {
26216
26355
  logger.error(
26217
26356
  `[Daemon] computer upgrade reconcile failed: ${err instanceof Error ? err.message : String(err)}`
package/dist/cli/index.js CHANGED
@@ -45610,6 +45610,57 @@ var CANONICAL_MESSAGE_MANIFEST = Object.freeze({
45610
45610
  excludedClientOnly: EXCLUDED_CLIENT_ONLY_MESSAGE_FIELDS
45611
45611
  });
45612
45612
 
45613
+ // ../shared/src/canonicalMessageV2.ts
45614
+ init_esm_shims();
45615
+ var CANONICAL_MESSAGE_V2_SCHEMA_VERSION = 5;
45616
+ var CANONICAL_MESSAGE_V2_ENVELOPE_KIND = "normalized-message-v2";
45617
+ var CANONICAL_REACTION_PREVIEW_LIMIT = 3;
45618
+ var CANONICAL_REACTION_LIMIT = 30;
45619
+ var CANONICAL_MESSAGE_V2_MANIFEST = Object.freeze({
45620
+ schemaVersion: CANONICAL_MESSAGE_V2_SCHEMA_VERSION,
45621
+ envelopeKind: CANONICAL_MESSAGE_V2_ENVELOPE_KIND,
45622
+ legacyIngressManifestVersion: CANONICAL_MESSAGE_MANIFEST_VERSION,
45623
+ soleApplyEligible: true,
45624
+ reactions: Object.freeze({
45625
+ mergePolicy: "present-overwrite",
45626
+ maxItems: CANONICAL_REACTION_LIMIT,
45627
+ fields: Object.freeze(["count", "emoji", "previewK"]),
45628
+ previewFields: Object.freeze(["displayName", "id"]),
45629
+ previewLimit: CANONICAL_REACTION_PREVIEW_LIMIT,
45630
+ legacyCompatibilityPreviewPolicy: "empty-without-room-common-provenance",
45631
+ deterministicOrder: "emoji-code-unit/actor-id-code-unit"
45632
+ }),
45633
+ viewerOverlayFields: Object.freeze(["reactions.reactedByMe"]),
45634
+ readCacheRelations: Object.freeze(["Message.ReactionActors"]),
45635
+ forbiddenCanonicalPaths: Object.freeze([
45636
+ "reactions[].reactorIds",
45637
+ "reactions[].reactorNames"
45638
+ ])
45639
+ });
45640
+
45641
+ // ../shared/src/discussionGraph.ts
45642
+ init_esm_shims();
45643
+ var DISCUSSION_RELATION_REGISTRY = Object.freeze({
45644
+ messageReactionActors: Object.freeze({
45645
+ rootKind: "message",
45646
+ relation: "reaction-actors",
45647
+ backing: "read-cache",
45648
+ consistency: "read-page",
45649
+ provenance: Object.freeze({ count: "shared-parent-fold", previewK: "shared-parent-fold" }),
45650
+ invalidation: "parent-scope-epoch",
45651
+ allowedCommands: Object.freeze(["set-interaction"])
45652
+ }),
45653
+ messageReplies: Object.freeze({
45654
+ rootKind: "message",
45655
+ relation: "replies",
45656
+ backing: "sync-scope",
45657
+ consistency: "sync-scope-window",
45658
+ provenance: Object.freeze({ replyCount: "shared-parent-fold" }),
45659
+ invalidation: "own-scope-rebaseline",
45660
+ allowedCommands: Object.freeze(["reply"])
45661
+ })
45662
+ });
45663
+
45613
45664
  // ../shared/src/index.ts
45614
45665
  var BUILTIN_RUNTIME_PROVIDER_ENV_KEYS = PI_BUILTIN_PROVIDER_API_KEY_ENV_KEYS_GENERATED;
45615
45666
  var BUILTIN_RUNTIME_PROVIDERS = Object.entries(BUILTIN_RUNTIME_PROVIDER_ENV_KEYS).map(([id, envKey]) => ({ id, envKey }));
package/dist/core.js CHANGED
@@ -36,7 +36,7 @@ import {
36
36
  stageAgentMigrationObjectStoreBundle,
37
37
  subscribeDaemonLogs,
38
38
  verifyAgentMigrationAdoptPlan
39
- } from "./chunk-FNFNAY5B.js";
39
+ } from "./chunk-LHJUHF42.js";
40
40
  export {
41
41
  AGENT_MIGRATION_BUNDLE_SCHEMA_VERSION,
42
42
  AGENT_MIGRATION_CONTROL_SEAM_ENV,
@@ -45111,6 +45111,53 @@ var CANONICAL_MESSAGE_MANIFEST = Object.freeze({
45111
45111
  exclusions: CANONICAL_MESSAGE_EXCLUSIONS,
45112
45112
  excludedClientOnly: EXCLUDED_CLIENT_ONLY_MESSAGE_FIELDS
45113
45113
  });
45114
+ init_esm_shims();
45115
+ var CANONICAL_MESSAGE_V2_SCHEMA_VERSION = 5;
45116
+ var CANONICAL_MESSAGE_V2_ENVELOPE_KIND = "normalized-message-v2";
45117
+ var CANONICAL_REACTION_PREVIEW_LIMIT = 3;
45118
+ var CANONICAL_REACTION_LIMIT = 30;
45119
+ var CANONICAL_MESSAGE_V2_MANIFEST = Object.freeze({
45120
+ schemaVersion: CANONICAL_MESSAGE_V2_SCHEMA_VERSION,
45121
+ envelopeKind: CANONICAL_MESSAGE_V2_ENVELOPE_KIND,
45122
+ legacyIngressManifestVersion: CANONICAL_MESSAGE_MANIFEST_VERSION,
45123
+ soleApplyEligible: true,
45124
+ reactions: Object.freeze({
45125
+ mergePolicy: "present-overwrite",
45126
+ maxItems: CANONICAL_REACTION_LIMIT,
45127
+ fields: Object.freeze(["count", "emoji", "previewK"]),
45128
+ previewFields: Object.freeze(["displayName", "id"]),
45129
+ previewLimit: CANONICAL_REACTION_PREVIEW_LIMIT,
45130
+ legacyCompatibilityPreviewPolicy: "empty-without-room-common-provenance",
45131
+ deterministicOrder: "emoji-code-unit/actor-id-code-unit"
45132
+ }),
45133
+ viewerOverlayFields: Object.freeze(["reactions.reactedByMe"]),
45134
+ readCacheRelations: Object.freeze(["Message.ReactionActors"]),
45135
+ forbiddenCanonicalPaths: Object.freeze([
45136
+ "reactions[].reactorIds",
45137
+ "reactions[].reactorNames"
45138
+ ])
45139
+ });
45140
+ init_esm_shims();
45141
+ var DISCUSSION_RELATION_REGISTRY = Object.freeze({
45142
+ messageReactionActors: Object.freeze({
45143
+ rootKind: "message",
45144
+ relation: "reaction-actors",
45145
+ backing: "read-cache",
45146
+ consistency: "read-page",
45147
+ provenance: Object.freeze({ count: "shared-parent-fold", previewK: "shared-parent-fold" }),
45148
+ invalidation: "parent-scope-epoch",
45149
+ allowedCommands: Object.freeze(["set-interaction"])
45150
+ }),
45151
+ messageReplies: Object.freeze({
45152
+ rootKind: "message",
45153
+ relation: "replies",
45154
+ backing: "sync-scope",
45155
+ consistency: "sync-scope-window",
45156
+ provenance: Object.freeze({ replyCount: "shared-parent-fold" }),
45157
+ invalidation: "own-scope-rebaseline",
45158
+ allowedCommands: Object.freeze(["reply"])
45159
+ })
45160
+ });
45114
45161
  var BUILTIN_RUNTIME_PROVIDER_ENV_KEYS = PI_BUILTIN_PROVIDER_API_KEY_ENV_KEYS_GENERATED;
45115
45162
  var BUILTIN_RUNTIME_PROVIDERS = Object.entries(BUILTIN_RUNTIME_PROVIDER_ENV_KEYS).map(([id, envKey]) => ({ id, envKey }));
45116
45163
  var PI_BUILTIN_PROVIDER_ENV_KEYS = {
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  DAEMON_CLI_USAGE,
4
4
  DaemonCore,
5
5
  parseDaemonCliArgs
6
- } from "./chunk-FNFNAY5B.js";
6
+ } from "./chunk-LHJUHF42.js";
7
7
 
8
8
  // src/index.ts
9
9
  var parsedArgs = parseDaemonCliArgs(process.argv.slice(2));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botiverse/raft-daemon",
3
- "version": "0.72.8",
3
+ "version": "0.72.12",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "raft-daemon": "dist/raft-daemon.js",