@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.
- package/dist/{A2AAuthService-7UGQ7GMW.mjs → A2AAuthService-UKN53ZGP.mjs} +2 -2
- package/dist/{a2a-BHBLACJV.mjs → a2a-TDZ3TT6H.mjs} +3 -3
- package/dist/{a2a-standard-VL5I7B4W.mjs → a2a-standard-INVCUSAW.mjs} +39 -2
- package/dist/a2a-standard-INVCUSAW.mjs.map +1 -0
- package/dist/chunk-A7YNAU5L.mjs +377 -0
- package/dist/chunk-A7YNAU5L.mjs.map +1 -0
- package/dist/{chunk-3XIIQ6EK.mjs → chunk-BOPNXTMO.mjs} +66 -5
- package/dist/chunk-BOPNXTMO.mjs.map +1 -0
- package/dist/{chunk-L6MBEEII.mjs → chunk-JGQURU44.mjs} +24 -6
- package/dist/chunk-JGQURU44.mjs.map +1 -0
- package/dist/{chunk-GPHOYR3X.mjs → chunk-LCM4OQTI.mjs} +30 -1
- package/dist/chunk-LCM4OQTI.mjs.map +1 -0
- package/dist/{chunk-HVIKCUOF.mjs → chunk-MFWTGNQR.mjs} +74 -5
- package/dist/chunk-MFWTGNQR.mjs.map +1 -0
- package/dist/{chunk-HYYLYIMH.mjs → chunk-OBODBHIS.mjs} +2 -2
- package/dist/chunk-T2HIWZGP.mjs +580 -0
- package/dist/chunk-T2HIWZGP.mjs.map +1 -0
- package/dist/chunk-Y7OVVPVU.mjs +13 -0
- package/dist/chunk-Y7OVVPVU.mjs.map +1 -0
- package/dist/{chunk-GL7RV5L3.mjs → chunk-YR32MWEJ.mjs} +36 -73
- package/dist/chunk-YR32MWEJ.mjs.map +1 -0
- package/dist/embed/{embed-page-AgentDetailSideApp-O6G4NJ7I.css → embed-page-AgentDetailSideApp-JMJOOC4V.css} +1 -1
- package/dist/embed/{embed-page-AgentDetailSideApp-7YTMN643.js → embed-page-AgentDetailSideApp-TQEJK6ZF.js} +1 -1
- package/dist/embed/{embed-page-AgentGovernanceWorkbench-SFZNVMUH.css → embed-page-AgentGovernanceWorkbench-3T3ZFJI5.css} +1 -1
- package/dist/embed/{embed-page-AgentGovernanceWorkbench-YWJ4ZLEV.js → embed-page-AgentGovernanceWorkbench-II2MRGCG.js} +1 -1
- package/dist/embed/{embed-page-LangfuseDashboard-BEOJDMWF.js → embed-page-LangfuseDashboard-7OANGQXY.js} +1 -1
- package/dist/embed/{embed-page-MessageGraph-N2DXVMEK.js → embed-page-MessageGraph-KJPQWTHE.js} +1 -1
- package/dist/embed/{embed-page-TopologyRuntimeView-CWOXLVFW.css → embed-page-MessageGraph-UDC6GQA5.css} +1 -1
- package/dist/embed/{embed-page-ReactChart-3QDZX2WG.js → embed-page-ReactChart-2CAIM4JD.js} +1 -1
- package/dist/embed/{embed-page-ReactChart-MXGF35OQ.css → embed-page-ReactChart-URBKYQYE.css} +1 -1
- package/dist/embed/{embed-page-SkillFlow-3X24ILKU.js → embed-page-SkillFlow-243MXRXC.js} +1 -1
- package/dist/embed/{embed-page-TasksSideApp-MYIRJWFM.js → embed-page-TasksSideApp-OA7CULHS.js} +1 -1
- package/dist/embed/{embed-page-TasksSideApp-HV6DKQ26.css → embed-page-TasksSideApp-TTCP4ENP.css} +1 -1
- package/dist/embed/{embed-page-ThreadMaintenancePanel-V327PV5R.js → embed-page-ThreadMaintenancePanel-Z4424X3J.js} +1 -1
- package/dist/embed/{embed-page-WorkflowAutomationView-YQFB3CTV.css → embed-page-TopologyRuntimeView-S4AMB4RI.css} +1 -1
- package/dist/embed/{embed-page-TopologyRuntimeView-3O6VJUZR.js → embed-page-TopologyRuntimeView-THTCZUS7.js} +1 -1
- package/dist/embed/{embed-page-MessageGraph-UT2TCPSO.css → embed-page-WorkflowAutomationView-FWVCQ3YM.css} +1 -1
- package/dist/embed/{embed-page-WorkflowAutomationView-YHOS4WQR.js → embed-page-WorkflowAutomationView-YDIDG35E.js} +1 -1
- package/dist/embed/{embed-page-chunk-4XKCMM5C.js → embed-page-chunk-7ULTMRM2.js} +1 -1
- package/dist/embed/{embed-page-chunk-BSRASK7V.js → embed-page-chunk-FZX4A32D.js} +5 -5
- package/dist/embed/{embed-page-chunk-PMOGSY6W.js → embed-page-chunk-JMP7EQEF.js} +1 -1
- package/dist/embed/{embed-page-chunk-IELKCYQX.js → embed-page-chunk-L2EGVVJS.js} +1 -1
- package/dist/embed/{embed-page-chunk-WGEXK773.js → embed-page-chunk-LDQGH44H.js} +1 -1
- package/dist/embed/{embed-page-chunk-JTL73EBV.js → embed-page-chunk-OMN6G52V.js} +1 -1
- package/dist/embed/{embed-page-chunk-PROZXFWS.js → embed-page-chunk-RKQJBKN2.js} +1 -1
- package/dist/embed/{embed-page-chunk-YMVKQQXJ.js → embed-page-chunk-VYS3TAK4.js} +1 -1
- package/dist/embed/{embed-page-chunk-ASEIOK7X.js → embed-page-chunk-W5OP2CZG.js} +2 -2
- package/dist/embed/embed-page-chunk-Z6KWW64I.js +6837 -0
- package/dist/embed/{embed-page-en-E35GE7TA.js → embed-page-en-D4M3DPFT.js} +1 -1
- package/dist/embed/{embed-page-en-XJYWUJEL.js → embed-page-en-DNDGCPMA.js} +1 -1
- package/dist/embed/embed-page-en-H5NOZEKE.js +1 -0
- package/dist/embed/{embed-page-en-HDSVQ4O6.js → embed-page-en-QJRX2NQE.js} +1 -1
- package/dist/embed/{embed-page-zh-6EBUEFKP.js → embed-page-zh-2H4EB3F3.js} +1 -1
- package/dist/embed/embed-page-zh-4C2K3RH2.js +1 -0
- package/dist/embed/{embed-page-zh-IR652A6J.js → embed-page-zh-HTEHFCSL.js} +1 -1
- package/dist/embed/{embed-page-zh-ZLK3GLM3.js → embed-page-zh-NEXLMDHF.js} +1 -1
- package/dist/embed/embed-page.css +1 -1
- package/dist/embed/embed-page.js +1 -1
- package/dist/embed/mcp-app-page.js +61 -0
- package/dist/index.d.mts +29 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +2551 -1476
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +116 -690
- package/dist/index.mjs.map +1 -1
- package/dist/mcp-app-shares-SHPBJQXS.mjs +300 -0
- package/dist/mcp-app-shares-SHPBJQXS.mjs.map +1 -0
- package/dist/mcp-apps-QVUK6UBA.mjs +26 -0
- package/dist/{open-7ED27I5B.mjs → open-27ZPLBIW.mjs} +101 -18
- package/dist/open-27ZPLBIW.mjs.map +1 -0
- package/dist/{open-catalog-SZQ435AY.mjs → open-catalog-NVGP6SQP.mjs} +38 -7
- package/dist/open-catalog-NVGP6SQP.mjs.map +1 -0
- package/dist/{open-exposure-I3DN2X4E.mjs → open-exposure-BPLYUIX6.mjs} +4 -4
- package/dist/{open-files-V3R2BFTV.mjs → open-files-JPB2NBL6.mjs} +4 -4
- package/dist/{open-session-2Y7XJJW2.mjs → open-session-CLZT3HVG.mjs} +5 -5
- package/dist/open-session-CLZT3HVG.mjs.map +1 -0
- package/dist/openLattice-D5YTSZBY.mjs +28 -0
- package/dist/{registerExposedPlugins-6GCOE64C.mjs → registerExposedPlugins-2JGXSMAL.mjs} +4 -3
- package/dist/{resources-DAU5ZIPB.mjs → resources-YD5DOPGD.mjs} +83 -3
- package/dist/resources-YD5DOPGD.mjs.map +1 -0
- package/dist/{sandboxOpenCredentialProvider-AT227D4N.mjs → sandboxOpenCredentialProvider-RTYOYRCT.mjs} +19 -14
- package/dist/sandboxOpenCredentialProvider-RTYOYRCT.mjs.map +1 -0
- package/package.json +10 -8
- package/dist/a2a-standard-VL5I7B4W.mjs.map +0 -1
- package/dist/chunk-3XIIQ6EK.mjs.map +0 -1
- package/dist/chunk-GL7RV5L3.mjs.map +0 -1
- package/dist/chunk-GPHOYR3X.mjs.map +0 -1
- package/dist/chunk-GXZFO3VU.mjs +0 -42
- package/dist/chunk-GXZFO3VU.mjs.map +0 -1
- package/dist/chunk-HVIKCUOF.mjs.map +0 -1
- package/dist/chunk-L6MBEEII.mjs.map +0 -1
- package/dist/embed/embed-page-chunk-IBRMWDHE.js +0 -6835
- package/dist/embed/embed-page-en-GLT2HEZZ.js +0 -1
- package/dist/embed/embed-page-zh-XMEJPDMF.js +0 -1
- package/dist/open-7ED27I5B.mjs.map +0 -1
- package/dist/open-catalog-SZQ435AY.mjs.map +0 -1
- package/dist/open-session-2Y7XJJW2.mjs.map +0 -1
- package/dist/openLattice-Q6M5S6CY.mjs +0 -18
- package/dist/openRateLimiter-XEOL3A5G.mjs +0 -8
- package/dist/resources-DAU5ZIPB.mjs.map +0 -1
- package/dist/sandboxOpenCredentialProvider-AT227D4N.mjs.map +0 -1
- /package/dist/{A2AAuthService-7UGQ7GMW.mjs.map → A2AAuthService-UKN53ZGP.mjs.map} +0 -0
- /package/dist/{a2a-BHBLACJV.mjs.map → a2a-TDZ3TT6H.mjs.map} +0 -0
- /package/dist/{chunk-HYYLYIMH.mjs.map → chunk-OBODBHIS.mjs.map} +0 -0
- /package/dist/{openLattice-Q6M5S6CY.mjs.map → mcp-apps-QVUK6UBA.mjs.map} +0 -0
- /package/dist/{open-exposure-I3DN2X4E.mjs.map → open-exposure-BPLYUIX6.mjs.map} +0 -0
- /package/dist/{open-files-V3R2BFTV.mjs.map → open-files-JPB2NBL6.mjs.map} +0 -0
- /package/dist/{openRateLimiter-XEOL3A5G.mjs.map → openLattice-D5YTSZBY.mjs.map} +0 -0
- /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
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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-
|
|
63
|
+
} from "./chunk-OBODBHIS.mjs";
|
|
47
64
|
import {
|
|
48
65
|
A2AAuthService,
|
|
49
66
|
parseEnvKeys
|
|
50
|
-
} from "./chunk-
|
|
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, "&").replace(/"/g, """);
|
|
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
|
|
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}:${
|
|
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
|
|
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 =
|
|
20312
|
-
const contentDigest =
|
|
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 =
|
|
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[
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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}:${
|
|
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
|
|
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
|
|
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}:${
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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:
|
|
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-
|
|
39209
|
-
const { registerA2AStandardRoutes } = await import("./a2a-standard-
|
|
39210
|
-
const a2a = await import("./a2a-
|
|
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-
|
|
39240
|
-
const { registerOpenSessionRoutes } = await import("./open-session-
|
|
39241
|
-
const { registerOpenCatalogRoutes } = await import("./open-catalog-
|
|
39242
|
-
const { registerOpenFilesRoutes } = await import("./open-files-
|
|
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-
|
|
39245
|
-
const { openLattice } = await import("./openLattice-
|
|
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-
|
|
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
|
-
|
|
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-
|
|
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:
|
|
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-
|
|
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:
|
|
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
|
-
|
|
39459
|
-
invalidatePluginReflectionCache(tenantId);
|
|
38885
|
+
getSandboxPluginCatalog2().invalidate(tenantId);
|
|
39460
38886
|
invalidateAgentReflectionCache(tenantId);
|
|
39461
38887
|
await getMcpUiResourceResolver()?.invalidateTenantPlugins(tenantId);
|
|
39462
38888
|
}
|