@axiom-lattice/gateway 8.3.0 → 8.4.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.
Files changed (109) hide show
  1. package/dist/{A2AAuthService-7UGQ7GMW.mjs → A2AAuthService-UKN53ZGP.mjs} +2 -2
  2. package/dist/{a2a-BHBLACJV.mjs → a2a-TDZ3TT6H.mjs} +3 -3
  3. package/dist/{a2a-standard-VL5I7B4W.mjs → a2a-standard-INVCUSAW.mjs} +39 -2
  4. package/dist/a2a-standard-INVCUSAW.mjs.map +1 -0
  5. package/dist/chunk-A7YNAU5L.mjs +377 -0
  6. package/dist/chunk-A7YNAU5L.mjs.map +1 -0
  7. package/dist/{chunk-3XIIQ6EK.mjs → chunk-BOPNXTMO.mjs} +66 -5
  8. package/dist/chunk-BOPNXTMO.mjs.map +1 -0
  9. package/dist/{chunk-L6MBEEII.mjs → chunk-JGQURU44.mjs} +24 -6
  10. package/dist/chunk-JGQURU44.mjs.map +1 -0
  11. package/dist/{chunk-GPHOYR3X.mjs → chunk-LCM4OQTI.mjs} +30 -1
  12. package/dist/chunk-LCM4OQTI.mjs.map +1 -0
  13. package/dist/{chunk-HVIKCUOF.mjs → chunk-MFWTGNQR.mjs} +74 -5
  14. package/dist/chunk-MFWTGNQR.mjs.map +1 -0
  15. package/dist/{chunk-HYYLYIMH.mjs → chunk-OBODBHIS.mjs} +2 -2
  16. package/dist/chunk-T2HIWZGP.mjs +580 -0
  17. package/dist/chunk-T2HIWZGP.mjs.map +1 -0
  18. package/dist/chunk-Y7OVVPVU.mjs +13 -0
  19. package/dist/chunk-Y7OVVPVU.mjs.map +1 -0
  20. package/dist/{chunk-GL7RV5L3.mjs → chunk-YR32MWEJ.mjs} +36 -73
  21. package/dist/chunk-YR32MWEJ.mjs.map +1 -0
  22. package/dist/embed/{embed-page-AgentDetailSideApp-O6G4NJ7I.css → embed-page-AgentDetailSideApp-JMJOOC4V.css} +1 -1
  23. package/dist/embed/{embed-page-AgentDetailSideApp-7YTMN643.js → embed-page-AgentDetailSideApp-TQEJK6ZF.js} +1 -1
  24. package/dist/embed/{embed-page-AgentGovernanceWorkbench-SFZNVMUH.css → embed-page-AgentGovernanceWorkbench-3T3ZFJI5.css} +1 -1
  25. package/dist/embed/{embed-page-AgentGovernanceWorkbench-YWJ4ZLEV.js → embed-page-AgentGovernanceWorkbench-II2MRGCG.js} +1 -1
  26. package/dist/embed/{embed-page-LangfuseDashboard-BEOJDMWF.js → embed-page-LangfuseDashboard-7OANGQXY.js} +1 -1
  27. package/dist/embed/{embed-page-MessageGraph-N2DXVMEK.js → embed-page-MessageGraph-KJPQWTHE.js} +1 -1
  28. package/dist/embed/{embed-page-TopologyRuntimeView-CWOXLVFW.css → embed-page-MessageGraph-UDC6GQA5.css} +1 -1
  29. package/dist/embed/{embed-page-ReactChart-3QDZX2WG.js → embed-page-ReactChart-2CAIM4JD.js} +1 -1
  30. package/dist/embed/{embed-page-ReactChart-MXGF35OQ.css → embed-page-ReactChart-URBKYQYE.css} +1 -1
  31. package/dist/embed/{embed-page-SkillFlow-3X24ILKU.js → embed-page-SkillFlow-243MXRXC.js} +1 -1
  32. package/dist/embed/{embed-page-TasksSideApp-MYIRJWFM.js → embed-page-TasksSideApp-OA7CULHS.js} +1 -1
  33. package/dist/embed/{embed-page-TasksSideApp-HV6DKQ26.css → embed-page-TasksSideApp-TTCP4ENP.css} +1 -1
  34. package/dist/embed/{embed-page-ThreadMaintenancePanel-V327PV5R.js → embed-page-ThreadMaintenancePanel-Z4424X3J.js} +1 -1
  35. package/dist/embed/{embed-page-WorkflowAutomationView-YQFB3CTV.css → embed-page-TopologyRuntimeView-S4AMB4RI.css} +1 -1
  36. package/dist/embed/{embed-page-TopologyRuntimeView-3O6VJUZR.js → embed-page-TopologyRuntimeView-THTCZUS7.js} +1 -1
  37. package/dist/embed/{embed-page-MessageGraph-UT2TCPSO.css → embed-page-WorkflowAutomationView-FWVCQ3YM.css} +1 -1
  38. package/dist/embed/{embed-page-WorkflowAutomationView-YHOS4WQR.js → embed-page-WorkflowAutomationView-YDIDG35E.js} +1 -1
  39. package/dist/embed/{embed-page-chunk-4XKCMM5C.js → embed-page-chunk-7ULTMRM2.js} +1 -1
  40. package/dist/embed/{embed-page-chunk-BSRASK7V.js → embed-page-chunk-FZX4A32D.js} +5 -5
  41. package/dist/embed/{embed-page-chunk-PMOGSY6W.js → embed-page-chunk-JMP7EQEF.js} +1 -1
  42. package/dist/embed/{embed-page-chunk-IELKCYQX.js → embed-page-chunk-L2EGVVJS.js} +1 -1
  43. package/dist/embed/{embed-page-chunk-WGEXK773.js → embed-page-chunk-LDQGH44H.js} +1 -1
  44. package/dist/embed/{embed-page-chunk-JTL73EBV.js → embed-page-chunk-OMN6G52V.js} +1 -1
  45. package/dist/embed/{embed-page-chunk-PROZXFWS.js → embed-page-chunk-RKQJBKN2.js} +1 -1
  46. package/dist/embed/{embed-page-chunk-YMVKQQXJ.js → embed-page-chunk-VYS3TAK4.js} +1 -1
  47. package/dist/embed/{embed-page-chunk-ASEIOK7X.js → embed-page-chunk-W5OP2CZG.js} +2 -2
  48. package/dist/embed/embed-page-chunk-Z6KWW64I.js +6837 -0
  49. package/dist/embed/{embed-page-en-E35GE7TA.js → embed-page-en-D4M3DPFT.js} +1 -1
  50. package/dist/embed/{embed-page-en-XJYWUJEL.js → embed-page-en-DNDGCPMA.js} +1 -1
  51. package/dist/embed/embed-page-en-H5NOZEKE.js +1 -0
  52. package/dist/embed/{embed-page-en-HDSVQ4O6.js → embed-page-en-QJRX2NQE.js} +1 -1
  53. package/dist/embed/{embed-page-zh-6EBUEFKP.js → embed-page-zh-2H4EB3F3.js} +1 -1
  54. package/dist/embed/embed-page-zh-4C2K3RH2.js +1 -0
  55. package/dist/embed/{embed-page-zh-IR652A6J.js → embed-page-zh-HTEHFCSL.js} +1 -1
  56. package/dist/embed/{embed-page-zh-ZLK3GLM3.js → embed-page-zh-NEXLMDHF.js} +1 -1
  57. package/dist/embed/embed-page.css +1 -1
  58. package/dist/embed/embed-page.js +1 -1
  59. package/dist/embed/mcp-app-page.js +61 -0
  60. package/dist/index.d.mts +29 -0
  61. package/dist/index.d.ts +29 -0
  62. package/dist/index.js +2551 -1476
  63. package/dist/index.js.map +1 -1
  64. package/dist/index.mjs +116 -690
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/mcp-app-shares-SHPBJQXS.mjs +300 -0
  67. package/dist/mcp-app-shares-SHPBJQXS.mjs.map +1 -0
  68. package/dist/mcp-apps-QVUK6UBA.mjs +26 -0
  69. package/dist/{open-7ED27I5B.mjs → open-27ZPLBIW.mjs} +101 -18
  70. package/dist/open-27ZPLBIW.mjs.map +1 -0
  71. package/dist/{open-catalog-SZQ435AY.mjs → open-catalog-NVGP6SQP.mjs} +38 -7
  72. package/dist/open-catalog-NVGP6SQP.mjs.map +1 -0
  73. package/dist/{open-exposure-I3DN2X4E.mjs → open-exposure-BPLYUIX6.mjs} +4 -4
  74. package/dist/{open-files-V3R2BFTV.mjs → open-files-JPB2NBL6.mjs} +4 -4
  75. package/dist/{open-session-2Y7XJJW2.mjs → open-session-CLZT3HVG.mjs} +5 -5
  76. package/dist/open-session-CLZT3HVG.mjs.map +1 -0
  77. package/dist/openLattice-D5YTSZBY.mjs +28 -0
  78. package/dist/{registerExposedPlugins-6GCOE64C.mjs → registerExposedPlugins-2JGXSMAL.mjs} +4 -3
  79. package/dist/{resources-DAU5ZIPB.mjs → resources-YD5DOPGD.mjs} +83 -3
  80. package/dist/resources-YD5DOPGD.mjs.map +1 -0
  81. package/dist/{sandboxOpenCredentialProvider-AT227D4N.mjs → sandboxOpenCredentialProvider-RTYOYRCT.mjs} +19 -14
  82. package/dist/sandboxOpenCredentialProvider-RTYOYRCT.mjs.map +1 -0
  83. package/package.json +10 -8
  84. package/dist/a2a-standard-VL5I7B4W.mjs.map +0 -1
  85. package/dist/chunk-3XIIQ6EK.mjs.map +0 -1
  86. package/dist/chunk-GL7RV5L3.mjs.map +0 -1
  87. package/dist/chunk-GPHOYR3X.mjs.map +0 -1
  88. package/dist/chunk-GXZFO3VU.mjs +0 -42
  89. package/dist/chunk-GXZFO3VU.mjs.map +0 -1
  90. package/dist/chunk-HVIKCUOF.mjs.map +0 -1
  91. package/dist/chunk-L6MBEEII.mjs.map +0 -1
  92. package/dist/embed/embed-page-chunk-IBRMWDHE.js +0 -6835
  93. package/dist/embed/embed-page-en-GLT2HEZZ.js +0 -1
  94. package/dist/embed/embed-page-zh-XMEJPDMF.js +0 -1
  95. package/dist/open-7ED27I5B.mjs.map +0 -1
  96. package/dist/open-catalog-SZQ435AY.mjs.map +0 -1
  97. package/dist/open-session-2Y7XJJW2.mjs.map +0 -1
  98. package/dist/openLattice-Q6M5S6CY.mjs +0 -18
  99. package/dist/openRateLimiter-XEOL3A5G.mjs +0 -8
  100. package/dist/resources-DAU5ZIPB.mjs.map +0 -1
  101. package/dist/sandboxOpenCredentialProvider-AT227D4N.mjs.map +0 -1
  102. /package/dist/{A2AAuthService-7UGQ7GMW.mjs.map → A2AAuthService-UKN53ZGP.mjs.map} +0 -0
  103. /package/dist/{a2a-BHBLACJV.mjs.map → a2a-TDZ3TT6H.mjs.map} +0 -0
  104. /package/dist/{chunk-HYYLYIMH.mjs.map → chunk-OBODBHIS.mjs.map} +0 -0
  105. /package/dist/{openLattice-Q6M5S6CY.mjs.map → mcp-apps-QVUK6UBA.mjs.map} +0 -0
  106. /package/dist/{open-exposure-I3DN2X4E.mjs.map → open-exposure-BPLYUIX6.mjs.map} +0 -0
  107. /package/dist/{open-files-V3R2BFTV.mjs.map → open-files-JPB2NBL6.mjs.map} +0 -0
  108. /package/dist/{openRateLimiter-XEOL3A5G.mjs.map → openLattice-D5YTSZBY.mjs.map} +0 -0
  109. /package/dist/{registerExposedPlugins-6GCOE64C.mjs.map → registerExposedPlugins-2JGXSMAL.mjs.map} +0 -0
package/dist/index.mjs CHANGED
@@ -1,12 +1,19 @@
1
1
  import {
2
- invalidateAgentReflectionCache,
3
- invalidatePluginReflectionCache
4
- } from "./chunk-GL7RV5L3.mjs";
2
+ invalidateAgentReflectionCache
3
+ } from "./chunk-YR32MWEJ.mjs";
5
4
  import {
6
5
  getContentTypeFromFilename,
7
6
  getFilenameFromPath,
8
7
  sendBufferWithRange
9
8
  } from "./chunk-EMYRCJOI.mjs";
9
+ import {
10
+ createRecoveryCallerDeps
11
+ } from "./chunk-NOXGKYUV.mjs";
12
+ import {
13
+ Logger,
14
+ getQrCode,
15
+ getQrCodeStatus
16
+ } from "./chunk-6CUQGDJI.mjs";
10
17
  import {
11
18
  PathOutsideRootError,
12
19
  ProjectFileValidationError,
@@ -28,9 +35,12 @@ import {
28
35
  wakeRunTaskQueue
29
36
  } from "./chunk-2SR4F3ZD.mjs";
30
37
  import {
31
- PluginToolScopeError,
32
- invokePluginTool
33
- } from "./chunk-XUWD4VKY.mjs";
38
+ claimDedupKey,
39
+ createRateLimitService,
40
+ getRateLimitService,
41
+ incrementRateCounter,
42
+ setRateLimitService
43
+ } from "./chunk-A7YNAU5L.mjs";
34
44
  import {
35
45
  buildPreviewTokenScript
36
46
  } from "./chunk-7CG57LEF.mjs";
@@ -38,16 +48,24 @@ import "./chunk-EXPERMZR.mjs";
38
48
  import {
39
49
  CollectionService
40
50
  } from "./chunk-PWHUWFXL.mjs";
51
+ import {
52
+ getMcpUiResourceResolver,
53
+ listTenantPlugins,
54
+ registerMcpAppRoutes,
55
+ resolveTenantPluginByType
56
+ } from "./chunk-T2HIWZGP.mjs";
57
+ import "./chunk-XUWD4VKY.mjs";
41
58
  import {
42
59
  A2A_KEY_CHANGED_TOPIC,
43
60
  handleA2AKeyChanged,
44
61
  publishA2AKeyChanged,
45
62
  refreshStoreKeyMap
46
- } from "./chunk-HYYLYIMH.mjs";
63
+ } from "./chunk-OBODBHIS.mjs";
47
64
  import {
48
65
  A2AAuthService,
49
66
  parseEnvKeys
50
- } from "./chunk-GPHOYR3X.mjs";
67
+ } from "./chunk-LCM4OQTI.mjs";
68
+ import "./chunk-MFWTGNQR.mjs";
51
69
  import {
52
70
  createOrphanRecoveryRuntime,
53
71
  createTaskRunLiveness,
@@ -59,14 +77,6 @@ import {
59
77
  resolveTopCaller,
60
78
  runOrphanRecovery
61
79
  } from "./chunk-NZXKECNN.mjs";
62
- import {
63
- createRecoveryCallerDeps
64
- } from "./chunk-NOXGKYUV.mjs";
65
- import {
66
- Logger,
67
- getQrCode,
68
- getQrCodeStatus
69
- } from "./chunk-6CUQGDJI.mjs";
70
80
  import "./chunk-NFEGQTCC.mjs";
71
81
 
72
82
  // src/index.ts
@@ -10003,14 +10013,6 @@ async function importApply(request, reply) {
10003
10013
 
10004
10014
  // src/controllers/middleware-types.ts
10005
10015
  import { serializePluginMeta } from "@axiom-lattice/core";
10006
-
10007
- // src/services/plugins/tenantPluginResolver.ts
10008
- import { listTenantPlugins } from "@axiom-lattice/core";
10009
- async function resolveTenantPluginByType(tenantId, type) {
10010
- return (await listTenantPlugins(tenantId)).find((p) => p.meta.type === type);
10011
- }
10012
-
10013
- // src/controllers/middleware-types.ts
10014
10016
  async function collectMiddlewareMetas(tenantId) {
10015
10017
  return (await listTenantPlugins(tenantId)).map(serializePluginMeta);
10016
10018
  }
@@ -13726,562 +13728,6 @@ function registerMcpServerConfigRoutes(app2) {
13726
13728
  app2.post("/api/mcp-servers/test-tools", testMcpServerTools);
13727
13729
  }
13728
13730
 
13729
- // src/routes/mcp-apps.ts
13730
- import {
13731
- parseMcpUiRef
13732
- } from "@axiom-lattice/protocols";
13733
- import {
13734
- getSandboxPluginCatalog as getSandboxPluginCatalog2,
13735
- mcpManager as mcpManager2,
13736
- resolvePluginConnections,
13737
- verifyMcpUiScope
13738
- } from "@axiom-lattice/core";
13739
-
13740
- // src/services/mcp-ui/UiResourceResolver.ts
13741
- import { createHash as createHash3 } from "crypto";
13742
- var DEFAULT_TTL_MS = 5 * 60 * 1e3;
13743
- function publicFieldsOf(payload) {
13744
- return {
13745
- mimeType: payload.mimeType,
13746
- html: payload.html,
13747
- ...payload.csp !== void 0 ? { csp: payload.csp } : {},
13748
- ...payload.permissions !== void 0 ? { permissions: payload.permissions } : {},
13749
- ...payload.prefersBorder !== void 0 ? { prefersBorder: payload.prefersBorder } : {}
13750
- };
13751
- }
13752
- var UiResourceResolver = class {
13753
- constructor(deps) {
13754
- this.deps = deps;
13755
- this.inFlight = /* @__PURE__ */ new Map();
13756
- }
13757
- keyOf(ref) {
13758
- return ref.kind === "mcp" ? `mcp\0${ref.serverKey}\0${ref.resourceUri}` : `plugin\0${ref.pluginType}\0${ref.resource}`;
13759
- }
13760
- fullKey(tenantId, ref) {
13761
- return `${tenantId}\0${this.keyOf(ref)}`;
13762
- }
13763
- /**
13764
- * Resolve a UI resource for a tenant.
13765
- *
13766
- * @param tenantId Tenant scope.
13767
- * @param ref The fence ref.
13768
- * @returns Public UI resource payload (no cache metadata).
13769
- */
13770
- async resolve(tenantId, ref) {
13771
- const key = this.fullKey(tenantId, ref);
13772
- const ttl = this.deps.ttlMs ?? DEFAULT_TTL_MS;
13773
- const cached = await this.deps.store.get(key);
13774
- if (cached && Date.now() - cached.fetchedAt < ttl) return publicFieldsOf(cached);
13775
- const existing = this.inFlight.get(key);
13776
- if (existing) return existing;
13777
- const promise = this.fetchAndCache(tenantId, ref, key, cached);
13778
- this.inFlight.set(key, promise);
13779
- try {
13780
- return await promise;
13781
- } finally {
13782
- this.inFlight.delete(key);
13783
- }
13784
- }
13785
- /**
13786
- * Evict the cached entry for a tenant/ref.
13787
- *
13788
- * @param tenantId Tenant scope.
13789
- * @param ref The fence ref.
13790
- */
13791
- async invalidate(tenantId, ref) {
13792
- await this.deps.store.delete(this.fullKey(tenantId, ref));
13793
- }
13794
- /**
13795
- * Evict every cached plugin UI resource for a tenant.
13796
- *
13797
- * @param tenantId Tenant whose plugin UI resources to drop.
13798
- * @remarks Called when a tenant's plugin catalog changes so an edited
13799
- * `ui/*.html` is re-fetched instead of being served from the TTL cache
13800
- * (which is keyed by ref identity, not content).
13801
- */
13802
- async invalidateTenantPlugins(tenantId) {
13803
- await this.deps.store.deleteByPrefix(`${tenantId}\0plugin\0`);
13804
- }
13805
- async fetchAndCache(tenantId, ref, key, cached) {
13806
- try {
13807
- const fresh = ref.kind === "mcp" ? await this.deps.fetchMcp(tenantId, ref.serverKey, ref.resourceUri) : await this.deps.fetchPlugin(tenantId, ref.pluginType, ref.resource);
13808
- const entry = {
13809
- ...publicFieldsOf(fresh),
13810
- hash: createHash3("sha256").update(fresh.html).digest("hex"),
13811
- fetchedAt: Date.now()
13812
- };
13813
- await this.deps.store.set(key, entry);
13814
- return publicFieldsOf(fresh);
13815
- } catch (error) {
13816
- if (cached) return { ...publicFieldsOf(cached), stale: true };
13817
- throw error;
13818
- }
13819
- }
13820
- };
13821
-
13822
- // src/services/mcp-ui/McpUiResourceCacheStore.ts
13823
- var InMemoryMcpUiResourceCacheStore = class {
13824
- constructor() {
13825
- this.map = /* @__PURE__ */ new Map();
13826
- }
13827
- async get(key) {
13828
- return this.map.get(key);
13829
- }
13830
- async set(key, entry) {
13831
- this.map.set(key, entry);
13832
- }
13833
- async delete(key) {
13834
- this.map.delete(key);
13835
- }
13836
- async deleteByPrefix(prefix) {
13837
- for (const key of this.map.keys()) {
13838
- if (key.startsWith(prefix)) this.map.delete(key);
13839
- }
13840
- }
13841
- };
13842
-
13843
- // src/services/mcp-ui/buildCsp.ts
13844
- var DEFAULT_CSP = [
13845
- "default-src 'none'",
13846
- "script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval'",
13847
- "style-src 'self' 'unsafe-inline'",
13848
- "img-src 'self' data:",
13849
- "media-src 'self' data:",
13850
- // Fonts are restricted to the document origin; declared `resourceDomains`
13851
- // are the only origins ever added (no `data:` — a base64-embedded font must
13852
- // be served from a declared origin).
13853
- "font-src 'self'",
13854
- "object-src 'none'",
13855
- "connect-src 'none'",
13856
- "frame-src 'none'",
13857
- "base-uri 'self'"
13858
- ].join("; ");
13859
- var ORIGIN_PATTERN = /^(https?|wss?):\/\/(\*\.)?[^\s;,'"*]+$/;
13860
- function declaredOrigins(domains) {
13861
- if (!Array.isArray(domains)) return [];
13862
- return domains.filter((domain) => typeof domain === "string" && ORIGIN_PATTERN.test(domain));
13863
- }
13864
- function buildCsp(csp) {
13865
- if (!csp) return DEFAULT_CSP;
13866
- const resourceOrigins = declaredOrigins(csp.resourceDomains);
13867
- const resource = resourceOrigins.join(" ");
13868
- const withResourceOrigins = (base) => resource ? `${base} ${resource}` : base;
13869
- const img = ["'self'", "data:", ...resourceOrigins].join(" ");
13870
- const connect = declaredOrigins(csp.connectDomains);
13871
- const frame = declaredOrigins(csp.frameDomains);
13872
- const baseUri = declaredOrigins(csp.baseUriDomains);
13873
- const parts = [
13874
- "default-src 'none'",
13875
- withResourceOrigins("script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval'"),
13876
- withResourceOrigins("style-src 'self' 'unsafe-inline'"),
13877
- `img-src ${img}`,
13878
- `media-src ${["'self'", "data:", ...resourceOrigins].join(" ")}`,
13879
- withResourceOrigins("font-src 'self'"),
13880
- "object-src 'none'",
13881
- `connect-src ${connect.length ? connect.join(" ") : "'none'"}`,
13882
- `frame-src ${frame.length ? frame.join(" ") : "'none'"}`,
13883
- `base-uri ${baseUri.length ? baseUri.join(" ") : "'self'"}`
13884
- ];
13885
- return parts.join("; ");
13886
- }
13887
-
13888
- // src/services/mcp-ui/sandboxPage.ts
13889
- var DEFAULT_CSP_LITERAL = JSON.stringify(buildCsp(void 0));
13890
- var SANDBOX_HTML = `<!doctype html>
13891
- <html lang="en">
13892
- <head>
13893
- <meta charset="utf-8" />
13894
- <meta name="viewport" content="width=device-width, initial-scale=1" />
13895
- <title>MCP App Sandbox</title>
13896
- <style>html, body { margin: 0; height: 100%; }</style>
13897
- </head>
13898
- <body>
13899
- <script>
13900
- (function () {
13901
- var HOST_READY = "ui/notifications/sandbox-proxy-ready";
13902
- var RESOURCE_READY = "ui/notifications/sandbox-resource-ready";
13903
- var CONTROL_PREFIX = "ui/notifications/sandbox-";
13904
- var DEFAULT_CSP = ${DEFAULT_CSP_LITERAL};
13905
-
13906
- function withCsp(html, csp) {
13907
- var policy = typeof csp === "string" && csp.length > 0 ? csp : DEFAULT_CSP;
13908
- var escaped = policy.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
13909
- var meta = '<meta http-equiv="Content-Security-Policy" content="' + escaped + '">';
13910
- // Insert at the very start (after an optional doctype) so the parser
13911
- // places the meta in the implicit head. Never search for a literal
13912
- // <head>: a resource could hide a decoy inside a comment/string and
13913
- // slip its real head past the splice.
13914
- var doctype = /^\\s*<!doctype[^>]*>/i.exec(html);
13915
- if (doctype) {
13916
- return html.slice(0, doctype[0].length) + meta + html.slice(doctype[0].length);
13917
- }
13918
- return meta + html;
13919
- }
13920
-
13921
- // Size reporter injected into every View document. The host renders the
13922
- // View inside an opaque-origin iframe it cannot measure, so auto-height
13923
- // only happens when the View posts ui/notifications/size-changed. Most
13924
- // hand-written plugin apps never do; this script makes every app report
13925
- // its own content size. It only measures and postMessages \u2014 it never
13926
- // mutates the app's DOM.
13927
- var SIZE_REPORTER = [
13928
- "(function(){",
13929
- "function send(){",
13930
- "try{",
13931
- "var d=document.documentElement,b=document.body;",
13932
- "var w=Math.ceil(Math.max(d?d.scrollWidth:0,b?b.scrollWidth:0));",
13933
- "var h=Math.ceil(Math.max(d?d.scrollHeight:0,b?b.scrollHeight:0));",
13934
- "window.parent.postMessage({jsonrpc:'2.0',method:'ui/notifications/size-changed',params:{width:w,height:h}},'*');",
13935
- "}catch(e){}",
13936
- "}",
13937
- "send();",
13938
- "window.addEventListener('load',send);",
13939
- "if(typeof ResizeObserver!=='undefined'){",
13940
- "var ro=new ResizeObserver(send);",
13941
- "ro.observe(document.documentElement);",
13942
- "if(document.body)ro.observe(document.body);",
13943
- "}else{window.addEventListener('resize',send);}",
13944
- "})();"
13945
- ].join("");
13946
-
13947
- function withSizeReporter(html) {
13948
- // Split the closing tag so this template literal never contains a
13949
- // literal script terminator that would end the sandbox page's own
13950
- // script block during HTML parsing.
13951
- var tag = "<scr" + "ipt>" + SIZE_REPORTER + "<" + "/scr" + "ipt>";
13952
- var lower = html.toLowerCase();
13953
- var bodyEnd = lower.lastIndexOf("</body>");
13954
- if (bodyEnd >= 0) return html.slice(0, bodyEnd) + tag + html.slice(bodyEnd);
13955
- return html + tag;
13956
- }
13957
-
13958
- var inner = null;
13959
-
13960
- window.parent.postMessage({ jsonrpc: "2.0", method: HOST_READY, params: {} }, "*");
13961
-
13962
- window.addEventListener("message", function (event) {
13963
- if (event.source !== window.parent) return;
13964
- var data = event.data;
13965
- if (!data || typeof data !== "object") return;
13966
-
13967
- if (data.method === RESOURCE_READY) {
13968
- var params = data.params || {};
13969
- if (inner && inner.parentNode) inner.parentNode.removeChild(inner);
13970
- inner = document.createElement("iframe");
13971
- inner.setAttribute("sandbox", params.sandbox || "allow-scripts");
13972
- inner.setAttribute("srcdoc", withCsp(withSizeReporter(String(params.html || "")), params.csp));
13973
- inner.style.cssText = "width:100%;height:100%;border:0;display:block";
13974
- document.body.appendChild(inner);
13975
- return;
13976
- }
13977
-
13978
- if (typeof data.method === "string" && data.method.indexOf(CONTROL_PREFIX) === 0) return;
13979
- if (inner && inner.contentWindow) inner.contentWindow.postMessage(data, "*");
13980
- });
13981
-
13982
- window.addEventListener("message", function (event) {
13983
- if (inner && event.source === inner.contentWindow) {
13984
- var data = event.data;
13985
- if (data && typeof data === "object" && typeof data.method === "string"
13986
- && data.method.indexOf(CONTROL_PREFIX) === 0) return;
13987
- window.parent.postMessage(event.data, "*");
13988
- }
13989
- });
13990
- })();
13991
- </script>
13992
- </body>
13993
- </html>
13994
- `;
13995
-
13996
- // src/routes/mcp-apps.ts
13997
- var SANDBOX_HTML_CONTENT_TYPE = "text/html; charset=utf-8";
13998
- var PluginMethodNotSupportedError = class extends Error {
13999
- /**
14000
- * @param method - Unsupported JSON-RPC method.
14001
- */
14002
- constructor(method) {
14003
- super(`plugin backend does not support ${method}`);
14004
- this.name = "PluginMethodNotSupportedError";
14005
- }
14006
- };
14007
- var McpAppScopeError = class extends Error {
14008
- /**
14009
- * @param status - HTTP status to return.
14010
- * @param code - Stable machine-readable denial code.
14011
- */
14012
- constructor(status, code) {
14013
- super(code);
14014
- this.status = status;
14015
- this.code = code;
14016
- this.name = "McpAppScopeError";
14017
- }
14018
- };
14019
- function denyScope(status, code, detail) {
14020
- console.warn(JSON.stringify({ event: "mcp-apps:scope-denied", ...detail, code }));
14021
- return new McpAppScopeError(status, code);
14022
- }
14023
- var ALLOWED_METHODS = /* @__PURE__ */ new Set(["tools/call", "tools/list", "resources/read"]);
14024
- function asRecord(value) {
14025
- return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
14026
- }
14027
- function makeMcpAppHandlers(deps) {
14028
- return {
14029
- /**
14030
- * Resolve the `mcp_app` UI resource for a parsed ref.
14031
- *
14032
- * @param tenantId Tenant scope.
14033
- * @param rawRef Untrusted ref payload.
14034
- * @returns The resource payload plus a ready-to-use `cspPolicy` string
14035
- * ({@link buildCsp}, always non-empty), or a 400/502 error envelope.
14036
- */
14037
- async resource(tenantId, rawRef) {
14038
- const ref = parseMcpUiRef(rawRef);
14039
- if (!ref) return { status: 400, body: { error: "INVALID_REF" } };
14040
- if (ref.kind === "plugin" && ref.pluginType === "") {
14041
- return { status: 400, body: { error: "INVALID_REF" } };
14042
- }
14043
- try {
14044
- const payload = await deps.resolveUiResource(tenantId, ref);
14045
- return { status: 200, body: { ...payload, cspPolicy: buildCsp(payload.csp) } };
14046
- } catch (error) {
14047
- console.warn(JSON.stringify({
14048
- event: "mcp-apps:resource-failed",
14049
- tenantId,
14050
- kind: ref.kind,
14051
- error: error instanceof Error ? error.message : String(error)
14052
- }));
14053
- return { status: 502, body: { error: "RESOURCE_UNAVAILABLE" } };
14054
- }
14055
- },
14056
- /**
14057
- * Proxy an allow-listed JSON-RPC method for a parsed ref.
14058
- *
14059
- * @param tenantId Tenant scope.
14060
- * @param rawRef Untrusted ref payload.
14061
- * @param method JSON-RPC method name.
14062
- * @param params JSON-RPC params.
14063
- * @param context Request-scoped run context forwarded to `tools/call`.
14064
- * @returns The backend result, or a 400/403/502 error envelope.
14065
- */
14066
- async rpc(tenantId, rawRef, method, params, context) {
14067
- const ref = parseMcpUiRef(rawRef);
14068
- if (!ref) return { status: 400, body: { error: "INVALID_REF" } };
14069
- if (!ALLOWED_METHODS.has(method)) return { status: 403, body: { error: "METHOD_NOT_ALLOWED" } };
14070
- try {
14071
- if (method === "tools/call") {
14072
- const name = typeof params.name === "string" ? params.name : "";
14073
- if (name === "") return { status: 400, body: { error: "INVALID_PARAMS" } };
14074
- if ("pluginType" in ref && ref.pluginType === "") {
14075
- return { status: 400, body: { error: "INVALID_REF" } };
14076
- }
14077
- return {
14078
- status: 200,
14079
- body: await deps.callTool(tenantId, ref, name, asRecord(params.arguments) ?? {}, context)
14080
- };
14081
- }
14082
- if (method === "resources/read") {
14083
- const uri = typeof params.uri === "string" ? params.uri : "";
14084
- if (uri === "") return { status: 400, body: { error: "INVALID_PARAMS" } };
14085
- return { status: 200, body: await deps.readResource(tenantId, ref, uri) };
14086
- }
14087
- return { status: 200, body: { tools: await deps.listTools(tenantId, ref) } };
14088
- } catch (error) {
14089
- if (error instanceof McpAppScopeError) {
14090
- return { status: error.status, body: { error: error.code } };
14091
- }
14092
- if (error instanceof PluginToolScopeError) {
14093
- return { status: 403, body: { error: "PLUGIN_TOOL_SCOPE" } };
14094
- }
14095
- if (error instanceof PluginMethodNotSupportedError) {
14096
- return { status: 403, body: { error: "PLUGIN_METHOD_UNSUPPORTED" } };
14097
- }
14098
- const context2 = { tenantId, kind: ref.kind, method };
14099
- if (method === "resources/read") context2.uri = typeof params.uri === "string" ? params.uri : "";
14100
- if (method === "tools/call") context2.name = typeof params.name === "string" ? params.name : "";
14101
- console.warn(JSON.stringify({
14102
- event: "mcp-apps:rpc-failed",
14103
- ...context2,
14104
- error: error instanceof Error ? error.message : String(error)
14105
- }));
14106
- return { status: 502, body: { error: "RPC_FAILED" } };
14107
- }
14108
- }
14109
- };
14110
- }
14111
- async function fetchPluginUiResource(backend, tenantId, pluginType, resource) {
14112
- const plugin = await backend.resolvePlugin(tenantId, pluginType);
14113
- if (!plugin) throw new Error(`plugin "${pluginType}" not found`);
14114
- const tool = (plugin.meta.tools ?? []).find((t2) => t2.ui?.resource === resource);
14115
- if (!tool?.ui) throw new Error(`plugin "${pluginType}" has no tool declaring ui resource "${resource}"`);
14116
- const inline = plugin.meta.uiResources?.[resource];
14117
- if (inline) {
14118
- return {
14119
- mimeType: inline.mimeType ?? "text/html;profile=mcp-app",
14120
- html: inline.html,
14121
- csp: inline.csp ?? tool.ui.csp,
14122
- permissions: tool.ui.permissions,
14123
- prefersBorder: tool.ui.prefersBorder
14124
- };
14125
- }
14126
- const html = await backend.catalog.readPluginFile(tenantId, pluginType, resource);
14127
- return {
14128
- mimeType: "text/html",
14129
- html,
14130
- csp: tool.ui.csp,
14131
- permissions: tool.ui.permissions,
14132
- prefersBorder: tool.ui.prefersBorder
14133
- };
14134
- }
14135
- async function callPluginTool(backend, tenantId, ref, name, args, context, deps) {
14136
- const scope = ref.scope ? (deps?.verifyScope ?? verifyMcpUiScope)(ref.scope) : null;
14137
- if (ref.scope && !scope) {
14138
- throw denyScope(403, "SCOPE_INVALID", {
14139
- tenantId,
14140
- pluginType: ref.pluginType,
14141
- tool: name
14142
- });
14143
- }
14144
- if (scope) {
14145
- const mismatched = scope.tid !== tenantId || scope.plugin !== ref.pluginType || scope.resource !== ref.resource;
14146
- if (mismatched) {
14147
- throw denyScope(403, "SCOPE_MISMATCH", {
14148
- tenantId,
14149
- pluginType: ref.pluginType,
14150
- tool: name,
14151
- jti: scope.jti,
14152
- threadId: scope.thid
14153
- });
14154
- }
14155
- }
14156
- const manifest = await backend.catalog.getValidatedManifest(tenantId, ref.pluginType);
14157
- const rawConnectionKey = args.connectionKey;
14158
- const explicit = typeof rawConnectionKey === "string" ? rawConnectionKey : void 0;
14159
- const scoped = scope?.ck;
14160
- const connectionRelevant = Boolean(manifest?.connection) || scoped !== void 0;
14161
- if (connectionRelevant && (explicit !== void 0 ? explicit !== scoped : rawConnectionKey !== void 0)) {
14162
- throw denyScope(403, "CONNECTION_NOT_ALLOWED", {
14163
- tenantId,
14164
- pluginType: ref.pluginType,
14165
- tool: name,
14166
- jti: scope?.jti,
14167
- threadId: scope?.thid
14168
- });
14169
- }
14170
- let connection;
14171
- let connectionKey;
14172
- if (scoped !== void 0) {
14173
- const resolveConnections = deps?.resolveConnections ?? resolvePluginConnections;
14174
- const resolved = await resolveConnections(
14175
- ref.pluginType,
14176
- { connections: [scoped] },
14177
- { tenantId }
14178
- );
14179
- if (resolved.length === 0) {
14180
- throw denyScope(403, "CONNECTION_NOT_ALLOWED", {
14181
- tenantId,
14182
- pluginType: ref.pluginType,
14183
- tool: name,
14184
- jti: scope?.jti,
14185
- threadId: scope?.thid
14186
- });
14187
- }
14188
- connection = resolved[0].config;
14189
- connectionKey = resolved[0].key;
14190
- }
14191
- if (manifest?.connection && !connectionKey) {
14192
- throw denyScope(409, "CONNECTION_REQUIRED", {
14193
- tenantId,
14194
- pluginType: ref.pluginType,
14195
- tool: name,
14196
- jti: scope?.jti,
14197
- threadId: scope?.thid
14198
- });
14199
- }
14200
- const identity = scope ? {
14201
- workspaceId: scope.wid,
14202
- projectId: scope.pid,
14203
- threadId: scope.thid,
14204
- assistantId: scope.aid
14205
- } : {
14206
- workspaceId: context?.workspaceId,
14207
- projectId: context?.projectId
14208
- };
14209
- return invokePluginTool(backend, tenantId, ref.pluginType, name, args, {
14210
- ...identity,
14211
- ...connection === void 0 ? {} : { connection }
14212
- });
14213
- }
14214
- function createDefaultPluginBackend() {
14215
- return {
14216
- resolvePlugin: (tenantId, type) => resolveTenantPluginByType(tenantId, type),
14217
- catalog: {
14218
- readPluginFile: (tenantId, pluginType, relPath) => getSandboxPluginCatalog2().readPluginFile(tenantId, pluginType, relPath),
14219
- getValidatedManifest: (tenantId, pluginType) => getSandboxPluginCatalog2().getValidatedManifest(tenantId, pluginType),
14220
- getExecutor: () => getSandboxPluginCatalog2().getExecutor()
14221
- }
14222
- };
14223
- }
14224
- var uiResourceResolverSingleton;
14225
- function getMcpUiResourceResolver() {
14226
- return uiResourceResolverSingleton;
14227
- }
14228
- function resolveMcpAppDeps(pluginBackend = createDefaultPluginBackend()) {
14229
- const uiResourceResolver = new UiResourceResolver({
14230
- store: new InMemoryMcpUiResourceCacheStore(),
14231
- fetchMcp: (tenantId, serverKey, resourceUri) => mcpManager2.readUiResource(tenantId, serverKey, resourceUri),
14232
- fetchPlugin: (tenantId, pluginType, resource) => fetchPluginUiResource(pluginBackend, tenantId, pluginType, resource)
14233
- });
14234
- uiResourceResolverSingleton = uiResourceResolver;
14235
- return {
14236
- resolveUiResource: (tenantId, ref) => uiResourceResolver.resolve(tenantId, ref),
14237
- callTool: (tenantId, ref, name, args, context) => ref.kind === "mcp" ? mcpManager2.callServerTool(tenantId, ref.serverKey, name, args) : callPluginTool(pluginBackend, tenantId, ref, name, args, context),
14238
- // Plugin refs reach these only after `tools/call`; the handler treats the
14239
- // rejection as an unsupported method (403). The branches are live because
14240
- // the pure handler deliberately delegates method policy to the deps.
14241
- readResource: (tenantId, ref, uri) => ref.kind === "mcp" ? mcpManager2.readServerResource(tenantId, ref.serverKey, uri) : Promise.reject(new PluginMethodNotSupportedError("resources/read")),
14242
- listTools: (tenantId, ref) => ref.kind === "mcp" ? mcpManager2.getAvailableTools(tenantId, ref.serverKey) : Promise.reject(new PluginMethodNotSupportedError("tools/list"))
14243
- };
14244
- }
14245
- function firstHeader(request, name) {
14246
- const header2 = request.headers[name];
14247
- return Array.isArray(header2) ? header2[0] : header2;
14248
- }
14249
- function tenantOf(request) {
14250
- const user = request.user;
14251
- return user?.tenantId ?? firstHeader(request, "x-tenant-id") ?? "default";
14252
- }
14253
- function runContextOf(request) {
14254
- return {
14255
- tenantId: tenantOf(request),
14256
- workspaceId: firstHeader(request, "x-workspace-id"),
14257
- projectId: firstHeader(request, "x-project-id")
14258
- };
14259
- }
14260
- function registerMcpAppRoutes(fastify2, deps = resolveMcpAppDeps()) {
14261
- const handlers = makeMcpAppHandlers(deps);
14262
- fastify2.get("/mcp-apps/sandbox.html", async (_request, reply) => {
14263
- return reply.header("content-type", SANDBOX_HTML_CONTENT_TYPE).header("x-content-type-options", "nosniff").header("cache-control", "no-store").send(SANDBOX_HTML);
14264
- });
14265
- fastify2.post("/api/mcp-apps/resource", async (request, reply) => {
14266
- const body = asRecord(request.body) ?? {};
14267
- const result = await handlers.resource(tenantOf(request), body.ref);
14268
- return reply.code(result.status).send(result.body);
14269
- });
14270
- fastify2.post("/api/mcp-apps/rpc", async (request, reply) => {
14271
- const body = asRecord(request.body) ?? {};
14272
- const params = asRecord(body.params) ?? {};
14273
- const context = runContextOf(request);
14274
- const result = await handlers.rpc(
14275
- context.tenantId,
14276
- body.ref,
14277
- String(body.method ?? ""),
14278
- params,
14279
- context
14280
- );
14281
- return reply.code(result.status).send(result.body);
14282
- });
14283
- }
14284
-
14285
13731
  // src/controllers/eval.ts
14286
13732
  import { getStoreLattice as getStoreLattice21, hasModelLatticeForTenant as hasModelLatticeForTenant2, modelLatticeManager as modelLatticeManager2 } from "@axiom-lattice/core";
14287
13733
  import { v4 as uuidv43 } from "uuid";
@@ -15431,6 +14877,16 @@ var AuthController = class {
15431
14877
  }
15432
14878
  async login(request, reply) {
15433
14879
  const { email, password } = request.body;
14880
+ const rateLimit = await getRateLimitService().consume("auth.login", {
14881
+ ip: request.ip
14882
+ });
14883
+ if (!rateLimit.allowed) {
14884
+ return reply.header("Retry-After", String(rateLimit.retryAfterSeconds)).status(429).send({
14885
+ success: false,
14886
+ error: "RATE_LIMITED",
14887
+ retryAfterSeconds: rateLimit.retryAfterSeconds
14888
+ });
14889
+ }
15434
14890
  try {
15435
14891
  const user = await this.userStore.getUserByEmail(email);
15436
14892
  if (!user) {
@@ -15799,7 +15255,7 @@ function isStaleConsoleSessionCredential(authHeader) {
15799
15255
  function bypassesConsoleAuth(request) {
15800
15256
  const path5 = request.url.split("?")[0];
15801
15257
  const method = request.method;
15802
- if (method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/bootstrap$/.test(path5) || (method === "GET" || method === "POST") && /^\/api\/web-apps\/[^/]+\/runtime\/threads$/.test(path5) || (method === "PATCH" || method === "DELETE") && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/messages$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/files\/(viewfile|downloadfile)$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/api\/assistants\/[^/]+\/threads\/[^/]+\/sandbox\/(viewfile|downloadfile)$/.test(path5) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/(messages\/stream|abort|attachments)$/.test(path5) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/interrupts\/[^/]+\/resume$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime(?:\/api)?\/assistants\/[^/]+\/threads\/[^/]+\/runs$/.test(path5) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime(?:\/api)?\/assistants\/[^/]+\/threads\/[^/]+\/runs$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime(?:\/api)?\/assistants\/[^/]+\/threads\/[^/]+\/runs\/[^/]+$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime(?:\/api)?\/assistants\/[^/]+\/threads\/[^/]+\/runs\/[^/]+\/join$/.test(path5) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime(?:\/api)?\/assistants\/[^/]+\/threads\/[^/]+\/runs\/[^/]+\/cancel$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/chat$/.test(path5) || method === "GET" && /^\/embed\/[^/]+$/.test(path5) || method === "GET" && path5 === "/mcp-apps/sandbox.html" || (method === "POST" || method === "DELETE") && path5 === "/open/mcp" || (method === "POST" || method === "GET") && (path5 === "/mcp" || path5 === "/mcp/") || method === "POST" && path5 === "/open/session" || (method === "GET" || method === "POST") && path5.startsWith("/open/sandbox/files/")) return true;
15258
+ if (method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/bootstrap$/.test(path5) || (method === "GET" || method === "POST") && /^\/api\/web-apps\/[^/]+\/runtime\/threads$/.test(path5) || (method === "PATCH" || method === "DELETE") && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/messages$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/files\/(viewfile|downloadfile)$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/api\/assistants\/[^/]+\/threads\/[^/]+\/sandbox\/(viewfile|downloadfile)$/.test(path5) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/(messages\/stream|abort|attachments)$/.test(path5) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/interrupts\/[^/]+\/resume$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime(?:\/api)?\/assistants\/[^/]+\/threads\/[^/]+\/runs$/.test(path5) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime(?:\/api)?\/assistants\/[^/]+\/threads\/[^/]+\/runs$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime(?:\/api)?\/assistants\/[^/]+\/threads\/[^/]+\/runs\/[^/]+$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime(?:\/api)?\/assistants\/[^/]+\/threads\/[^/]+\/runs\/[^/]+\/join$/.test(path5) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime(?:\/api)?\/assistants\/[^/]+\/threads\/[^/]+\/runs\/[^/]+\/cancel$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/chat$/.test(path5) || method === "GET" && /^\/embed\/[^/]+$/.test(path5) || method === "GET" && path5 === "/mcp-apps/sandbox.html" || method === "GET" && /^\/api\/mcp-app-shares\/[^/]+\/bootstrap$/.test(path5) || method === "POST" && /^\/api\/mcp-app-shares\/[^/]+\/(resource|rpc|unlock)$/.test(path5) || (method === "POST" || method === "DELETE") && path5 === "/open/mcp" || (method === "POST" || method === "GET") && (path5 === "/mcp" || path5 === "/mcp/") || method === "POST" && path5 === "/open/session" || (method === "GET" || method === "POST") && path5.startsWith("/open/sandbox/files/")) return true;
15803
15259
  if (request.method === "GET" && (/^\/api\/a2a\/agents\/[^/]+\/\.well-known\/agent-card\.json$/.test(path5) || /^\/a2a\/(?:v1\/)?[^/]+\/\.well-known\/agent-card\.json$/.test(path5))) {
15804
15260
  return true;
15805
15261
  }
@@ -17565,6 +17021,7 @@ import {
17565
17021
  ProjectTaskOwnerPolicyError as ProjectTaskOwnerPolicyError2,
17566
17022
  projectMutationMutex as projectMutationMutex2,
17567
17023
  projectTaskAdmissionNotifier,
17024
+ projectRoomMessageNotifier,
17568
17025
  taskLifecycleNotifier as taskLifecycleNotifier2
17569
17026
  } from "@axiom-lattice/core";
17570
17027
 
@@ -17903,7 +17360,7 @@ function snapshotEnsureInput(input) {
17903
17360
  }
17904
17361
 
17905
17362
  // src/services/tasks/TaskCommandService.ts
17906
- import { createHash as createHash4 } from "crypto";
17363
+ import { createHash as createHash3 } from "crypto";
17907
17364
 
17908
17365
  // src/services/collaboration/ProjectTaskRunService.ts
17909
17366
  import { randomUUID as randomUUID21 } from "crypto";
@@ -19040,7 +18497,7 @@ var _TaskCommandService = class _TaskCommandService {
19040
18497
  threadId,
19041
18498
  summary: "User comment",
19042
18499
  detail: { markdown: text, type: "user_comment" },
19043
- fallbackEventKey: `task-comment:${task.id}:${createHash4("sha256").update(text).digest("hex")}`
18500
+ fallbackEventKey: `task-comment:${task.id}:${createHash3("sha256").update(text).digest("hex")}`
19044
18501
  });
19045
18502
  const agent = this.deps.agents.getAgent(this.agentScope(task, threadId));
19046
18503
  await agent.addMessage({ input: { message: text } });
@@ -20013,7 +19470,7 @@ import { createHmac as createHmac3 } from "crypto";
20013
19470
  import { z as z5, ZodError as ZodError2 } from "zod";
20014
19471
 
20015
19472
  // src/services/agent-web-app/AgentWebAppRuntimeService.ts
20016
- import { createHash as createHash5, randomUUID as randomUUID22 } from "crypto";
19473
+ import { createHash as createHash4, randomUUID as randomUUID22 } from "crypto";
20017
19474
  import { MessageChunkTypes as MessageChunkTypes3, parseAgentWebAppGenUIBlock, buildAffinityMissChunk as buildAffinityMissChunk2 } from "@axiom-lattice/protocols";
20018
19475
  import { getReplicaId as getReplicaId7, getThreadRunOwner as getThreadRunOwner2, normalizeAgentInterrupts as normalizeAgentInterrupts2 } from "@axiom-lattice/core";
20019
19476
  function isRecord9(value) {
@@ -20308,8 +19765,8 @@ ${formatFileRefsSection(refs)}` : input.content;
20308
19765
  const runtime = await this.resolveOwnedRuntime(webAppId, userId, threadId, selection);
20309
19766
  this.requireNamedFeature(runtime.webApp.features.attachments, "Attachments are disabled");
20310
19767
  if (!this.deps.saveProjectFile || !this.deps.attachmentRefs) this.fail("INTERNAL_ERROR", 500, "Attachment service is unavailable");
20311
- const userDigest = createHash5("sha256").update(userId, "utf8").digest("hex");
20312
- const contentDigest = createHash5("sha256").update(file.bytes).digest("hex");
19768
+ const userDigest = createHash4("sha256").update(userId, "utf8").digest("hex");
19769
+ const contentDigest = createHash4("sha256").update(file.bytes).digest("hex");
20313
19770
  const displayName = file.name;
20314
19771
  const physicalName = `${randomUUID22()}-${sanitizePhysicalFilename(file.name)}`;
20315
19772
  const saved = await this.deps.saveProjectFile({
@@ -20517,7 +19974,7 @@ function implicitThreadId(runtime, userId) {
20517
19974
  userId,
20518
19975
  runtime.project.id
20519
19976
  ]);
20520
- const bytes = createHash5("sha256").update(canonicalTuple, "utf8").digest().subarray(0, 16);
19977
+ const bytes = createHash4("sha256").update(canonicalTuple, "utf8").digest().subarray(0, 16);
20521
19978
  bytes[6] = bytes[6] & 15 | 128;
20522
19979
  bytes[8] = bytes[8] & 63 | 128;
20523
19980
  const hex = bytes.toString("hex");
@@ -21331,17 +20788,19 @@ var CSS_CONTENT_TYPE = "text/css; charset=utf-8";
21331
20788
  var EXACT_ASSETS = {
21332
20789
  "agent-chat-loader.js": { contentType: JS_CONTENT_TYPE },
21333
20790
  "embed-page.js": { contentType: JS_CONTENT_TYPE },
21334
- "embed-page.css": { contentType: CSS_CONTENT_TYPE }
20791
+ "embed-page.css": { contentType: CSS_CONTENT_TYPE },
20792
+ "mcp-app-page.js": { contentType: JS_CONTENT_TYPE },
20793
+ "mcp-app-page.css": { contentType: CSS_CONTENT_TYPE }
21335
20794
  };
21336
- var HASHED_CHUNK_PATTERN = /^embed-page-[A-Za-z0-9._-]+\.(js|css)$/;
21337
- var CHUNK_CSS_PATTERN = /^embed-page-[A-Za-z0-9._-]+\.css$/;
20795
+ var HASHED_CHUNK_PATTERN = /^(embed-page|mcp-app-page)-[A-Za-z0-9._-]+\.(js|css)$/;
20796
+ var CHUNK_CSS_PATTERN = /^(embed-page|mcp-app-page)-[A-Za-z0-9._-]+\.css$/;
21338
20797
  function resolveAsset(asset) {
21339
20798
  if (asset.includes("..")) return null;
21340
20799
  const exact2 = EXACT_ASSETS[asset];
21341
20800
  if (exact2 !== void 0) return { contentType: exact2.contentType, immutable: false };
21342
20801
  const hashed = HASHED_CHUNK_PATTERN.exec(asset);
21343
20802
  if (hashed) {
21344
- return { contentType: hashed[1] === "css" ? CSS_CONTENT_TYPE : JS_CONTENT_TYPE, immutable: true };
20803
+ return { contentType: hashed[2] === "css" ? CSS_CONTENT_TYPE : JS_CONTENT_TYPE, immutable: true };
21345
20804
  }
21346
20805
  return null;
21347
20806
  }
@@ -21446,7 +20905,7 @@ function registerAgentWebAppEmbedRoutes(app2, deps = {}) {
21446
20905
  }
21447
20906
 
21448
20907
  // src/services/agent-web-app/AgentWebAppAttachmentRef.ts
21449
- import { createCipheriv, createDecipheriv, createHash as createHash6, randomBytes as randomBytes2 } from "crypto";
20908
+ import { createCipheriv, createDecipheriv, createHash as createHash5, randomBytes as randomBytes2 } from "crypto";
21450
20909
  var TTL_MS = 15 * 6e4;
21451
20910
  function resolveAgentWebAppAttachmentSecret(consoleSecret) {
21452
20911
  return process.env.WEB_APP_ATTACHMENT_SECRET || process.env.AUTH_TOKEN_SECRET || process.env.JWT_SECRET || consoleSecret;
@@ -21455,7 +20914,7 @@ var AgentWebAppAttachmentRefService = class {
21455
20914
  constructor(secret, now = Date.now) {
21456
20915
  this.now = now;
21457
20916
  if (!secret) throw new Error("Attachment signing secret is required");
21458
- this.key = createHash6("sha256").update(secret, "utf8").digest();
20917
+ this.key = createHash5("sha256").update(secret, "utf8").digest();
21459
20918
  }
21460
20919
  sign(input) {
21461
20920
  const payload = {
@@ -21517,7 +20976,7 @@ function decodeCanonical(value, expectedBytes) {
21517
20976
  return decoded;
21518
20977
  }
21519
20978
  function digestUser(userId) {
21520
- return createHash6("sha256").update(userId, "utf8").digest("hex");
20979
+ return createHash5("sha256").update(userId, "utf8").digest("hex");
21521
20980
  }
21522
20981
  function isAttachmentPayload(value) {
21523
20982
  if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
@@ -24091,7 +23550,7 @@ function virtualPublicProjectBot(project, room, agent, mentionName, now) {
24091
23550
  }
24092
23551
 
24093
23552
  // src/services/collaboration/RoomMessageService.ts
24094
- import { createHash as createHash7, randomUUID as randomUUID27 } from "crypto";
23553
+ import { createHash as createHash6, randomUUID as randomUUID27 } from "crypto";
24095
23554
 
24096
23555
  // src/services/collaboration/ProjectBotMembershipSnapshot.ts
24097
23556
  import { snapshotExactRecord as snapshotExactRecord5 } from "@axiom-lattice/protocols";
@@ -24394,7 +23853,7 @@ var RoomMessageService = class {
24394
23853
  let idempotencyKey;
24395
23854
  if (value.requestIdempotencyKey !== void 0) {
24396
23855
  if (typeof value.requestIdempotencyKey !== "string" || !/^[\x21-\x7e]{1,200}$/.test(value.requestIdempotencyKey.trim())) throw new RoomMessageServiceError("INVALID_MESSAGE", 400, "Invalid idempotency key");
24397
- idempotencyKey = `room-human:${actor3.userId}:${createHash7("sha256").update(value.requestIdempotencyKey.trim(), "utf8").digest("hex")}`;
23856
+ idempotencyKey = `room-human:${actor3.userId}:${createHash6("sha256").update(value.requestIdempotencyKey.trim(), "utf8").digest("hex")}`;
24398
23857
  }
24399
23858
  return { text, mentions, botIds, ...value.replyToMessageId === void 0 ? {} : { replyToMessageId: value.replyToMessageId }, ...idempotencyKey === void 0 ? {} : { idempotencyKey } };
24400
23859
  }
@@ -24451,7 +23910,7 @@ function cloneRoomMessage(message) {
24451
23910
  };
24452
23911
  }
24453
23912
  function fingerprintRequest(input) {
24454
- return createHash7("sha256").update(JSON.stringify({
23913
+ return createHash6("sha256").update(JSON.stringify({
24455
23914
  text: input.text,
24456
23915
  mentions: input.mentions,
24457
23916
  replyToMessageId: input.replyToMessageId ?? null
@@ -26515,7 +25974,7 @@ var TaskInterruptCardProjector = class {
26515
25974
  };
26516
25975
 
26517
25976
  // src/services/collaboration/ProjectTaskObserver.ts
26518
- import { createHash as createHash8 } from "crypto";
25977
+ import { createHash as createHash7 } from "crypto";
26519
25978
  import {
26520
25979
  createTaskRunBridge as createTaskRunBridge3,
26521
25980
  probeThreadRunOwner as defaultProbeThreadRunOwner
@@ -27086,7 +26545,7 @@ var ProjectTaskObserver = class {
27086
26545
  action: "activity",
27087
26546
  summary: "Project task recovery warning",
27088
26547
  detail: { type: "project_task_recovery_warning", phase, message },
27089
- eventKey: `project-task-recovery-warning:${task.id}:${phase}:${createHash8("sha256").update(message).digest("hex")}`
26548
+ eventKey: `project-task-recovery-warning:${task.id}:${phase}:${createHash7("sha256").update(message).digest("hex")}`
27090
26549
  });
27091
26550
  }
27092
26551
  async safeWarning(task, phase, error) {
@@ -27329,7 +26788,7 @@ var ProjectTaskObserver = class {
27329
26788
  }
27330
26789
  }
27331
26790
  async persistOverflowWarning(event) {
27332
- const scopeDigest = createHash8("sha256").update(JSON.stringify([event.tenantId, event.workspaceId, event.projectId])).digest("hex");
26791
+ const scopeDigest = createHash7("sha256").update(JSON.stringify([event.tenantId, event.workspaceId, event.projectId])).digest("hex");
27333
26792
  try {
27334
26793
  await this.deps.workItems.createIfAbsentByEventKey({
27335
26794
  tenantId: event.tenantId,
@@ -27434,7 +26893,7 @@ function combineSignals(left, right) {
27434
26893
  }
27435
26894
 
27436
26895
  // src/services/collaboration/RoomProjectionService.ts
27437
- import { createHash as createHash9 } from "crypto";
26896
+ import { createHash as createHash8 } from "crypto";
27438
26897
  import {
27439
26898
  PROJECT_ROOM_TASK_DELEGATED_LABEL,
27440
26899
  PROJECT_ROOM_TASK_DELEGATED_SEPARATOR,
@@ -27655,7 +27114,7 @@ function safeRepairIdentity(value, scope) {
27655
27114
  return taskId && eventKey && tenantId === scope.tenantId && workspaceId === scope.workspaceId && projectId === scope.projectId ? { taskId, eventKey } : void 0;
27656
27115
  }
27657
27116
  function tupleKey(prefix, values) {
27658
- const digest = createHash9("sha256").update(JSON.stringify(values)).digest("hex");
27117
+ const digest = createHash8("sha256").update(JSON.stringify(values)).digest("hex");
27659
27118
  return `${prefix}:${digest}`;
27660
27119
  }
27661
27120
  function parseProjectionInput(taskValue, itemValue) {
@@ -28234,7 +27693,7 @@ function snapshotJson(value, ancestors = /* @__PURE__ */ new Set()) {
28234
27693
  }
28235
27694
 
28236
27695
  // src/services/collaboration/ProjectRoomRealtimePublisher.ts
28237
- import { createHash as createHash10 } from "crypto";
27696
+ import { createHash as createHash9 } from "crypto";
28238
27697
  import {
28239
27698
  projectRoomUserEventScope,
28240
27699
  snapshotExactRecord as snapshotExactRecord11,
@@ -28356,7 +27815,7 @@ var BrokerProjectRoomRealtimePublisher = class {
28356
27815
  try {
28357
27816
  event = build();
28358
27817
  if (!event) throw new Error("Invalid Project Room realtime projection");
28359
- const dedupeKey = createHash10("sha256").update(JSON.stringify([type, event.scope.tenantId, event.scope.projectId, event.scope.roomId, event.sourceKey])).digest("hex");
27818
+ const dedupeKey = createHash9("sha256").update(JSON.stringify([type, event.scope.tenantId, event.scope.projectId, event.scope.roomId, event.sourceKey])).digest("hex");
28360
27819
  if (this.sourceKeys.has(dedupeKey)) return;
28361
27820
  this.deps.broker.publish(event.scope, event.draft, event.sourceKey);
28362
27821
  this.sourceKeys.set(dedupeKey, true);
@@ -28601,12 +28060,21 @@ function createProjectRoomRealtimeRuntime(deps) {
28601
28060
  shutdownTimeoutMs: deps.shutdownTimeoutMs
28602
28061
  });
28603
28062
  }
28063
+ var PUSH_DEDUPE_LIMIT = 2e3;
28604
28064
  function withPushNotifier(target, notifier) {
28065
+ const pushedMessageIds = /* @__PURE__ */ new Set();
28605
28066
  return new Proxy(target, {
28606
28067
  get(inner, prop, receiver) {
28607
28068
  if (prop === "messageCreated") {
28608
28069
  return (message) => {
28609
28070
  inner.messageCreated(message);
28071
+ if (pushedMessageIds.has(message.id)) return;
28072
+ pushedMessageIds.add(message.id);
28073
+ while (pushedMessageIds.size > PUSH_DEDUPE_LIMIT) {
28074
+ const oldest = pushedMessageIds.values().next().value;
28075
+ if (oldest === void 0) break;
28076
+ pushedMessageIds.delete(oldest);
28077
+ }
28610
28078
  void notifier.notifyMessage(message).catch(() => void 0);
28611
28079
  };
28612
28080
  }
@@ -29521,7 +28989,14 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
29521
28989
  log: realtimeLog
29522
28990
  }) : void 0;
29523
28991
  if (projectRoomRealtimeRuntime) {
29524
- app2.addHook("onClose", async () => projectRoomRealtimeRuntime?.close());
28992
+ const runtime = projectRoomRealtimeRuntime;
28993
+ const unsubscribeProjectRoomMessages = projectRoomMessageNotifier.subscribe((message) => {
28994
+ runtime.publisher.messageCreated(message);
28995
+ });
28996
+ app2.addHook("onClose", async () => {
28997
+ unsubscribeProjectRoomMessages();
28998
+ await runtime.close();
28999
+ });
29525
29000
  const workspaceRoomEventsService = new WorkspaceRoomEventsService({
29526
29001
  broker: projectRoomRealtimeRuntime.broker,
29527
29002
  listMemberRooms: createWorkspaceMemberRoomLister({
@@ -31792,50 +31267,6 @@ var ChannelAdapterRegistry = class {
31792
31267
  }
31793
31268
  };
31794
31269
 
31795
- // src/router/middlewares/channelSharedState.ts
31796
- import { createClient as createClient2 } from "redis";
31797
- var clientPromise;
31798
- async function redis() {
31799
- const url = process.env.REDIS_URL?.trim();
31800
- if (!url) return void 0;
31801
- if (!clientPromise) {
31802
- clientPromise = (async () => {
31803
- const client = createClient2({ url });
31804
- client.on("error", () => void 0);
31805
- await client.connect();
31806
- return client;
31807
- })();
31808
- }
31809
- try {
31810
- const client = await clientPromise;
31811
- return client.isOpen ? client : void 0;
31812
- } catch {
31813
- clientPromise = void 0;
31814
- return void 0;
31815
- }
31816
- }
31817
- async function claimDedupKey(key, ttlMs) {
31818
- try {
31819
- const client = await redis();
31820
- if (!client) return void 0;
31821
- const result = await client.set(key, "1", { NX: true, PX: ttlMs });
31822
- return result === "OK";
31823
- } catch {
31824
- return void 0;
31825
- }
31826
- }
31827
- async function incrementRateCounter(key, windowMs) {
31828
- try {
31829
- const client = await redis();
31830
- if (!client) return void 0;
31831
- const count = await client.incr(key);
31832
- if (count === 1) await client.pExpire(key, windowMs);
31833
- return count;
31834
- } catch {
31835
- return void 0;
31836
- }
31837
- }
31838
-
31839
31270
  // src/router/middlewares/deduplication.ts
31840
31271
  var processedMessages = /* @__PURE__ */ new Map();
31841
31272
  function createDeduplicationMiddleware(ttlMs = 5 * 60 * 1e3) {
@@ -32904,7 +32335,7 @@ import {
32904
32335
  agentInstanceManager as agentInstanceManager13,
32905
32336
  createSandboxProvider,
32906
32337
  TokenCache,
32907
- mcpManager as mcpManager3,
32338
+ mcpManager as mcpManager2,
32908
32339
  convertToConnection as convertToConnection2,
32909
32340
  createTrustedAgentMessageDispatcher as createTrustedAgentMessageDispatcher2,
32910
32341
  ChannelConnectionLeader,
@@ -32924,7 +32355,7 @@ import {
32924
32355
  COLLECTION_CHANGED_TOPIC,
32925
32356
  vectorStoreLatticeManager as vectorStoreLatticeManager2,
32926
32357
  observabilityLatticeManager,
32927
- getSandboxPluginCatalog as getSandboxPluginCatalog3,
32358
+ getSandboxPluginCatalog as getSandboxPluginCatalog2,
32928
32359
  getSandBoxManager as getSandBoxManager4,
32929
32360
  installPluginHost,
32930
32361
  ThreadExecutionSupervisor,
@@ -32935,7 +32366,7 @@ import {
32935
32366
  } from "@axiom-lattice/core";
32936
32367
 
32937
32368
  // src/services/chunk/redisAppendLog.ts
32938
- import { createClient as createClient3 } from "redis";
32369
+ import { createClient as createClient2 } from "redis";
32939
32370
  var VALUE_FIELD = "v";
32940
32371
  var START_ID = "0-0";
32941
32372
  var ChunkLogCorruptionError = class extends Error {
@@ -32952,7 +32383,7 @@ var ChunkLogCorruptionError = class extends Error {
32952
32383
  }
32953
32384
  };
32954
32385
  async function createRedisAppendLog(url, options = {}) {
32955
- const client = createClient3({
32386
+ const client = createClient2({
32956
32387
  url,
32957
32388
  disableOfflineQueue: true,
32958
32389
  socket: {
@@ -33142,7 +32573,7 @@ function readField(fields, name) {
33142
32573
  }
33143
32574
 
33144
32575
  // src/services/run-cancel/RedisRunCancelNotifier.ts
33145
- import { createClient as createClient4 } from "redis";
32576
+ import { createClient as createClient3 } from "redis";
33146
32577
  import {
33147
32578
  runCancelSignalSchema as runCancelSignalSchema2
33148
32579
  } from "@axiom-lattice/protocols";
@@ -33543,7 +32974,7 @@ function createRedisRunCancelNotifier(options) {
33543
32974
  });
33544
32975
  }
33545
32976
  function createNodeRedisClient2(url) {
33546
- const client = createClient4({
32977
+ const client = createClient3({
33547
32978
  url,
33548
32979
  disableOfflineQueue: true,
33549
32980
  socket: {
@@ -34857,7 +34288,7 @@ import {
34857
34288
  } from "@axiom-lattice/core";
34858
34289
 
34859
34290
  // src/services/plugins/pluginDeploymentNaming.ts
34860
- import { createHash as createHash11 } from "crypto";
34291
+ import { createHash as createHash10 } from "crypto";
34861
34292
  var PLUGIN_GUEST_PORT = 8080;
34862
34293
  var SANDBOX_NAME_HASH_LENGTH = 16;
34863
34294
  function pluginSandboxName(tenantId, pluginType) {
@@ -34867,7 +34298,7 @@ function pluginSandboxName(tenantId, pluginType) {
34867
34298
  if (!pluginType || typeof pluginType !== "string") {
34868
34299
  throw new Error("pluginSandboxName: pluginType must be a non-empty string");
34869
34300
  }
34870
- const hash = createHash11("sha256").update(`${tenantId}\0${pluginType}`).digest("hex").slice(0, SANDBOX_NAME_HASH_LENGTH);
34301
+ const hash = createHash10("sha256").update(`${tenantId}\0${pluginType}`).digest("hex").slice(0, SANDBOX_NAME_HASH_LENGTH);
34871
34302
  return `plugin-${hash}`;
34872
34303
  }
34873
34304
 
@@ -37444,7 +36875,7 @@ function createAgentRunRetentionJob(input) {
37444
36875
  }
37445
36876
 
37446
36877
  // src/services/run-task/RedisRunTaskWake.ts
37447
- import { createClient as createClient5 } from "redis";
36878
+ import { createClient as createClient4 } from "redis";
37448
36879
  var RUN_TASK_WAKE_CHANNEL = "run-task:wake";
37449
36880
  var DEFAULT_OPERATION_TIMEOUT_MS = 2e3;
37450
36881
  var DEFAULT_RETRY_DELAYS_MS = [500, 2e3, 5e3, 1e4];
@@ -37837,7 +37268,7 @@ function createConfiguredRedisRunTaskWake(options) {
37837
37268
  return createRedisRunTaskWake({ ...options, url });
37838
37269
  }
37839
37270
  function createNodeRedisClient3(url) {
37840
- const client = createClient5({
37271
+ const client = createClient4({
37841
37272
  url,
37842
37273
  disableOfflineQueue: true,
37843
37274
  socket: {
@@ -38928,7 +38359,7 @@ async function restoreMcpConnections() {
38928
38359
  logger8.info(`Restoring ${configs.length} MCP server connections...`);
38929
38360
  const deps = {
38930
38361
  store: store2,
38931
- manager: mcpManager3,
38362
+ manager: mcpManager2,
38932
38363
  convertToConnection: convertToConnection2
38933
38364
  };
38934
38365
  const results = await Promise.allSettled(
@@ -38966,6 +38397,8 @@ var start = async (config) => {
38966
38397
  logger8 = loggerLattice.client;
38967
38398
  }
38968
38399
  app.decorate("loggerLattice", loggerLattice);
38400
+ const rateLimitService = createRateLimitService(config?.rateLimits);
38401
+ setRateLimitService(rateLimitService);
38969
38402
  const observabilityProvider = observabilityLatticeManager.getDefault();
38970
38403
  if (observabilityProvider) {
38971
38404
  try {
@@ -39205,9 +38638,9 @@ var start = async (config) => {
39205
38638
  projectRoomRealtimeRuntime
39206
38639
  });
39207
38640
  try {
39208
- const { A2AAuthService: A2AAuthService2, parseEnvKeys: parseEnvKeys2 } = await import("./A2AAuthService-7UGQ7GMW.mjs");
39209
- const { registerA2AStandardRoutes } = await import("./a2a-standard-VL5I7B4W.mjs");
39210
- const a2a = await import("./a2a-BHBLACJV.mjs");
38641
+ const { A2AAuthService: A2AAuthService2, parseEnvKeys: parseEnvKeys2 } = await import("./A2AAuthService-UKN53ZGP.mjs");
38642
+ const { registerA2AStandardRoutes } = await import("./a2a-standard-INVCUSAW.mjs");
38643
+ const a2a = await import("./a2a-TDZ3TT6H.mjs");
39211
38644
  const a2aKeyStore = getStoreLattice42("default", "a2aApiKey").store;
39212
38645
  const assistantStore = getStoreLattice42("default", "assistant").store;
39213
38646
  const projectStore = getStoreLattice42("default", "project").store;
@@ -39236,18 +38669,17 @@ var start = async (config) => {
39236
38669
  });
39237
38670
  }
39238
38671
  try {
39239
- const { registerOpenRoutes } = await import("./open-7ED27I5B.mjs");
39240
- const { registerOpenSessionRoutes } = await import("./open-session-2Y7XJJW2.mjs");
39241
- const { registerOpenCatalogRoutes } = await import("./open-catalog-SZQ435AY.mjs");
39242
- const { registerOpenFilesRoutes } = await import("./open-files-V3R2BFTV.mjs");
38672
+ const { registerOpenRoutes } = await import("./open-27ZPLBIW.mjs");
38673
+ const { registerOpenSessionRoutes } = await import("./open-session-CLZT3HVG.mjs");
38674
+ const { registerOpenCatalogRoutes } = await import("./open-catalog-NVGP6SQP.mjs");
38675
+ const { registerOpenFilesRoutes } = await import("./open-files-JPB2NBL6.mjs");
39243
38676
  const { registerOpenAuditRoutes } = await import("./open-audit-UJ3NXCGW.mjs");
39244
- const { registerOpenExposureRoutes } = await import("./open-exposure-I3DN2X4E.mjs");
39245
- const { openLattice } = await import("./openLattice-Q6M5S6CY.mjs");
39246
- const { OpenRateLimiter } = await import("./openRateLimiter-XEOL3A5G.mjs");
38677
+ const { registerOpenExposureRoutes } = await import("./open-exposure-BPLYUIX6.mjs");
38678
+ const { openLattice } = await import("./openLattice-D5YTSZBY.mjs");
39247
38679
  const { createKbProvider } = await import("./kbProvider-2D6DZ34N.mjs");
39248
38680
  const { createOpenSandboxProvider } = await import("./sandboxProvider-FILMFVIM.mjs");
39249
38681
  const { createAgentProvider } = await import("./agentProvider-X4FVQPKW.mjs");
39250
- const { registerExposedPluginTools } = await import("./registerExposedPlugins-6GCOE64C.mjs");
38682
+ const { registerExposedPluginTools } = await import("./registerExposedPlugins-2JGXSMAL.mjs");
39251
38683
  const { CollectionService: CollectionService2 } = await import("./collection_service-RTRJEQFL.mjs");
39252
38684
  openLattice.register(createKbProvider(new CollectionService2()));
39253
38685
  openLattice.register(createOpenSandboxProvider());
@@ -39263,18 +38695,7 @@ var start = async (config) => {
39263
38695
  })
39264
38696
  );
39265
38697
  await registerExposedPluginTools();
39266
- const openRateLimitPerMinute = Number(
39267
- process.env.OPEN_RATE_LIMIT_PER_MINUTE
39268
- );
39269
- const openAgentRateLimitPerMinute = Number(
39270
- process.env.OPEN_AGENT_RATE_LIMIT_PER_MINUTE
39271
- );
39272
- registerOpenRoutes(app, {
39273
- rateLimiter: new OpenRateLimiter({
39274
- ...Number.isFinite(openRateLimitPerMinute) && openRateLimitPerMinute > 0 ? { defaultPerMinute: openRateLimitPerMinute } : {},
39275
- ...Number.isFinite(openAgentRateLimitPerMinute) && openAgentRateLimitPerMinute > 0 ? { agentPerMinute: openAgentRateLimitPerMinute } : {}
39276
- })
39277
- });
38698
+ registerOpenRoutes(app, { rateLimits: rateLimitService });
39278
38699
  registerOpenSessionRoutes(app);
39279
38700
  registerOpenCatalogRoutes(app);
39280
38701
  registerOpenFilesRoutes(app);
@@ -39287,7 +38708,7 @@ var start = async (config) => {
39287
38708
  });
39288
38709
  }
39289
38710
  try {
39290
- const { registerGatewaySandboxOpenCredentialProvider } = await import("./sandboxOpenCredentialProvider-AT227D4N.mjs");
38711
+ const { registerGatewaySandboxOpenCredentialProvider } = await import("./sandboxOpenCredentialProvider-RTYOYRCT.mjs");
39291
38712
  registerGatewaySandboxOpenCredentialProvider((error) => {
39292
38713
  logger8.warn("sandbox open-credential provider failed", { error });
39293
38714
  });
@@ -39319,7 +38740,7 @@ var start = async (config) => {
39319
38740
  wiring: {
39320
38741
  store: pluginDeploymentStore,
39321
38742
  sandboxManager: getSandBoxManager4(),
39322
- catalog: getSandboxPluginCatalog3(),
38743
+ catalog: getSandboxPluginCatalog2(),
39323
38744
  installPluginHost,
39324
38745
  limits: readPluginDeploymentLimits(),
39325
38746
  serviceKey: process.env.MICROSANDBOX_API_KEY,
@@ -39346,7 +38767,7 @@ var start = async (config) => {
39346
38767
  }
39347
38768
  }
39348
38769
  try {
39349
- const { ResourceController } = await import("./resources-DAU5ZIPB.mjs");
38770
+ const { ResourceController } = await import("./resources-YD5DOPGD.mjs");
39350
38771
  const sharedResourceStore = getStoreLattice42("default", "sharedResource").store;
39351
38772
  const cache = new TokenCache();
39352
38773
  const resourceController = new ResourceController({
@@ -39356,6 +38777,13 @@ var start = async (config) => {
39356
38777
  logger: logger8
39357
38778
  });
39358
38779
  registerResourceRoutes(app, resourceController);
38780
+ const { registerMcpAppShareRoutes } = await import("./mcp-app-shares-SHPBJQXS.mjs");
38781
+ const { makeMcpAppHandlers, resolveMcpAppDeps } = await import("./mcp-apps-QVUK6UBA.mjs");
38782
+ registerMcpAppShareRoutes(app, {
38783
+ store: sharedResourceStore,
38784
+ handlers: makeMcpAppHandlers(resolveMcpAppDeps()),
38785
+ rateLimits: rateLimitService
38786
+ });
39359
38787
  logger8.info("Resource share routes registered");
39360
38788
  } catch (err) {
39361
38789
  logger8.warn("Resource share infrastructure unavailable", {
@@ -39435,7 +38863,6 @@ var start = async (config) => {
39435
38863
  "assistant-changed": (payload) => handleAssistantChanged(payload, async (tenantId) => {
39436
38864
  await agentLatticeManager6.initializeStoredAssistantsForTenant(tenantId);
39437
38865
  invalidateAgentReflectionCache(tenantId);
39438
- invalidatePluginReflectionCache(tenantId);
39439
38866
  }),
39440
38867
  [AGENT_LIFECYCLE_TOPIC]: async (payload) => {
39441
38868
  handleAgentLifecycle(payload);
@@ -39443,7 +38870,7 @@ var start = async (config) => {
39443
38870
  [A2A_KEY_CHANGED_TOPIC]: (payload) => handleA2AKeyChanged(payload, () => refreshStoreKeyMap()),
39444
38871
  [MCP_CONFIG_CHANGED_TOPIC]: (payload) => reconcileMcpConfigChange(payload, {
39445
38872
  store: getStoreLattice42("default", "mcp").store,
39446
- manager: mcpManager3,
38873
+ manager: mcpManager2,
39447
38874
  convertToConnection: convertToConnection2
39448
38875
  }),
39449
38876
  [COLLECTION_CHANGED_TOPIC]: async (payload) => {
@@ -39455,8 +38882,7 @@ var start = async (config) => {
39455
38882
  [PLUGIN_CATALOG_CHANGED_TOPIC]: async (payload) => {
39456
38883
  const tenantId = payload?.tenantId;
39457
38884
  if (typeof tenantId === "string" && tenantId.length > 0) {
39458
- getSandboxPluginCatalog3().invalidate(tenantId);
39459
- invalidatePluginReflectionCache(tenantId);
38885
+ getSandboxPluginCatalog2().invalidate(tenantId);
39460
38886
  invalidateAgentReflectionCache(tenantId);
39461
38887
  await getMcpUiResourceResolver()?.invalidateTenantPlugins(tenantId);
39462
38888
  }