@axiom-lattice/core 9.0.0 → 10.0.0

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.
package/dist/index.js CHANGED
@@ -734,6 +734,11 @@ var init_parse_yaml = __esm({
734
734
  });
735
735
 
736
736
  // src/workflow/utils.ts
737
+ function workflowAbortSignal(runId, parentSignal) {
738
+ const signals = [parentSignal, runId ? getWorkflowSignal(runId) : void 0].filter((signal) => signal !== void 0);
739
+ if (signals.length === 0) return void 0;
740
+ return signals.length === 1 ? signals[0] : AbortSignal.any(signals);
741
+ }
737
742
  function buildStateAnnotation(fields) {
738
743
  const annotations = {};
739
744
  if (fields) {
@@ -1079,7 +1084,7 @@ ${renderedInput}
1079
1084
  === END INPUT ===`);
1080
1085
  const subConfig = {
1081
1086
  ...config,
1082
- signal: getWorkflowSignal(runId),
1087
+ signal: workflowAbortSignal(runId, config?.signal),
1083
1088
  configurable: {
1084
1089
  ...config?.configurable ?? {},
1085
1090
  thread_id: `${config?.configurable?.thread_id ?? "default"}:${node.id}`
@@ -1299,7 +1304,7 @@ function createMapNode(node, resolveAgent, trackingStore) {
1299
1304
  const input = buildInput(node.node.input, state, itemCtx);
1300
1305
  const subConfig = {
1301
1306
  ...config,
1302
- signal: getWorkflowSignal(runId),
1307
+ signal: workflowAbortSignal(runId, config?.signal),
1303
1308
  configurable: {
1304
1309
  ...config?.configurable ?? {},
1305
1310
  thread_id: `${config?.configurable?.thread_id ?? "default"}:${node.id}:item:${globalIdx}`
@@ -1517,12 +1522,12 @@ __export(compile_exports, {
1517
1522
  compileWorkflow: () => compileWorkflow,
1518
1523
  validateDSL: () => validateDSL
1519
1524
  });
1520
- function compileWorkflow(yamlStr, resolveAgent, checkpointer, trackingStore) {
1525
+ function compileWorkflow(yamlStr, resolveAgent, checkpointer, trackingStore, options = {}) {
1521
1526
  console.log(`[WF COMPILE] compiling YAML workflow`);
1522
1527
  const ir = parseYaml(yamlStr);
1523
- return compileInternal(ir, resolveAgent, checkpointer, trackingStore);
1528
+ return compileInternal(ir, resolveAgent, checkpointer, trackingStore, options);
1524
1529
  }
1525
- function compileInternal(ir, resolveAgent, checkpointer, trackingStore) {
1530
+ function compileInternal(ir, resolveAgent, checkpointer, trackingStore, options = {}) {
1526
1531
  validateAndThrow(ir);
1527
1532
  console.log(`[WF COMPILE] validation passed`);
1528
1533
  const StateAnnotation = buildStateAnnotation(ir.state?.fields);
@@ -1544,7 +1549,7 @@ function compileInternal(ir, resolveAgent, checkpointer, trackingStore) {
1544
1549
  builder.addEdge(from, to === "END" ? import_langgraph11.END : to);
1545
1550
  }
1546
1551
  }
1547
- const graph = builder.compile({ checkpointer, name: ir.name });
1552
+ const graph = builder.compile({ checkpointer, name: options.name || ir.name });
1548
1553
  console.log(`[WF COMPILE] graph compiled successfully`);
1549
1554
  return graph;
1550
1555
  }
@@ -1723,6 +1728,9 @@ __export(index_exports, {
1723
1728
  MicrosandboxServiceClient: () => MicrosandboxServiceClient,
1724
1729
  ModelLatticeManager: () => ModelLatticeManager,
1725
1730
  MysqlDatabase: () => MysqlDatabase,
1731
+ ObservabilityDashboardUnavailableError: () => ObservabilityDashboardUnavailableError,
1732
+ ObservabilityDashboardUnsupportedError: () => ObservabilityDashboardUnsupportedError,
1733
+ ObservabilityLatticeManager: () => ObservabilityLatticeManager,
1726
1734
  OutboxPoller: () => OutboxPoller,
1727
1735
  PACK_DIRECTORY_TIMEOUT_MS: () => PACK_DIRECTORY_TIMEOUT_MS,
1728
1736
  PLATFORM_SECRET_ENV_VARS: () => PLATFORM_SECRET_ENV_VARS,
@@ -1816,6 +1824,7 @@ __export(index_exports, {
1816
1824
  buildTaskMutationFallback: () => buildTaskMutationFallback,
1817
1825
  buildTaskNormalizationFallback: () => buildTaskNormalizationFallback,
1818
1826
  canConvergeOrphan: () => canConvergeOrphan,
1827
+ channelShardForInstallation: () => channelShardForInstallation,
1819
1828
  checkEmptyContent: () => checkEmptyContent,
1820
1829
  chunkBufferStreamKey: () => chunkBufferStreamKey,
1821
1830
  clearEncryptionKeyCache: () => clearEncryptionKeyCache,
@@ -1920,6 +1929,7 @@ __export(index_exports, {
1920
1929
  getEncryptionKey: () => getEncryptionKey,
1921
1930
  getEvalRunService: () => getEvalRunService,
1922
1931
  getLoggerLattice: () => getLoggerLattice,
1932
+ getMcpUiScopeSecret: () => getMcpUiScopeSecret,
1923
1933
  getMenuRegistry: () => getMenuRegistry,
1924
1934
  getModelLattice: () => getModelLattice,
1925
1935
  getNextCronTime: () => getNextCronTime,
@@ -1988,6 +1998,7 @@ __export(index_exports, {
1988
1998
  normalizeAgentInterrupts: () => normalizeAgentInterrupts,
1989
1999
  normalizeAgentRunMessageIds: () => normalizeAgentRunMessageIds,
1990
2000
  normalizeSandboxName: () => normalizeSandboxName,
2001
+ observabilityLatticeManager: () => observabilityLatticeManager,
1991
2002
  ownTaskResponseField: () => ownTaskResponseField,
1992
2003
  parallelLimit: () => parallelLimit,
1993
2004
  parseCronExpression: () => parseCronExpression,
@@ -2028,6 +2039,7 @@ __export(index_exports, {
2028
2039
  registerLoggerLattice: () => registerLoggerLattice,
2029
2040
  registerModelLattice: () => registerModelLattice,
2030
2041
  registerModelLatticeForTenant: () => registerModelLatticeForTenant,
2042
+ registerObservabilityLattice: () => registerObservabilityLattice,
2031
2043
  registerQueueLattice: () => registerQueueLattice,
2032
2044
  registerSTTModelLattice: () => registerSTTModelLattice,
2033
2045
  registerSandboxOpenCredentialProvider: () => registerSandboxOpenCredentialProvider,
@@ -2045,6 +2057,7 @@ __export(index_exports, {
2045
2057
  resolveHandlerTimeoutMs: () => resolveHandlerTimeoutMs,
2046
2058
  resolveJudgeModelKey: () => resolveJudgeModelKey,
2047
2059
  resolveModelLatticeForTenant: () => resolveModelLatticeForTenant,
2060
+ resolveObservabilityCallbacks: () => resolveObservabilityCallbacks,
2048
2061
  resolvePath: () => resolvePath,
2049
2062
  resolvePluginConnections: () => resolvePluginConnections,
2050
2063
  resolveSandboxPluginConnections: () => resolveSandboxPluginConnections,
@@ -2065,11 +2078,13 @@ __export(index_exports, {
2065
2078
  serializeTaskReadResponse: () => serializeTaskReadResponse,
2066
2079
  setAgentLifecycleTap: () => setAgentLifecycleTap,
2067
2080
  setBindingRegistry: () => setBindingRegistry,
2081
+ setDefaultObservabilityLattice: () => setDefaultObservabilityLattice,
2068
2082
  setEvalRunService: () => setEvalRunService,
2069
2083
  setMenuRegistry: () => setMenuRegistry,
2070
2084
  setPluginDeploymentService: () => setPluginDeploymentService,
2071
2085
  setRunCancelHeartbeatFallbackObserver: () => setRunCancelHeartbeatFallbackObserver,
2072
2086
  setSandboxPluginCatalog: () => setSandboxPluginCatalog,
2087
+ signMcpUiScope: () => signMcpUiScope,
2073
2088
  skillLatticeManager: () => skillLatticeManager,
2074
2089
  sqlDatabaseManager: () => sqlDatabaseManager,
2075
2090
  storeLatticeManager: () => storeLatticeManager,
@@ -2098,6 +2113,7 @@ __export(index_exports, {
2098
2113
  validateToolInput: () => validateToolInput,
2099
2114
  vectorStoreLatticeManager: () => vectorStoreLatticeManager,
2100
2115
  vectorStoreProviderManager: () => vectorStoreProviderManager,
2116
+ verifyMcpUiScope: () => verifyMcpUiScope,
2101
2117
  withLease: () => withLease,
2102
2118
  withTimeout: () => withTimeout2,
2103
2119
  wrapMcpToolWithUi: () => wrapMcpToolWithUi
@@ -6340,6 +6356,7 @@ var InMemoryTaskStore = class {
6340
6356
  if (filter2.ownerId) results = results.filter((t) => t.ownerId === filter2.ownerId);
6341
6357
  if (filter2.status) results = results.filter((t) => t.status === filter2.status);
6342
6358
  if (filter2.priority) results = results.filter((t) => t.priority === filter2.priority);
6359
+ if (filter2.threadId) results = results.filter((t) => t.context?.thread_id === filter2.threadId);
6343
6360
  if (filter2.workspaceId) results = results.filter((t) => t.workspaceId === filter2.workspaceId);
6344
6361
  if (filter2.projectId === null) results = results.filter((task) => !task.projectId || task.projectId === "default");
6345
6362
  else if (filter2.projectId !== void 0) results = results.filter((task) => task.projectId === filter2.projectId);
@@ -7771,6 +7788,7 @@ var _DefaultScheduleClient = class _DefaultScheduleClient {
7771
7788
  }
7772
7789
  // ===== Recovery =====
7773
7790
  async restore() {
7791
+ this.clearAllTimers();
7774
7792
  try {
7775
7793
  const requeued = await this.storage.requeueStaleRunning(STALE_RUNNING_MS);
7776
7794
  if (requeued > 0) {
@@ -7784,41 +7802,89 @@ var _DefaultScheduleClient = class _DefaultScheduleClient {
7784
7802
  error
7785
7803
  );
7786
7804
  }
7805
+ const restored = await this.reconcileTimers(true);
7806
+ console.log(`[Scheduler] Restored ${restored} tasks`);
7807
+ return restored;
7808
+ }
7809
+ /**
7810
+ * Reconcile this replica's timers with the shared schedule store.
7811
+ *
7812
+ * @remarks Safe to call periodically and on every replica. Execution still
7813
+ * goes through `claimScheduledRun`, so duplicate timer fires execute once.
7814
+ */
7815
+ async reconcile() {
7816
+ try {
7817
+ await this.storage.requeueStaleRunning(STALE_RUNNING_MS);
7818
+ } catch (error) {
7819
+ console.error(
7820
+ "[Scheduler] Failed to requeue stale running tasks during reconcile:",
7821
+ error
7822
+ );
7823
+ }
7824
+ return this.reconcileTimers(false);
7825
+ }
7826
+ clearTimer(taskId) {
7827
+ const timer = this.timers.get(taskId);
7828
+ if (!timer) return;
7829
+ clearTimeout(timer.timerId);
7830
+ this.timers.delete(taskId);
7831
+ }
7832
+ clearAllTimers() {
7833
+ for (const timer of this.timers.values()) clearTimeout(timer.timerId);
7834
+ this.timers.clear();
7835
+ }
7836
+ async reconcileTimers(recomputeCronNextRun) {
7787
7837
  const activeTasks = await this.storage.getActiveTasks();
7788
- let restored = 0;
7838
+ const activeById = new Map(activeTasks.map((task) => [task.taskId, task]));
7839
+ for (const taskId of [...this.timers.keys()]) {
7840
+ const task = activeById.get(taskId);
7841
+ if (!task || task.status === import_protocols8.ScheduledTaskStatus.PAUSED) {
7842
+ this.clearTimer(taskId);
7843
+ }
7844
+ }
7845
+ let reconciled = 0;
7789
7846
  for (const task of activeTasks) {
7790
7847
  if (!this.handlers.has(task.taskType)) {
7791
7848
  console.warn(
7792
- `[Scheduler] No handler for task type ${task.taskType}, skipping restore for task ${task.taskId}`
7849
+ `[Scheduler] No handler for task type ${task.taskType}, skipping reconcile for task ${task.taskId}`
7793
7850
  );
7851
+ this.clearTimer(task.taskId);
7794
7852
  continue;
7795
7853
  }
7796
7854
  if (task.status === import_protocols8.ScheduledTaskStatus.PAUSED) {
7855
+ this.clearTimer(task.taskId);
7797
7856
  continue;
7798
7857
  }
7799
7858
  if (task.executionType === import_protocols8.ScheduleExecutionType.ONCE) {
7800
- if (task.executeAt && task.executeAt <= Date.now()) {
7801
- console.log(
7802
- `[Scheduler] Executing overdue one-time task: ${task.taskId}`
7803
- );
7804
- this.executeTask(task);
7805
- } else {
7859
+ if (task.executeAt !== void 0 && task.executeAt <= Date.now()) {
7860
+ this.clearTimer(task.taskId);
7861
+ void this.executeTask(task);
7862
+ } else if (task.executeAt !== void 0) {
7806
7863
  this.scheduleTimer(task);
7807
7864
  }
7808
7865
  } else if (task.executionType === import_protocols8.ScheduleExecutionType.CRON) {
7809
- const nextRunAt = getNextCronTime(task.cronExpression, /* @__PURE__ */ new Date(), task.timezone);
7810
- await this.storage.update(task.taskId, {
7811
- nextRunAt: nextRunAt.getTime()
7812
- });
7813
- const updatedTask = await this.storage.get(task.taskId);
7814
- if (updatedTask) {
7815
- this.scheduleTimer(updatedTask);
7866
+ let nextRunAt = task.nextRunAt;
7867
+ if (recomputeCronNextRun || nextRunAt === void 0) {
7868
+ nextRunAt = getNextCronTime(task.cronExpression, /* @__PURE__ */ new Date(), task.timezone).getTime();
7869
+ await this.storage.update(task.taskId, { nextRunAt });
7870
+ const updated = await this.storage.get(task.taskId);
7871
+ if (!updated) continue;
7872
+ if (updated.nextRunAt !== void 0 && updated.nextRunAt <= Date.now()) {
7873
+ this.clearTimer(updated.taskId);
7874
+ void this.executeTask(updated);
7875
+ } else {
7876
+ this.scheduleTimer(updated);
7877
+ }
7878
+ } else if (nextRunAt <= Date.now()) {
7879
+ this.clearTimer(task.taskId);
7880
+ void this.executeTask(task);
7881
+ } else {
7882
+ this.scheduleTimer(task);
7816
7883
  }
7817
7884
  }
7818
- restored++;
7885
+ reconciled++;
7819
7886
  }
7820
- console.log(`[Scheduler] Restored ${restored} tasks`);
7821
- return restored;
7887
+ return reconciled;
7822
7888
  }
7823
7889
  // ===== Storage =====
7824
7890
  setStorage(storage) {
@@ -7829,6 +7895,7 @@ var _DefaultScheduleClient = class _DefaultScheduleClient {
7829
7895
  }
7830
7896
  // ===== Private Methods =====
7831
7897
  scheduleTimer(task) {
7898
+ this.clearTimer(task.taskId);
7832
7899
  const targetTime = task.executionType === import_protocols8.ScheduleExecutionType.CRON ? task.nextRunAt : task.executeAt;
7833
7900
  if (targetTime === void 0) {
7834
7901
  console.error(`[Scheduler] No execution time for task: ${task.taskId}`);
@@ -8097,6 +8164,9 @@ var ScheduleLatticeManager = class _ScheduleLatticeManager extends BaseLatticeMa
8097
8164
  // Recovery
8098
8165
  restore: async () => {
8099
8166
  return scheduleClient.restore();
8167
+ },
8168
+ reconcile: async () => {
8169
+ return scheduleClient.reconcile?.() ?? 0;
8100
8170
  }
8101
8171
  };
8102
8172
  this.register(key5, scheduleLattice);
@@ -22347,7 +22417,7 @@ function getPluginDeploymentService() {
22347
22417
  }
22348
22418
 
22349
22419
  // src/sandbox_plugin/TenantPluginCatalog.ts
22350
- var import_node_crypto3 = require("crypto");
22420
+ var import_node_crypto4 = require("crypto");
22351
22421
 
22352
22422
  // src/sandbox_plugin/jsonSchemaToZod.ts
22353
22423
  var import_zod47 = require("zod");
@@ -22713,6 +22783,19 @@ async function resolveSandboxPluginConnections(type, config, runConfig) {
22713
22783
  return { connection: connections[0]?.config, connections };
22714
22784
  }
22715
22785
 
22786
+ // src/sandbox_plugin/sandboxRunConfig.ts
22787
+ function sandboxRunConfigFrom(exeConfig) {
22788
+ const config = exeConfig;
22789
+ const raw = config?.configurable?.runConfig ?? {};
22790
+ return {
22791
+ tenantId: typeof raw.tenantId === "string" && raw.tenantId.length > 0 ? raw.tenantId : void 0,
22792
+ assistantId: typeof raw.assistant_id === "string" && raw.assistant_id.length > 0 ? raw.assistant_id : void 0,
22793
+ threadId: typeof raw.thread_id === "string" && raw.thread_id.length > 0 ? raw.thread_id : void 0,
22794
+ workspaceId: typeof raw.workspaceId === "string" && raw.workspaceId.length > 0 ? raw.workspaceId : void 0,
22795
+ projectId: typeof raw.projectId === "string" && raw.projectId.length > 0 ? raw.projectId : void 0
22796
+ };
22797
+ }
22798
+
22716
22799
  // src/mcp_lattice/mcpUi.ts
22717
22800
  var import_tools2 = require("@langchain/core/tools");
22718
22801
  var isObj = (v) => typeof v === "object" && v !== null;
@@ -22793,6 +22876,145 @@ function wrapMcpToolWithUi(raw, ref) {
22793
22876
  });
22794
22877
  }
22795
22878
 
22879
+ // src/mcp_lattice/mcpUiScope.ts
22880
+ var import_node_crypto3 = require("crypto");
22881
+ var MIN_SECRET_LENGTH = 32;
22882
+ var MAX_PAYLOAD_BYTES = 2048;
22883
+ var MAX_TOKEN_LENGTH = 4096;
22884
+ var SCOPE_KEY_INFO = "mcp-ui-scope";
22885
+ var warnedMessages = /* @__PURE__ */ new Set();
22886
+ function getMcpUiScopeSecret() {
22887
+ const explicit = process.env.MCP_UI_SCOPE_SECRET;
22888
+ if (explicit) {
22889
+ return explicit.length >= MIN_SECRET_LENGTH ? explicit : void 0;
22890
+ }
22891
+ const encryptionKey = process.env.LATTICE_ENCRYPTION_KEY;
22892
+ if (!encryptionKey) return void 0;
22893
+ return Buffer.from(
22894
+ (0, import_node_crypto3.hkdfSync)("sha256", encryptionKey, "", SCOPE_KEY_INFO, 32)
22895
+ ).toString("base64url");
22896
+ }
22897
+ function warnOnce(message) {
22898
+ if (warnedMessages.has(message)) return;
22899
+ warnedMessages.add(message);
22900
+ console.warn(JSON.stringify({ event: "mcp-ui-scope:warning", message }));
22901
+ }
22902
+ function isRecord8(value) {
22903
+ return typeof value === "object" && value !== null && !Array.isArray(value);
22904
+ }
22905
+ function signMcpUiScope(input, secret = getMcpUiScopeSecret()) {
22906
+ if (!secret || secret.length < MIN_SECRET_LENGTH) {
22907
+ warnOnce(
22908
+ "no usable MCP UI scope signing secret (set MCP_UI_SCOPE_SECRET or LATTICE_ENCRYPTION_KEY)"
22909
+ );
22910
+ return void 0;
22911
+ }
22912
+ if (typeof input.tid !== "string" || input.tid === "" || typeof input.plugin !== "string" || input.plugin === "" || typeof input.resource !== "string" || input.resource === "") {
22913
+ warnOnce("scope identity is missing tid/plugin/resource");
22914
+ return void 0;
22915
+ }
22916
+ const optionalStrings = [input.thid, input.aid, input.wid, input.pid, input.ck];
22917
+ if (optionalStrings.some(
22918
+ (value) => value !== void 0 && typeof value !== "string"
22919
+ )) {
22920
+ warnOnce("scope optional identity fields must be strings");
22921
+ return void 0;
22922
+ }
22923
+ if (input.iat !== void 0 && (typeof input.iat !== "number" || !Number.isFinite(input.iat))) {
22924
+ warnOnce("scope iat must be a finite number");
22925
+ return void 0;
22926
+ }
22927
+ if (input.jti !== void 0 && typeof input.jti !== "string") {
22928
+ warnOnce("scope jti must be a string");
22929
+ return void 0;
22930
+ }
22931
+ const payload = {
22932
+ v: 1,
22933
+ tid: input.tid,
22934
+ thid: input.thid,
22935
+ aid: input.aid,
22936
+ wid: input.wid,
22937
+ pid: input.pid,
22938
+ plugin: input.plugin,
22939
+ resource: input.resource,
22940
+ ck: input.ck === "" ? void 0 : input.ck,
22941
+ iat: input.iat ?? Math.floor(Date.now() / 1e3),
22942
+ jti: input.jti ?? (0, import_node_crypto3.randomUUID)()
22943
+ };
22944
+ const json = JSON.stringify(payload);
22945
+ if (Buffer.byteLength(json, "utf8") > MAX_PAYLOAD_BYTES) {
22946
+ warnOnce("scope payload exceeds 2048 bytes");
22947
+ return void 0;
22948
+ }
22949
+ const body = Buffer.from(json, "utf8").toString("base64url");
22950
+ const sig = (0, import_node_crypto3.createHmac)("sha256", secret).update(body).digest("base64url");
22951
+ const token = `${body}.${sig}`;
22952
+ if (token.length > MAX_TOKEN_LENGTH) {
22953
+ warnOnce("signed scope token exceeds 4096 characters");
22954
+ return void 0;
22955
+ }
22956
+ return token;
22957
+ }
22958
+ function verifyMcpUiScope(token, secret = getMcpUiScopeSecret()) {
22959
+ if (!token || token.length > MAX_TOKEN_LENGTH || !secret || secret.length < MIN_SECRET_LENGTH) {
22960
+ return null;
22961
+ }
22962
+ const parts = token.split(".");
22963
+ if (parts.length !== 2) return null;
22964
+ const [body, sig] = parts;
22965
+ if (!body || !sig) return null;
22966
+ try {
22967
+ const expected = (0, import_node_crypto3.createHmac)("sha256", secret).update(body).digest("base64url");
22968
+ const expectedBuf = Buffer.from(expected, "utf8");
22969
+ const sigBuf = Buffer.from(sig, "utf8");
22970
+ if (expectedBuf.length !== sigBuf.length || !(0, import_node_crypto3.timingSafeEqual)(expectedBuf, sigBuf)) {
22971
+ return null;
22972
+ }
22973
+ } catch {
22974
+ return null;
22975
+ }
22976
+ let parsed;
22977
+ try {
22978
+ parsed = JSON.parse(Buffer.from(body, "base64url").toString("utf8"));
22979
+ } catch {
22980
+ return null;
22981
+ }
22982
+ if (!isRecord8(parsed) || parsed.v !== 1) return null;
22983
+ const tid = parsed.tid;
22984
+ const plugin = parsed.plugin;
22985
+ const resource = parsed.resource;
22986
+ const thid = parsed.thid;
22987
+ const aid = parsed.aid;
22988
+ const wid = parsed.wid;
22989
+ const pid = parsed.pid;
22990
+ const ck = parsed.ck;
22991
+ const iat = parsed.iat;
22992
+ const jti = parsed.jti;
22993
+ if (typeof tid !== "string" || tid === "") return null;
22994
+ if (typeof plugin !== "string" || plugin === "") return null;
22995
+ if (typeof resource !== "string" || resource === "") return null;
22996
+ if (thid !== void 0 && typeof thid !== "string") return null;
22997
+ if (aid !== void 0 && typeof aid !== "string") return null;
22998
+ if (wid !== void 0 && typeof wid !== "string") return null;
22999
+ if (pid !== void 0 && typeof pid !== "string") return null;
23000
+ if (ck !== void 0 && (typeof ck !== "string" || ck === "")) return null;
23001
+ if (typeof iat !== "number" || !Number.isFinite(iat)) return null;
23002
+ if (typeof jti !== "string") return null;
23003
+ return {
23004
+ v: 1,
23005
+ tid,
23006
+ ...thid === void 0 ? {} : { thid },
23007
+ ...aid === void 0 ? {} : { aid },
23008
+ ...wid === void 0 ? {} : { wid },
23009
+ ...pid === void 0 ? {} : { pid },
23010
+ plugin,
23011
+ resource,
23012
+ ...ck === void 0 ? {} : { ck },
23013
+ iat,
23014
+ jti
23015
+ };
23016
+ }
23017
+
22796
23018
  // src/sandbox_plugin/SandboxPluginCompiler.ts
22797
23019
  var EMPTY_CONFIG_SCHEMA = Object.freeze({ type: "object", properties: Object.freeze({}) });
22798
23020
  var STANDARD_CONNECTION_SCHEMA = Object.freeze({
@@ -22807,20 +23029,9 @@ var STANDARD_CONNECTION_DEFAULT_CONFIG = Object.freeze({
22807
23029
  connectAll: false
22808
23030
  });
22809
23031
  var EMPTY_DEFAULT_CONFIG = Object.freeze({});
22810
- function isRecord8(value) {
23032
+ function isRecord9(value) {
22811
23033
  return typeof value === "object" && value !== null && !Array.isArray(value);
22812
23034
  }
22813
- function runConfigFrom(exeConfig) {
22814
- const c = exeConfig;
22815
- const r = c?.configurable?.runConfig ?? {};
22816
- return {
22817
- tenantId: typeof r.tenantId === "string" ? r.tenantId : void 0,
22818
- assistantId: typeof r.assistant_id === "string" ? r.assistant_id : void 0,
22819
- threadId: typeof r.thread_id === "string" ? r.thread_id : void 0,
22820
- workspaceId: typeof r.workspaceId === "string" ? r.workspaceId : void 0,
22821
- projectId: typeof r.projectId === "string" ? r.projectId : void 0
22822
- };
22823
- }
22824
23035
  function compileSandboxPlugin(args) {
22825
23036
  const { manifest, executor, tenantId: tenantId2 } = args;
22826
23037
  const plugin = {
@@ -22837,11 +23048,10 @@ function compileSandboxPlugin(args) {
22837
23048
  defaultConfig: manifest.defaultConfig ?? (manifest.connection ? STANDARD_CONNECTION_DEFAULT_CONFIG : EMPTY_DEFAULT_CONFIG)
22838
23049
  },
22839
23050
  middleware: (config) => {
22840
- const runConfigFor = (exeConfig) => runConfigFrom(exeConfig);
22841
23051
  const tools = manifest.tools.map(
22842
23052
  (t) => (0, import_langchain48.tool)(
22843
23053
  async (input, exeConfig) => {
22844
- const runConfig = runConfigFor(exeConfig);
23054
+ const runConfig = sandboxRunConfigFrom(exeConfig);
22845
23055
  const resolution = await resolveConnection(manifest.type, config, runConfig);
22846
23056
  const result = await executor.invoke({
22847
23057
  manifest,
@@ -22860,7 +23070,24 @@ function compileSandboxPlugin(args) {
22860
23070
  });
22861
23071
  if (!result.ok) return result.error ?? "sandbox plugin execution failed";
22862
23072
  const text = handlerResultText(result);
22863
- const ref = t.ui ? { kind: "plugin", pluginType: manifest.type, resource: t.ui.resource, displayMode: t.ui.displayMode ?? "inline" } : null;
23073
+ const ui = t.ui;
23074
+ const scope = ui ? signMcpUiScope({
23075
+ tid: runConfig.tenantId || tenantId2,
23076
+ thid: runConfig.threadId,
23077
+ aid: runConfig.assistantId,
23078
+ wid: runConfig.workspaceId,
23079
+ pid: runConfig.projectId,
23080
+ plugin: manifest.type,
23081
+ resource: ui.resource,
23082
+ ck: resolution.connections?.[0]?.key
23083
+ }) : void 0;
23084
+ const ref = ui ? {
23085
+ kind: "plugin",
23086
+ pluginType: manifest.type,
23087
+ resource: ui.resource,
23088
+ displayMode: ui.displayMode ?? "inline",
23089
+ ...scope ? { scope } : {}
23090
+ } : null;
22864
23091
  return ref ? appendUiFence(text, ref) : text;
22865
23092
  },
22866
23093
  { name: t.name, description: t.description, schema: jsonSchemaToZod(t.schema) }
@@ -22897,11 +23124,11 @@ async function runConnectionHandler(executor, manifest, handler, config, tenantI
22897
23124
  return { ok: false, message: result.error ?? "connection test failed" };
22898
23125
  }
22899
23126
  const value = result.result;
22900
- if (isRecord8(value) && typeof value.ok === "boolean" && typeof value.message === "string") {
23127
+ if (isRecord9(value) && typeof value.ok === "boolean" && typeof value.message === "string") {
22901
23128
  return {
22902
23129
  ok: value.ok,
22903
23130
  message: value.message,
22904
- details: isRecord8(value.details) ? value.details : void 0
23131
+ details: isRecord9(value.details) ? value.details : void 0
22905
23132
  };
22906
23133
  }
22907
23134
  return { ok: false, message: result.error ?? "connection test returned an invalid result" };
@@ -23397,7 +23624,7 @@ var TenantPluginCatalog = class {
23397
23624
  hashParts.push(`${type}:${manifestJson}:${relPaths.join(",")}`);
23398
23625
  candidates.push({ type, dirPath: dir.path, raw, manifestJson, files: dirFiles });
23399
23626
  }
23400
- const hash = (0, import_node_crypto3.createHash)("sha256").update(hashParts.sort().join("\n")).digest("hex").slice(0, 16);
23627
+ const hash = (0, import_node_crypto4.createHash)("sha256").update(hashParts.sort().join("\n")).digest("hex").slice(0, 16);
23401
23628
  const cached2 = this.cache.get(tenantId2)?.value;
23402
23629
  if (cached2 && cached2.hash === hash) {
23403
23630
  this.cache.set(tenantId2, { value: cached2, checkedAt: this.now() });
@@ -23636,23 +23863,23 @@ function toolName(tool67) {
23636
23863
  return typeof tool67.name === "string" ? tool67.name : void 0;
23637
23864
  }
23638
23865
  function schemaHasConnectionKey(schema6) {
23639
- const definition = isRecord9(schema6._def) ? schema6._def : void 0;
23866
+ const definition = isRecord10(schema6._def) ? schema6._def : void 0;
23640
23867
  const shape = definition?.shape;
23641
23868
  const fields = typeof shape === "function" ? shape() : shape;
23642
- return isRecord9(fields) && Object.prototype.hasOwnProperty.call(fields, "connectionKey");
23869
+ return isRecord10(fields) && Object.prototype.hasOwnProperty.call(fields, "connectionKey");
23643
23870
  }
23644
23871
  function hasConnectionKeySchema(tool67) {
23645
- if (!isRecord9(tool67) || !isRecord9(tool67.schema)) return false;
23872
+ if (!isRecord10(tool67) || !isRecord10(tool67.schema)) return false;
23646
23873
  if (schemaHasConnectionKey(tool67.schema)) return true;
23647
- const definition = isRecord9(tool67.schema._def) ? tool67.schema._def : void 0;
23874
+ const definition = isRecord10(tool67.schema._def) ? tool67.schema._def : void 0;
23648
23875
  if (Array.isArray(definition?.options) && definition.options.length > 0) {
23649
23876
  return definition.options.every(
23650
- (option) => isRecord9(option) && schemaHasConnectionKey(option)
23877
+ (option) => isRecord10(option) && schemaHasConnectionKey(option)
23651
23878
  );
23652
23879
  }
23653
23880
  return false;
23654
23881
  }
23655
- function isRecord9(value) {
23882
+ function isRecord10(value) {
23656
23883
  return typeof value === "object" && value !== null && !Array.isArray(value);
23657
23884
  }
23658
23885
  var CapabilityToolRegistry = class {
@@ -23744,17 +23971,17 @@ var CapabilityToolRegistry = class {
23744
23971
  // src/middlewares/capabilityGuardMiddleware.ts
23745
23972
  var import_messages4 = require("@langchain/core/messages");
23746
23973
  var import_langchain49 = require("langchain");
23747
- function isRecord10(value) {
23974
+ function isRecord11(value) {
23748
23975
  return typeof value === "object" && value !== null && !Array.isArray(value);
23749
23976
  }
23750
23977
  function capabilityRuntimeFromRequest(request) {
23751
- if (!isRecord10(request) || !isRecord10(request.runtime)) return void 0;
23978
+ if (!isRecord11(request) || !isRecord11(request.runtime)) return void 0;
23752
23979
  const configurable = request.runtime.configurable;
23753
23980
  const context = request.runtime.context;
23754
- const runConfig = isRecord10(configurable) && isRecord10(configurable.runConfig) ? configurable.runConfig : isRecord10(context) && isRecord10(context.runConfig) ? context.runConfig : void 0;
23981
+ const runConfig = isRecord11(configurable) && isRecord11(configurable.runConfig) ? configurable.runConfig : isRecord11(context) && isRecord11(context.runConfig) ? context.runConfig : void 0;
23755
23982
  if (!runConfig) return void 0;
23756
23983
  const value = runConfig.capabilityRuntime;
23757
- if (!isRecord10(value) || typeof value.revision !== "string" || !isRecord10(value.middleware)) {
23984
+ if (!isRecord11(value) || typeof value.revision !== "string" || !isRecord11(value.middleware)) {
23758
23985
  return void 0;
23759
23986
  }
23760
23987
  return value;
@@ -23766,10 +23993,10 @@ function hasActiveRuntimePolicy(runtime) {
23766
23993
  return Object.keys(runtime.middleware).length > 0;
23767
23994
  }
23768
23995
  function tenantIdFromRequest(request) {
23769
- if (!isRecord10(request) || !isRecord10(request.runtime)) return void 0;
23996
+ if (!isRecord11(request) || !isRecord11(request.runtime)) return void 0;
23770
23997
  const configurable = request.runtime.configurable;
23771
23998
  const context = request.runtime.context;
23772
- const runConfig = isRecord10(configurable) && isRecord10(configurable.runConfig) ? configurable.runConfig : isRecord10(context) && isRecord10(context.runConfig) ? context.runConfig : void 0;
23999
+ const runConfig = isRecord11(configurable) && isRecord11(configurable.runConfig) ? configurable.runConfig : isRecord11(context) && isRecord11(context.runConfig) ? context.runConfig : void 0;
23773
24000
  return runConfig && typeof runConfig.tenantId === "string" ? runConfig.tenantId : void 0;
23774
24001
  }
23775
24002
  async function standardConnectionAllowed(request, capabilityType, config) {
@@ -23777,8 +24004,8 @@ async function standardConnectionAllowed(request, capabilityType, config) {
23777
24004
  const hasConnectAll = Object.prototype.hasOwnProperty.call(config, "connectAll");
23778
24005
  if (!hasConnections && (!hasConnectAll || config.connectAll !== true)) return false;
23779
24006
  const tenantId2 = tenantIdFromRequest(request);
23780
- const resource = isRecord10(request.toolCall) && isRecord10(request.toolCall.args) ? request.toolCall.args.connectionKey : void 0;
23781
- const hasConnectionKey = isRecord10(request.toolCall) && isRecord10(request.toolCall.args) && Object.prototype.hasOwnProperty.call(
24007
+ const resource = isRecord11(request.toolCall) && isRecord11(request.toolCall.args) ? request.toolCall.args.connectionKey : void 0;
24008
+ const hasConnectionKey = isRecord11(request.toolCall) && isRecord11(request.toolCall.args) && Object.prototype.hasOwnProperty.call(
23782
24009
  request.toolCall.args,
23783
24010
  "connectionKey"
23784
24011
  );
@@ -23844,10 +24071,10 @@ function createCapabilityGuardMiddleware(registry4) {
23844
24071
  toolName: toolName2
23845
24072
  });
23846
24073
  }
23847
- const standardConfig = isRecord10(policy.config) ? policy.config : {};
24074
+ const standardConfig = isRecord11(policy.config) ? policy.config : {};
23848
24075
  if (registry4.isStandardConnectionTool(toolName2) && !await standardConnectionAllowed(request, metadata.capabilityType, standardConfig)) {
23849
24076
  const args2 = request.toolCall.args;
23850
- const resource = isRecord10(args2) && typeof args2.connectionKey === "string" ? args2.connectionKey : void 0;
24077
+ const resource = isRecord11(args2) && typeof args2.connectionKey === "string" ? args2.connectionKey : void 0;
23851
24078
  return denialMessage(request.toolCall, {
23852
24079
  code: "RESOURCE_NOT_ALLOWED",
23853
24080
  message: typeof resource === "string" ? `Resource '${resource}' is not allowed by the capability policy` : "Resource selector 'connectionKey' must be a permitted string",
@@ -23860,8 +24087,8 @@ function createCapabilityGuardMiddleware(registry4) {
23860
24087
  const selector = metadata.resourceSelector;
23861
24088
  const args = request.toolCall.args;
23862
24089
  if (selector) {
23863
- const resource = isRecord10(args) ? args[selector.argumentField] : void 0;
23864
- const config = isRecord10(policy.config) ? policy.config : {};
24090
+ const resource = isRecord11(args) ? args[selector.argumentField] : void 0;
24091
+ const config = isRecord11(policy.config) ? policy.config : {};
23865
24092
  const hasExplicitResources = Object.prototype.hasOwnProperty.call(config, selector.configField);
23866
24093
  const allowsAll = !hasExplicitResources && selector.allowAllField !== void 0 && config[selector.allowAllField] === true;
23867
24094
  const allowedResources = config[selector.configField];
@@ -24438,7 +24665,17 @@ var import_langgraph6 = require("@langchain/langgraph");
24438
24665
  var import_protocols17 = require("@axiom-lattice/protocols");
24439
24666
 
24440
24667
  // src/services/Agent.ts
24441
- var import_node_crypto6 = require("crypto");
24668
+ var import_node_crypto7 = require("crypto");
24669
+
24670
+ // src/services/agentRecursionLimit.ts
24671
+ var DEFAULT_AGENT_RECURSION_LIMIT = 500;
24672
+ function readAgentRecursionLimit(env = process.env) {
24673
+ const raw = env.AGENT_RECURSION_LIMIT;
24674
+ if (raw === void 0 || raw.trim() === "") return DEFAULT_AGENT_RECURSION_LIMIT;
24675
+ const parsed = Number(raw);
24676
+ if (!Number.isFinite(parsed) || parsed < 1) return DEFAULT_AGENT_RECURSION_LIMIT;
24677
+ return Math.floor(parsed);
24678
+ }
24442
24679
 
24443
24680
  // src/services/DelegationCancellation.ts
24444
24681
  var DelegationCancellationRegistry = class {
@@ -25045,7 +25282,7 @@ var import_langgraph5 = require("@langchain/langgraph");
25045
25282
 
25046
25283
  // src/services/agentInterrupts.ts
25047
25284
  var FENCE = /^```([A-Za-z0-9_-]+)\n([\s\S]*?)\n```$/;
25048
- function isRecord11(value) {
25285
+ function isRecord12(value) {
25049
25286
  return typeof value === "object" && value !== null && !Array.isArray(value);
25050
25287
  }
25051
25288
  function parseFence(value) {
@@ -25059,7 +25296,7 @@ function parseFence(value) {
25059
25296
  }
25060
25297
  }
25061
25298
  function isTaskReview(value) {
25062
- return isRecord11(value) && (value.type === "task_review" || value.kind === "task_review" || "task_review" in value);
25299
+ return isRecord12(value) && (value.type === "task_review" || value.kind === "task_review" || "task_review" in value);
25063
25300
  }
25064
25301
  function isOfficialInterruptId(interruptId) {
25065
25302
  return /^[a-f0-9]{32}$/i.test(interruptId);
@@ -25074,28 +25311,28 @@ function hasExpectedInterrupt(interrupts, expectedInterruptId) {
25074
25311
  ).length === 1;
25075
25312
  }
25076
25313
  function normalizeAgentInterrupts(state, threadId) {
25077
- if (!isRecord11(state) || !Array.isArray(state.tasks)) return [];
25314
+ if (!isRecord12(state) || !Array.isArray(state.tasks)) return [];
25078
25315
  const result = [];
25079
25316
  state.tasks.forEach((task, taskIndex) => {
25080
- if (!isRecord11(task) || !Array.isArray(task.interrupts)) return;
25317
+ if (!isRecord12(task) || !Array.isArray(task.interrupts)) return;
25081
25318
  const rawTaskId = task.id;
25082
25319
  const taskId = typeof rawTaskId === "string" || typeof rawTaskId === "number" ? String(rawTaskId) : void 0;
25083
25320
  task.interrupts.forEach((interrupt5, index) => {
25084
- const record = isRecord11(interrupt5) ? interrupt5 : {};
25321
+ const record = isRecord12(interrupt5) ? interrupt5 : {};
25085
25322
  const rawId = record.id;
25086
25323
  const interruptId = typeof rawId === "string" || typeof rawId === "number" ? String(rawId) : `${taskId ?? `task-${taskIndex}`}:${index}`;
25087
- const rawValue = isRecord11(interrupt5) ? record.value : interrupt5;
25324
+ const rawValue = isRecord12(interrupt5) ? record.value : interrupt5;
25088
25325
  const fenced = parseFence(rawValue);
25089
25326
  const value = fenced ? fenced.payload : rawValue;
25090
25327
  let type;
25091
- if (fenced?.type === "clarify" || isRecord11(value) && Array.isArray(value.questions)) {
25328
+ if (fenced?.type === "clarify" || isRecord12(value) && Array.isArray(value.questions)) {
25092
25329
  type = "clarify";
25093
25330
  } else if (fenced?.type === "task_review" || isTaskReview(value)) {
25094
25331
  type = "task_review";
25095
25332
  } else {
25096
25333
  type = "custom";
25097
25334
  }
25098
- const payload = type === "clarify" && isRecord11(value) && Array.isArray(value.questions) ? { questions: value.questions } : value;
25335
+ const payload = type === "clarify" && isRecord12(value) && Array.isArray(value.questions) ? { questions: value.questions } : value;
25099
25336
  result.push({
25100
25337
  interruptId,
25101
25338
  type,
@@ -26103,7 +26340,7 @@ var import_uuid5 = require("uuid");
26103
26340
  var import_zod48 = require("zod");
26104
26341
 
26105
26342
  // src/capability/CapabilityBundleMerger.ts
26106
- var import_node_crypto4 = require("crypto");
26343
+ var import_node_crypto5 = require("crypto");
26107
26344
  var import_node_util = require("util");
26108
26345
 
26109
26346
  // src/capability/CredentialFieldPolicy.ts
@@ -26539,7 +26776,7 @@ function createCapabilityRevision(bundles, effectivePolicy) {
26539
26776
  bundles: bundles.map(({ id, updatedAt }) => [id, updatedAt]),
26540
26777
  effectivePolicy
26541
26778
  };
26542
- return (0, import_node_crypto4.createHash)("sha256").update(JSON.stringify(canonicalize(revisionInput))).digest("hex");
26779
+ return (0, import_node_crypto5.createHash)("sha256").update(JSON.stringify(canonicalize(revisionInput))).digest("hex");
26543
26780
  }
26544
26781
  var LEGACY_UNION_CONFIG_FIELDS = new Set(
26545
26782
  Object.values(LEGACY_PLUGIN_CONNECTION_FIELDS).map(({ selectorField }) => selectorField)
@@ -27057,6 +27294,114 @@ var CapabilityRuntimeResolver = class {
27057
27294
  }
27058
27295
  };
27059
27296
 
27297
+ // src/observability_lattice/ObservabilityProvider.ts
27298
+ var ObservabilityDashboardUnsupportedError = class extends Error {
27299
+ /**
27300
+ * @param message - Stable diagnostic message.
27301
+ */
27302
+ constructor(message = "Observability dashboard is not supported") {
27303
+ super(message);
27304
+ this.name = "ObservabilityDashboardUnsupportedError";
27305
+ }
27306
+ };
27307
+ var ObservabilityDashboardUnavailableError = class extends Error {
27308
+ /**
27309
+ * @param message - Stable diagnostic message.
27310
+ */
27311
+ constructor(message = "Observability dashboard is unavailable") {
27312
+ super(message);
27313
+ this.name = "ObservabilityDashboardUnavailableError";
27314
+ }
27315
+ };
27316
+
27317
+ // src/observability_lattice/ObservabilityLatticeManager.ts
27318
+ init_BaseLatticeManager();
27319
+ var ObservabilityLatticeManager = class _ObservabilityLatticeManager extends BaseLatticeManager {
27320
+ constructor() {
27321
+ super(...arguments);
27322
+ this.defaultKey = "default";
27323
+ }
27324
+ /** Returns the process-wide singleton manager. */
27325
+ static getInstance() {
27326
+ if (!_ObservabilityLatticeManager.instance) {
27327
+ _ObservabilityLatticeManager.instance = new _ObservabilityLatticeManager();
27328
+ }
27329
+ return _ObservabilityLatticeManager.instance;
27330
+ }
27331
+ getLatticeType() {
27332
+ return "observability";
27333
+ }
27334
+ /** Registers a provider under a caller-chosen key. */
27335
+ registerLattice(key5, provider2) {
27336
+ this.register(key5, provider2);
27337
+ }
27338
+ /**
27339
+ * Returns the provider registered under `key`.
27340
+ *
27341
+ * @throws Error when no provider is registered under `key`.
27342
+ */
27343
+ getObservabilityLattice(key5) {
27344
+ const provider2 = this.get(key5);
27345
+ if (!provider2) throw new Error(`Observability lattice "${key5}" not registered`);
27346
+ return provider2;
27347
+ }
27348
+ /** Returns whether a provider is registered under `key`. */
27349
+ hasLattice(key5) {
27350
+ return this.has(key5);
27351
+ }
27352
+ /**
27353
+ * Removes the provider under `key`.
27354
+ *
27355
+ * @returns `true` when a provider was removed. Removing the active default
27356
+ * falls back to the `"default"` key.
27357
+ */
27358
+ removeLattice(key5) {
27359
+ const removed = this.remove(key5);
27360
+ if (removed && this.defaultKey === key5) this.defaultKey = "default";
27361
+ return removed;
27362
+ }
27363
+ /** Removes all providers and resets the active default. */
27364
+ clear() {
27365
+ super.clear();
27366
+ this.defaultKey = "default";
27367
+ }
27368
+ /**
27369
+ * Selects the provider used for new invocations.
27370
+ *
27371
+ * @throws Error when no provider is registered under `key`.
27372
+ */
27373
+ setDefault(key5) {
27374
+ if (!this.has(key5)) {
27375
+ throw new Error(`Observability lattice "${key5}" is not registered`);
27376
+ }
27377
+ this.defaultKey = key5;
27378
+ }
27379
+ /** Returns the key of the active default provider. */
27380
+ getDefaultKey() {
27381
+ return this.defaultKey;
27382
+ }
27383
+ /** Returns the active default provider, if registered. */
27384
+ getDefault() {
27385
+ return this.get(this.defaultKey);
27386
+ }
27387
+ };
27388
+ var observabilityLatticeManager = ObservabilityLatticeManager.getInstance();
27389
+ function registerObservabilityLattice(key5, provider2) {
27390
+ observabilityLatticeManager.registerLattice(key5, provider2);
27391
+ }
27392
+ function setDefaultObservabilityLattice(key5) {
27393
+ observabilityLatticeManager.setDefault(key5);
27394
+ }
27395
+ function resolveObservabilityCallbacks(context) {
27396
+ const provider2 = observabilityLatticeManager.getDefault();
27397
+ if (!provider2?.createCallbacks) return [];
27398
+ try {
27399
+ return [...provider2.createCallbacks(context) ?? []];
27400
+ } catch {
27401
+ return [];
27402
+ }
27403
+ }
27404
+
27060
27405
  // src/services/TaskExecutionContext.ts
27061
27406
  var DELEGATED_WORKER_SCOPE_TOKEN = Symbol("delegated-worker-scope");
27062
27407
  var delegatedWorkerScopeSecret = Object.freeze({});
@@ -27147,13 +27492,13 @@ function preserveDelegationContext(source, target) {
27147
27492
  var TRUSTED_AGENT_DISPATCH = Symbol("axiom.trustedAgentDispatch");
27148
27493
 
27149
27494
  // src/services/threadRunLease.ts
27150
- var import_node_crypto5 = require("crypto");
27495
+ var import_node_crypto6 = require("crypto");
27151
27496
  function threadRunLeaseKey(tenantId2, assistantId, threadId) {
27152
27497
  return `thread-run:${tenantId2}:${assistantId}:${threadId}`;
27153
27498
  }
27154
27499
  async function tryAcquireThreadRun(input) {
27155
27500
  const key5 = threadRunLeaseKey(input.tenantId, input.assistantId, input.threadId);
27156
- const holder = `${input.owner}#${(0, import_node_crypto5.randomUUID)()}`;
27501
+ const holder = `${input.owner}#${(0, import_node_crypto6.randomUUID)()}`;
27157
27502
  if (!await input.store.tryAcquire(key5, holder, input.ttlMs)) return null;
27158
27503
  const heartbeatMs = input.heartbeatMs ?? Math.max(1e3, Math.floor(input.ttlMs / 3));
27159
27504
  let released = false;
@@ -27874,7 +28219,6 @@ function checkpointCapabilityRevision(state) {
27874
28219
  }
27875
28220
  var QUEUE_PROCESSOR_RETRY_BASE_MS = 100;
27876
28221
  var QUEUE_PROCESSOR_MAX_RETRIES = 3;
27877
- var AGENT_RECURSION_LIMIT = 1e3;
27878
28222
  var THREAD_RUN_LEASE_TTL_MS = 6e4;
27879
28223
  var THREAD_RUN_LEASE_RETRY_BASE_MS = 150;
27880
28224
  var THREAD_RUN_LEASE_RETRY_CAP_MS = 1500;
@@ -27925,7 +28269,7 @@ var Agent = class {
27925
28269
  */
27926
28270
  this.threadRunLease = null;
27927
28271
  this.threadRunLeaseRetryAttempt = 0;
27928
- this.runIdFactory = import_node_crypto6.randomUUID;
28272
+ this.runIdFactory = import_node_crypto7.randomUUID;
27929
28273
  this.ledgerChain = Promise.resolve();
27930
28274
  this.agentExecutor = async ({ input, command, custom_run_config, expected_capability_revision, trusted_run_context }, signal) => {
27931
28275
  const { runnable_agent, runConfig } = await this.getLatticeClientAndRuntimeConfig(
@@ -27939,6 +28283,8 @@ var Agent = class {
27939
28283
  throw new Error("Agent execution was aborted");
27940
28284
  }
27941
28285
  try {
28286
+ const runId = (0, import_uuid5.v4)();
28287
+ const callbacks = this.observabilityCallbacks(executionRunConfig, runId, "agent-executor");
27942
28288
  const result = await runnable_agent.invoke(
27943
28289
  command ? new import_langgraph5.Command(command) : { ...stateInput, "x-tenant-id": this.tenant_id },
27944
28290
  {
@@ -27946,11 +28292,12 @@ var Agent = class {
27946
28292
  runConfig: executionRunConfig
27947
28293
  },
27948
28294
  configurable: {
27949
- run_id: (0, import_uuid5.v4)(),
27950
28295
  ...executionRunConfig,
28296
+ run_id: runId,
27951
28297
  runConfig: executionRunConfig
27952
28298
  },
27953
- recursionLimit: AGENT_RECURSION_LIMIT,
28299
+ ...callbacks ? { callbacks } : {},
28300
+ recursionLimit: readAgentRecursionLimit(),
27954
28301
  signal
27955
28302
  }
27956
28303
  );
@@ -28016,6 +28363,8 @@ var Agent = class {
28016
28363
  data: { id: message.id, content: message.content }
28017
28364
  });
28018
28365
  });
28366
+ const runId = execution_run_id ?? (0, import_uuid5.v4)();
28367
+ const callbacks = this.observabilityCallbacks(executionRunConfig, runId, "stream");
28019
28368
  const agentStream = await runnable_agent.stream(
28020
28369
  command ? new import_langgraph5.Command(command) : {
28021
28370
  ...stateInput,
@@ -28026,15 +28375,16 @@ var Agent = class {
28026
28375
  runConfig: executionRunConfig
28027
28376
  },
28028
28377
  configurable: {
28029
- run_id: execution_run_id ?? (0, import_uuid5.v4)(),
28030
28378
  ...executionRunConfig,
28379
+ run_id: runId,
28031
28380
  runConfig: executionRunConfig
28032
28381
  // Inject runConfig for tools to access
28033
28382
  },
28383
+ ...callbacks ? { callbacks } : {},
28034
28384
  ...execution_run_id === void 0 ? {} : { metadata: { run_id: execution_run_id } },
28035
28385
  streamMode: ["updates", "messages"],
28036
28386
  subgraphs: false,
28037
- recursionLimit: AGENT_RECURSION_LIMIT,
28387
+ recursionLimit: readAgentRecursionLimit(),
28038
28388
  signal
28039
28389
  }
28040
28390
  );
@@ -28442,6 +28792,28 @@ var Agent = class {
28442
28792
  this.queue_project_id = project_id == null || project_id === "" ? null : this.project_id;
28443
28793
  this.custom_run_config = custom_run_config;
28444
28794
  }
28795
+ /**
28796
+ * Re-pins the workspace/project scope used by the next execution.
28797
+ *
28798
+ * @param params - Concrete scope of the run about to execute; absent or
28799
+ * `null`/empty values keep the run unscoped.
28800
+ * @throws {Error} When this Agent is actively executing.
28801
+ * @remarks `AgentInstanceManager` is keyed by
28802
+ * `(tenant_id, assistant_id, thread_id)` only, so a control-plane caller can
28803
+ * create the instance before the durable run worker does. The worker calls
28804
+ * this method while holding the thread-run lease (no other execution can be
28805
+ * active) so the run's authoritative scope cannot inherit a stale default and
28806
+ * fail capability resolution with `Project 'default' was not found`.
28807
+ */
28808
+ applyExecutionScope(params) {
28809
+ if (this.activeExecutionPromise !== void 0) {
28810
+ throw new Error("Cannot re-pin execution scope while the agent is executing");
28811
+ }
28812
+ this.workspace_id = params.workspace_id || "default";
28813
+ this.project_id = params.project_id || "default";
28814
+ this.queue_workspace_id = params.workspace_id === null ? null : this.workspace_id;
28815
+ this.queue_project_id = params.project_id == null || params.project_id === "" ? null : this.project_id;
28816
+ }
28445
28817
  /**
28446
28818
  * Accepts host-authenticated queue metadata through the package-private symbol capability.
28447
28819
  *
@@ -28568,6 +28940,22 @@ var Agent = class {
28568
28940
  }
28569
28941
  return base;
28570
28942
  }
28943
+ observabilityCallbacks(runConfig, runId, source) {
28944
+ const execution = isPlainRecord(runConfig.execution) ? runConfig.execution : void 0;
28945
+ const taskId = typeof runConfig.taskId === "string" ? runConfig.taskId : execution && typeof execution.taskId === "string" ? execution.taskId : void 0;
28946
+ const callbacks = resolveObservabilityCallbacks({
28947
+ tenantId: this.tenant_id,
28948
+ ...this.queue_project_id ? { projectId: this.queue_project_id } : {},
28949
+ ...this.workspace_id ? { workspaceId: this.workspace_id } : {},
28950
+ assistantId: this.assistant_id,
28951
+ threadId: this.thread_id,
28952
+ runId,
28953
+ ...taskId ? { taskId } : {},
28954
+ ...typeof runConfig.user_id === "string" ? { userId: runConfig.user_id } : {},
28955
+ source: typeof runConfig.source === "string" ? runConfig.source : source
28956
+ });
28957
+ return callbacks.length > 0 ? callbacks : void 0;
28958
+ }
28571
28959
  getHumanPendingContent(message) {
28572
28960
  if (typeof message.content === "string" || !message.content || !("id" in message.content) || !("message" in message.content)) {
28573
28961
  throw new Error(`Expected human pending message content for message ${message.id}`);
@@ -28798,16 +29186,19 @@ var Agent = class {
28798
29186
  if (combinedSignal.aborted) {
28799
29187
  throw new Error("Agent execution was aborted");
28800
29188
  }
29189
+ const runId = (0, import_uuid5.v4)();
29190
+ const callbacks = this.observabilityCallbacks(executionRunConfig, runId, "invoke");
28801
29191
  const result = await runnable_agent.invoke(
28802
29192
  inputMessage.command ? new import_langgraph5.Command(inputMessage.command) : { ...rest, messages, "x-tenant-id": this.tenant_id },
28803
29193
  {
28804
29194
  context: { runConfig: executionRunConfig },
28805
29195
  configurable: {
28806
- run_id: (0, import_uuid5.v4)(),
28807
29196
  ...executionRunConfig,
29197
+ run_id: runId,
28808
29198
  runConfig: executionRunConfig
28809
29199
  },
28810
- recursionLimit: AGENT_RECURSION_LIMIT,
29200
+ ...callbacks ? { callbacks } : {},
29201
+ recursionLimit: readAgentRecursionLimit(),
28811
29202
  signal: combinedSignal
28812
29203
  }
28813
29204
  );
@@ -29207,6 +29598,8 @@ var Agent = class {
29207
29598
  capabilityRuntimeRevision
29208
29599
  );
29209
29600
  const executionRunConfig = this.executionRunConfig(runConfig, trustedRunContext);
29601
+ const runId = executionRunId ?? (0, import_uuid5.v4)();
29602
+ const callbacks = this.observabilityCallbacks(executionRunConfig, runId, "stream");
29210
29603
  const agentStream = await runnable_agent.stream(
29211
29604
  null,
29212
29605
  {
@@ -29215,13 +29608,14 @@ var Agent = class {
29215
29608
  },
29216
29609
  configurable: {
29217
29610
  ...executionRunConfig,
29218
- ...executionRunId === void 0 ? {} : { run_id: executionRunId },
29611
+ run_id: runId,
29219
29612
  runConfig: executionRunConfig
29220
29613
  },
29614
+ ...callbacks ? { callbacks } : {},
29221
29615
  ...executionRunId === void 0 ? {} : { metadata: { run_id: executionRunId } },
29222
29616
  streamMode: ["updates", "messages"],
29223
29617
  subgraphs: false,
29224
- recursionLimit: AGENT_RECURSION_LIMIT,
29618
+ recursionLimit: readAgentRecursionLimit(),
29225
29619
  signal
29226
29620
  }
29227
29621
  );
@@ -30571,6 +30965,25 @@ var AgentInstanceManager = class _AgentInstanceManager {
30571
30965
  }
30572
30966
  return this.agents.get(key5);
30573
30967
  }
30968
+ /**
30969
+ * Get the managed Agent for an exclusive execution and re-pin its scope.
30970
+ *
30971
+ * @param params - Thread identity plus the authoritative run scope.
30972
+ * @returns The singleton Agent whose next execution uses `params` scope.
30973
+ * @throws {Error} When the resolved Agent is actively executing.
30974
+ * @remarks Callers must already hold the thread-run lease (the durable run
30975
+ * worker does), so no execution can be in flight. This keeps the one-instance
30976
+ * identity while preventing a control-plane caller's default scope from
30977
+ * deciding how the durable run resolves Projects.
30978
+ */
30979
+ getAgentForExecution(params) {
30980
+ const agent = this.getAgent(params);
30981
+ agent.applyExecutionScope({
30982
+ workspace_id: params.workspace_id,
30983
+ project_id: params.project_id
30984
+ });
30985
+ return agent;
30986
+ }
30574
30987
  /**
30575
30988
  * Get the managed Agent for a thread WITHOUT creating or registering one.
30576
30989
  *
@@ -30700,8 +31113,13 @@ var DelegationService = class {
30700
31113
  if (!agent) {
30701
31114
  throw new Error(`Delegated agent ${request.assistant_id} not found`);
30702
31115
  }
31116
+ let childAbort;
31117
+ const abortChild = () => {
31118
+ childAbort ?? (childAbort = agent.abort().catch(() => void 0));
31119
+ return childAbort;
31120
+ };
30703
31121
  const onCancel = () => {
30704
- void agent.abort().catch(() => void 0);
31122
+ void abortChild();
30705
31123
  };
30706
31124
  if (cancellation) {
30707
31125
  if (cancellation.signal.aborted) onCancel();
@@ -30722,7 +31140,14 @@ var DelegationService = class {
30722
31140
  });
30723
31141
  try {
30724
31142
  await Promise.race([invocation, aborted]);
31143
+ if (signal.aborted) {
31144
+ await abortChild();
31145
+ throw new Error("Delegated child aborted");
31146
+ }
30725
31147
  return await agent.getCurrentState();
31148
+ } catch (error) {
31149
+ if (signal.aborted) await abortChild();
31150
+ throw error;
30726
31151
  } finally {
30727
31152
  signal.removeEventListener("abort", onAbort);
30728
31153
  }
@@ -30892,7 +31317,15 @@ var agentWorkerGraph = createAgentWorkerGraph();
30892
31317
  // src/deep_agent_new/middleware/subagents.ts
30893
31318
  init_MemoryLatticeManager();
30894
31319
  var DEFAULT_SUBAGENT_PROMPT = "In order to complete the objective that the user asks of you, you have access to a number of standard tools.";
30895
- var EXCLUDED_STATE_KEYS = ["messages", "todos", "jumpTo"];
31320
+ var EXCLUDED_STATE_KEYS = [
31321
+ "messages",
31322
+ "todos",
31323
+ "jumpTo",
31324
+ "repeatedToolCallSignature",
31325
+ "repeatedToolCallCount",
31326
+ "repeatedToolCallRunMarker",
31327
+ "repeatedToolCallMemberSignatures"
31328
+ ];
30896
31329
  var DEFAULT_GENERAL_PURPOSE_DESCRIPTION = "General-purpose agent for researching complex questions, searching for files and content, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. This agent has access to all tools as the main agent.";
30897
31330
  function createGeneralPurposeAgent(options) {
30898
31331
  const middleware = [...options.middleware];
@@ -31488,8 +31921,12 @@ function registerAgentAddMessageHandler() {
31488
31921
  tenant_id: taskInfo.tenantId,
31489
31922
  assistant_id: taskInfo.assistantId ?? "",
31490
31923
  thread_id: taskInfo.threadId ?? "",
31491
- workspace_id: runConfigFromMetadata?.workspaceId ?? "default",
31492
- project_id: runConfigFromMetadata?.projectId ?? "default"
31924
+ // An absent scope must stay unscoped: defaulting the project to
31925
+ // `"default"` pinned the shared thread Agent to a project that may not
31926
+ // exist, so later runs on the same thread failed capability resolution
31927
+ // with `Project 'default' was not found`.
31928
+ workspace_id: runConfigFromMetadata?.workspaceId ?? "",
31929
+ project_id: runConfigFromMetadata?.projectId ?? ""
31493
31930
  });
31494
31931
  await agent.addMessage({
31495
31932
  input: {
@@ -33321,6 +33758,7 @@ var DeepAgentGraphBuilder = class {
33321
33758
  const deepAgent = createDeepAgent({
33322
33759
  tools,
33323
33760
  model: params.model,
33761
+ name: agentLattice.config.name,
33324
33762
  contextSchema: params.stateSchema,
33325
33763
  systemPrompt: params.prompt,
33326
33764
  subagents,
@@ -33790,6 +34228,7 @@ var WorkflowAgentGraphBuilder = class {
33790
34228
  }
33791
34229
  const config = agentLattice.config;
33792
34230
  const yaml2 = config.workflowYaml;
34231
+ const agentName = config.name?.trim() || config.key;
33793
34232
  const tenantId2 = agentLattice.config.tenantId ?? "default";
33794
34233
  const checkpointer = getCheckpointSaver("default");
33795
34234
  const tools = params.tools.map((t) => t.executor).filter(Boolean);
@@ -33812,6 +34251,7 @@ var WorkflowAgentGraphBuilder = class {
33812
34251
  model: params.model,
33813
34252
  tools,
33814
34253
  systemPrompt: buildStepSystemPrompt(false, params.prompt),
34254
+ name: agentName,
33815
34255
  checkpointer,
33816
34256
  middleware: middlewares,
33817
34257
  stateSchema: withToolCallLimitStateSchema()
@@ -33833,6 +34273,7 @@ var WorkflowAgentGraphBuilder = class {
33833
34273
  model: params.model,
33834
34274
  tools,
33835
34275
  systemPrompt: buildStepSystemPrompt(isAsk, params.prompt),
34276
+ name: agentName,
33836
34277
  checkpointer,
33837
34278
  middleware: isAsk ? noWrapAskMiddlewares : noWrapMiddlewares,
33838
34279
  stateSchema: withToolCallLimitStateSchema(),
@@ -33850,6 +34291,7 @@ var WorkflowAgentGraphBuilder = class {
33850
34291
  model: params.model,
33851
34292
  tools,
33852
34293
  systemPrompt: buildStepSystemPrompt(true, params.prompt),
34294
+ name: agentName,
33853
34295
  checkpointer,
33854
34296
  middleware: askMiddlewares
33855
34297
  });
@@ -33868,7 +34310,13 @@ var WorkflowAgentGraphBuilder = class {
33868
34310
  } catch {
33869
34311
  console.warn(`[WF BUILDER] no trackingStore registered`);
33870
34312
  }
33871
- const graph = compileWorkflow(yaml2, resolveAgent, checkpointer, trackingStore);
34313
+ const graph = compileWorkflow(
34314
+ yaml2,
34315
+ resolveAgent,
34316
+ checkpointer,
34317
+ trackingStore,
34318
+ { name: agentName }
34319
+ );
33872
34320
  return graph;
33873
34321
  }
33874
34322
  };
@@ -37338,7 +37786,7 @@ function parseRecursiveGrepOutput(output) {
37338
37786
  }
37339
37787
 
37340
37788
  // src/sandbox_lattice/packDirectory.ts
37341
- var import_node_crypto7 = require("crypto");
37789
+ var import_node_crypto8 = require("crypto");
37342
37790
  var posix2 = __toESM(require("path/posix"));
37343
37791
  var MAX_PACK_ENTRIES = 1e4;
37344
37792
  var MAX_PACK_FILE_BYTES = 100 * 1024 * 1024;
@@ -37364,7 +37812,7 @@ function buildRemotePackDirectoryCommand(parentDir, sourceName, archiveName) {
37364
37812
  const parent = quotePosixShellArg(parentDir);
37365
37813
  const name = quotePosixShellArg(sourceName);
37366
37814
  const lock = quotePosixShellArg(`.${archiveName}.lock`);
37367
- const tempDir = quotePosixShellArg(`.${archiveName}.tmp-${(0, import_node_crypto7.randomBytes)(16).toString("hex")}`);
37815
+ const tempDir = quotePosixShellArg(`.${archiveName}.tmp-${(0, import_node_crypto8.randomBytes)(16).toString("hex")}`);
37368
37816
  const archivePath = joinPhysicalPath(parentDir, archiveName);
37369
37817
  const archive = quotePosixShellArg(archivePath);
37370
37818
  return [
@@ -37843,7 +38291,7 @@ function getDefaultMicrosandboxRemoteConfig() {
37843
38291
  image: process.env.MICROSANDBOX_IMAGE ?? "kioko12520/sandbox:0.1.0",
37844
38292
  //"daytonaio/sandbox:0.6.0",
37845
38293
  cpus: parseOptionalNumberEnv("MICROSANDBOX_CPUS", 1),
37846
- memoryMib: parseOptionalNumberEnv("MICROSANDBOX_MEMORY", 512),
38294
+ memoryMib: parseOptionalNumberEnv("MICROSANDBOX_MEMORY", 1024),
37847
38295
  user: "root"
37848
38296
  };
37849
38297
  }
@@ -38948,7 +39396,7 @@ var fs4 = __toESM(require("fs/promises"));
38948
39396
 
38949
39397
  // src/sandbox_lattice/LocalSandboxInstance.ts
38950
39398
  var import_node_child_process = require("child_process");
38951
- var import_node_crypto8 = require("crypto");
39399
+ var import_node_crypto9 = require("crypto");
38952
39400
  var fs3 = __toESM(require("fs/promises"));
38953
39401
  var path5 = __toESM(require("path"));
38954
39402
  var posix5 = __toESM(require("path/posix"));
@@ -38987,7 +39435,8 @@ var PLATFORM_SECRET_ENV_VARS = [
38987
39435
  "TAVILY_API_KEY",
38988
39436
  "VAPID_PRIVATE_KEY",
38989
39437
  "SUPABASE_KEY",
38990
- "A2A_API_KEYS"
39438
+ "A2A_API_KEYS",
39439
+ "MCP_UI_SCOPE_SECRET"
38991
39440
  ];
38992
39441
  function stripPlatformSecrets(env) {
38993
39442
  const rest = { ...env };
@@ -39294,7 +39743,7 @@ ${errOut}`.trim() : out.trim();
39294
39743
  };
39295
39744
  await preflight(sourceHost);
39296
39745
  const lockName = `.${filename}.lock`;
39297
- const tempDirectoryName = `.${filename}.tmp-${(0, import_node_crypto8.randomBytes)(16).toString("hex")}`;
39746
+ const tempDirectoryName = `.${filename}.tmp-${(0, import_node_crypto9.randomBytes)(16).toString("hex")}`;
39298
39747
  const sourceOperand = `./${rootName}`;
39299
39748
  tempDirectoryHost = path5.join(realArchiveDirectory, tempDirectoryName);
39300
39749
  tempHost = path5.join(tempDirectoryHost, "archive.zip");
@@ -39674,11 +40123,20 @@ async function disconnectAllChannels(getAdapter) {
39674
40123
  }
39675
40124
 
39676
40125
  // src/channel/ChannelConnectionLeader.ts
39677
- var import_node_crypto9 = require("crypto");
40126
+ var import_node_crypto10 = require("crypto");
39678
40127
  var LEASE_KEY = "leader:channel-connections";
40128
+ function channelShardForInstallation(installationId, shardCount) {
40129
+ if (!Number.isSafeInteger(shardCount) || shardCount < 1) {
40130
+ throw new RangeError("shardCount must be a positive integer");
40131
+ }
40132
+ if (shardCount === 1) return 0;
40133
+ return (0, import_node_crypto10.createHash)("sha256").update(installationId).digest().readUInt32BE(0) % shardCount;
40134
+ }
39679
40135
  var ChannelConnectionLeader = class {
39680
40136
  constructor(deps) {
40137
+ this.active = /* @__PURE__ */ new Map();
39681
40138
  this.holder = null;
40139
+ this.renewFailures = 0;
39682
40140
  this.connected = false;
39683
40141
  this.attempted = false;
39684
40142
  this.inFlight = null;
@@ -39688,6 +40146,33 @@ var ChannelConnectionLeader = class {
39688
40146
  this.deps = deps;
39689
40147
  this.ttlMs = deps.ttlMs ?? 6e4;
39690
40148
  this.retryMs = deps.retryMs ?? Math.max(5e3, Math.floor(this.ttlMs / 3));
40149
+ this.shardCount = deps.shardCount ?? 1;
40150
+ this.shard = deps.shard ?? 0;
40151
+ if (!Number.isSafeInteger(this.shardCount) || this.shardCount < 1) {
40152
+ throw new RangeError("ChannelConnectionLeader shardCount must be a positive integer");
40153
+ }
40154
+ if (!Number.isSafeInteger(this.shard) || this.shard < 0 || this.shard >= this.shardCount) {
40155
+ throw new RangeError("ChannelConnectionLeader shard must be within shardCount");
40156
+ }
40157
+ this.leaseKey = deps.leaseKey ?? (this.shardCount === 1 ? LEASE_KEY : `${LEASE_KEY}:${this.shard}`);
40158
+ this.reconciler = deps.loadDesired !== void 0;
40159
+ if (this.reconciler && (!deps.connectInstallation || !deps.disconnectInstallation)) {
40160
+ throw new Error("ChannelConnectionLeader reconcile mode requires connectInstallation and disconnectInstallation");
40161
+ }
40162
+ }
40163
+ /** Whether this shard owns an installation id. */
40164
+ owns(installationId) {
40165
+ return channelShardForInstallation(installationId, this.shardCount) === this.shard;
40166
+ }
40167
+ /** Wake the current leader so it reconciles the shared desired state. */
40168
+ wake() {
40169
+ if (this.stopped) return;
40170
+ void this.tickOnce();
40171
+ }
40172
+ /** Reconcile now when this instance currently holds the lease. */
40173
+ async reconcile() {
40174
+ if (!this.reconciler || !this.holder || this.stopped) return;
40175
+ await this.reconcileChannels();
39691
40176
  }
39692
40177
  /** Starts the ownership loop (immediate tick, then every `retryMs`). */
39693
40178
  start() {
@@ -39714,13 +40199,17 @@ var ChannelConnectionLeader = class {
39714
40199
  if (this.holder) {
39715
40200
  const holder = this.holder;
39716
40201
  this.holder = null;
39717
- await this.deps.leaseStore.release(LEASE_KEY, holder).catch((error) => {
40202
+ await this.deps.leaseStore.release(this.leaseKey, holder).catch((error) => {
39718
40203
  this.deps.log?.warn("Channel leader lease release failed", {
39719
40204
  error: error instanceof Error ? error.message : String(error)
39720
40205
  });
39721
40206
  });
39722
40207
  }
39723
- await this.disconnectChannels();
40208
+ if (this.reconciler) {
40209
+ await this.disconnectTracked();
40210
+ } else {
40211
+ await this.disconnectChannels();
40212
+ }
39724
40213
  }
39725
40214
  /**
39726
40215
  * Runs one ownership/health step. Public for deterministic tests.
@@ -39751,39 +40240,64 @@ var ChannelConnectionLeader = class {
39751
40240
  let renewed = false;
39752
40241
  let renewFailed = false;
39753
40242
  try {
39754
- renewed = await this.deps.leaseStore.renew(LEASE_KEY, this.holder, this.ttlMs);
40243
+ renewed = await this.deps.leaseStore.renew(this.leaseKey, this.holder, this.ttlMs);
39755
40244
  } catch (error) {
39756
40245
  renewFailed = true;
39757
40246
  this.deps.log?.warn("Channel leader lease renew failed", {
39758
40247
  error: error instanceof Error ? error.message : String(error)
39759
40248
  });
39760
40249
  }
39761
- if (renewFailed) return;
40250
+ if (renewFailed) {
40251
+ this.renewFailures += 1;
40252
+ if (this.renewFailures * this.retryMs < this.ttlMs) return;
40253
+ await this.loseLeadership();
40254
+ return;
40255
+ }
40256
+ this.renewFailures = 0;
39762
40257
  if (renewed) {
39763
- if (!this.connected) await this.connectChannels();
40258
+ if (this.reconciler) {
40259
+ await this.reconcileChannels();
40260
+ } else if (!this.connected) {
40261
+ await this.connectChannels();
40262
+ }
39764
40263
  return;
39765
40264
  }
39766
40265
  await this.loseLeadership();
39767
40266
  }
40267
+ if (this.reconciler && this.active.size > 0) {
40268
+ await this.disconnectTracked();
40269
+ if (this.active.size > 0) return;
40270
+ }
39768
40271
  await this.tryAcquire();
39769
40272
  }
39770
40273
  async tryAcquire() {
39771
- const holder = `${this.deps.owner}#${(0, import_node_crypto9.randomUUID)()}`;
39772
- const acquired = await this.deps.leaseStore.tryAcquire(LEASE_KEY, holder, this.ttlMs).catch((error) => {
40274
+ const holder = `${this.deps.owner}#${(0, import_node_crypto10.randomUUID)()}`;
40275
+ const acquired = await this.deps.leaseStore.tryAcquire(this.leaseKey, holder, this.ttlMs).catch((error) => {
39773
40276
  this.deps.log?.warn("Channel leader lease acquire failed", {
39774
40277
  error: error instanceof Error ? error.message : String(error)
39775
40278
  });
39776
40279
  return false;
39777
40280
  });
39778
40281
  if (!acquired) return;
40282
+ this.renewFailures = 0;
39779
40283
  this.holder = holder;
39780
- await this.connectChannels();
40284
+ if (this.reconciler) {
40285
+ await this.reconcileChannels();
40286
+ } else {
40287
+ await this.connectChannels();
40288
+ }
39781
40289
  }
39782
40290
  async loseLeadership() {
39783
40291
  this.holder = null;
39784
- await this.disconnectChannels();
40292
+ this.renewFailures = 0;
40293
+ if (this.reconciler) {
40294
+ await this.disconnectTracked();
40295
+ } else {
40296
+ await this.disconnectChannels();
40297
+ }
39785
40298
  }
39786
40299
  async connectChannels() {
40300
+ if (!this.deps.connect) return;
39787
40301
  this.attempted = true;
39788
40302
  try {
39789
40303
  await this.deps.connect();
@@ -39796,7 +40310,7 @@ var ChannelConnectionLeader = class {
39796
40310
  }
39797
40311
  }
39798
40312
  async disconnectChannels() {
39799
- if (!this.attempted) return;
40313
+ if (!this.attempted || !this.deps.disconnect) return;
39800
40314
  this.attempted = false;
39801
40315
  this.connected = false;
39802
40316
  try {
@@ -39807,6 +40321,74 @@ var ChannelConnectionLeader = class {
39807
40321
  });
39808
40322
  }
39809
40323
  }
40324
+ /** Reconcile desired installations against the connections this shard holds. */
40325
+ async reconcileChannels() {
40326
+ if (!this.reconciler || !this.holder || this.stopped) return;
40327
+ let desired;
40328
+ try {
40329
+ desired = (await this.deps.loadDesired()).filter(
40330
+ (installation) => installation.enabled && this.owns(installation.id)
40331
+ );
40332
+ } catch (error) {
40333
+ this.deps.log?.warn("Channel leader desired-state read failed", {
40334
+ error: error instanceof Error ? error.message : String(error)
40335
+ });
40336
+ return;
40337
+ }
40338
+ const desiredById = new Map(desired.map((installation) => [installation.id, installation]));
40339
+ for (const [id, active] of [...this.active]) {
40340
+ const next = desiredById.get(id);
40341
+ if (next && this.fingerprint(next) === active.fingerprint) continue;
40342
+ if (await this.safeDisconnect(active.installation)) this.active.delete(id);
40343
+ }
40344
+ for (const installation of desired) {
40345
+ if (this.active.has(installation.id)) continue;
40346
+ if (await this.safeConnect(installation)) {
40347
+ this.active.set(installation.id, {
40348
+ installation,
40349
+ fingerprint: this.fingerprint(installation)
40350
+ });
40351
+ }
40352
+ }
40353
+ }
40354
+ fingerprint(installation) {
40355
+ if (this.deps.fingerprint) return this.deps.fingerprint(installation);
40356
+ return JSON.stringify({
40357
+ channel: installation.channel,
40358
+ config: installation.config,
40359
+ fallbackAgentId: installation.fallbackAgentId,
40360
+ rejectWhenNoBinding: installation.rejectWhenNoBinding
40361
+ });
40362
+ }
40363
+ async safeConnect(installation) {
40364
+ try {
40365
+ await this.deps.connectInstallation(installation);
40366
+ return true;
40367
+ } catch (error) {
40368
+ this.deps.log?.warn("Channel installation connect failed", {
40369
+ installationId: installation.id,
40370
+ error: error instanceof Error ? error.message : String(error)
40371
+ });
40372
+ return false;
40373
+ }
40374
+ }
40375
+ async safeDisconnect(installation) {
40376
+ try {
40377
+ await this.deps.disconnectInstallation(installation);
40378
+ return true;
40379
+ } catch (error) {
40380
+ this.deps.log?.warn("Channel installation disconnect failed", {
40381
+ installationId: installation.id,
40382
+ error: error instanceof Error ? error.message : String(error)
40383
+ });
40384
+ return false;
40385
+ }
40386
+ }
40387
+ async disconnectTracked() {
40388
+ for (const [id, active] of [...this.active]) {
40389
+ if (await this.safeDisconnect(active.installation)) this.active.delete(id);
40390
+ }
40391
+ }
39810
40392
  };
39811
40393
 
39812
40394
  // src/eval_lattice/LatticeEval.ts
@@ -41270,7 +41852,7 @@ function getCoordinationLeaseStore() {
41270
41852
  }
41271
41853
 
41272
41854
  // src/services/withLease.ts
41273
- var import_node_crypto10 = require("crypto");
41855
+ var import_node_crypto11 = require("crypto");
41274
41856
  var LeaseAcquisitionTimeoutError = class extends Error {
41275
41857
  /**
41276
41858
  * @param key Lease key that could not be acquired.
@@ -41295,7 +41877,7 @@ async function withLease(store2, key5, ownerLabel, fn, options = {}) {
41295
41877
  const acquireTimeoutMs = options.acquireTimeoutMs ?? 1e4;
41296
41878
  const retryDelayMs = options.retryDelayMs ?? 50;
41297
41879
  const heartbeatMs = options.heartbeatMs ?? Math.max(1e3, Math.floor(ttlMs / 3));
41298
- const holder = `${ownerLabel}#${(0, import_node_crypto10.randomUUID)()}`;
41880
+ const holder = `${ownerLabel}#${(0, import_node_crypto11.randomUUID)()}`;
41299
41881
  const deadline = Date.now() + acquireTimeoutMs;
41300
41882
  for (; ; ) {
41301
41883
  if (await store2.tryAcquire(key5, holder, ttlMs)) break;
@@ -42127,11 +42709,11 @@ function describe(error) {
42127
42709
  }
42128
42710
 
42129
42711
  // src/services/TaskLifecycleService.ts
42130
- var import_node_crypto12 = require("crypto");
42712
+ var import_node_crypto13 = require("crypto");
42131
42713
  var import_protocols35 = require("@axiom-lattice/protocols");
42132
42714
 
42133
42715
  // src/middlewares/taskBelief.ts
42134
- var import_node_crypto11 = require("crypto");
42716
+ var import_node_crypto12 = require("crypto");
42135
42717
  function buildBeliefCompletionEventKey(taskId, result, impacts) {
42136
42718
  const canonical = JSON.stringify({
42137
42719
  beliefImpact: impacts.map((impact) => ({
@@ -42142,7 +42724,7 @@ function buildBeliefCompletionEventKey(taskId, result, impacts) {
42142
42724
  })),
42143
42725
  result: result.trim()
42144
42726
  });
42145
- return (0, import_node_crypto11.createHash)("sha256").update(canonical).digest("hex");
42727
+ return (0, import_node_crypto12.createHash)("sha256").update(canonical).digest("hex");
42146
42728
  }
42147
42729
  function buildCompletionEvidenceDetail(result, impacts, eventKey) {
42148
42730
  return { result, beliefImpact: impacts, eventKey };
@@ -42345,7 +42927,7 @@ function canonicalJson(value) {
42345
42927
  return JSON.stringify(value);
42346
42928
  }
42347
42929
  function sha256(value) {
42348
- return (0, import_node_crypto12.createHash)("sha256").update(canonicalJson(value)).digest("hex");
42930
+ return (0, import_node_crypto13.createHash)("sha256").update(canonicalJson(value)).digest("hex");
42349
42931
  }
42350
42932
  function sameEvidenceDetail(detail, taskId, result, impacts, eventKey, beliefOwner) {
42351
42933
  const storedOwner = detail.beliefOwner;
@@ -44427,7 +45009,7 @@ function createTaskLifecycleService(deps) {
44427
45009
  }
44428
45010
 
44429
45011
  // src/services/TaskExecutionService.ts
44430
- var import_node_crypto14 = require("crypto");
45012
+ var import_node_crypto15 = require("crypto");
44431
45013
  var import_node_util3 = require("util");
44432
45014
  var import_protocols36 = require("@axiom-lattice/protocols");
44433
45015
 
@@ -44783,13 +45365,13 @@ async function reconcileAllTenantTaskRuns(input) {
44783
45365
  }
44784
45366
 
44785
45367
  // src/services/taskRunLease.ts
44786
- var import_node_crypto13 = require("crypto");
45368
+ var import_node_crypto14 = require("crypto");
44787
45369
  function taskRunLeaseKey(taskId) {
44788
45370
  return `task-run:${taskId}`;
44789
45371
  }
44790
45372
  async function tryAcquireTaskRun(input) {
44791
45373
  const key5 = taskRunLeaseKey(input.taskId);
44792
- const holder = `${input.owner}#${(0, import_node_crypto13.randomUUID)()}`;
45374
+ const holder = `${input.owner}#${(0, import_node_crypto14.randomUUID)()}`;
44793
45375
  if (!await input.store.tryAcquire(key5, holder, input.ttlMs)) return null;
44794
45376
  const heartbeatMs = input.heartbeatMs ?? Math.max(1e3, Math.floor(input.ttlMs / 3));
44795
45377
  let released = false;
@@ -45209,11 +45791,11 @@ function createTaskExecutionService(deps) {
45209
45791
  let threadId;
45210
45792
  let runId;
45211
45793
  try {
45212
- threadId = storedThreadId ?? (deps.createThreadId ?? import_node_crypto14.randomUUID)();
45794
+ threadId = storedThreadId ?? (deps.createThreadId ?? import_node_crypto15.randomUUID)();
45213
45795
  if (task.status === "interrupted" && reuseCurrentRun) {
45214
45796
  runId = storedRunId;
45215
45797
  } else if (task.status === "interrupted" || task.status === "failed") {
45216
- runId = (deps.createRunId ?? import_node_crypto14.randomUUID)();
45798
+ runId = (deps.createRunId ?? import_node_crypto15.randomUUID)();
45217
45799
  }
45218
45800
  } catch (error) {
45219
45801
  return {
@@ -45493,11 +46075,11 @@ function createTaskExecutionService(deps) {
45493
46075
  }
45494
46076
 
45495
46077
  // src/services/leadership.ts
45496
- var import_node_crypto15 = require("crypto");
46078
+ var import_node_crypto16 = require("crypto");
45497
46079
  async function runAsLeader(store2, name, fn, options = {}) {
45498
46080
  const key5 = `leader:${name}`;
45499
46081
  const owner3 = options.owner ?? getReplicaId();
45500
- const holder = `${owner3}#${(0, import_node_crypto15.randomUUID)()}`;
46082
+ const holder = `${owner3}#${(0, import_node_crypto16.randomUUID)()}`;
45501
46083
  const ttlMs = options.ttlMs ?? 6e4;
45502
46084
  if (!await store2.tryAcquire(key5, holder, ttlMs)) return { ran: false };
45503
46085
  const heartbeat = setInterval(() => {
@@ -46746,16 +47328,16 @@ function createAskUserToClarifyTool() {
46746
47328
  }
46747
47329
 
46748
47330
  // src/middlewares/askUserClarifyMiddleware.ts
46749
- function isRecord12(value) {
47331
+ function isRecord13(value) {
46750
47332
  return typeof value === "object" && value !== null && !Array.isArray(value);
46751
47333
  }
46752
47334
  function isProjectRoomRun(request) {
46753
- if (!isRecord12(request) || !isRecord12(request.runtime)) return false;
47335
+ if (!isRecord13(request) || !isRecord13(request.runtime)) return false;
46754
47336
  const runtime = request.runtime;
46755
- const configurable = isRecord12(runtime.configurable) ? runtime.configurable.runConfig : void 0;
46756
- const context = isRecord12(runtime.context) ? runtime.context.runConfig : void 0;
46757
- const runConfig = isRecord12(configurable) ? configurable : isRecord12(context) ? context : void 0;
46758
- return isRecord12(runConfig?.projectRoom);
47337
+ const configurable = isRecord13(runtime.configurable) ? runtime.configurable.runConfig : void 0;
47338
+ const context = isRecord13(runtime.context) ? runtime.context.runConfig : void 0;
47339
+ const runConfig = isRecord13(configurable) ? configurable : isRecord13(context) ? context : void 0;
47340
+ return isRecord13(runConfig?.projectRoom);
46759
47341
  }
46760
47342
  function createAskUserClarifyMiddleware() {
46761
47343
  return (0, import_langchain76.createMiddleware)({
@@ -53339,11 +53921,14 @@ var sandboxPluginsPlugin = {
53339
53921
  }
53340
53922
  const toolDef = (parsedManifest.tools ?? []).find((t) => t.name === input.target?.name);
53341
53923
  if (!toolDef) return `tool "${input.target.name ?? ""}" not found`;
53342
- const runCfg = exeConfig?.configurable?.runConfig ?? {};
53924
+ const runConfig = {
53925
+ ...sandboxRunConfigFrom(exeConfig),
53926
+ tenantId: tenantId2
53927
+ };
53343
53928
  const resolved = input.target.connectionKey ? await resolveSandboxPluginConnections(
53344
53929
  input.type,
53345
53930
  { connections: [input.target.connectionKey] },
53346
- { tenantId: tenantId2 }
53931
+ runConfig
53347
53932
  ) : {};
53348
53933
  const secrets = collectSecretValues(resolved.connection, connectionSecretFields(plugin));
53349
53934
  try {
@@ -53354,19 +53939,27 @@ var sandboxPluginsPlugin = {
53354
53939
  connection: resolved.connection,
53355
53940
  connections: resolved.connections,
53356
53941
  context: { tenantId: tenantId2, pluginType: input.type, tool: toolDef.name },
53357
- runConfig: {
53358
- tenantId: tenantId2,
53359
- assistantId: typeof runCfg.assistant_id === "string" ? runCfg.assistant_id : void 0
53360
- }
53942
+ runConfig
53361
53943
  });
53362
53944
  const text = handlerResultText(redactSecretValues(result, secrets));
53363
53945
  const ui = toolDef.ui;
53364
53946
  if (!ui?.resource) return text;
53947
+ const scope = result.ok && ui?.resource ? signMcpUiScope({
53948
+ tid: runConfig.tenantId || tenantId2,
53949
+ thid: runConfig.threadId,
53950
+ aid: runConfig.assistantId,
53951
+ wid: runConfig.workspaceId,
53952
+ pid: runConfig.projectId,
53953
+ plugin: input.type,
53954
+ resource: ui.resource,
53955
+ ck: resolved.connections?.[0]?.key
53956
+ }) : void 0;
53365
53957
  const uiRef = {
53366
53958
  kind: "plugin",
53367
53959
  pluginType: input.type,
53368
53960
  resource: ui.resource,
53369
- displayMode: ui.displayMode ?? "inline"
53961
+ displayMode: ui.displayMode ?? "inline",
53962
+ ...scope ? { scope } : {}
53370
53963
  };
53371
53964
  return appendUiFence(text, uiRef);
53372
53965
  } catch (err) {
@@ -54064,11 +54657,11 @@ var INLINE_INPUT_LIMIT_BYTES2 = 48 * 1024;
54064
54657
  var DEFAULT_HANDLER_TIMEOUT_MS = 6e4;
54065
54658
  var MIN_HANDLER_TIMEOUT_MS = 1e3;
54066
54659
  var MAX_HANDLER_TIMEOUT_MS = 3e5;
54067
- function isRecord13(value) {
54660
+ function isRecord14(value) {
54068
54661
  return typeof value === "object" && value !== null && !Array.isArray(value);
54069
54662
  }
54070
54663
  function isEnvelope3(value) {
54071
- return isRecord13(value) && typeof value.ok === "boolean";
54664
+ return isRecord14(value) && typeof value.ok === "boolean";
54072
54665
  }
54073
54666
  function parseHostArgs(argv) {
54074
54667
  let type;
@@ -54150,7 +54743,7 @@ function normalizeEnvelope(parsed) {
54150
54743
  }
54151
54744
 
54152
54745
  // src/sandbox_plugin/host/pluginHostSource.ts
54153
- var import_node_crypto16 = require("crypto");
54746
+ var import_node_crypto17 = require("crypto");
54154
54747
  var PLUGIN_HOST_VERSION = "1.1.0";
54155
54748
  var PLUGIN_HOST_SERVER_SOURCE = String.raw`#!/usr/bin/env node
54156
54749
  "use strict";
@@ -54352,6 +54945,8 @@ async function runHandler(body) {
54352
54945
  var needsTempDir = inputIsLarge || connectionPayload !== null;
54353
54946
  var tempDir = null;
54354
54947
  var env = Object.assign({}, process.env);
54948
+ // Handler processes must never inherit scope signing secrets.
54949
+ delete env.MCP_UI_SCOPE_SECRET;
54355
54950
  try {
54356
54951
  if (needsTempDir) {
54357
54952
  tempDir = path.join(os.tmpdir(), "plugin-run-" + Date.now() + "-" + Math.random().toString(36).slice(2));
@@ -54443,7 +55038,7 @@ server.listen(config.port, "0.0.0.0", function () {
54443
55038
  });
54444
55039
  `;
54445
55040
  function pluginHostContentHash() {
54446
- return (0, import_node_crypto16.createHash)("sha256").update(`${PLUGIN_HOST_VERSION}:${PLUGIN_HOST_SERVER_SOURCE}`).digest("hex").slice(0, 16);
55041
+ return (0, import_node_crypto17.createHash)("sha256").update(`${PLUGIN_HOST_VERSION}:${PLUGIN_HOST_SERVER_SOURCE}`).digest("hex").slice(0, 16);
54447
55042
  }
54448
55043
 
54449
55044
  // src/sandbox_plugin/host/pluginHostInstaller.ts
@@ -54857,16 +55452,16 @@ var IdRemapper = class {
54857
55452
  };
54858
55453
 
54859
55454
  // src/util/directRoomId.ts
54860
- var import_node_crypto17 = require("crypto");
55455
+ var import_node_crypto18 = require("crypto");
54861
55456
  function generateDirectHumanProjectId(tenantId2, workspaceId, userId1, userId2) {
54862
55457
  const sortedUserIds = [userId1, userId2].sort();
54863
55458
  const parts = [tenantId2, workspaceId, ...sortedUserIds];
54864
- const hash = (0, import_node_crypto17.createHash)("sha256").update(parts.join(":")).digest("hex");
55459
+ const hash = (0, import_node_crypto18.createHash)("sha256").update(parts.join(":")).digest("hex");
54865
55460
  return `direct_human_${hash}`;
54866
55461
  }
54867
55462
  function generateDirectBotProjectId(tenantId2, workspaceId, userId, assistantId) {
54868
55463
  const parts = [tenantId2, workspaceId, userId, assistantId];
54869
- const hash = (0, import_node_crypto17.createHash)("sha256").update(parts.join(":")).digest("hex");
55464
+ const hash = (0, import_node_crypto18.createHash)("sha256").update(parts.join(":")).digest("hex");
54870
55465
  return `direct_bot_${hash}`;
54871
55466
  }
54872
55467
  function parseDirectRoomType(projectId) {
@@ -54998,6 +55593,9 @@ registerBuiltinPlugins();
54998
55593
  MicrosandboxServiceClient,
54999
55594
  ModelLatticeManager,
55000
55595
  MysqlDatabase,
55596
+ ObservabilityDashboardUnavailableError,
55597
+ ObservabilityDashboardUnsupportedError,
55598
+ ObservabilityLatticeManager,
55001
55599
  OutboxPoller,
55002
55600
  PACK_DIRECTORY_TIMEOUT_MS,
55003
55601
  PLATFORM_SECRET_ENV_VARS,
@@ -55091,6 +55689,7 @@ registerBuiltinPlugins();
55091
55689
  buildTaskMutationFallback,
55092
55690
  buildTaskNormalizationFallback,
55093
55691
  canConvergeOrphan,
55692
+ channelShardForInstallation,
55094
55693
  checkEmptyContent,
55095
55694
  chunkBufferStreamKey,
55096
55695
  clearEncryptionKeyCache,
@@ -55195,6 +55794,7 @@ registerBuiltinPlugins();
55195
55794
  getEncryptionKey,
55196
55795
  getEvalRunService,
55197
55796
  getLoggerLattice,
55797
+ getMcpUiScopeSecret,
55198
55798
  getMenuRegistry,
55199
55799
  getModelLattice,
55200
55800
  getNextCronTime,
@@ -55263,6 +55863,7 @@ registerBuiltinPlugins();
55263
55863
  normalizeAgentInterrupts,
55264
55864
  normalizeAgentRunMessageIds,
55265
55865
  normalizeSandboxName,
55866
+ observabilityLatticeManager,
55266
55867
  ownTaskResponseField,
55267
55868
  parallelLimit,
55268
55869
  parseCronExpression,
@@ -55303,6 +55904,7 @@ registerBuiltinPlugins();
55303
55904
  registerLoggerLattice,
55304
55905
  registerModelLattice,
55305
55906
  registerModelLatticeForTenant,
55907
+ registerObservabilityLattice,
55306
55908
  registerQueueLattice,
55307
55909
  registerSTTModelLattice,
55308
55910
  registerSandboxOpenCredentialProvider,
@@ -55320,6 +55922,7 @@ registerBuiltinPlugins();
55320
55922
  resolveHandlerTimeoutMs,
55321
55923
  resolveJudgeModelKey,
55322
55924
  resolveModelLatticeForTenant,
55925
+ resolveObservabilityCallbacks,
55323
55926
  resolvePath,
55324
55927
  resolvePluginConnections,
55325
55928
  resolveSandboxPluginConnections,
@@ -55340,11 +55943,13 @@ registerBuiltinPlugins();
55340
55943
  serializeTaskReadResponse,
55341
55944
  setAgentLifecycleTap,
55342
55945
  setBindingRegistry,
55946
+ setDefaultObservabilityLattice,
55343
55947
  setEvalRunService,
55344
55948
  setMenuRegistry,
55345
55949
  setPluginDeploymentService,
55346
55950
  setRunCancelHeartbeatFallbackObserver,
55347
55951
  setSandboxPluginCatalog,
55952
+ signMcpUiScope,
55348
55953
  skillLatticeManager,
55349
55954
  sqlDatabaseManager,
55350
55955
  storeLatticeManager,
@@ -55373,6 +55978,7 @@ registerBuiltinPlugins();
55373
55978
  validateToolInput,
55374
55979
  vectorStoreLatticeManager,
55375
55980
  vectorStoreProviderManager,
55981
+ verifyMcpUiScope,
55376
55982
  withLease,
55377
55983
  withTimeout,
55378
55984
  wrapMcpToolWithUi