@axiom-lattice/gateway 4.2.0 → 4.2.2
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-DK5X6VIL.mjs → A2AAuthService-7UGQ7GMW.mjs} +3 -2
- package/dist/{WechatChannelAdapter-WSDKR4OA.mjs → WechatChannelAdapter-7WHE5UGY.mjs} +2 -1
- package/dist/{WechatChannelAdapter-WSDKR4OA.mjs.map → WechatChannelAdapter-7WHE5UGY.mjs.map} +1 -1
- package/dist/{a2a-7N3WDAOP.mjs → a2a-FGYX2HH3.mjs} +71 -32
- package/dist/a2a-FGYX2HH3.mjs.map +1 -0
- package/dist/{a2a-standard-WC2BSOFV.mjs → a2a-standard-VEQBXBMM.mjs} +93 -115
- package/dist/a2a-standard-VEQBXBMM.mjs.map +1 -0
- package/dist/agentProvider-X4FVQPKW.mjs +88 -0
- package/dist/agentProvider-X4FVQPKW.mjs.map +1 -0
- package/dist/chunk-2POW27EI.mjs +27 -0
- package/dist/chunk-2POW27EI.mjs.map +1 -0
- package/dist/chunk-52SUWMOX.mjs +121 -0
- package/dist/chunk-52SUWMOX.mjs.map +1 -0
- package/dist/chunk-GF4GGTWJ.mjs +164 -0
- package/dist/chunk-GF4GGTWJ.mjs.map +1 -0
- package/dist/{chunk-2HOCF46L.mjs → chunk-GPHOYR3X.mjs} +33 -11
- package/dist/chunk-GPHOYR3X.mjs.map +1 -0
- package/dist/chunk-NFEGQTCC.mjs +27 -0
- package/dist/chunk-PWHUWFXL.mjs +173 -0
- package/dist/chunk-PWHUWFXL.mjs.map +1 -0
- package/dist/chunk-QUT2DS4R.mjs +50 -0
- package/dist/chunk-QUT2DS4R.mjs.map +1 -0
- package/dist/chunk-TJAUXMYJ.mjs +109 -0
- package/dist/chunk-TJAUXMYJ.mjs.map +1 -0
- package/dist/chunk-WKNZ7GBC.mjs +56 -0
- package/dist/chunk-WKNZ7GBC.mjs.map +1 -0
- package/dist/collection_service-RTRJEQFL.mjs +8 -0
- package/dist/embed/agent-chat-loader.js +1 -1
- package/dist/embed/{embed-page-AgentDetailSideApp-6CVXM3P3.js → embed-page-AgentDetailSideApp-DTDBMB2U.js} +1 -1
- package/dist/embed/{embed-page-AgentDetailSideApp-DRGKJ6C5.css → embed-page-AgentDetailSideApp-O6G4NJ7I.css} +1 -1
- package/dist/embed/{embed-page-AgentGovernanceWorkbench-4B3NJPCY.js → embed-page-AgentGovernanceWorkbench-JUP6SNBX.js} +1 -1
- package/dist/embed/embed-page-AgentGovernanceWorkbench-SFZNVMUH.css +1 -0
- package/dist/embed/embed-page-MessageGraph-H5S7SARE.js +6 -0
- package/dist/embed/{embed-page-ReactChart-OG5Z43H7.js → embed-page-ReactChart-FWXMXO7F.js} +1 -1
- package/dist/embed/{embed-page-SkillFlow-GS4OUCJJ.js → embed-page-SkillFlow-SFZ5HLMK.js} +1 -1
- package/dist/embed/{embed-page-TasksSideApp-I6Z7BOT2.js → embed-page-TasksSideApp-Q6HTW6S6.js} +1 -1
- package/dist/embed/{embed-page-TeamWorkspace-LSCUIJDA.js → embed-page-TeamWorkspace-6KFWCIKW.js} +4 -4
- package/dist/embed/{embed-page-TopologyRuntimeView-RY7NOUB7.js → embed-page-TopologyRuntimeView-MASWKWXA.js} +1 -1
- package/dist/embed/{embed-page-WorkflowAutomationView-RNKIKDUX.js → embed-page-WorkflowAutomationView-6UOT36GW.js} +1 -1
- package/dist/embed/{embed-page-chunk-4BIOW547.js → embed-page-chunk-2WCPJYBC.js} +1 -1
- package/dist/embed/{embed-page-chunk-7CFGO35V.js → embed-page-chunk-3EUETTEM.js} +1 -1
- package/dist/embed/{embed-page-chunk-4X5XHAMX.js → embed-page-chunk-74BPRLSV.js} +4 -4
- package/dist/embed/embed-page-chunk-7SO4HHS4.js +4084 -0
- package/dist/embed/{embed-page-chunk-DVHOG6AY.js → embed-page-chunk-AC6X2XRH.js} +1 -1
- package/dist/embed/{embed-page-chunk-SU5GXLKX.js → embed-page-chunk-AVZ7FKIO.js} +4 -4
- package/dist/embed/{embed-page-chunk-EPEKIAZP.js → embed-page-chunk-FJ3SFKJY.js} +1 -1
- package/dist/embed/{embed-page-chunk-Q32Y7CP2.js → embed-page-chunk-IV5C4DYL.js} +1 -1
- package/dist/embed/{embed-page-chunk-KGX7G7XQ.js → embed-page-chunk-KEL6XU6R.js} +1 -1
- package/dist/embed/{embed-page-chunk-BZI3YCE7.js → embed-page-chunk-N46WJ2FS.js} +1 -1
- package/dist/embed/embed-page-chunk-NFLB3VUZ.js +245 -0
- package/dist/embed/{embed-page-chunk-AYOVLRHX.js → embed-page-chunk-NHOWQIND.js} +182 -70
- package/dist/embed/{embed-page-chunk-KG5A66WX.js → embed-page-chunk-O4QK5LWZ.js} +83 -83
- package/dist/embed/{embed-page-chunk-JLWIJ4BP.js → embed-page-chunk-X4DK4JRG.js} +1 -1
- package/dist/embed/{embed-page-chunk-ESLOGPBN.js → embed-page-chunk-Z7USDLHI.js} +1 -1
- package/dist/embed/{embed-page-code-highlighter-TBT4ICNZ.js → embed-page-code-highlighter-Y6CQA4CN.js} +1 -1
- package/dist/embed/{embed-page-mermaid-TBO3M7GX.js → embed-page-mermaid-CW4QCAH3.js} +1 -1
- package/dist/embed/embed-page.css +1 -1
- package/dist/embed/embed-page.js +1 -1
- package/dist/index.js +2067 -585
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +374 -348
- package/dist/index.mjs.map +1 -1
- package/dist/kbProvider-2D6DZ34N.mjs +50 -0
- package/dist/kbProvider-2D6DZ34N.mjs.map +1 -0
- package/dist/{mcp-configs-IIKQM5GM.mjs → mcp-configs-WCY5EXCW.mjs} +2 -1
- package/dist/mcp-configs-WCY5EXCW.mjs.map +1 -0
- package/dist/{mcpTransportRegistry-XMJ5Y2RG.mjs → mcpTransportRegistry-VXUVJKBC.mjs} +2 -1
- package/dist/mcpTransportRegistry-VXUVJKBC.mjs.map +1 -0
- package/dist/open-HH7RKGML.mjs +260 -0
- package/dist/open-HH7RKGML.mjs.map +1 -0
- package/dist/open-audit-UJ3NXCGW.mjs +32 -0
- package/dist/open-audit-UJ3NXCGW.mjs.map +1 -0
- package/dist/open-catalog-WYS2AENM.mjs +59 -0
- package/dist/open-catalog-WYS2AENM.mjs.map +1 -0
- package/dist/open-exposure-FK4G6O6L.mjs +67 -0
- package/dist/open-exposure-FK4G6O6L.mjs.map +1 -0
- package/dist/open-files-GVRMK5PL.mjs +146 -0
- package/dist/open-files-GVRMK5PL.mjs.map +1 -0
- package/dist/open-session-3VN65PRR.mjs +53 -0
- package/dist/open-session-3VN65PRR.mjs.map +1 -0
- package/dist/openLattice-GAAGQJST.mjs +16 -0
- package/dist/openLattice-GAAGQJST.mjs.map +1 -0
- package/dist/registerExposedPlugins-63EUF4VS.mjs +99 -0
- package/dist/registerExposedPlugins-63EUF4VS.mjs.map +1 -0
- package/dist/{resources-VA7LSDKN.mjs → resources-SRQRKW5G.mjs} +47 -4
- package/dist/resources-SRQRKW5G.mjs.map +1 -0
- package/dist/sandboxProvider-I3P66VXT.mjs +10 -0
- package/dist/sandboxProvider-I3P66VXT.mjs.map +1 -0
- package/dist/{sender-PX32VSHB.mjs → sender-PLDU5EZ3.mjs} +3 -1
- package/dist/{sender-PX32VSHB.mjs.map → sender-PLDU5EZ3.mjs.map} +1 -1
- package/package.json +7 -7
- package/dist/a2a-7N3WDAOP.mjs.map +0 -1
- package/dist/a2a-standard-WC2BSOFV.mjs.map +0 -1
- package/dist/chunk-2HOCF46L.mjs.map +0 -1
- package/dist/embed/embed-page-chunk-A2LQIHX4.js +0 -261
- package/dist/embed/embed-page-chunk-OWGBADV6.js +0 -3880
- package/dist/open-DCAOL5CG.mjs +0 -176
- package/dist/open-DCAOL5CG.mjs.map +0 -1
- package/dist/resources-VA7LSDKN.mjs.map +0 -1
- /package/dist/{A2AAuthService-DK5X6VIL.mjs.map → A2AAuthService-7UGQ7GMW.mjs.map} +0 -0
- /package/dist/{mcp-configs-IIKQM5GM.mjs.map → chunk-NFEGQTCC.mjs.map} +0 -0
- /package/dist/{mcpTransportRegistry-XMJ5Y2RG.mjs.map → collection_service-RTRJEQFL.mjs.map} +0 -0
- /package/dist/embed/{embed-page-AgentGovernanceWorkbench-SDS3GBCC.css → embed-page-MessageGraph-TYOOATYV.css} +0 -0
package/dist/index.js
CHANGED
|
@@ -30,6 +30,178 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
30
|
));
|
|
31
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
32
|
|
|
33
|
+
// src/services/collection_service.ts
|
|
34
|
+
var collection_service_exports = {};
|
|
35
|
+
__export(collection_service_exports, {
|
|
36
|
+
CollectionService: () => CollectionService
|
|
37
|
+
});
|
|
38
|
+
function getTenantId5(request) {
|
|
39
|
+
return request.user?.tenantId || request.headers["x-tenant-id"] || "default";
|
|
40
|
+
}
|
|
41
|
+
var import_uuid2, import_documents, import_core11, CollectionService;
|
|
42
|
+
var init_collection_service = __esm({
|
|
43
|
+
"src/services/collection_service.ts"() {
|
|
44
|
+
"use strict";
|
|
45
|
+
import_uuid2 = require("uuid");
|
|
46
|
+
import_documents = require("@langchain/core/documents");
|
|
47
|
+
import_core11 = require("@axiom-lattice/core");
|
|
48
|
+
CollectionService = class {
|
|
49
|
+
// ─── Collection CRUD ──────────────────────────────────────────
|
|
50
|
+
async getAllCollections(request) {
|
|
51
|
+
const tenantId = getTenantId5(request);
|
|
52
|
+
const collections = await import_core11.collectionLatticeManager.getAllCollections(tenantId);
|
|
53
|
+
for (const c2 of collections) {
|
|
54
|
+
try {
|
|
55
|
+
c2._entryCount = await (0, import_core11.getCollectionEntryCount)(c2.name, c2.embeddingKey, c2.tenantId);
|
|
56
|
+
} catch {
|
|
57
|
+
c2._entryCount = 0;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return collections;
|
|
61
|
+
}
|
|
62
|
+
async getCollectionByName(request, name) {
|
|
63
|
+
const tenantId = getTenantId5(request);
|
|
64
|
+
return import_core11.collectionLatticeManager.getCollection(tenantId, name);
|
|
65
|
+
}
|
|
66
|
+
async createCollection(request, data) {
|
|
67
|
+
const tenantId = getTenantId5(request);
|
|
68
|
+
const collection = await import_core11.collectionLatticeManager.registerCollection(tenantId, data);
|
|
69
|
+
try {
|
|
70
|
+
await (0, import_core11.getOrCreateCollectionVectorStore)(data.name, data.embeddingKey, tenantId);
|
|
71
|
+
} catch (err) {
|
|
72
|
+
console.warn(`[CollectionService] Failed to init vector store for ${data.name}:`, err);
|
|
73
|
+
}
|
|
74
|
+
return collection;
|
|
75
|
+
}
|
|
76
|
+
async updateCollection(request, name, updates) {
|
|
77
|
+
const tenantId = getTenantId5(request);
|
|
78
|
+
return import_core11.collectionLatticeManager.updateCollection(tenantId, name, updates);
|
|
79
|
+
}
|
|
80
|
+
async deleteCollection(request, name) {
|
|
81
|
+
const tenantId = getTenantId5(request);
|
|
82
|
+
await (0, import_core11.removeCollectionVectorStore)(name, tenantId);
|
|
83
|
+
return import_core11.collectionLatticeManager.removeCollection(tenantId, name);
|
|
84
|
+
}
|
|
85
|
+
// ─── Entry CRUD ───────────────────────────────────────────────
|
|
86
|
+
async getEntries(request, collectionName) {
|
|
87
|
+
const collection = await this.getCollectionByName(request, collectionName);
|
|
88
|
+
if (!collection) throw new Error(`Collection "${collectionName}" not found`);
|
|
89
|
+
const docs = await (0, import_core11.listCollectionEntries)(collectionName, collection.embeddingKey, collection.tenantId);
|
|
90
|
+
return docs.map((doc) => ({
|
|
91
|
+
id: doc.metadata._id || "",
|
|
92
|
+
content: doc.pageContent,
|
|
93
|
+
metadata: Object.fromEntries(
|
|
94
|
+
Object.entries(doc.metadata).filter(([k]) => !k.startsWith("_"))
|
|
95
|
+
)
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
async createEntry(request, collectionName, data) {
|
|
99
|
+
const collection = await this.getCollectionByName(request, collectionName);
|
|
100
|
+
if (!collection) throw new Error(`Collection "${collectionName}" not found`);
|
|
101
|
+
const vectorStore = await (0, import_core11.getOrCreateCollectionVectorStore)(
|
|
102
|
+
collectionName,
|
|
103
|
+
collection.embeddingKey,
|
|
104
|
+
collection.tenantId
|
|
105
|
+
);
|
|
106
|
+
const entryId = (0, import_uuid2.v4)();
|
|
107
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
108
|
+
const doc = new import_documents.Document({
|
|
109
|
+
pageContent: data.content,
|
|
110
|
+
metadata: {
|
|
111
|
+
_id: entryId,
|
|
112
|
+
_created_at: now,
|
|
113
|
+
_updated_at: now,
|
|
114
|
+
...data.metadata || {}
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
await vectorStore.addDocuments([doc]);
|
|
118
|
+
return { id: entryId, content: data.content, metadata: data.metadata || {} };
|
|
119
|
+
}
|
|
120
|
+
async getEntry(request, collectionName, entryId) {
|
|
121
|
+
const collection = await this.getCollectionByName(request, collectionName);
|
|
122
|
+
if (!collection) throw new Error(`Collection "${collectionName}" not found`);
|
|
123
|
+
const docs = await (0, import_core11.listCollectionEntries)(collectionName, collection.embeddingKey, collection.tenantId);
|
|
124
|
+
const doc = docs.find((d) => d.metadata._id === entryId);
|
|
125
|
+
if (!doc) return null;
|
|
126
|
+
return {
|
|
127
|
+
id: entryId,
|
|
128
|
+
content: doc.pageContent,
|
|
129
|
+
metadata: Object.fromEntries(
|
|
130
|
+
Object.entries(doc.metadata).filter(([k]) => !k.startsWith("_"))
|
|
131
|
+
)
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
async updateEntry(request, collectionName, entryId, data) {
|
|
135
|
+
const existing = await this.getEntry(request, collectionName, entryId);
|
|
136
|
+
if (!existing) return null;
|
|
137
|
+
const collection = await this.getCollectionByName(request, collectionName);
|
|
138
|
+
if (!collection) throw new Error(`Collection "${collectionName}" not found`);
|
|
139
|
+
const vectorStore = await (0, import_core11.getOrCreateCollectionVectorStore)(
|
|
140
|
+
collectionName,
|
|
141
|
+
collection.embeddingKey,
|
|
142
|
+
collection.tenantId
|
|
143
|
+
);
|
|
144
|
+
try {
|
|
145
|
+
await vectorStore.delete({ filter: { _id: entryId } });
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
148
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
149
|
+
const mergedMetadata = { ...existing.metadata, ...data.metadata || {} };
|
|
150
|
+
const doc = new import_documents.Document({
|
|
151
|
+
pageContent: data.content ?? existing.content,
|
|
152
|
+
metadata: { _id: entryId, _created_at: now, _updated_at: now, ...mergedMetadata }
|
|
153
|
+
});
|
|
154
|
+
await vectorStore.addDocuments([doc]);
|
|
155
|
+
return { id: entryId, content: data.content ?? existing.content, metadata: mergedMetadata };
|
|
156
|
+
}
|
|
157
|
+
async deleteEntry(request, collectionName, entryId) {
|
|
158
|
+
const collection = await this.getCollectionByName(request, collectionName);
|
|
159
|
+
if (!collection) throw new Error(`Collection "${collectionName}" not found`);
|
|
160
|
+
const vectorStore = await (0, import_core11.getOrCreateCollectionVectorStore)(
|
|
161
|
+
collectionName,
|
|
162
|
+
collection.embeddingKey,
|
|
163
|
+
collection.tenantId
|
|
164
|
+
);
|
|
165
|
+
try {
|
|
166
|
+
await vectorStore.delete({ filter: { _id: entryId } });
|
|
167
|
+
return true;
|
|
168
|
+
} catch {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async searchEntries(request, collectionName, params) {
|
|
173
|
+
const collection = await this.getCollectionByName(request, collectionName);
|
|
174
|
+
if (!collection) throw new Error(`Collection "${collectionName}" not found`);
|
|
175
|
+
const vectorStore = await (0, import_core11.getOrCreateCollectionVectorStore)(
|
|
176
|
+
collectionName,
|
|
177
|
+
collection.embeddingKey,
|
|
178
|
+
collection.tenantId
|
|
179
|
+
);
|
|
180
|
+
let embeddings;
|
|
181
|
+
try {
|
|
182
|
+
embeddings = import_core11.embeddingsLatticeManager.getEmbeddingsClient(collection.embeddingKey);
|
|
183
|
+
} catch {
|
|
184
|
+
embeddings = import_core11.embeddingsLatticeManager.getEmbeddingsClient("default");
|
|
185
|
+
}
|
|
186
|
+
const queryVector = await embeddings.embedQuery(params.query);
|
|
187
|
+
const results = await vectorStore.similaritySearchVectorWithScore(
|
|
188
|
+
queryVector,
|
|
189
|
+
params.top_k || 5,
|
|
190
|
+
params.filter
|
|
191
|
+
);
|
|
192
|
+
return results.map(([doc, score]) => ({
|
|
193
|
+
id: doc.metadata._id || (0, import_uuid2.v4)(),
|
|
194
|
+
content: doc.pageContent,
|
|
195
|
+
metadata: Object.fromEntries(
|
|
196
|
+
Object.entries(doc.metadata).filter(([k]) => !k.startsWith("_"))
|
|
197
|
+
),
|
|
198
|
+
score
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
|
|
33
205
|
// src/utils/mime.ts
|
|
34
206
|
function getContentTypeFromFilename(filename) {
|
|
35
207
|
const ext = filename.includes(".") ? filename.slice(filename.lastIndexOf(".")).toLowerCase() : "";
|
|
@@ -78,6 +250,74 @@ var init_mime = __esm({
|
|
|
78
250
|
}
|
|
79
251
|
});
|
|
80
252
|
|
|
253
|
+
// src/services/open/openToken.ts
|
|
254
|
+
var openToken_exports = {};
|
|
255
|
+
__export(openToken_exports, {
|
|
256
|
+
signOpenToken: () => signOpenToken,
|
|
257
|
+
verifyOpenToken: () => verifyOpenToken
|
|
258
|
+
});
|
|
259
|
+
function secret() {
|
|
260
|
+
return process.env.OPEN_TOKEN_SECRET || process.env.AUTH_TOKEN_SECRET || "open-token-dev-secret-fallback";
|
|
261
|
+
}
|
|
262
|
+
function signOpenToken(payload) {
|
|
263
|
+
const data = { ...payload, exp: payload.exp ?? Date.now() + 15 * 60 * 1e3 };
|
|
264
|
+
const encoded = Buffer.from(JSON.stringify(data)).toString("base64url");
|
|
265
|
+
const sig = (0, import_crypto5.createHmac)("sha256", secret()).update(encoded).digest("base64url");
|
|
266
|
+
return `${encoded}.${sig}`;
|
|
267
|
+
}
|
|
268
|
+
function verifyOpenToken(bearer) {
|
|
269
|
+
if (!bearer) return null;
|
|
270
|
+
const parts = bearer.split(".");
|
|
271
|
+
if (parts.length !== 2) return null;
|
|
272
|
+
const [encoded, sigStr] = parts;
|
|
273
|
+
if (!/^[A-Za-z0-9_-]{43}$/.test(sigStr)) return null;
|
|
274
|
+
try {
|
|
275
|
+
const actual = Buffer.from(sigStr, "base64url");
|
|
276
|
+
if (actual.toString("base64url") !== sigStr) return null;
|
|
277
|
+
const expected = (0, import_crypto5.createHmac)("sha256", secret()).update(encoded).digest();
|
|
278
|
+
if (actual.length !== expected.length || !(0, import_crypto5.timingSafeEqual)(actual, expected)) return null;
|
|
279
|
+
const payload = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
280
|
+
if (typeof payload !== "object" || payload === null) return null;
|
|
281
|
+
const p = payload;
|
|
282
|
+
if (typeof p.exp !== "number" || p.exp < Date.now() || p.kind !== "sandbox_token" && p.kind !== "browser_token" || typeof p.tenantId !== "string" || typeof p.projectId !== "string" || typeof p.grants !== "object") {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
return p;
|
|
286
|
+
} catch {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
var import_crypto5;
|
|
291
|
+
var init_openToken = __esm({
|
|
292
|
+
"src/services/open/openToken.ts"() {
|
|
293
|
+
"use strict";
|
|
294
|
+
import_crypto5 = require("crypto");
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// src/services/open/previewToken.ts
|
|
299
|
+
function buildPreviewToken(ids) {
|
|
300
|
+
return signOpenToken({
|
|
301
|
+
kind: "browser_token",
|
|
302
|
+
tenantId: ids.tenantId,
|
|
303
|
+
workspaceId: ids.workspaceId,
|
|
304
|
+
projectId: ids.projectId,
|
|
305
|
+
preview: true,
|
|
306
|
+
grants: BROWSER_GRANTS
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
function buildPreviewTokenScript(ids) {
|
|
310
|
+
return `<script>window.__OPEN_API_TOKEN__=${JSON.stringify(buildPreviewToken(ids))};</script>`;
|
|
311
|
+
}
|
|
312
|
+
var BROWSER_GRANTS;
|
|
313
|
+
var init_previewToken = __esm({
|
|
314
|
+
"src/services/open/previewToken.ts"() {
|
|
315
|
+
"use strict";
|
|
316
|
+
init_openToken();
|
|
317
|
+
BROWSER_GRANTS = [{ domain: "kb", items: ["search"] }];
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
|
|
81
321
|
// src/utils/path-containment.ts
|
|
82
322
|
function isPathWithinRoot(rootPath, targetPath) {
|
|
83
323
|
const relative2 = path2.relative(rootPath, targetPath);
|
|
@@ -333,7 +573,7 @@ async function createMcpServerConfig(request, reply) {
|
|
|
333
573
|
message: "MCP server configuration with this key already exists"
|
|
334
574
|
};
|
|
335
575
|
}
|
|
336
|
-
const id3 = body.id || (0,
|
|
576
|
+
const id3 = body.id || (0, import_crypto8.randomUUID)();
|
|
337
577
|
const config = await store2.createConfig(tenantId, id3, body);
|
|
338
578
|
try {
|
|
339
579
|
await connectAndRegisterTools(config);
|
|
@@ -670,12 +910,12 @@ function registerMcpServerConfigRoutes(app2) {
|
|
|
670
910
|
app2.post("/api/mcp-servers/:key/disconnect", disconnectMcpServer);
|
|
671
911
|
app2.post("/api/mcp-servers/test-tools", testMcpServerTools);
|
|
672
912
|
}
|
|
673
|
-
var import_core30,
|
|
913
|
+
var import_core30, import_crypto8;
|
|
674
914
|
var init_mcp_configs = __esm({
|
|
675
915
|
"src/controllers/mcp-configs.ts"() {
|
|
676
916
|
"use strict";
|
|
677
917
|
import_core30 = require("@axiom-lattice/core");
|
|
678
|
-
|
|
918
|
+
import_crypto8 = require("crypto");
|
|
679
919
|
}
|
|
680
920
|
});
|
|
681
921
|
|
|
@@ -1264,10 +1504,11 @@ function devModeDefaults() {
|
|
|
1264
1504
|
const projectId = process.env[DEFAULT_PROJECT_ENV] || void 0;
|
|
1265
1505
|
return { tenantId, projectId };
|
|
1266
1506
|
}
|
|
1267
|
-
var A2AAuthError, DEFAULT_TENANT_ENV, DEFAULT_TENANT_ID, DEFAULT_PROJECT_ENV, BEARER_SCHEME_RE, A2AAuthService;
|
|
1507
|
+
var import_protocols29, A2AAuthError, DEFAULT_TENANT_ENV, DEFAULT_TENANT_ID, DEFAULT_PROJECT_ENV, BEARER_SCHEME_RE, A2AAuthService;
|
|
1268
1508
|
var init_A2AAuthService = __esm({
|
|
1269
1509
|
"src/services/a2a/A2AAuthService.ts"() {
|
|
1270
1510
|
"use strict";
|
|
1511
|
+
import_protocols29 = require("@axiom-lattice/protocols");
|
|
1271
1512
|
A2AAuthError = class extends Error {
|
|
1272
1513
|
constructor(message, statusCode) {
|
|
1273
1514
|
super(message);
|
|
@@ -1321,20 +1562,26 @@ var init_A2AAuthService = __esm({
|
|
|
1321
1562
|
const merged = new Map([...this.envKeyMap, ...storeMap]);
|
|
1322
1563
|
const entry = merged.get(token);
|
|
1323
1564
|
if (!entry) return { authenticated: false };
|
|
1565
|
+
const hasExplicitGrants = Array.isArray(entry.grants) && entry.grants.length > 0;
|
|
1566
|
+
const agentGrant = (0, import_protocols29.effectiveGrants)(entry).find((g) => g.domain === "agent");
|
|
1567
|
+
const assistantIds = hasExplicitGrants ? agentGrant?.items ?? [] : entry.assistantIds;
|
|
1324
1568
|
return {
|
|
1325
1569
|
authenticated: true,
|
|
1326
1570
|
apiKey: token,
|
|
1327
1571
|
tenantId: entry.tenantId,
|
|
1328
1572
|
projectId: entry.projectId,
|
|
1329
|
-
assistantIds
|
|
1573
|
+
assistantIds,
|
|
1330
1574
|
source: header2 && BEARER_SCHEME_RE.test(header2) ? "bearer" : "x-api-key"
|
|
1331
1575
|
};
|
|
1332
1576
|
}
|
|
1333
1577
|
/**
|
|
1334
|
-
* Assert that the given assistant is reachable under the provided auth
|
|
1335
|
-
* authenticated, within the key's
|
|
1578
|
+
* Assert that the given assistant is reachable under the provided auth
|
|
1579
|
+
* context: authenticated, same tenant, and within the key's whitelist.
|
|
1580
|
+
*
|
|
1581
|
+
* Authorization is unified on the API key — the agent no longer carries an
|
|
1582
|
+
* exposure flag; the key's assistant whitelist / grants is the single source.
|
|
1336
1583
|
*/
|
|
1337
|
-
async
|
|
1584
|
+
async assertAgentAccess(auth, assistantId) {
|
|
1338
1585
|
if (!auth.authenticated || !auth.tenantId) {
|
|
1339
1586
|
throw new A2AAuthError("Unauthorized", 401);
|
|
1340
1587
|
}
|
|
@@ -1343,12 +1590,9 @@ var init_A2AAuthService = __esm({
|
|
|
1343
1590
|
throw new A2AAuthError("Agent not found", 404);
|
|
1344
1591
|
}
|
|
1345
1592
|
const whitelist = auth.assistantIds;
|
|
1346
|
-
if (whitelist
|
|
1593
|
+
if (whitelist !== void 0 && !whitelist.includes(assistantId)) {
|
|
1347
1594
|
throw new A2AAuthError("Agent not allowed for this key", 403);
|
|
1348
1595
|
}
|
|
1349
|
-
if (assistant.graphDefinition?.a2aExposure?.enabled !== true) {
|
|
1350
|
-
throw new A2AAuthError("Agent not exposed", 404);
|
|
1351
|
-
}
|
|
1352
1596
|
return assistant;
|
|
1353
1597
|
}
|
|
1354
1598
|
/**
|
|
@@ -1356,7 +1600,7 @@ var init_A2AAuthService = __esm({
|
|
|
1356
1600
|
* in the tenant and every assistant belongs to the same tenant.
|
|
1357
1601
|
*/
|
|
1358
1602
|
async createKeyScoped(input) {
|
|
1359
|
-
const { tenantId, projectId, assistantIds, label } = input;
|
|
1603
|
+
const { tenantId, projectId, assistantIds, grants, label } = input;
|
|
1360
1604
|
if (!projectId) {
|
|
1361
1605
|
throw new A2AAuthError("projectId is required", 400);
|
|
1362
1606
|
}
|
|
@@ -1372,7 +1616,25 @@ var init_A2AAuthService = __esm({
|
|
|
1372
1616
|
}
|
|
1373
1617
|
}
|
|
1374
1618
|
}
|
|
1375
|
-
return this.keyStore.create({ tenantId, projectId, assistantIds, label });
|
|
1619
|
+
return this.keyStore.create({ tenantId, projectId, assistantIds, grants, label });
|
|
1620
|
+
}
|
|
1621
|
+
async updateKeyScoped(id3, tenantId, input) {
|
|
1622
|
+
const { projectId, assistantIds, grants, label } = input;
|
|
1623
|
+
if (projectId) {
|
|
1624
|
+
const project = await this.projectStore.getProjectById(tenantId, projectId);
|
|
1625
|
+
if (!project || project.tenantId !== tenantId) {
|
|
1626
|
+
throw new A2AAuthError("Project not found", 400);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
if (assistantIds && assistantIds.length > 0) {
|
|
1630
|
+
for (const aId of assistantIds) {
|
|
1631
|
+
const assistant = await this.assistantStore.getAssistantById(tenantId, aId);
|
|
1632
|
+
if (!assistant || assistant.tenantId !== tenantId) {
|
|
1633
|
+
throw new A2AAuthError("Assistant not found", 400);
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
return this.keyStore.update(id3, { label, projectId, assistantIds, grants });
|
|
1376
1638
|
}
|
|
1377
1639
|
extractToken(header2) {
|
|
1378
1640
|
if (!header2) return void 0;
|
|
@@ -1387,42 +1649,45 @@ var init_A2AAuthService = __esm({
|
|
|
1387
1649
|
});
|
|
1388
1650
|
|
|
1389
1651
|
// src/services/a2a/A2AAgentCardBuilder.ts
|
|
1652
|
+
function deriveAgentSkills(assistant) {
|
|
1653
|
+
const enabled = assistant.graphDefinition?.middleware?.filter((m) => m.enabled) ?? [];
|
|
1654
|
+
return enabled.map((m) => ({
|
|
1655
|
+
id: m.type || m.id,
|
|
1656
|
+
name: m.name || m.type || m.id,
|
|
1657
|
+
description: m.description || "",
|
|
1658
|
+
tags: [],
|
|
1659
|
+
examples: []
|
|
1660
|
+
}));
|
|
1661
|
+
}
|
|
1390
1662
|
function buildAgentCardForAssistant(params) {
|
|
1391
|
-
const { assistant,
|
|
1663
|
+
const { assistant, baseUrl } = params;
|
|
1392
1664
|
const jsonRpcUrl = `${baseUrl}/api/a2a/agents/${assistant.id}/jsonrpc`;
|
|
1393
|
-
const skills = (exposure?.skills ?? []).map((s) => ({
|
|
1394
|
-
id: s.id,
|
|
1395
|
-
name: s.name,
|
|
1396
|
-
description: s.description,
|
|
1397
|
-
tags: s.tags ?? [],
|
|
1398
|
-
examples: s.examples ?? []
|
|
1399
|
-
}));
|
|
1400
1665
|
return {
|
|
1401
1666
|
name: assistant.name,
|
|
1402
1667
|
description: assistant.description ?? "",
|
|
1403
1668
|
url: jsonRpcUrl,
|
|
1404
1669
|
protocolVersion: "0.3.0",
|
|
1405
1670
|
version: "1.0.0",
|
|
1406
|
-
defaultInputModes:
|
|
1407
|
-
defaultOutputModes:
|
|
1671
|
+
defaultInputModes: ["text"],
|
|
1672
|
+
defaultOutputModes: ["text"],
|
|
1408
1673
|
capabilities: {
|
|
1409
1674
|
streaming: true,
|
|
1410
1675
|
pushNotifications: false,
|
|
1411
1676
|
stateTransitionHistory: true
|
|
1412
1677
|
},
|
|
1413
|
-
skills,
|
|
1678
|
+
skills: deriveAgentSkills(assistant),
|
|
1414
1679
|
additionalInterfaces: [{ transport: "JSONRPC", url: jsonRpcUrl }],
|
|
1415
1680
|
securitySchemes: {
|
|
1416
1681
|
bearer: {
|
|
1417
1682
|
type: "http",
|
|
1418
1683
|
scheme: "Bearer",
|
|
1419
|
-
description: "
|
|
1684
|
+
description: "API key sent as an Authorization Bearer token"
|
|
1420
1685
|
},
|
|
1421
1686
|
apiKeyHeader: {
|
|
1422
1687
|
type: "apiKey",
|
|
1423
1688
|
in: "header",
|
|
1424
1689
|
name: "x-api-key",
|
|
1425
|
-
description: "
|
|
1690
|
+
description: "API key sent via the x-api-key header"
|
|
1426
1691
|
}
|
|
1427
1692
|
},
|
|
1428
1693
|
security: [{ bearer: [] }, { apiKeyHeader: [] }]
|
|
@@ -1896,13 +2161,20 @@ function agentMessage(text) {
|
|
|
1896
2161
|
parts: [{ kind: "text", text }]
|
|
1897
2162
|
};
|
|
1898
2163
|
}
|
|
1899
|
-
|
|
2164
|
+
function assistantHasGovernedTask(assistant) {
|
|
2165
|
+
const graph = assistant.graphDefinition;
|
|
2166
|
+
const middleware = graph && typeof graph === "object" ? graph.middleware : void 0;
|
|
2167
|
+
const taskMiddleware = Array.isArray(middleware) ? middleware.find((entry) => !!entry && typeof entry === "object" && entry.type === "task" && entry.enabled === true) : void 0;
|
|
2168
|
+
const allowedTools = taskMiddleware?.allowedTools;
|
|
2169
|
+
return !!taskMiddleware && (allowedTools === void 0 || Array.isArray(allowedTools) && (allowedTools.length === 0 || allowedTools.includes("manage_task")));
|
|
2170
|
+
}
|
|
2171
|
+
var import_uuid11, import_core66, import_protocols30, _AxiomAgentExecutor, AxiomAgentExecutor;
|
|
1900
2172
|
var init_AxiomAgentExecutor = __esm({
|
|
1901
2173
|
"src/services/a2a/AxiomAgentExecutor.ts"() {
|
|
1902
2174
|
"use strict";
|
|
1903
2175
|
import_uuid11 = require("uuid");
|
|
1904
2176
|
import_core66 = require("@axiom-lattice/core");
|
|
1905
|
-
|
|
2177
|
+
import_protocols30 = require("@axiom-lattice/protocols");
|
|
1906
2178
|
init_a2aFileRefs();
|
|
1907
2179
|
init_task_file_refs();
|
|
1908
2180
|
_AxiomAgentExecutor = class _AxiomAgentExecutor {
|
|
@@ -1949,18 +2221,13 @@ var init_AxiomAgentExecutor = __esm({
|
|
|
1949
2221
|
});
|
|
1950
2222
|
};
|
|
1951
2223
|
try {
|
|
1952
|
-
|
|
1953
|
-
if (!this.taskStore) {
|
|
1954
|
-
throw new Error("A2A governed execution requires a canonical task store");
|
|
1955
|
-
}
|
|
1956
|
-
this.assertGovernedTaskCapability();
|
|
1957
|
-
} catch (err) {
|
|
2224
|
+
if (!this.taskStore) {
|
|
1958
2225
|
const initialTask2 = createTask([]);
|
|
1959
|
-
if (this.taskStore) await this.taskStore.save(initialTask2);
|
|
1960
2226
|
bus.publish(initialTask2);
|
|
1961
|
-
publishFailed(
|
|
2227
|
+
publishFailed(new Error("A2A execution requires a canonical task store"));
|
|
1962
2228
|
return;
|
|
1963
2229
|
}
|
|
2230
|
+
const governed = this.hasGovernedTaskCapability();
|
|
1964
2231
|
const interruption = existing?.metadata?.interruption;
|
|
1965
2232
|
const reviewInterruption = interruption && typeof interruption === "object" && interruption.type === "review_required";
|
|
1966
2233
|
const reviewCommand = reviewInterruption ? this.reviewCommand(text) : void 0;
|
|
@@ -1997,13 +2264,13 @@ var init_AxiomAgentExecutor = __esm({
|
|
|
1997
2264
|
const requestText = inputFiles.length > 0 ? `${text}
|
|
1998
2265
|
|
|
1999
2266
|
${formatFileRefsSection(inputFiles)}` : text;
|
|
2000
|
-
const messageText = [
|
|
2267
|
+
const messageText = governed ? [
|
|
2001
2268
|
`A2A governed task instruction: get and update the existing TaskItem ${ctx.taskId}; do not create a replacement task.`,
|
|
2002
2269
|
"Before doing the requested work, initialize its canonical description through manage_task with ## Objective, ## Acceptance Criteria, and ## Belief State sections.",
|
|
2003
2270
|
"Keep lifecycle status truthful. Change status only through manage_task set_status; complete with a nonblank result and structured beliefImpact, and use interrupted, failed, or cancelled when appropriate. Use manage_task update for content fields only.",
|
|
2004
2271
|
"",
|
|
2005
2272
|
requestText
|
|
2006
|
-
].join("\n");
|
|
2273
|
+
].join("\n") : requestText;
|
|
2007
2274
|
const continuationCommand = interruption && typeof interruption === "object" ? { resume: text } : void 0;
|
|
2008
2275
|
const { messageId } = await agent.addMessage({
|
|
2009
2276
|
input: { message: messageText },
|
|
@@ -2011,16 +2278,22 @@ ${formatFileRefsSection(inputFiles)}` : text;
|
|
|
2011
2278
|
custom_run_config: { taskId: ctx.taskId }
|
|
2012
2279
|
});
|
|
2013
2280
|
const stream = agent.chunkStream(messageId, [
|
|
2014
|
-
|
|
2281
|
+
import_protocols30.MessageChunkTypes.MESSAGE_COMPLETED
|
|
2015
2282
|
]);
|
|
2283
|
+
let outputText = "";
|
|
2284
|
+
let interrupted = false;
|
|
2016
2285
|
for await (const chunk of stream) {
|
|
2017
2286
|
if (execution.canceled) return;
|
|
2018
2287
|
const chunkType = chunk.type;
|
|
2019
2288
|
const chunkText = chunk.data?.content ?? "";
|
|
2020
|
-
if (chunkType ===
|
|
2289
|
+
if (chunkType === import_protocols30.MessageChunkTypes.INTERRUPT) {
|
|
2290
|
+
interrupted = true;
|
|
2021
2291
|
break;
|
|
2022
2292
|
}
|
|
2023
|
-
if (chunkType ===
|
|
2293
|
+
if (chunkType === import_protocols30.MessageChunkTypes.AI && chunkText) {
|
|
2294
|
+
outputText += chunkText;
|
|
2295
|
+
}
|
|
2296
|
+
if (chunkType === import_protocols30.MessageChunkTypes.AI || chunkType === import_protocols30.MessageChunkTypes.TOOL) {
|
|
2024
2297
|
if (chunkText) {
|
|
2025
2298
|
bus.publish({
|
|
2026
2299
|
kind: "status-update",
|
|
@@ -2037,6 +2310,48 @@ ${formatFileRefsSection(inputFiles)}` : text;
|
|
|
2037
2310
|
}
|
|
2038
2311
|
}
|
|
2039
2312
|
if (execution.canceled) return;
|
|
2313
|
+
if (!governed) {
|
|
2314
|
+
if (interrupted) {
|
|
2315
|
+
const paused = {
|
|
2316
|
+
...createTask(inputFiles),
|
|
2317
|
+
status: { state: "input-required", timestamp: isoNow() }
|
|
2318
|
+
};
|
|
2319
|
+
await this.taskStore.save(paused);
|
|
2320
|
+
bus.publish({
|
|
2321
|
+
kind: "status-update",
|
|
2322
|
+
taskId: ctx.taskId,
|
|
2323
|
+
contextId: ctx.contextId,
|
|
2324
|
+
status: { state: "input-required", timestamp: isoNow() },
|
|
2325
|
+
final: true
|
|
2326
|
+
});
|
|
2327
|
+
return;
|
|
2328
|
+
}
|
|
2329
|
+
const resultArtifact = {
|
|
2330
|
+
artifactId: (0, import_uuid11.v4)(),
|
|
2331
|
+
name: "result",
|
|
2332
|
+
parts: [{ kind: "text", text: outputText }]
|
|
2333
|
+
};
|
|
2334
|
+
const completed = {
|
|
2335
|
+
...createTask(inputFiles),
|
|
2336
|
+
artifacts: [...existing?.artifacts ?? [], resultArtifact],
|
|
2337
|
+
status: { state: "completed", timestamp: isoNow() }
|
|
2338
|
+
};
|
|
2339
|
+
await this.taskStore.save(completed);
|
|
2340
|
+
bus.publish({
|
|
2341
|
+
kind: "artifact-update",
|
|
2342
|
+
taskId: ctx.taskId,
|
|
2343
|
+
contextId: ctx.contextId,
|
|
2344
|
+
artifact: resultArtifact
|
|
2345
|
+
});
|
|
2346
|
+
bus.publish({
|
|
2347
|
+
kind: "status-update",
|
|
2348
|
+
taskId: ctx.taskId,
|
|
2349
|
+
contextId: ctx.contextId,
|
|
2350
|
+
status: { state: "completed", timestamp: isoNow() },
|
|
2351
|
+
final: true
|
|
2352
|
+
});
|
|
2353
|
+
return;
|
|
2354
|
+
}
|
|
2040
2355
|
const canonical = await this.taskStore.load(ctx.taskId);
|
|
2041
2356
|
const canonicalState = canonical?.status.state;
|
|
2042
2357
|
if (canonicalState === "completed") {
|
|
@@ -2116,15 +2431,8 @@ ${formatFileRefsSection(inputFiles)}` : text;
|
|
|
2116
2431
|
taskKey(taskId) {
|
|
2117
2432
|
return `${this.scope.tenantId}:${this.scope.projectId}:${this.scope.assistantId}:${taskId}`;
|
|
2118
2433
|
}
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
const middleware = graph && typeof graph === "object" ? graph.middleware : void 0;
|
|
2122
|
-
const taskMiddleware = Array.isArray(middleware) ? middleware.find((entry) => !!entry && typeof entry === "object" && entry.type === "task" && entry.enabled === true) : void 0;
|
|
2123
|
-
const allowedTools = taskMiddleware?.allowedTools;
|
|
2124
|
-
const exposesManageTask = taskMiddleware && (allowedTools === void 0 || Array.isArray(allowedTools) && (allowedTools.length === 0 || allowedTools.includes("manage_task")));
|
|
2125
|
-
if (!exposesManageTask) {
|
|
2126
|
-
throw new Error("A2A execution requires enabled TaskMiddleware exposing manage_task");
|
|
2127
|
-
}
|
|
2434
|
+
hasGovernedTaskCapability() {
|
|
2435
|
+
return assistantHasGovernedTask(this.assistant);
|
|
2128
2436
|
}
|
|
2129
2437
|
/**
|
|
2130
2438
|
* Cancel a running task: resolve its thread id from the task store, abort the
|
|
@@ -2444,27 +2752,15 @@ function getHeader(value) {
|
|
|
2444
2752
|
if (Array.isArray(value)) return value[0];
|
|
2445
2753
|
return value;
|
|
2446
2754
|
}
|
|
2447
|
-
function getTenantHeader(request) {
|
|
2448
|
-
return getHeader(request.headers["x-tenant-id"]) ?? "default";
|
|
2449
|
-
}
|
|
2450
2755
|
function getSessionUser(request) {
|
|
2451
2756
|
return request.user;
|
|
2452
2757
|
}
|
|
2453
|
-
function getSessionTenantId(request) {
|
|
2454
|
-
const userTenantId = getSessionUser(request)?.tenantId;
|
|
2455
|
-
if (userTenantId) return userTenantId;
|
|
2456
|
-
return getTenantHeader(request);
|
|
2457
|
-
}
|
|
2458
2758
|
function buildBaseUrl(request) {
|
|
2459
2759
|
const protocol = getHeader(request.headers["x-forwarded-proto"]) ?? request.protocol;
|
|
2460
2760
|
const forwardedHost = getHeader(request.headers["x-forwarded-host"]);
|
|
2461
2761
|
const host = forwardedHost ? forwardedHost.split(",")[0].trim() : request.host;
|
|
2462
2762
|
return `${protocol}://${host}`;
|
|
2463
2763
|
}
|
|
2464
|
-
function getExposure(assistant) {
|
|
2465
|
-
const graphDefinition = assistant.graphDefinition;
|
|
2466
|
-
return graphDefinition?.a2aExposure;
|
|
2467
|
-
}
|
|
2468
2764
|
function makeFileIngestor(tenantId, maxFileBytes) {
|
|
2469
2765
|
return new A2AFileIngestor({
|
|
2470
2766
|
saveProjectFile: (params) => saveProjectFile({ tenantId, ...params }),
|
|
@@ -2504,33 +2800,6 @@ function registerA2AStandardRoutes(app2, deps) {
|
|
|
2504
2800
|
const resolveTaskWorkItems = deps.getTaskWorkItemStore ?? (() => (0, import_core67.getStoreLattice)("default", "taskWorkItem").store);
|
|
2505
2801
|
const getAssistantStore2 = deps.getAssistantStore ?? (() => (0, import_core67.getStoreLattice)("default", "assistant").store);
|
|
2506
2802
|
const getProjectStore2 = deps.getProjectStore ?? (() => (0, import_core67.getStoreLattice)("default", "project").store);
|
|
2507
|
-
const getTenantStore = deps.getTenantStore ?? (() => {
|
|
2508
|
-
try {
|
|
2509
|
-
return (0, import_core67.getStoreLattice)("default", "tenant").store;
|
|
2510
|
-
} catch {
|
|
2511
|
-
return void 0;
|
|
2512
|
-
}
|
|
2513
|
-
});
|
|
2514
|
-
async function findExposedAssistant(request, assistantId) {
|
|
2515
|
-
const tenantId = getSessionTenantId(request);
|
|
2516
|
-
const direct = await getAssistantStore2().getAssistantById(
|
|
2517
|
-
tenantId,
|
|
2518
|
-
assistantId
|
|
2519
|
-
);
|
|
2520
|
-
if (direct) return direct;
|
|
2521
|
-
const tenantStore = getTenantStore();
|
|
2522
|
-
if (!tenantStore) return null;
|
|
2523
|
-
const tenants = await tenantStore.getAllTenants();
|
|
2524
|
-
for (const tenant2 of tenants) {
|
|
2525
|
-
if (tenant2.id === tenantId) continue;
|
|
2526
|
-
const found = await getAssistantStore2().getAssistantById(
|
|
2527
|
-
tenant2.id,
|
|
2528
|
-
assistantId
|
|
2529
|
-
);
|
|
2530
|
-
if (found) return found;
|
|
2531
|
-
}
|
|
2532
|
-
return null;
|
|
2533
|
-
}
|
|
2534
2803
|
const runtimeRegistry = deps.runtimeRegistry ?? new A2ARuntimeRegistry();
|
|
2535
2804
|
app2.addHook("onClose", async () => {
|
|
2536
2805
|
runtimeRegistry.close();
|
|
@@ -2538,19 +2807,32 @@ function registerA2AStandardRoutes(app2, deps) {
|
|
|
2538
2807
|
app2.get(
|
|
2539
2808
|
"/api/a2a/agents/:assistantId/.well-known/agent-card.json",
|
|
2540
2809
|
async (request, reply) => {
|
|
2541
|
-
const
|
|
2542
|
-
request
|
|
2543
|
-
request.params.assistantId
|
|
2810
|
+
const auth = await authService.authenticate(
|
|
2811
|
+
getHeader(request.headers.authorization) ?? getHeader(request.headers["x-api-key"])
|
|
2544
2812
|
);
|
|
2545
|
-
if (!
|
|
2546
|
-
reply.status(
|
|
2813
|
+
if (!auth.authenticated) {
|
|
2814
|
+
reply.status(401).send({ error: "Unauthorized" });
|
|
2815
|
+
return;
|
|
2816
|
+
}
|
|
2817
|
+
let assistant;
|
|
2818
|
+
try {
|
|
2819
|
+
assistant = await authService.assertAgentAccess(
|
|
2820
|
+
auth,
|
|
2821
|
+
request.params.assistantId
|
|
2822
|
+
);
|
|
2823
|
+
} catch (err) {
|
|
2824
|
+
if (err instanceof A2AAuthError) {
|
|
2825
|
+
reply.status(err.statusCode).send({ error: err.message });
|
|
2826
|
+
return;
|
|
2827
|
+
}
|
|
2828
|
+
request.log.error({ err }, "a2a:agent-card:auth");
|
|
2829
|
+
reply.status(500).send({ error: "Internal error" });
|
|
2547
2830
|
return;
|
|
2548
2831
|
}
|
|
2549
2832
|
reply.header("A2A-Version", "0.3");
|
|
2550
2833
|
reply.status(200).send(
|
|
2551
2834
|
buildAgentCardForAssistant({
|
|
2552
2835
|
assistant,
|
|
2553
|
-
exposure: getExposure(assistant),
|
|
2554
2836
|
baseUrl: buildBaseUrl(request)
|
|
2555
2837
|
})
|
|
2556
2838
|
);
|
|
@@ -2569,7 +2851,7 @@ function registerA2AStandardRoutes(app2, deps) {
|
|
|
2569
2851
|
}
|
|
2570
2852
|
let assistant;
|
|
2571
2853
|
try {
|
|
2572
|
-
assistant = await authService.
|
|
2854
|
+
assistant = await authService.assertAgentAccess(
|
|
2573
2855
|
auth,
|
|
2574
2856
|
request.params.assistantId
|
|
2575
2857
|
);
|
|
@@ -2595,7 +2877,7 @@ function registerA2AStandardRoutes(app2, deps) {
|
|
|
2595
2877
|
};
|
|
2596
2878
|
const internalTasks = resolveTasks();
|
|
2597
2879
|
const workItems = resolveTaskWorkItems();
|
|
2598
|
-
const taskStore = new A2ATaskStoreAdapter({
|
|
2880
|
+
const taskStore = assistantHasGovernedTask(assistant) ? new A2ATaskStoreAdapter({
|
|
2599
2881
|
taskStore: internalTasks,
|
|
2600
2882
|
workItemStore: workItems,
|
|
2601
2883
|
lifecycle: (0, import_core67.createTaskLifecycleService)({
|
|
@@ -2603,12 +2885,11 @@ function registerA2AStandardRoutes(app2, deps) {
|
|
|
2603
2885
|
workItemStore: workItems
|
|
2604
2886
|
}),
|
|
2605
2887
|
scope
|
|
2606
|
-
});
|
|
2888
|
+
}) : new import_server2.InMemoryTaskStore();
|
|
2607
2889
|
const ingestor = makeFileIngestor(scope.tenantId, deps.maxFileBytes);
|
|
2608
2890
|
const executor = new AxiomAgentExecutor({ scope, assistant, taskStore, ingestor });
|
|
2609
2891
|
const card = buildAgentCardForAssistant({
|
|
2610
2892
|
assistant,
|
|
2611
|
-
exposure: getExposure(assistant),
|
|
2612
2893
|
baseUrl: buildBaseUrl(request)
|
|
2613
2894
|
});
|
|
2614
2895
|
let runtimeLease;
|
|
@@ -2714,7 +2995,7 @@ data: ${JSON.stringify(errorResponse)}
|
|
|
2714
2995
|
const ingestor = makeFileIngestor(scope.tenantId, deps.maxFileBytes);
|
|
2715
2996
|
const internalTasks = resolveTasks();
|
|
2716
2997
|
const workItems = resolveTaskWorkItems();
|
|
2717
|
-
const taskStore = new A2ATaskStoreAdapter({
|
|
2998
|
+
const taskStore = assistantHasGovernedTask(assistant) ? new A2ATaskStoreAdapter({
|
|
2718
2999
|
taskStore: internalTasks,
|
|
2719
3000
|
workItemStore: workItems,
|
|
2720
3001
|
lifecycle: (0, import_core67.createTaskLifecycleService)({
|
|
@@ -2722,7 +3003,7 @@ data: ${JSON.stringify(errorResponse)}
|
|
|
2722
3003
|
workItemStore: workItems
|
|
2723
3004
|
}),
|
|
2724
3005
|
scope
|
|
2725
|
-
});
|
|
3006
|
+
}) : new import_server2.InMemoryTaskStore();
|
|
2726
3007
|
const executor = new AxiomAgentExecutor({ scope, assistant, taskStore, ingestor });
|
|
2727
3008
|
const taskId = (0, import_uuid12.v4)();
|
|
2728
3009
|
const contextId = (0, import_uuid12.v4)();
|
|
@@ -2857,6 +3138,7 @@ async function handleApiKeyCreate(request, reply) {
|
|
|
2857
3138
|
tenantId,
|
|
2858
3139
|
projectId: body.projectId,
|
|
2859
3140
|
assistantIds: body.assistantIds,
|
|
3141
|
+
grants: body.grants,
|
|
2860
3142
|
label: body.label
|
|
2861
3143
|
});
|
|
2862
3144
|
await refreshStoreKeyMap();
|
|
@@ -2870,6 +3152,36 @@ async function handleApiKeyCreate(request, reply) {
|
|
|
2870
3152
|
reply.status(500).send({ success: false, error: "Failed to create key" });
|
|
2871
3153
|
}
|
|
2872
3154
|
}
|
|
3155
|
+
async function handleApiKeyUpdate(request, reply) {
|
|
3156
|
+
if (!_a2aKeyStore || !_a2aAuthService) {
|
|
3157
|
+
reply.status(501).send({ error: "Key store not configured" });
|
|
3158
|
+
return;
|
|
3159
|
+
}
|
|
3160
|
+
if (!await authorizeKeyMutation(request, reply)) return;
|
|
3161
|
+
const body = request.body;
|
|
3162
|
+
const tenantId = getUserTenantId(request);
|
|
3163
|
+
try {
|
|
3164
|
+
const record = await _a2aAuthService.updateKeyScoped(
|
|
3165
|
+
request.params.id,
|
|
3166
|
+
tenantId,
|
|
3167
|
+
{
|
|
3168
|
+
label: body.label,
|
|
3169
|
+
projectId: body.projectId,
|
|
3170
|
+
assistantIds: body.assistantIds,
|
|
3171
|
+
grants: body.grants
|
|
3172
|
+
}
|
|
3173
|
+
);
|
|
3174
|
+
await refreshStoreKeyMap();
|
|
3175
|
+
reply.status(200).send({ success: true, data: record });
|
|
3176
|
+
} catch (err) {
|
|
3177
|
+
if (err instanceof A2AAuthError) {
|
|
3178
|
+
reply.status(err.statusCode).send({ success: false, error: err.message });
|
|
3179
|
+
return;
|
|
3180
|
+
}
|
|
3181
|
+
request.log.error({ err }, "a2a:keys:update");
|
|
3182
|
+
reply.status(500).send({ success: false, error: "Failed to update key" });
|
|
3183
|
+
}
|
|
3184
|
+
}
|
|
2873
3185
|
async function handleApiKeyDelete(request, reply) {
|
|
2874
3186
|
if (!await authorizeKeyMutation(request, reply)) return;
|
|
2875
3187
|
await _a2aKeyStore.delete(request.params.id);
|
|
@@ -2896,36 +3208,43 @@ async function handleApiKeyRotate(request, reply) {
|
|
|
2896
3208
|
}
|
|
2897
3209
|
function registerA2ARoutes(app2) {
|
|
2898
3210
|
const options = { preHandler: requireTenantSession };
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
3211
|
+
for (const base of ["/api/keys", "/api/a2a/keys"]) {
|
|
3212
|
+
app2.get(
|
|
3213
|
+
base,
|
|
3214
|
+
options,
|
|
3215
|
+
handleApiKeyList
|
|
3216
|
+
);
|
|
3217
|
+
app2.post(
|
|
3218
|
+
base,
|
|
3219
|
+
options,
|
|
3220
|
+
handleApiKeyCreate
|
|
3221
|
+
);
|
|
3222
|
+
app2.delete(
|
|
3223
|
+
`${base}/:id`,
|
|
3224
|
+
options,
|
|
3225
|
+
handleApiKeyDelete
|
|
3226
|
+
);
|
|
3227
|
+
app2.post(
|
|
3228
|
+
`${base}/:id/disable`,
|
|
3229
|
+
options,
|
|
3230
|
+
handleApiKeyDisable
|
|
3231
|
+
);
|
|
3232
|
+
app2.post(
|
|
3233
|
+
`${base}/:id/enable`,
|
|
3234
|
+
options,
|
|
3235
|
+
handleApiKeyEnable
|
|
3236
|
+
);
|
|
3237
|
+
app2.post(
|
|
3238
|
+
`${base}/:id/rotate`,
|
|
3239
|
+
options,
|
|
3240
|
+
handleApiKeyRotate
|
|
3241
|
+
);
|
|
3242
|
+
app2.patch(
|
|
3243
|
+
`${base}/:id`,
|
|
3244
|
+
options,
|
|
3245
|
+
handleApiKeyUpdate
|
|
3246
|
+
);
|
|
3247
|
+
}
|
|
2929
3248
|
}
|
|
2930
3249
|
var _a2aKeyStore, _a2aAuthService;
|
|
2931
3250
|
var init_a2a = __esm({
|
|
@@ -2937,120 +3256,387 @@ var init_a2a = __esm({
|
|
|
2937
3256
|
}
|
|
2938
3257
|
});
|
|
2939
3258
|
|
|
2940
|
-
// src/services/open/
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
}
|
|
2945
|
-
var SPIKE_CREDENTIALS;
|
|
2946
|
-
var init_openCredentials = __esm({
|
|
2947
|
-
"src/services/open/openCredentials.ts"() {
|
|
3259
|
+
// src/services/open/openAuthService.ts
|
|
3260
|
+
var import_protocols31, OpenAuthService;
|
|
3261
|
+
var init_openAuthService = __esm({
|
|
3262
|
+
"src/services/open/openAuthService.ts"() {
|
|
2948
3263
|
"use strict";
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
3264
|
+
import_protocols31 = require("@axiom-lattice/protocols");
|
|
3265
|
+
OpenAuthService = class {
|
|
3266
|
+
constructor(keyStore) {
|
|
3267
|
+
this.keyStore = keyStore;
|
|
3268
|
+
}
|
|
3269
|
+
async resolve(bearer) {
|
|
3270
|
+
if (!bearer) return null;
|
|
3271
|
+
const record = await this.keyStore.findByKey(bearer);
|
|
3272
|
+
if (!record || !record.enabled) return null;
|
|
3273
|
+
return {
|
|
3274
|
+
credentialId: record.id,
|
|
2954
3275
|
kind: "api_key",
|
|
2955
|
-
tenantId:
|
|
2956
|
-
projectId:
|
|
2957
|
-
grants:
|
|
3276
|
+
tenantId: record.tenantId,
|
|
3277
|
+
projectId: record.projectId,
|
|
3278
|
+
grants: (0, import_protocols31.effectiveGrants)(record)
|
|
3279
|
+
};
|
|
3280
|
+
}
|
|
3281
|
+
};
|
|
3282
|
+
}
|
|
3283
|
+
});
|
|
3284
|
+
|
|
3285
|
+
// src/services/open/openCredentialService.ts
|
|
3286
|
+
var import_protocols32, OpenCredentialService;
|
|
3287
|
+
var init_openCredentialService = __esm({
|
|
3288
|
+
"src/services/open/openCredentialService.ts"() {
|
|
3289
|
+
"use strict";
|
|
3290
|
+
import_protocols32 = require("@axiom-lattice/protocols");
|
|
3291
|
+
init_openToken();
|
|
3292
|
+
init_openAuthService();
|
|
3293
|
+
OpenCredentialService = class {
|
|
3294
|
+
constructor(keyStore, projectStore) {
|
|
3295
|
+
this.projectStore = projectStore;
|
|
3296
|
+
this.auth = new OpenAuthService(keyStore);
|
|
3297
|
+
}
|
|
3298
|
+
async resolve(bearer) {
|
|
3299
|
+
if (!bearer) return null;
|
|
3300
|
+
const token = verifyOpenToken(bearer);
|
|
3301
|
+
if (token) {
|
|
3302
|
+
if (token.kind === "sandbox_token") {
|
|
3303
|
+
return {
|
|
3304
|
+
credentialId: `sandbox:${token.sandboxName}`,
|
|
3305
|
+
kind: "sandbox_token",
|
|
3306
|
+
tenantId: token.tenantId,
|
|
3307
|
+
projectId: token.projectId,
|
|
3308
|
+
workspaceId: token.workspaceId,
|
|
3309
|
+
sandboxName: token.sandboxName,
|
|
3310
|
+
grants: token.grants
|
|
3311
|
+
};
|
|
3312
|
+
}
|
|
3313
|
+
return {
|
|
3314
|
+
credentialId: `browser:${token.preview ? "preview:" : ""}${token.shareId ?? token.tenantId}`,
|
|
3315
|
+
kind: "browser_token",
|
|
3316
|
+
tenantId: token.tenantId,
|
|
3317
|
+
projectId: token.projectId,
|
|
3318
|
+
workspaceId: token.workspaceId,
|
|
3319
|
+
grants: token.grants
|
|
3320
|
+
};
|
|
2958
3321
|
}
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
{
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
3322
|
+
const ctx = await this.auth.resolve(bearer);
|
|
3323
|
+
if (!ctx) return null;
|
|
3324
|
+
let workspaceId;
|
|
3325
|
+
if (this.projectStore) {
|
|
3326
|
+
try {
|
|
3327
|
+
const project = await this.projectStore.getProjectById(
|
|
3328
|
+
ctx.tenantId,
|
|
3329
|
+
ctx.projectId
|
|
3330
|
+
);
|
|
3331
|
+
workspaceId = project?.workspaceId;
|
|
3332
|
+
} catch {
|
|
3333
|
+
}
|
|
2968
3334
|
}
|
|
2969
|
-
|
|
2970
|
-
|
|
3335
|
+
return {
|
|
3336
|
+
credentialId: ctx.credentialId,
|
|
3337
|
+
kind: "api_key",
|
|
3338
|
+
tenantId: ctx.tenantId,
|
|
3339
|
+
projectId: ctx.projectId,
|
|
3340
|
+
workspaceId,
|
|
3341
|
+
grants: ctx.grants
|
|
3342
|
+
};
|
|
3343
|
+
}
|
|
3344
|
+
};
|
|
2971
3345
|
}
|
|
2972
3346
|
});
|
|
2973
3347
|
|
|
2974
|
-
// src/services/open/
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
}
|
|
2985
|
-
async function getSession(sessionId) {
|
|
2986
|
-
return sessions.get(sessionId) ?? null;
|
|
3348
|
+
// src/services/open/openAuditService.ts
|
|
3349
|
+
function redactArgs(args, depth = 0) {
|
|
3350
|
+
if (args === null || typeof args !== "object") return args;
|
|
3351
|
+
if (depth > 6) return "[depth-limit]";
|
|
3352
|
+
if (Array.isArray(args)) return args.map((v) => redactArgs(v, depth + 1));
|
|
3353
|
+
const out = {};
|
|
3354
|
+
for (const [key, value] of Object.entries(args)) {
|
|
3355
|
+
out[key] = SENSITIVE_KEY.test(key) ? "[redacted]" : redactArgs(value, depth + 1);
|
|
3356
|
+
}
|
|
3357
|
+
return out;
|
|
2987
3358
|
}
|
|
2988
|
-
|
|
2989
|
-
const
|
|
2990
|
-
if (
|
|
2991
|
-
|
|
2992
|
-
await entry.transport.close().catch(() => void 0);
|
|
2993
|
-
await entry.server.close().catch(() => void 0);
|
|
3359
|
+
function truncate2(value) {
|
|
3360
|
+
const s = JSON.stringify(value ?? null);
|
|
3361
|
+
if (s.length <= MAX_ARGS_CHARS) return value ?? null;
|
|
3362
|
+
return `${s.slice(0, MAX_ARGS_CHARS)}...[truncated]`;
|
|
2994
3363
|
}
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
3364
|
+
var SENSITIVE_KEY, MAX_ARGS_CHARS, OpenAuditService;
|
|
3365
|
+
var init_openAuditService = __esm({
|
|
3366
|
+
"src/services/open/openAuditService.ts"() {
|
|
3367
|
+
"use strict";
|
|
3368
|
+
SENSITIVE_KEY = /pass(word)?|secret|token|api[-_]?key|authorization|credential/i;
|
|
3369
|
+
MAX_ARGS_CHARS = 2e3;
|
|
3370
|
+
OpenAuditService = class {
|
|
3371
|
+
constructor(store2) {
|
|
3372
|
+
this.store = store2;
|
|
3373
|
+
}
|
|
3374
|
+
async record(input) {
|
|
3375
|
+
try {
|
|
3376
|
+
await this.store.append({
|
|
3377
|
+
...input,
|
|
3378
|
+
args: truncate2(redactArgs(input.args))
|
|
3379
|
+
});
|
|
3380
|
+
} catch {
|
|
3381
|
+
}
|
|
3382
|
+
}
|
|
3383
|
+
};
|
|
2998
3384
|
}
|
|
2999
|
-
}
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3385
|
+
});
|
|
3386
|
+
|
|
3387
|
+
// src/services/open/openRateLimiter.ts
|
|
3388
|
+
var OpenRateLimiter;
|
|
3389
|
+
var init_openRateLimiter = __esm({
|
|
3390
|
+
"src/services/open/openRateLimiter.ts"() {
|
|
3003
3391
|
"use strict";
|
|
3004
|
-
|
|
3392
|
+
OpenRateLimiter = class {
|
|
3393
|
+
constructor(options = {}) {
|
|
3394
|
+
this.buckets = /* @__PURE__ */ new Map();
|
|
3395
|
+
this.defaultPerMinute = options.defaultPerMinute ?? 60;
|
|
3396
|
+
this.agentPerMinute = options.agentPerMinute ?? 10;
|
|
3397
|
+
}
|
|
3398
|
+
bucketClass(domain) {
|
|
3399
|
+
return domain === "agent" ? "agent" : "default";
|
|
3400
|
+
}
|
|
3401
|
+
limitFor(domain) {
|
|
3402
|
+
return domain === "agent" ? this.agentPerMinute : this.defaultPerMinute;
|
|
3403
|
+
}
|
|
3404
|
+
/** Consume one token; denied calls report how long to wait. */
|
|
3405
|
+
check(credentialId, domain) {
|
|
3406
|
+
const limit = this.limitFor(domain);
|
|
3407
|
+
const key = `${this.bucketClass(domain)}:${credentialId}`;
|
|
3408
|
+
const now = Date.now();
|
|
3409
|
+
const bucket = this.buckets.get(key) ?? { tokens: limit, updatedAt: now };
|
|
3410
|
+
const refillPerMs = limit / 6e4;
|
|
3411
|
+
const elapsed = now - bucket.updatedAt;
|
|
3412
|
+
bucket.tokens = Math.min(limit, bucket.tokens + elapsed * refillPerMs);
|
|
3413
|
+
bucket.updatedAt = now;
|
|
3414
|
+
if (bucket.tokens >= 1) {
|
|
3415
|
+
bucket.tokens -= 1;
|
|
3416
|
+
this.buckets.set(key, bucket);
|
|
3417
|
+
return { allowed: true };
|
|
3418
|
+
}
|
|
3419
|
+
this.buckets.set(key, bucket);
|
|
3420
|
+
const deficit = 1 - bucket.tokens;
|
|
3421
|
+
return { allowed: false, retryAfterMs: Math.ceil(deficit / refillPerMs) };
|
|
3422
|
+
}
|
|
3423
|
+
/** Test helper. */
|
|
3424
|
+
reset() {
|
|
3425
|
+
this.buckets.clear();
|
|
3426
|
+
}
|
|
3427
|
+
};
|
|
3005
3428
|
}
|
|
3006
3429
|
});
|
|
3007
3430
|
|
|
3008
|
-
// src/services/open/
|
|
3009
|
-
|
|
3010
|
-
|
|
3431
|
+
// src/services/open/openLattice.ts
|
|
3432
|
+
var openLattice_exports = {};
|
|
3433
|
+
__export(openLattice_exports, {
|
|
3434
|
+
ActionNotFoundError: () => ActionNotFoundError,
|
|
3435
|
+
GrantDeniedError: () => GrantDeniedError,
|
|
3436
|
+
OpenLattice: () => OpenLattice,
|
|
3437
|
+
ValidationError: () => ValidationError,
|
|
3438
|
+
openLattice: () => openLattice
|
|
3439
|
+
});
|
|
3440
|
+
function effectiveToolName(domain, action) {
|
|
3441
|
+
return action.toolName ?? `${domain}_${action.name}`;
|
|
3011
3442
|
}
|
|
3012
|
-
function
|
|
3013
|
-
|
|
3014
|
-
|
|
3443
|
+
function grantCoversAction(grants, domain, action) {
|
|
3444
|
+
return grants.some(
|
|
3445
|
+
(g) => g.domain === domain && (!g.items || g.items.length === 0 || g.items.includes(action))
|
|
3446
|
+
);
|
|
3015
3447
|
}
|
|
3016
|
-
var import_zod16,
|
|
3017
|
-
var
|
|
3018
|
-
"src/services/open/
|
|
3448
|
+
var import_zod16, GrantDeniedError, ValidationError, ActionNotFoundError, OpenLattice, openLattice;
|
|
3449
|
+
var init_openLattice = __esm({
|
|
3450
|
+
"src/services/open/openLattice.ts"() {
|
|
3019
3451
|
"use strict";
|
|
3020
3452
|
import_zod16 = require("zod");
|
|
3021
|
-
|
|
3022
|
-
{
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3453
|
+
GrantDeniedError = class extends Error {
|
|
3454
|
+
constructor(toolName) {
|
|
3455
|
+
super(`GRANT_DENIED: no grant covers ${toolName}`);
|
|
3456
|
+
this.code = "GRANT_DENIED";
|
|
3457
|
+
this.name = "GrantDeniedError";
|
|
3458
|
+
}
|
|
3459
|
+
};
|
|
3460
|
+
ValidationError = class extends Error {
|
|
3461
|
+
constructor(detail) {
|
|
3462
|
+
super(`VALIDATION_FAILED: ${detail}`);
|
|
3463
|
+
this.code = "VALIDATION_FAILED";
|
|
3464
|
+
this.name = "ValidationError";
|
|
3465
|
+
}
|
|
3466
|
+
};
|
|
3467
|
+
ActionNotFoundError = class extends Error {
|
|
3468
|
+
constructor(toolName) {
|
|
3469
|
+
super(`ACTION_NOT_FOUND: ${toolName}`);
|
|
3470
|
+
this.code = "ACTION_NOT_FOUND";
|
|
3471
|
+
this.name = "ActionNotFoundError";
|
|
3472
|
+
}
|
|
3473
|
+
};
|
|
3474
|
+
OpenLattice = class {
|
|
3475
|
+
constructor() {
|
|
3476
|
+
this.providers = /* @__PURE__ */ new Map();
|
|
3477
|
+
}
|
|
3478
|
+
/** Register a provider; domain+action collisions are rejected. */
|
|
3479
|
+
register(declaration) {
|
|
3480
|
+
const existing = this.providers.get(declaration.domain);
|
|
3481
|
+
if (existing) {
|
|
3482
|
+
throw new Error(
|
|
3483
|
+
`Open provider domain already registered: ${declaration.domain}`
|
|
3484
|
+
);
|
|
3034
3485
|
}
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3486
|
+
const actions = /* @__PURE__ */ new Map();
|
|
3487
|
+
for (const action of declaration.actions) {
|
|
3488
|
+
actions.set(action.name, action);
|
|
3489
|
+
}
|
|
3490
|
+
this.providers.set(declaration.domain, { declaration, actions });
|
|
3491
|
+
}
|
|
3492
|
+
/** Tool descriptors visible under the given grants (default-deny). */
|
|
3493
|
+
async catalogFor(grants, ctx) {
|
|
3494
|
+
const catalog = [];
|
|
3495
|
+
for (const [domain, entry] of this.providers) {
|
|
3496
|
+
for (const [actionName, action] of entry.actions) {
|
|
3497
|
+
if (!grantCoversAction(grants, domain, actionName)) continue;
|
|
3498
|
+
catalog.push({
|
|
3499
|
+
toolName: effectiveToolName(domain, action),
|
|
3500
|
+
domain,
|
|
3501
|
+
action: actionName,
|
|
3502
|
+
description: action.description,
|
|
3503
|
+
schema: action.schema,
|
|
3504
|
+
annotations: action.annotations
|
|
3505
|
+
});
|
|
3506
|
+
}
|
|
3507
|
+
if (entry.declaration.instanceActions) {
|
|
3508
|
+
const instances = await entry.declaration.instanceActions(grants, ctx);
|
|
3509
|
+
for (const action of instances) {
|
|
3510
|
+
catalog.push({
|
|
3511
|
+
toolName: effectiveToolName(domain, action),
|
|
3512
|
+
domain,
|
|
3513
|
+
action: action.name,
|
|
3514
|
+
description: action.description,
|
|
3515
|
+
schema: action.schema,
|
|
3516
|
+
annotations: action.annotations
|
|
3517
|
+
});
|
|
3518
|
+
}
|
|
3519
|
+
}
|
|
3045
3520
|
}
|
|
3521
|
+
return catalog;
|
|
3046
3522
|
}
|
|
3047
|
-
|
|
3523
|
+
/**
|
|
3524
|
+
* Full grantable catalog (unfiltered by grants) for the management picker.
|
|
3525
|
+
* Instance domains (agent) return an empty item list — the catalog service
|
|
3526
|
+
* fills their per-tenant instances.
|
|
3527
|
+
*/
|
|
3528
|
+
describeCatalog() {
|
|
3529
|
+
const domains = [];
|
|
3530
|
+
for (const [domain, entry] of this.providers) {
|
|
3531
|
+
const declaration = entry.declaration;
|
|
3532
|
+
const items = [];
|
|
3533
|
+
if ((declaration.itemKind ?? "action") === "action") {
|
|
3534
|
+
for (const [actionName, action] of entry.actions) {
|
|
3535
|
+
items.push({
|
|
3536
|
+
id: actionName,
|
|
3537
|
+
toolName: `${domain}_${actionName}`,
|
|
3538
|
+
label: action.label ?? actionName,
|
|
3539
|
+
description: action.description,
|
|
3540
|
+
annotations: action.annotations
|
|
3541
|
+
});
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3544
|
+
domains.push({
|
|
3545
|
+
domain,
|
|
3546
|
+
label: declaration.label ?? domain,
|
|
3547
|
+
source: declaration.source ?? "builtin",
|
|
3548
|
+
scopeKind: declaration.scopeKind ?? "tenant",
|
|
3549
|
+
itemKind: declaration.itemKind ?? "action",
|
|
3550
|
+
items
|
|
3551
|
+
});
|
|
3552
|
+
}
|
|
3553
|
+
return domains;
|
|
3554
|
+
}
|
|
3555
|
+
async resolveAction(grants, toolName, ctx) {
|
|
3556
|
+
for (const [domain, entry] of this.providers) {
|
|
3557
|
+
for (const [actionName, action] of entry.actions) {
|
|
3558
|
+
if (effectiveToolName(domain, action) === toolName) {
|
|
3559
|
+
return { domain, entry, action, actionName };
|
|
3560
|
+
}
|
|
3561
|
+
}
|
|
3562
|
+
if (entry.declaration.instanceActions) {
|
|
3563
|
+
const instances = await entry.declaration.instanceActions(grants, ctx);
|
|
3564
|
+
for (const action of instances) {
|
|
3565
|
+
if (effectiveToolName(domain, action) === toolName) {
|
|
3566
|
+
return { domain, entry, action, actionName: action.name };
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
}
|
|
3570
|
+
}
|
|
3571
|
+
return null;
|
|
3572
|
+
}
|
|
3573
|
+
/** Whether the given grants cover a tool (`{domain}_{action}`). */
|
|
3574
|
+
isAllowed(grants, toolName) {
|
|
3575
|
+
const sep2 = toolName.indexOf("_");
|
|
3576
|
+
const domain = sep2 > 0 ? toolName.slice(0, sep2) : toolName;
|
|
3577
|
+
const action = sep2 > 0 ? toolName.slice(sep2 + 1) : "";
|
|
3578
|
+
return grantCoversAction(grants, domain, action);
|
|
3579
|
+
}
|
|
3580
|
+
/** The single credential-driven execution path. */
|
|
3581
|
+
async invoke(grants, ctx, toolName, args) {
|
|
3582
|
+
const resolved = await this.resolveAction(grants, toolName, { tenantId: ctx.tenantId });
|
|
3583
|
+
if (!resolved) {
|
|
3584
|
+
throw new ActionNotFoundError(toolName);
|
|
3585
|
+
}
|
|
3586
|
+
if (!grantCoversAction(grants, resolved.domain, resolved.actionName)) {
|
|
3587
|
+
throw new GrantDeniedError(toolName);
|
|
3588
|
+
}
|
|
3589
|
+
const resolvedSchema = resolved.action.schema;
|
|
3590
|
+
const parsed = "safeParse" in resolvedSchema ? resolvedSchema.safeParse(args) : import_zod16.z.object(resolvedSchema).safeParse(args);
|
|
3591
|
+
if (!parsed.success) {
|
|
3592
|
+
throw new ValidationError(parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; "));
|
|
3593
|
+
}
|
|
3594
|
+
return resolved.entry.declaration.execute(resolved.actionName, parsed.data, ctx);
|
|
3595
|
+
}
|
|
3596
|
+
};
|
|
3597
|
+
openLattice = new OpenLattice();
|
|
3598
|
+
}
|
|
3599
|
+
});
|
|
3600
|
+
|
|
3601
|
+
// src/services/open/mcpTransportRegistry.ts
|
|
3602
|
+
var mcpTransportRegistry_exports = {};
|
|
3603
|
+
__export(mcpTransportRegistry_exports, {
|
|
3604
|
+
clearSessions: () => clearSessions,
|
|
3605
|
+
deleteSession: () => deleteSession,
|
|
3606
|
+
getSession: () => getSession,
|
|
3607
|
+
registerSession: () => registerSession
|
|
3608
|
+
});
|
|
3609
|
+
async function registerSession(sessionId, credential, parts) {
|
|
3610
|
+
sessions.set(sessionId, { ...parts, credential });
|
|
3611
|
+
}
|
|
3612
|
+
async function getSession(sessionId) {
|
|
3613
|
+
return sessions.get(sessionId) ?? null;
|
|
3614
|
+
}
|
|
3615
|
+
async function deleteSession(sessionId) {
|
|
3616
|
+
const entry = sessions.get(sessionId);
|
|
3617
|
+
if (!entry) return;
|
|
3618
|
+
sessions.delete(sessionId);
|
|
3619
|
+
await entry.transport.close().catch(() => void 0);
|
|
3620
|
+
await entry.server.close().catch(() => void 0);
|
|
3621
|
+
}
|
|
3622
|
+
async function clearSessions() {
|
|
3623
|
+
for (const sessionId of [...sessions.keys()]) {
|
|
3624
|
+
await deleteSession(sessionId);
|
|
3625
|
+
}
|
|
3626
|
+
}
|
|
3627
|
+
var sessions;
|
|
3628
|
+
var init_mcpTransportRegistry = __esm({
|
|
3629
|
+
"src/services/open/mcpTransportRegistry.ts"() {
|
|
3630
|
+
"use strict";
|
|
3631
|
+
sessions = /* @__PURE__ */ new Map();
|
|
3048
3632
|
}
|
|
3049
3633
|
});
|
|
3050
3634
|
|
|
3051
3635
|
// src/services/open/openMcpServer.ts
|
|
3052
|
-
function
|
|
3053
|
-
|
|
3636
|
+
async function buildSessionServer(options) {
|
|
3637
|
+
const { credential, grants, catalog, invoke } = options;
|
|
3638
|
+
const server = new import_mcp.McpServer(OPEN_MCP_SERVER_INFO);
|
|
3639
|
+
for (const tool of catalog) {
|
|
3054
3640
|
server.registerTool(
|
|
3055
3641
|
tool.toolName,
|
|
3056
3642
|
{
|
|
@@ -3061,17 +3647,15 @@ function registerTools(server, tools) {
|
|
|
3061
3647
|
destructiveHint: tool.annotations.destructiveHint
|
|
3062
3648
|
}
|
|
3063
3649
|
},
|
|
3064
|
-
async (args) =>
|
|
3650
|
+
async (args) => {
|
|
3651
|
+
const result = await invoke(tool.toolName, args);
|
|
3652
|
+
return { content: result.content, isError: result.isError };
|
|
3653
|
+
}
|
|
3065
3654
|
);
|
|
3066
3655
|
}
|
|
3067
|
-
}
|
|
3068
|
-
async function buildSessionServer(credential) {
|
|
3069
|
-
const tools = filterCatalogByGrants(credential);
|
|
3070
|
-
const server = new import_mcp.McpServer(OPEN_MCP_SERVER_INFO);
|
|
3071
|
-
registerTools(server, tools);
|
|
3072
3656
|
const transport = new import_streamableHttp.StreamableHTTPServerTransport({
|
|
3073
3657
|
sessionIdGenerator: () => {
|
|
3074
|
-
const sessionId = (0,
|
|
3658
|
+
const sessionId = (0, import_crypto13.randomUUID)();
|
|
3075
3659
|
void registerSession(
|
|
3076
3660
|
sessionId,
|
|
3077
3661
|
{ credentialId: credential.credentialId, kind: credential.kind },
|
|
@@ -3085,85 +3669,945 @@ async function buildSessionServer(credential) {
|
|
|
3085
3669
|
({ deleteSession: deleteSession2 }) => deleteSession2(closedId)
|
|
3086
3670
|
);
|
|
3087
3671
|
}
|
|
3088
|
-
});
|
|
3089
|
-
await server.connect(transport);
|
|
3090
|
-
return { server, transport, tools };
|
|
3672
|
+
});
|
|
3673
|
+
await server.connect(transport);
|
|
3674
|
+
return { server, transport, tools: catalog };
|
|
3675
|
+
}
|
|
3676
|
+
var import_mcp, import_streamableHttp, import_crypto13, OPEN_MCP_SERVER_INFO;
|
|
3677
|
+
var init_openMcpServer = __esm({
|
|
3678
|
+
"src/services/open/openMcpServer.ts"() {
|
|
3679
|
+
"use strict";
|
|
3680
|
+
import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
3681
|
+
import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
3682
|
+
import_crypto13 = require("crypto");
|
|
3683
|
+
init_mcpTransportRegistry();
|
|
3684
|
+
OPEN_MCP_SERVER_INFO = {
|
|
3685
|
+
name: "axiom-open",
|
|
3686
|
+
version: "0.1.0"
|
|
3687
|
+
};
|
|
3688
|
+
}
|
|
3689
|
+
});
|
|
3690
|
+
|
|
3691
|
+
// src/routes/open.ts
|
|
3692
|
+
var open_exports = {};
|
|
3693
|
+
__export(open_exports, {
|
|
3694
|
+
registerOpenRoutes: () => registerOpenRoutes
|
|
3695
|
+
});
|
|
3696
|
+
function extractBearer(request) {
|
|
3697
|
+
const header2 = request.headers.authorization;
|
|
3698
|
+
if (!header2?.startsWith("Bearer ")) return void 0;
|
|
3699
|
+
return header2.slice("Bearer ".length).trim() || void 0;
|
|
3700
|
+
}
|
|
3701
|
+
function readSessionId(request) {
|
|
3702
|
+
const raw = request.headers["mcp-session-id"];
|
|
3703
|
+
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
3704
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
3705
|
+
}
|
|
3706
|
+
function registerOpenRoutes(app2, deps = {}) {
|
|
3707
|
+
const openAuth = deps.openAuth ?? new OpenCredentialService(
|
|
3708
|
+
(0, import_core68.getStoreLattice)("default", "a2aApiKey").store,
|
|
3709
|
+
(0, import_core68.getStoreLattice)("default", "project").store
|
|
3710
|
+
);
|
|
3711
|
+
const grantsSource = deps.grantsSource ?? ((ctx) => ctx.grants);
|
|
3712
|
+
const audit = deps.audit ?? (() => {
|
|
3713
|
+
try {
|
|
3714
|
+
const store2 = (0, import_core68.getStoreLattice)("default", "openAudit").store;
|
|
3715
|
+
return new OpenAuditService(store2);
|
|
3716
|
+
} catch {
|
|
3717
|
+
return void 0;
|
|
3718
|
+
}
|
|
3719
|
+
})();
|
|
3720
|
+
const rateLimiter = deps.rateLimiter ?? new OpenRateLimiter();
|
|
3721
|
+
app2.post("/open/mcp", async (request, reply) => {
|
|
3722
|
+
const context = await openAuth.resolve(extractBearer(request));
|
|
3723
|
+
if (!context) {
|
|
3724
|
+
return reply.status(401).send({ error: "AUTH_FAILED" });
|
|
3725
|
+
}
|
|
3726
|
+
const body = request.body;
|
|
3727
|
+
const sessionId = readSessionId(request);
|
|
3728
|
+
if (sessionId) {
|
|
3729
|
+
const session = await getSession(sessionId);
|
|
3730
|
+
if (!session || session.credential.credentialId !== context.credentialId) {
|
|
3731
|
+
return reply.status(404).send({ error: "SESSION_NOT_FOUND" });
|
|
3732
|
+
}
|
|
3733
|
+
reply.hijack();
|
|
3734
|
+
await session.transport.handleRequest(request.raw, reply.raw, body);
|
|
3735
|
+
return;
|
|
3736
|
+
}
|
|
3737
|
+
if (!(0, import_types.isInitializeRequest)(body)) {
|
|
3738
|
+
return reply.status(400).send({ error: "SESSION_REQUIRED" });
|
|
3739
|
+
}
|
|
3740
|
+
const grants = grantsSource(context);
|
|
3741
|
+
const catalog = await openLattice.catalogFor(grants, { tenantId: context.tenantId });
|
|
3742
|
+
const built = await buildSessionServer({
|
|
3743
|
+
credential: { credentialId: context.credentialId, kind: context.kind },
|
|
3744
|
+
grants,
|
|
3745
|
+
catalog,
|
|
3746
|
+
invoke: async (toolName, args) => {
|
|
3747
|
+
const startedAt = Date.now();
|
|
3748
|
+
const sep2 = toolName.indexOf("_");
|
|
3749
|
+
const auditDomain = sep2 > 0 ? toolName.slice(0, sep2) : toolName;
|
|
3750
|
+
const auditAction = sep2 > 0 ? toolName.slice(sep2 + 1) : "";
|
|
3751
|
+
const decision = rateLimiter.check(context.credentialId, auditDomain);
|
|
3752
|
+
if (!decision.allowed) {
|
|
3753
|
+
await audit?.record({
|
|
3754
|
+
tenantId: context.tenantId,
|
|
3755
|
+
credentialId: context.credentialId,
|
|
3756
|
+
credentialKind: context.kind,
|
|
3757
|
+
projectId: context.projectId,
|
|
3758
|
+
domain: auditDomain,
|
|
3759
|
+
action: auditAction,
|
|
3760
|
+
args,
|
|
3761
|
+
status: "error",
|
|
3762
|
+
errorCode: "RATE_LIMITED",
|
|
3763
|
+
durationMs: Date.now() - startedAt
|
|
3764
|
+
});
|
|
3765
|
+
throw Object.assign(
|
|
3766
|
+
new Error(
|
|
3767
|
+
`RATE_LIMITED: retry after ${decision.retryAfterMs ?? 1e3}ms`
|
|
3768
|
+
),
|
|
3769
|
+
{ rpcCode: RPC_ERROR.RATE_LIMITED }
|
|
3770
|
+
);
|
|
3771
|
+
}
|
|
3772
|
+
try {
|
|
3773
|
+
const result = await openLattice.invoke(
|
|
3774
|
+
grants,
|
|
3775
|
+
{
|
|
3776
|
+
tenantId: context.tenantId,
|
|
3777
|
+
projectId: context.projectId,
|
|
3778
|
+
workspaceId: context.workspaceId,
|
|
3779
|
+
runConfig: {
|
|
3780
|
+
sandboxName: context.sandboxName,
|
|
3781
|
+
credentialId: context.credentialId
|
|
3782
|
+
}
|
|
3783
|
+
},
|
|
3784
|
+
toolName,
|
|
3785
|
+
args
|
|
3786
|
+
);
|
|
3787
|
+
await audit?.record({
|
|
3788
|
+
tenantId: context.tenantId,
|
|
3789
|
+
credentialId: context.credentialId,
|
|
3790
|
+
credentialKind: context.kind,
|
|
3791
|
+
projectId: context.projectId,
|
|
3792
|
+
domain: auditDomain,
|
|
3793
|
+
action: auditAction,
|
|
3794
|
+
args,
|
|
3795
|
+
status: "ok",
|
|
3796
|
+
durationMs: Date.now() - startedAt
|
|
3797
|
+
});
|
|
3798
|
+
return result;
|
|
3799
|
+
} catch (err) {
|
|
3800
|
+
const code = err instanceof GrantDeniedError ? RPC_ERROR.GRANT_DENIED : err instanceof ActionNotFoundError ? RPC_ERROR.ACTION_NOT_FOUND : err instanceof ValidationError ? RPC_ERROR.VALIDATION_FAILED : RPC_ERROR.EXECUTION_ERROR;
|
|
3801
|
+
await audit?.record({
|
|
3802
|
+
tenantId: context.tenantId,
|
|
3803
|
+
credentialId: context.credentialId,
|
|
3804
|
+
credentialKind: context.kind,
|
|
3805
|
+
projectId: context.projectId,
|
|
3806
|
+
domain: auditDomain,
|
|
3807
|
+
action: auditAction,
|
|
3808
|
+
args,
|
|
3809
|
+
status: "error",
|
|
3810
|
+
errorCode: err instanceof GrantDeniedError ? "GRANT_DENIED" : err instanceof ActionNotFoundError ? "ACTION_NOT_FOUND" : err instanceof ValidationError ? "VALIDATION_FAILED" : "EXECUTION_ERROR",
|
|
3811
|
+
durationMs: Date.now() - startedAt
|
|
3812
|
+
});
|
|
3813
|
+
throw Object.assign(
|
|
3814
|
+
new Error(err instanceof Error ? err.message : String(err)),
|
|
3815
|
+
{ rpcCode: code }
|
|
3816
|
+
);
|
|
3817
|
+
}
|
|
3818
|
+
}
|
|
3819
|
+
});
|
|
3820
|
+
reply.hijack();
|
|
3821
|
+
await built.transport.handleRequest(request.raw, reply.raw, body);
|
|
3822
|
+
});
|
|
3823
|
+
app2.delete(
|
|
3824
|
+
"/open/mcp",
|
|
3825
|
+
async (request, reply) => {
|
|
3826
|
+
const sessionId = readSessionId(request);
|
|
3827
|
+
if (!sessionId) {
|
|
3828
|
+
return reply.status(400).send({ error: "SESSION_REQUIRED" });
|
|
3829
|
+
}
|
|
3830
|
+
await deleteSession(sessionId);
|
|
3831
|
+
return reply.status(204).send();
|
|
3832
|
+
}
|
|
3833
|
+
);
|
|
3834
|
+
}
|
|
3835
|
+
var import_types, import_core68, RPC_ERROR;
|
|
3836
|
+
var init_open = __esm({
|
|
3837
|
+
"src/routes/open.ts"() {
|
|
3838
|
+
"use strict";
|
|
3839
|
+
import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
3840
|
+
import_core68 = require("@axiom-lattice/core");
|
|
3841
|
+
init_openCredentialService();
|
|
3842
|
+
init_openAuditService();
|
|
3843
|
+
init_openRateLimiter();
|
|
3844
|
+
init_openLattice();
|
|
3845
|
+
init_openMcpServer();
|
|
3846
|
+
init_mcpTransportRegistry();
|
|
3847
|
+
RPC_ERROR = {
|
|
3848
|
+
GRANT_DENIED: -32001,
|
|
3849
|
+
ACTION_NOT_FOUND: -32002,
|
|
3850
|
+
VALIDATION_FAILED: -32003,
|
|
3851
|
+
EXECUTION_ERROR: -32004,
|
|
3852
|
+
RATE_LIMITED: -32005
|
|
3853
|
+
};
|
|
3854
|
+
}
|
|
3855
|
+
});
|
|
3856
|
+
|
|
3857
|
+
// src/routes/open-session.ts
|
|
3858
|
+
var open_session_exports = {};
|
|
3859
|
+
__export(open_session_exports, {
|
|
3860
|
+
registerOpenSessionRoutes: () => registerOpenSessionRoutes
|
|
3861
|
+
});
|
|
3862
|
+
function registerOpenSessionRoutes(app2) {
|
|
3863
|
+
app2.post(
|
|
3864
|
+
"/open/session",
|
|
3865
|
+
async (request, reply) => {
|
|
3866
|
+
const body = request.body ?? {};
|
|
3867
|
+
const shareToken = body.shareToken;
|
|
3868
|
+
if (typeof shareToken !== "string" || shareToken.length === 0) {
|
|
3869
|
+
return reply.status(400).send({ error: "SHARE_TOKEN_REQUIRED" });
|
|
3870
|
+
}
|
|
3871
|
+
const store2 = (0, import_core69.getStoreLattice)("default", "sharedResource").store;
|
|
3872
|
+
const record = await store2.findByToken(shareToken);
|
|
3873
|
+
if (!record || record.revoked) {
|
|
3874
|
+
return reply.status(404).send({ error: "SHARE_NOT_FOUND" });
|
|
3875
|
+
}
|
|
3876
|
+
if (record.expiresAt && new Date(record.expiresAt) < /* @__PURE__ */ new Date()) {
|
|
3877
|
+
return reply.status(410).send({ error: "SHARE_EXPIRED" });
|
|
3878
|
+
}
|
|
3879
|
+
const grants = BROWSER_GRANTS;
|
|
3880
|
+
const browserToken = signOpenToken({
|
|
3881
|
+
kind: "browser_token",
|
|
3882
|
+
tenantId: record.tenantId,
|
|
3883
|
+
projectId: record.projectId,
|
|
3884
|
+
shareId: record.token,
|
|
3885
|
+
grants
|
|
3886
|
+
});
|
|
3887
|
+
const actions = await openLattice.catalogFor(grants, { tenantId: record.tenantId });
|
|
3888
|
+
return reply.status(200).send({
|
|
3889
|
+
browserToken,
|
|
3890
|
+
expiresAt: Date.now() + 15 * 60 * 1e3,
|
|
3891
|
+
actions: actions.map((a) => a.toolName)
|
|
3892
|
+
});
|
|
3893
|
+
}
|
|
3894
|
+
);
|
|
3895
|
+
}
|
|
3896
|
+
var import_core69;
|
|
3897
|
+
var init_open_session = __esm({
|
|
3898
|
+
"src/routes/open-session.ts"() {
|
|
3899
|
+
"use strict";
|
|
3900
|
+
import_core69 = require("@axiom-lattice/core");
|
|
3901
|
+
init_openToken();
|
|
3902
|
+
init_previewToken();
|
|
3903
|
+
init_openLattice();
|
|
3904
|
+
}
|
|
3905
|
+
});
|
|
3906
|
+
|
|
3907
|
+
// src/services/open/openCatalogService.ts
|
|
3908
|
+
var OpenCatalogService;
|
|
3909
|
+
var init_openCatalogService = __esm({
|
|
3910
|
+
"src/services/open/openCatalogService.ts"() {
|
|
3911
|
+
"use strict";
|
|
3912
|
+
init_openLattice();
|
|
3913
|
+
OpenCatalogService = class {
|
|
3914
|
+
constructor(assistantStore, lattice = openLattice) {
|
|
3915
|
+
this.assistantStore = assistantStore;
|
|
3916
|
+
this.lattice = lattice;
|
|
3917
|
+
}
|
|
3918
|
+
async buildForTenant(tenantId) {
|
|
3919
|
+
const domains = this.lattice.describeCatalog();
|
|
3920
|
+
const enriched = [];
|
|
3921
|
+
for (const domain of domains) {
|
|
3922
|
+
if (domain.domain === "agent" && domain.itemKind === "instance") {
|
|
3923
|
+
let items = [];
|
|
3924
|
+
try {
|
|
3925
|
+
const assistants = await this.assistantStore.getAllAssistants(tenantId);
|
|
3926
|
+
items = assistants.map((a) => ({
|
|
3927
|
+
id: a.id,
|
|
3928
|
+
toolName: `invoke_${a.id}`,
|
|
3929
|
+
label: a.name || a.id
|
|
3930
|
+
}));
|
|
3931
|
+
} catch {
|
|
3932
|
+
items = [];
|
|
3933
|
+
}
|
|
3934
|
+
enriched.push({ ...domain, items });
|
|
3935
|
+
} else {
|
|
3936
|
+
enriched.push(domain);
|
|
3937
|
+
}
|
|
3938
|
+
}
|
|
3939
|
+
return { domains: enriched };
|
|
3940
|
+
}
|
|
3941
|
+
};
|
|
3942
|
+
}
|
|
3943
|
+
});
|
|
3944
|
+
|
|
3945
|
+
// src/routes/open-catalog.ts
|
|
3946
|
+
var open_catalog_exports = {};
|
|
3947
|
+
__export(open_catalog_exports, {
|
|
3948
|
+
registerOpenCatalogRoutes: () => registerOpenCatalogRoutes
|
|
3949
|
+
});
|
|
3950
|
+
function tenantIdOf(request) {
|
|
3951
|
+
return request.user?.tenantId;
|
|
3952
|
+
}
|
|
3953
|
+
function registerOpenCatalogRoutes(app2) {
|
|
3954
|
+
app2.get("/api/open/catalog", async (request, reply) => {
|
|
3955
|
+
const tenantId = tenantIdOf(request);
|
|
3956
|
+
if (!tenantId) {
|
|
3957
|
+
return reply.status(401).send({ success: false, error: "Unauthorized" });
|
|
3958
|
+
}
|
|
3959
|
+
const assistantStore = (0, import_core70.getStoreLattice)("default", "assistant").store;
|
|
3960
|
+
const service2 = new OpenCatalogService(assistantStore);
|
|
3961
|
+
const catalog = await service2.buildForTenant(tenantId);
|
|
3962
|
+
return reply.status(200).send({ success: true, data: catalog });
|
|
3963
|
+
});
|
|
3964
|
+
}
|
|
3965
|
+
var import_core70;
|
|
3966
|
+
var init_open_catalog = __esm({
|
|
3967
|
+
"src/routes/open-catalog.ts"() {
|
|
3968
|
+
"use strict";
|
|
3969
|
+
import_core70 = require("@axiom-lattice/core");
|
|
3970
|
+
init_openCatalogService();
|
|
3971
|
+
}
|
|
3972
|
+
});
|
|
3973
|
+
|
|
3974
|
+
// src/services/open/providers/sandboxProvider.ts
|
|
3975
|
+
var sandboxProvider_exports = {};
|
|
3976
|
+
__export(sandboxProvider_exports, {
|
|
3977
|
+
createOpenSandboxProvider: () => createOpenSandboxProvider,
|
|
3978
|
+
resolveContextSandbox: () => resolveContextSandbox
|
|
3979
|
+
});
|
|
3980
|
+
async function resolveContextSandbox(ctx) {
|
|
3981
|
+
return import_core71.sandboxLatticeManager.getSandboxFromConfig({
|
|
3982
|
+
assistant_id: "",
|
|
3983
|
+
thread_id: "",
|
|
3984
|
+
tenantId: ctx.tenantId,
|
|
3985
|
+
workspaceId: ctx.workspaceId ?? "",
|
|
3986
|
+
projectId: ctx.projectId
|
|
3987
|
+
});
|
|
3988
|
+
}
|
|
3989
|
+
function createOpenSandboxProvider() {
|
|
3990
|
+
return {
|
|
3991
|
+
domain: "sandbox",
|
|
3992
|
+
label: "Sandbox",
|
|
3993
|
+
source: "builtin",
|
|
3994
|
+
scopeKind: "project",
|
|
3995
|
+
actions: [
|
|
3996
|
+
{
|
|
3997
|
+
name: "files_read",
|
|
3998
|
+
label: "Read files",
|
|
3999
|
+
description: "Read a file from the project sandbox.",
|
|
4000
|
+
schema: { path: import_zod17.z.string().min(1) },
|
|
4001
|
+
annotations: { readOnlyHint: true, destructiveHint: false }
|
|
4002
|
+
},
|
|
4003
|
+
{
|
|
4004
|
+
name: "files_list",
|
|
4005
|
+
label: "List files",
|
|
4006
|
+
description: "List files under a directory in the project sandbox.",
|
|
4007
|
+
schema: { path: import_zod17.z.string(), recursive: import_zod17.z.boolean().optional() },
|
|
4008
|
+
annotations: { readOnlyHint: true, destructiveHint: false }
|
|
4009
|
+
},
|
|
4010
|
+
{
|
|
4011
|
+
name: "files_write",
|
|
4012
|
+
label: "Write files",
|
|
4013
|
+
description: "Write content to a file in the project sandbox.",
|
|
4014
|
+
schema: { path: import_zod17.z.string().min(1), content: import_zod17.z.string() },
|
|
4015
|
+
annotations: { readOnlyHint: false, destructiveHint: true }
|
|
4016
|
+
},
|
|
4017
|
+
{
|
|
4018
|
+
name: "shell_exec",
|
|
4019
|
+
label: "Run shell commands",
|
|
4020
|
+
description: "Execute a shell command in the project sandbox. Returns stdout (up to 64KB) and exit code.",
|
|
4021
|
+
schema: {
|
|
4022
|
+
command: import_zod17.z.string().min(1),
|
|
4023
|
+
exec_dir: import_zod17.z.string().optional(),
|
|
4024
|
+
timeout: import_zod17.z.number().int().min(1e3).optional()
|
|
4025
|
+
},
|
|
4026
|
+
annotations: { readOnlyHint: false, destructiveHint: true }
|
|
4027
|
+
}
|
|
4028
|
+
],
|
|
4029
|
+
execute: async (actionName, args, ctx) => {
|
|
4030
|
+
const sandbox = await resolveContextSandbox(ctx);
|
|
4031
|
+
switch (actionName) {
|
|
4032
|
+
case "files_read": {
|
|
4033
|
+
const { path: path7 } = args;
|
|
4034
|
+
const file = await sandbox.file.readFile(path7);
|
|
4035
|
+
return { content: [{ type: "text", text: file.content }] };
|
|
4036
|
+
}
|
|
4037
|
+
case "files_list": {
|
|
4038
|
+
const { path: path7, recursive } = args;
|
|
4039
|
+
const listing = await sandbox.file.listPath(path7, { recursive });
|
|
4040
|
+
return {
|
|
4041
|
+
content: [{ type: "text", text: JSON.stringify(listing.files) }]
|
|
4042
|
+
};
|
|
4043
|
+
}
|
|
4044
|
+
case "files_write": {
|
|
4045
|
+
const { path: path7, content } = args;
|
|
4046
|
+
await sandbox.file.writeFile(path7, content);
|
|
4047
|
+
return { content: [{ type: "text", text: `wrote ${path7}` }] };
|
|
4048
|
+
}
|
|
4049
|
+
case "shell_exec": {
|
|
4050
|
+
const { command, exec_dir, timeout } = args;
|
|
4051
|
+
const result = await sandbox.shell.execCommand({
|
|
4052
|
+
command,
|
|
4053
|
+
exec_dir,
|
|
4054
|
+
timeout: timeout ?? 12e4
|
|
4055
|
+
});
|
|
4056
|
+
const truncated = result.output.length > MAX_OUTPUT_BYTES ? result.output.slice(0, MAX_OUTPUT_BYTES) + `
|
|
4057
|
+
...[truncated ${result.output.length - MAX_OUTPUT_BYTES} bytes]` : result.output;
|
|
4058
|
+
return {
|
|
4059
|
+
content: [
|
|
4060
|
+
{
|
|
4061
|
+
type: "text",
|
|
4062
|
+
text: `exit_code: ${result.exit_code}
|
|
4063
|
+
${truncated}`
|
|
4064
|
+
}
|
|
4065
|
+
]
|
|
4066
|
+
};
|
|
4067
|
+
}
|
|
4068
|
+
default:
|
|
4069
|
+
return {
|
|
4070
|
+
content: [
|
|
4071
|
+
{ type: "text", text: `Unknown sandbox action: ${actionName}` }
|
|
4072
|
+
],
|
|
4073
|
+
isError: true
|
|
4074
|
+
};
|
|
4075
|
+
}
|
|
4076
|
+
}
|
|
4077
|
+
};
|
|
4078
|
+
}
|
|
4079
|
+
var import_zod17, import_core71, MAX_OUTPUT_BYTES;
|
|
4080
|
+
var init_sandboxProvider = __esm({
|
|
4081
|
+
"src/services/open/providers/sandboxProvider.ts"() {
|
|
4082
|
+
"use strict";
|
|
4083
|
+
import_zod17 = require("zod");
|
|
4084
|
+
import_core71 = require("@axiom-lattice/core");
|
|
4085
|
+
MAX_OUTPUT_BYTES = 64e3;
|
|
4086
|
+
}
|
|
4087
|
+
});
|
|
4088
|
+
|
|
4089
|
+
// src/routes/open-files.ts
|
|
4090
|
+
var open_files_exports = {};
|
|
4091
|
+
__export(open_files_exports, {
|
|
4092
|
+
registerOpenFilesRoutes: () => registerOpenFilesRoutes
|
|
4093
|
+
});
|
|
4094
|
+
function extractBearer2(request) {
|
|
4095
|
+
const header2 = request.headers.authorization;
|
|
4096
|
+
if (!header2?.startsWith("Bearer ")) return void 0;
|
|
4097
|
+
return header2.slice("Bearer ".length).trim() || void 0;
|
|
4098
|
+
}
|
|
4099
|
+
function safePath(raw) {
|
|
4100
|
+
if (typeof raw !== "string" || raw.length === 0) return null;
|
|
4101
|
+
if (raw.includes("..")) return null;
|
|
4102
|
+
return raw.startsWith("/") ? raw : `/${raw}`;
|
|
4103
|
+
}
|
|
4104
|
+
function registerOpenFilesRoutes(app2, deps = {}) {
|
|
4105
|
+
const openAuth = deps.openAuth ?? new OpenCredentialService(
|
|
4106
|
+
(0, import_core72.getStoreLattice)("default", "a2aApiKey").store,
|
|
4107
|
+
(0, import_core72.getStoreLattice)("default", "project").store
|
|
4108
|
+
);
|
|
4109
|
+
const audit = deps.audit ?? (() => {
|
|
4110
|
+
try {
|
|
4111
|
+
const store2 = (0, import_core72.getStoreLattice)("default", "openAudit").store;
|
|
4112
|
+
return new OpenAuditService(store2);
|
|
4113
|
+
} catch {
|
|
4114
|
+
return void 0;
|
|
4115
|
+
}
|
|
4116
|
+
})();
|
|
4117
|
+
app2.addContentTypeParser(
|
|
4118
|
+
"application/octet-stream",
|
|
4119
|
+
{ parseAs: "buffer" },
|
|
4120
|
+
(_req, body, done) => done(null, body)
|
|
4121
|
+
);
|
|
4122
|
+
app2.get("/open/sandbox/files/download", async (request, reply) => {
|
|
4123
|
+
const context = await openAuth.resolve(extractBearer2(request));
|
|
4124
|
+
if (!context) return reply.status(401).send({ error: "AUTH_FAILED" });
|
|
4125
|
+
const path7 = safePath(request.query.path);
|
|
4126
|
+
if (!path7) return reply.status(400).send({ error: "PATH_REQUIRED" });
|
|
4127
|
+
if (!openLattice.isAllowed(context.grants, "sandbox_files_read")) {
|
|
4128
|
+
return reply.status(403).send({ error: "GRANT_DENIED" });
|
|
4129
|
+
}
|
|
4130
|
+
const startedAt = Date.now();
|
|
4131
|
+
try {
|
|
4132
|
+
const sandbox = await resolveContextSandbox({
|
|
4133
|
+
tenantId: context.tenantId,
|
|
4134
|
+
projectId: context.projectId,
|
|
4135
|
+
workspaceId: context.workspaceId,
|
|
4136
|
+
runConfig: {}
|
|
4137
|
+
});
|
|
4138
|
+
const data = await sandbox.file.downloadFile({ file: path7 });
|
|
4139
|
+
await audit?.record({
|
|
4140
|
+
tenantId: context.tenantId,
|
|
4141
|
+
credentialId: context.credentialId,
|
|
4142
|
+
credentialKind: context.kind,
|
|
4143
|
+
projectId: context.projectId,
|
|
4144
|
+
domain: "sandbox",
|
|
4145
|
+
action: "files_read",
|
|
4146
|
+
args: { path: path7 },
|
|
4147
|
+
status: "ok",
|
|
4148
|
+
durationMs: Date.now() - startedAt
|
|
4149
|
+
});
|
|
4150
|
+
return reply.status(200).type("application/octet-stream").header("Content-Disposition", "attachment").send(data);
|
|
4151
|
+
} catch (err) {
|
|
4152
|
+
await audit?.record({
|
|
4153
|
+
tenantId: context.tenantId,
|
|
4154
|
+
credentialId: context.credentialId,
|
|
4155
|
+
credentialKind: context.kind,
|
|
4156
|
+
projectId: context.projectId,
|
|
4157
|
+
domain: "sandbox",
|
|
4158
|
+
action: "files_read",
|
|
4159
|
+
args: { path: path7 },
|
|
4160
|
+
status: "error",
|
|
4161
|
+
errorCode: "EXECUTION_ERROR",
|
|
4162
|
+
durationMs: Date.now() - startedAt
|
|
4163
|
+
});
|
|
4164
|
+
return reply.status(502).send({
|
|
4165
|
+
error: err instanceof Error ? err.message : "SANDBOX_ERROR"
|
|
4166
|
+
});
|
|
4167
|
+
}
|
|
4168
|
+
});
|
|
4169
|
+
app2.post("/open/sandbox/files/upload", async (request, reply) => {
|
|
4170
|
+
const context = await openAuth.resolve(extractBearer2(request));
|
|
4171
|
+
if (!context) return reply.status(401).send({ error: "AUTH_FAILED" });
|
|
4172
|
+
const path7 = safePath(request.query.path);
|
|
4173
|
+
if (!path7) return reply.status(400).send({ error: "PATH_REQUIRED" });
|
|
4174
|
+
if (!openLattice.isAllowed(context.grants, "sandbox_files_write")) {
|
|
4175
|
+
return reply.status(403).send({ error: "GRANT_DENIED" });
|
|
4176
|
+
}
|
|
4177
|
+
const body = request.body;
|
|
4178
|
+
if (!Buffer.isBuffer(body)) {
|
|
4179
|
+
return reply.status(400).send({ error: "BINARY_BODY_REQUIRED" });
|
|
4180
|
+
}
|
|
4181
|
+
const startedAt = Date.now();
|
|
4182
|
+
try {
|
|
4183
|
+
const sandbox = await resolveContextSandbox({
|
|
4184
|
+
tenantId: context.tenantId,
|
|
4185
|
+
projectId: context.projectId,
|
|
4186
|
+
workspaceId: context.workspaceId,
|
|
4187
|
+
runConfig: {}
|
|
4188
|
+
});
|
|
4189
|
+
await sandbox.file.uploadFile({ file: path7, data: body });
|
|
4190
|
+
await audit?.record({
|
|
4191
|
+
tenantId: context.tenantId,
|
|
4192
|
+
credentialId: context.credentialId,
|
|
4193
|
+
credentialKind: context.kind,
|
|
4194
|
+
projectId: context.projectId,
|
|
4195
|
+
domain: "sandbox",
|
|
4196
|
+
action: "files_write",
|
|
4197
|
+
args: { path: path7, bytes: body.length },
|
|
4198
|
+
status: "ok",
|
|
4199
|
+
durationMs: Date.now() - startedAt
|
|
4200
|
+
});
|
|
4201
|
+
return reply.status(200).send({ success: true, path: path7 });
|
|
4202
|
+
} catch (err) {
|
|
4203
|
+
await audit?.record({
|
|
4204
|
+
tenantId: context.tenantId,
|
|
4205
|
+
credentialId: context.credentialId,
|
|
4206
|
+
credentialKind: context.kind,
|
|
4207
|
+
projectId: context.projectId,
|
|
4208
|
+
domain: "sandbox",
|
|
4209
|
+
action: "files_write",
|
|
4210
|
+
args: { path: path7, bytes: body.length },
|
|
4211
|
+
status: "error",
|
|
4212
|
+
errorCode: "EXECUTION_ERROR",
|
|
4213
|
+
durationMs: Date.now() - startedAt
|
|
4214
|
+
});
|
|
4215
|
+
return reply.status(502).send({
|
|
4216
|
+
error: err instanceof Error ? err.message : "SANDBOX_ERROR"
|
|
4217
|
+
});
|
|
4218
|
+
}
|
|
4219
|
+
});
|
|
4220
|
+
}
|
|
4221
|
+
var import_core72;
|
|
4222
|
+
var init_open_files = __esm({
|
|
4223
|
+
"src/routes/open-files.ts"() {
|
|
4224
|
+
"use strict";
|
|
4225
|
+
import_core72 = require("@axiom-lattice/core");
|
|
4226
|
+
init_openCredentialService();
|
|
4227
|
+
init_openLattice();
|
|
4228
|
+
init_sandboxProvider();
|
|
4229
|
+
init_openAuditService();
|
|
4230
|
+
}
|
|
4231
|
+
});
|
|
4232
|
+
|
|
4233
|
+
// src/routes/open-audit.ts
|
|
4234
|
+
var open_audit_exports = {};
|
|
4235
|
+
__export(open_audit_exports, {
|
|
4236
|
+
registerOpenAuditRoutes: () => registerOpenAuditRoutes
|
|
4237
|
+
});
|
|
4238
|
+
function registerOpenAuditRoutes(app2) {
|
|
4239
|
+
app2.get(
|
|
4240
|
+
"/api/open/audit",
|
|
4241
|
+
async (request, reply) => {
|
|
4242
|
+
const tenantId = request.user?.tenantId;
|
|
4243
|
+
if (!tenantId) {
|
|
4244
|
+
return reply.status(401).send({ success: false, error: "Unauthorized" });
|
|
4245
|
+
}
|
|
4246
|
+
const status = request.query.status === "ok" || request.query.status === "error" ? request.query.status : void 0;
|
|
4247
|
+
const store2 = (0, import_core73.getStoreLattice)("default", "openAudit").store;
|
|
4248
|
+
const records = await store2.query({
|
|
4249
|
+
tenantId,
|
|
4250
|
+
credentialId: request.query.credentialId,
|
|
4251
|
+
domain: request.query.domain,
|
|
4252
|
+
status,
|
|
4253
|
+
from: request.query.from,
|
|
4254
|
+
to: request.query.to,
|
|
4255
|
+
limit: request.query.limit ? parseInt(request.query.limit, 10) : void 0,
|
|
4256
|
+
offset: request.query.offset ? parseInt(request.query.offset, 10) : void 0
|
|
4257
|
+
});
|
|
4258
|
+
return reply.status(200).send({ success: true, data: { records } });
|
|
4259
|
+
}
|
|
4260
|
+
);
|
|
4261
|
+
}
|
|
4262
|
+
var import_core73;
|
|
4263
|
+
var init_open_audit = __esm({
|
|
4264
|
+
"src/routes/open-audit.ts"() {
|
|
4265
|
+
"use strict";
|
|
4266
|
+
import_core73 = require("@axiom-lattice/core");
|
|
4267
|
+
}
|
|
4268
|
+
});
|
|
4269
|
+
|
|
4270
|
+
// src/routes/open-exposure.ts
|
|
4271
|
+
var open_exposure_exports = {};
|
|
4272
|
+
__export(open_exposure_exports, {
|
|
4273
|
+
registerOpenExposureRoutes: () => registerOpenExposureRoutes
|
|
4274
|
+
});
|
|
4275
|
+
function registerOpenExposureRoutes(app2) {
|
|
4276
|
+
app2.get(
|
|
4277
|
+
"/api/keys/:id/exposure",
|
|
4278
|
+
async (request, reply) => {
|
|
4279
|
+
const tenantId = request.user?.tenantId;
|
|
4280
|
+
if (!tenantId) {
|
|
4281
|
+
return reply.status(401).send({ success: false, error: "Unauthorized" });
|
|
4282
|
+
}
|
|
4283
|
+
const keyStore = (0, import_core74.getStoreLattice)("default", "a2aApiKey").store;
|
|
4284
|
+
const record = await keyStore.findById(request.params.id);
|
|
4285
|
+
if (!record || record.tenantId !== tenantId) {
|
|
4286
|
+
return reply.status(404).send({ success: false, error: "Key not found" });
|
|
4287
|
+
}
|
|
4288
|
+
const grants = (0, import_protocols33.effectiveGrants)(record);
|
|
4289
|
+
const forwardedHost = request.headers["x-forwarded-host"];
|
|
4290
|
+
const host = (Array.isArray(forwardedHost) ? forwardedHost[0] : forwardedHost) ?? (Array.isArray(request.headers.host) ? request.headers.host[0] : request.headers.host) ?? request.hostname;
|
|
4291
|
+
const baseUrl = `${request.protocol}://${host}`;
|
|
4292
|
+
const tools = (await openLattice.catalogFor(grants, { tenantId })).map((t2) => ({
|
|
4293
|
+
domain: t2.domain,
|
|
4294
|
+
toolName: t2.toolName,
|
|
4295
|
+
description: t2.description,
|
|
4296
|
+
annotations: t2.annotations
|
|
4297
|
+
}));
|
|
4298
|
+
const agentGrant = grants.find((g) => g.domain === "agent");
|
|
4299
|
+
const assistantStore = (0, import_core74.getStoreLattice)("default", "assistant").store;
|
|
4300
|
+
const agents = [];
|
|
4301
|
+
for (const assistantId of agentGrant?.items ?? []) {
|
|
4302
|
+
const assistant = await assistantStore.getAssistantById(
|
|
4303
|
+
tenantId,
|
|
4304
|
+
assistantId
|
|
4305
|
+
);
|
|
4306
|
+
if (!assistant) continue;
|
|
4307
|
+
agents.push({
|
|
4308
|
+
assistantId,
|
|
4309
|
+
cardUrl: `${baseUrl}/api/a2a/agents/${assistantId}/.well-known/agent-card.json`,
|
|
4310
|
+
jsonrpcUrl: `${baseUrl}/api/a2a/agents/${assistantId}/jsonrpc`,
|
|
4311
|
+
card: buildAgentCardForAssistant({ assistant, baseUrl })
|
|
4312
|
+
});
|
|
4313
|
+
}
|
|
4314
|
+
return reply.status(200).send({
|
|
4315
|
+
success: true,
|
|
4316
|
+
data: {
|
|
4317
|
+
tenantId,
|
|
4318
|
+
projectId: record.projectId,
|
|
4319
|
+
grants,
|
|
4320
|
+
mcp: { endpoint: `${baseUrl}/open/mcp`, tools },
|
|
4321
|
+
a2a: { agents }
|
|
4322
|
+
}
|
|
4323
|
+
});
|
|
4324
|
+
}
|
|
4325
|
+
);
|
|
4326
|
+
}
|
|
4327
|
+
var import_core74, import_protocols33;
|
|
4328
|
+
var init_open_exposure = __esm({
|
|
4329
|
+
"src/routes/open-exposure.ts"() {
|
|
4330
|
+
"use strict";
|
|
4331
|
+
import_core74 = require("@axiom-lattice/core");
|
|
4332
|
+
import_protocols33 = require("@axiom-lattice/protocols");
|
|
4333
|
+
init_openLattice();
|
|
4334
|
+
init_A2AAgentCardBuilder();
|
|
4335
|
+
}
|
|
4336
|
+
});
|
|
4337
|
+
|
|
4338
|
+
// src/services/open/providers/kbProvider.ts
|
|
4339
|
+
var kbProvider_exports = {};
|
|
4340
|
+
__export(kbProvider_exports, {
|
|
4341
|
+
createKbProvider: () => createKbProvider
|
|
4342
|
+
});
|
|
4343
|
+
function createKbProvider(collectionService3) {
|
|
4344
|
+
return {
|
|
4345
|
+
domain: "kb",
|
|
4346
|
+
label: "Knowledge Base",
|
|
4347
|
+
source: "builtin",
|
|
4348
|
+
scopeKind: "tenant",
|
|
4349
|
+
actions: [
|
|
4350
|
+
{
|
|
4351
|
+
name: "search",
|
|
4352
|
+
label: "Search collections",
|
|
4353
|
+
description: "Search a knowledge base collection. Returns matched entries with content, metadata and similarity score.",
|
|
4354
|
+
schema: {
|
|
4355
|
+
collection: import_zod18.z.string().min(1),
|
|
4356
|
+
query: import_zod18.z.string().min(1),
|
|
4357
|
+
limit: import_zod18.z.number().int().min(1).max(50).optional()
|
|
4358
|
+
},
|
|
4359
|
+
annotations: { readOnlyHint: true, destructiveHint: false }
|
|
4360
|
+
}
|
|
4361
|
+
],
|
|
4362
|
+
execute: async (action, args, ctx) => {
|
|
4363
|
+
if (action !== "search") {
|
|
4364
|
+
return {
|
|
4365
|
+
content: [{ type: "text", text: `Unknown kb action: ${action}` }],
|
|
4366
|
+
isError: true
|
|
4367
|
+
};
|
|
4368
|
+
}
|
|
4369
|
+
const { collection, query, limit } = args;
|
|
4370
|
+
const req = {
|
|
4371
|
+
user: { tenantId: ctx.tenantId },
|
|
4372
|
+
headers: {}
|
|
4373
|
+
};
|
|
4374
|
+
const entries = await collectionService3.searchEntries(
|
|
4375
|
+
req,
|
|
4376
|
+
collection,
|
|
4377
|
+
{ query, top_k: limit ?? 5 }
|
|
4378
|
+
);
|
|
4379
|
+
return {
|
|
4380
|
+
content: [{ type: "text", text: JSON.stringify(entries, null, 2) }]
|
|
4381
|
+
};
|
|
4382
|
+
}
|
|
4383
|
+
};
|
|
3091
4384
|
}
|
|
3092
|
-
var
|
|
3093
|
-
var
|
|
3094
|
-
"src/services/open/
|
|
4385
|
+
var import_zod18;
|
|
4386
|
+
var init_kbProvider = __esm({
|
|
4387
|
+
"src/services/open/providers/kbProvider.ts"() {
|
|
3095
4388
|
"use strict";
|
|
3096
|
-
|
|
3097
|
-
import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
3098
|
-
import_crypto12 = require("crypto");
|
|
3099
|
-
init_mcpTransportRegistry();
|
|
3100
|
-
init_mcpCatalog();
|
|
3101
|
-
OPEN_MCP_SERVER_INFO = {
|
|
3102
|
-
name: "axiom-open",
|
|
3103
|
-
version: "0.1.0"
|
|
3104
|
-
};
|
|
4389
|
+
import_zod18 = require("zod");
|
|
3105
4390
|
}
|
|
3106
4391
|
});
|
|
3107
4392
|
|
|
3108
|
-
// src/
|
|
3109
|
-
var
|
|
3110
|
-
__export(
|
|
3111
|
-
|
|
4393
|
+
// src/services/open/providers/agentProvider.ts
|
|
4394
|
+
var agentProvider_exports = {};
|
|
4395
|
+
__export(agentProvider_exports, {
|
|
4396
|
+
createAgentProvider: () => createAgentProvider
|
|
3112
4397
|
});
|
|
3113
|
-
function
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
4398
|
+
function createAgentProvider(deps = {}) {
|
|
4399
|
+
return {
|
|
4400
|
+
domain: "agent",
|
|
4401
|
+
label: "Agents",
|
|
4402
|
+
source: "agent",
|
|
4403
|
+
scopeKind: "project",
|
|
4404
|
+
itemKind: "instance",
|
|
4405
|
+
actions: [],
|
|
4406
|
+
instanceActions: async (grants, ctx) => {
|
|
4407
|
+
const agentGrant = grants.find((g) => g.domain === "agent");
|
|
4408
|
+
const assistantIds = agentGrant?.items ?? [];
|
|
4409
|
+
const tenantId = ctx?.tenantId;
|
|
4410
|
+
return Promise.all(
|
|
4411
|
+
assistantIds.map(async (assistantId) => {
|
|
4412
|
+
let name = assistantId;
|
|
4413
|
+
let description = "";
|
|
4414
|
+
if (tenantId && deps.resolveAssistant) {
|
|
4415
|
+
try {
|
|
4416
|
+
const meta = await deps.resolveAssistant(tenantId, assistantId);
|
|
4417
|
+
if (meta?.name) name = meta.name;
|
|
4418
|
+
if (meta?.description) description = meta.description;
|
|
4419
|
+
} catch {
|
|
4420
|
+
}
|
|
4421
|
+
}
|
|
4422
|
+
return {
|
|
4423
|
+
name: assistantId,
|
|
4424
|
+
toolName: `invoke_${assistantId}`,
|
|
4425
|
+
label: name,
|
|
4426
|
+
description: `Invoke the "${name}" agent${description ? ` \u2014 ${description}` : ""}. Returns its final reply.`,
|
|
4427
|
+
schema: { message: import_zod19.z.string().min(1) },
|
|
4428
|
+
annotations: { readOnlyHint: false, destructiveHint: false }
|
|
4429
|
+
};
|
|
4430
|
+
})
|
|
4431
|
+
);
|
|
4432
|
+
},
|
|
4433
|
+
execute: async (assistantId, args, ctx) => {
|
|
4434
|
+
const { message } = args;
|
|
4435
|
+
const credentialId = ctx.runConfig.credentialId ?? ctx.projectId;
|
|
4436
|
+
const threadId = `open:${credentialId}:${assistantId}`;
|
|
4437
|
+
if (deps.threadStore) {
|
|
4438
|
+
try {
|
|
4439
|
+
await deps.threadStore.createThread(ctx.tenantId, assistantId, threadId, {
|
|
4440
|
+
metadata: {
|
|
4441
|
+
source: "open_api",
|
|
4442
|
+
credentialId,
|
|
4443
|
+
workspaceId: ctx.workspaceId ?? void 0,
|
|
4444
|
+
projectId: ctx.projectId
|
|
4445
|
+
}
|
|
4446
|
+
});
|
|
4447
|
+
} catch {
|
|
4448
|
+
}
|
|
4449
|
+
}
|
|
4450
|
+
const agent = import_core75.agentInstanceManager.getAgent({
|
|
4451
|
+
tenant_id: ctx.tenantId,
|
|
4452
|
+
assistant_id: assistantId,
|
|
4453
|
+
thread_id: threadId,
|
|
4454
|
+
workspace_id: ctx.workspaceId ?? "",
|
|
4455
|
+
project_id: ctx.projectId
|
|
4456
|
+
});
|
|
4457
|
+
const { messageId } = await agent.addMessage({
|
|
4458
|
+
input: { message }
|
|
4459
|
+
});
|
|
4460
|
+
const parts = [];
|
|
4461
|
+
const stream = agent.chunkStream(messageId, [...STOP_TYPES]);
|
|
4462
|
+
for await (const chunk of stream) {
|
|
4463
|
+
const text = chunk.data?.content;
|
|
4464
|
+
if (chunk.type === import_protocols34.MessageChunkTypes.INTERRUPT) break;
|
|
4465
|
+
if (chunk.type === import_protocols34.MessageChunkTypes.AI && text) {
|
|
4466
|
+
parts.push(text);
|
|
4467
|
+
}
|
|
4468
|
+
}
|
|
4469
|
+
return {
|
|
4470
|
+
content: [{ type: "text", text: parts.join("") || "(no output)" }]
|
|
4471
|
+
};
|
|
4472
|
+
}
|
|
4473
|
+
};
|
|
3117
4474
|
}
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
4475
|
+
var import_zod19, import_core75, import_protocols34, STOP_TYPES;
|
|
4476
|
+
var init_agentProvider = __esm({
|
|
4477
|
+
"src/services/open/providers/agentProvider.ts"() {
|
|
4478
|
+
"use strict";
|
|
4479
|
+
import_zod19 = require("zod");
|
|
4480
|
+
import_core75 = require("@axiom-lattice/core");
|
|
4481
|
+
import_protocols34 = require("@axiom-lattice/protocols");
|
|
4482
|
+
STOP_TYPES = [import_protocols34.MessageChunkTypes.MESSAGE_COMPLETED];
|
|
4483
|
+
}
|
|
4484
|
+
});
|
|
4485
|
+
|
|
4486
|
+
// src/services/open/pluginExposeAdapter.ts
|
|
4487
|
+
function schemaOf(tool) {
|
|
4488
|
+
return tool.lc_kwargs?.schema ?? tool.schema ?? import_zod20.z.object({}).passthrough();
|
|
3122
4489
|
}
|
|
3123
|
-
function
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
const session = await getSession(sessionId);
|
|
3133
|
-
if (!session || session.credential.credentialId !== credential.credentialId) {
|
|
3134
|
-
return reply.status(404).send({ error: "SESSION_NOT_FOUND" });
|
|
4490
|
+
function createPluginProvider(domain, tools, options = {}) {
|
|
4491
|
+
function toAction(info) {
|
|
4492
|
+
return {
|
|
4493
|
+
name: info.name,
|
|
4494
|
+
description: info.description || info.tool.description || `Plugin tool ${info.name}`,
|
|
4495
|
+
schema: schemaOf(info.tool),
|
|
4496
|
+
annotations: {
|
|
4497
|
+
readOnlyHint: info.readOnly ?? false,
|
|
4498
|
+
destructiveHint: info.destructive ?? false
|
|
3135
4499
|
}
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
4500
|
+
};
|
|
4501
|
+
}
|
|
4502
|
+
const actions = tools.map(toAction);
|
|
4503
|
+
return {
|
|
4504
|
+
domain,
|
|
4505
|
+
label: options.label ?? domain,
|
|
4506
|
+
source: "plugin",
|
|
4507
|
+
scopeKind: "tenant",
|
|
4508
|
+
actions,
|
|
4509
|
+
execute: async (action, args, ctx) => {
|
|
4510
|
+
const info = tools.find((t2) => t2.name === action);
|
|
4511
|
+
if (!info) {
|
|
4512
|
+
return {
|
|
4513
|
+
content: [{ type: "text", text: `Unknown action: ${action}` }],
|
|
4514
|
+
isError: true
|
|
4515
|
+
};
|
|
4516
|
+
}
|
|
4517
|
+
const exeConfig = {
|
|
4518
|
+
configurable: {
|
|
4519
|
+
runConfig: {
|
|
4520
|
+
tenantId: ctx.tenantId,
|
|
4521
|
+
_resolvedConnections: ctx.runConfig._resolvedConnections ?? []
|
|
4522
|
+
}
|
|
4523
|
+
}
|
|
4524
|
+
};
|
|
4525
|
+
const output = await info.tool.invoke(args, exeConfig);
|
|
4526
|
+
return { content: [{ type: "text", text: output }] };
|
|
3142
4527
|
}
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
"
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
4528
|
+
};
|
|
4529
|
+
}
|
|
4530
|
+
var import_zod20;
|
|
4531
|
+
var init_pluginExposeAdapter = __esm({
|
|
4532
|
+
"src/services/open/pluginExposeAdapter.ts"() {
|
|
4533
|
+
"use strict";
|
|
4534
|
+
import_zod20 = require("zod");
|
|
4535
|
+
}
|
|
4536
|
+
});
|
|
4537
|
+
|
|
4538
|
+
// src/services/open/registerExposedPlugins.ts
|
|
4539
|
+
var registerExposedPlugins_exports = {};
|
|
4540
|
+
__export(registerExposedPlugins_exports, {
|
|
4541
|
+
registerExposedPluginTools: () => registerExposedPluginTools
|
|
4542
|
+
});
|
|
4543
|
+
async function registerExposedPluginTools() {
|
|
4544
|
+
for (const key of import_core76.PluginRegistry.list()) {
|
|
4545
|
+
const plugin = import_core76.PluginRegistry.get(key);
|
|
4546
|
+
if (!plugin?.middleware) continue;
|
|
4547
|
+
const openExpose = plugin.meta.openExpose;
|
|
4548
|
+
const exposed = openExpose ? openExpose.map(
|
|
4549
|
+
(entry) => typeof entry === "string" ? { name: entry, description: "", expose: true } : {
|
|
4550
|
+
name: entry.name,
|
|
4551
|
+
description: "",
|
|
4552
|
+
expose: true,
|
|
4553
|
+
readOnly: entry.readOnly,
|
|
4554
|
+
destructive: entry.destructive
|
|
3153
4555
|
}
|
|
3154
|
-
|
|
3155
|
-
|
|
4556
|
+
) : plugin.meta.tools?.filter((t2) => t2.expose) ?? [];
|
|
4557
|
+
if (exposed.length === 0) continue;
|
|
4558
|
+
try {
|
|
4559
|
+
const middleware = await plugin.middleware({
|
|
4560
|
+
...plugin.meta.defaultConfig ?? {},
|
|
4561
|
+
connectAll: true
|
|
4562
|
+
});
|
|
4563
|
+
const toolObjects = middleware.tools ?? [];
|
|
4564
|
+
const matched = exposed.map((tm) => {
|
|
4565
|
+
const tool = toolObjects.find((t2) => t2.name === tm.name);
|
|
4566
|
+
if (!tool) return null;
|
|
4567
|
+
const annotations = tm;
|
|
4568
|
+
return {
|
|
4569
|
+
name: tm.name,
|
|
4570
|
+
description: tm.description,
|
|
4571
|
+
tool,
|
|
4572
|
+
readOnly: annotations.readOnly,
|
|
4573
|
+
destructive: annotations.destructive
|
|
4574
|
+
};
|
|
4575
|
+
}).filter(Boolean);
|
|
4576
|
+
if (matched.length === 0) continue;
|
|
4577
|
+
const provider = createPluginProvider(key, matched, { label: plugin.meta.name });
|
|
4578
|
+
openLattice.register(provider);
|
|
4579
|
+
} catch {
|
|
3156
4580
|
}
|
|
3157
|
-
|
|
4581
|
+
}
|
|
3158
4582
|
}
|
|
3159
|
-
var
|
|
3160
|
-
var
|
|
3161
|
-
"src/
|
|
4583
|
+
var import_core76;
|
|
4584
|
+
var init_registerExposedPlugins = __esm({
|
|
4585
|
+
"src/services/open/registerExposedPlugins.ts"() {
|
|
3162
4586
|
"use strict";
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
4587
|
+
import_core76 = require("@axiom-lattice/core");
|
|
4588
|
+
init_openLattice();
|
|
4589
|
+
init_pluginExposeAdapter();
|
|
4590
|
+
}
|
|
4591
|
+
});
|
|
4592
|
+
|
|
4593
|
+
// src/services/open/sandboxGrants.ts
|
|
4594
|
+
function sanitizeShareOpenGrants(grants) {
|
|
4595
|
+
const out = [];
|
|
4596
|
+
for (const grant of grants ?? []) {
|
|
4597
|
+
const allowed = ALLOWED[grant.domain];
|
|
4598
|
+
if (!allowed) continue;
|
|
4599
|
+
const items = grant.items && grant.items.length > 0 ? grant.items.filter((item) => allowed.includes(item)) : allowed;
|
|
4600
|
+
if (items.length > 0) out.push({ domain: grant.domain, items });
|
|
4601
|
+
}
|
|
4602
|
+
return out;
|
|
4603
|
+
}
|
|
4604
|
+
var ALLOWED;
|
|
4605
|
+
var init_sandboxGrants = __esm({
|
|
4606
|
+
"src/services/open/sandboxGrants.ts"() {
|
|
4607
|
+
"use strict";
|
|
4608
|
+
ALLOWED = {
|
|
4609
|
+
kb: ["search", "entries_read"]
|
|
4610
|
+
};
|
|
3167
4611
|
}
|
|
3168
4612
|
});
|
|
3169
4613
|
|
|
@@ -3172,13 +4616,14 @@ var resources_exports = {};
|
|
|
3172
4616
|
__export(resources_exports, {
|
|
3173
4617
|
ResourceController: () => ResourceController
|
|
3174
4618
|
});
|
|
3175
|
-
var import_bcryptjs,
|
|
4619
|
+
var import_bcryptjs, import_core77, ResourceController;
|
|
3176
4620
|
var init_resources = __esm({
|
|
3177
4621
|
"src/controllers/resources.ts"() {
|
|
3178
4622
|
"use strict";
|
|
3179
4623
|
import_bcryptjs = __toESM(require("bcryptjs"));
|
|
3180
|
-
|
|
4624
|
+
import_core77 = require("@axiom-lattice/core");
|
|
3181
4625
|
init_mime();
|
|
4626
|
+
init_sandboxGrants();
|
|
3182
4627
|
ResourceController = class {
|
|
3183
4628
|
constructor(deps) {
|
|
3184
4629
|
this.deps = deps;
|
|
@@ -3192,14 +4637,14 @@ var init_resources = __esm({
|
|
|
3192
4637
|
if (!workspaceId || !projectId) {
|
|
3193
4638
|
return reply.status(400).send({ error: "x-workspace-id and x-project-id headers required" });
|
|
3194
4639
|
}
|
|
3195
|
-
const payload = (0,
|
|
4640
|
+
const payload = (0, import_core77.createSharePayload)(
|
|
3196
4641
|
tenantId,
|
|
3197
4642
|
workspaceId,
|
|
3198
4643
|
projectId,
|
|
3199
4644
|
userId,
|
|
3200
4645
|
body
|
|
3201
4646
|
);
|
|
3202
|
-
const token = (0,
|
|
4647
|
+
const token = (0, import_core77.generateToken)();
|
|
3203
4648
|
try {
|
|
3204
4649
|
await this.deps.store.create({ ...payload, token });
|
|
3205
4650
|
this.deps.logger.info(
|
|
@@ -3351,7 +4796,7 @@ var init_resources = __esm({
|
|
|
3351
4796
|
resourcePath: subPath
|
|
3352
4797
|
}, subPath, ext, request, reply);
|
|
3353
4798
|
}
|
|
3354
|
-
const volume = (0,
|
|
4799
|
+
const volume = (0, import_core77.buildNamedVolumeName)("p", "project", tenantId, workspaceId, projectId);
|
|
3355
4800
|
return this._resolveAndServe(
|
|
3356
4801
|
volume,
|
|
3357
4802
|
subPath,
|
|
@@ -3463,7 +4908,8 @@ var init_resources = __esm({
|
|
|
3463
4908
|
workspaceId: record.workspaceId,
|
|
3464
4909
|
projectId: record.projectId,
|
|
3465
4910
|
assistantId: record.assistantId,
|
|
3466
|
-
resourcePath: basePath + apiSubPath
|
|
4911
|
+
resourcePath: basePath + apiSubPath,
|
|
4912
|
+
openGrants: record.openGrants
|
|
3467
4913
|
}, apiSubPath, ext, request, reply);
|
|
3468
4914
|
}
|
|
3469
4915
|
async _execApiCore(config, apiSubPath, ext, request, reply) {
|
|
@@ -3494,9 +4940,10 @@ var init_resources = __esm({
|
|
|
3494
4940
|
`export API_QUERY='${JSON.stringify(queryObj).replace(/'/g, "'\\''")}'`,
|
|
3495
4941
|
`export API_BODY='${bodyStr.replace(/'/g, "'\\''")}'`,
|
|
3496
4942
|
`export API_METHOD='${request.method}'`,
|
|
3497
|
-
`export API_GATEWAY_URL='${request.protocol}://${request.hostname}'`,
|
|
4943
|
+
`export API_GATEWAY_URL='${request.protocol}://${request.headers["x-forwarded-host"] ?? request.headers.host ?? request.hostname}'`,
|
|
3498
4944
|
`export API_TENANT_ID='${config.tenantId}'`,
|
|
3499
|
-
`export API_ASSISTANT_ID='${config.assistantId || ""}'
|
|
4945
|
+
`export API_ASSISTANT_ID='${config.assistantId || ""}'`,
|
|
4946
|
+
`export OPEN_API_TOKEN='${this._mintSandboxToken(sandbox.name, config)}'`
|
|
3500
4947
|
].join(" && ");
|
|
3501
4948
|
const fullCmd = `${envVars} && ${cmd}`;
|
|
3502
4949
|
this.deps.logger.info("[api] exec", { scriptPath, cmd: cmd.substring(0, 80) });
|
|
@@ -3524,6 +4971,23 @@ var init_resources = __esm({
|
|
|
3524
4971
|
_passwordPage(token) {
|
|
3525
4972
|
return `<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Password Protected</title><style>body{font-family:-apple-system,BlinkMacSystemFont,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;background:#f5f5f5}.card{background:#fff;padding:32px;border-radius:12px;box-shadow:0 2px 8px rgba(0,0,0,.1);width:100%;max-width:360px;text-align:center}h2{margin:0 0 8px;font-size:20px}p{margin:0 0 20px;color:#666;font-size:14px}input{width:100%;padding:10px 12px;border:1px solid #d9d9d9;border-radius:8px;font-size:14px;box-sizing:border-box;margin-bottom:12px}button{width:100%;padding:10px;background:#6366f1;color:#fff;border:none;border-radius:8px;font-size:14px;cursor:pointer}.error{color:#ef4444;font-size:13px;margin-top:8px;display:none}</style></head><body><div class="card"><h2>Password Protected</h2><p>This share requires a password to access.</p><form id="f"><input type="password" id="p" placeholder="Enter password" required><button type="submit">Unlock</button><div class="error" id="e">Incorrect password</div></form></div><script>document.getElementById('f').onsubmit=async(e)=>{e.preventDefault();const r=await fetch('/s/${token}/unlock',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:document.getElementById('p').value})});if(r.ok)location.reload();else document.getElementById('e').style.display='block'}</script></body></html>`;
|
|
3526
4973
|
}
|
|
4974
|
+
_mintSandboxToken(sandboxName, config) {
|
|
4975
|
+
const { signOpenToken: signOpenToken2 } = (init_openToken(), __toCommonJS(openToken_exports));
|
|
4976
|
+
return signOpenToken2({
|
|
4977
|
+
kind: "sandbox_token",
|
|
4978
|
+
tenantId: config.tenantId,
|
|
4979
|
+
workspaceId: config.workspaceId,
|
|
4980
|
+
projectId: config.projectId,
|
|
4981
|
+
sandboxName,
|
|
4982
|
+
grants: [
|
|
4983
|
+
{
|
|
4984
|
+
domain: "sandbox",
|
|
4985
|
+
items: ["files_read", "files_list", "files_write", "shell_exec"]
|
|
4986
|
+
},
|
|
4987
|
+
...sanitizeShareOpenGrants(config.openGrants)
|
|
4988
|
+
]
|
|
4989
|
+
});
|
|
4990
|
+
}
|
|
3527
4991
|
};
|
|
3528
4992
|
}
|
|
3529
4993
|
});
|
|
@@ -5560,6 +7024,36 @@ var SkillService = class {
|
|
|
5560
7024
|
constructor() {
|
|
5561
7025
|
this.store = new import_core10.SandboxSkillStore();
|
|
5562
7026
|
}
|
|
7027
|
+
/**
|
|
7028
|
+
* Read the read-only skills contributed by the tenant's sandbox plugins.
|
|
7029
|
+
* Sandbox failures degrade silently so the system view still returns
|
|
7030
|
+
* built-in and store skills.
|
|
7031
|
+
*/
|
|
7032
|
+
async tenantPluginSkills(tenantId) {
|
|
7033
|
+
const items = [];
|
|
7034
|
+
try {
|
|
7035
|
+
const loaded = await (0, import_core10.getSandboxPluginCatalog)().ensureLoaded(tenantId);
|
|
7036
|
+
for (const plugin of loaded.plugins) {
|
|
7037
|
+
for (const [name, definition] of Object.entries(plugin.skills ?? {})) {
|
|
7038
|
+
const { meta } = (0, import_core10.parseSkillFrontmatter)(definition.content);
|
|
7039
|
+
items.push({
|
|
7040
|
+
id: name,
|
|
7041
|
+
name: meta.name || name,
|
|
7042
|
+
description: meta.description || "",
|
|
7043
|
+
version: definition.version,
|
|
7044
|
+
pluginType: plugin.meta.type,
|
|
7045
|
+
resourcePaths: Object.entries(definition.resources ?? {}).map(([path7, resource]) => ({
|
|
7046
|
+
path: path7,
|
|
7047
|
+
mimeType: resource.mimeType
|
|
7048
|
+
})),
|
|
7049
|
+
content: definition.content
|
|
7050
|
+
});
|
|
7051
|
+
}
|
|
7052
|
+
}
|
|
7053
|
+
} catch {
|
|
7054
|
+
}
|
|
7055
|
+
return items;
|
|
7056
|
+
}
|
|
5563
7057
|
async getAllSkills(request) {
|
|
5564
7058
|
const tenantId = getTenantId4(request);
|
|
5565
7059
|
const storeSkills = await this.store.getAllSkills(tenantId, buildContext(request));
|
|
@@ -5570,6 +7064,9 @@ var SkillService = class {
|
|
|
5570
7064
|
for (const item of import_core10.PluginRegistry.listSkills()) {
|
|
5571
7065
|
merged.set(item.id, pluginSkillToSkill(item, tenantId));
|
|
5572
7066
|
}
|
|
7067
|
+
for (const item of await this.tenantPluginSkills(tenantId)) {
|
|
7068
|
+
merged.set(item.id, pluginSkillToSkill(item, tenantId, item.content));
|
|
7069
|
+
}
|
|
5573
7070
|
return Array.from(merged.values());
|
|
5574
7071
|
}
|
|
5575
7072
|
async getSkillById(request, id3) {
|
|
@@ -5582,21 +7079,23 @@ var SkillService = class {
|
|
|
5582
7079
|
return pluginSkillToSkill(item, tenantId, definition.content);
|
|
5583
7080
|
}
|
|
5584
7081
|
}
|
|
7082
|
+
const tenantItem = (await this.tenantPluginSkills(tenantId)).find((entry) => entry.id === id3);
|
|
7083
|
+
if (tenantItem) return pluginSkillToSkill(tenantItem, tenantId, tenantItem.content);
|
|
5585
7084
|
return this.store.getSkillById(tenantId, id3, buildContext(request));
|
|
5586
7085
|
}
|
|
5587
7086
|
async createSkill(request, id3, data) {
|
|
5588
7087
|
const tenantId = getTenantId4(request);
|
|
5589
|
-
this.
|
|
7088
|
+
await this.assertMutable(tenantId, id3, "created");
|
|
5590
7089
|
return this.store.createSkill(tenantId, id3, data, buildContext(request));
|
|
5591
7090
|
}
|
|
5592
7091
|
async updateSkill(request, id3, updates) {
|
|
5593
7092
|
const tenantId = getTenantId4(request);
|
|
5594
|
-
this.
|
|
7093
|
+
await this.assertMutable(tenantId, id3, "modified");
|
|
5595
7094
|
return this.store.updateSkill(tenantId, id3, updates, buildContext(request));
|
|
5596
7095
|
}
|
|
5597
7096
|
async deleteSkill(request, id3) {
|
|
5598
7097
|
const tenantId = getTenantId4(request);
|
|
5599
|
-
this.
|
|
7098
|
+
await this.assertMutable(tenantId, id3, "deleted");
|
|
5600
7099
|
return this.store.deleteSkill(tenantId, id3, buildContext(request));
|
|
5601
7100
|
}
|
|
5602
7101
|
async searchByMetadata(request, key, value) {
|
|
@@ -5612,7 +7111,18 @@ var SkillService = class {
|
|
|
5612
7111
|
return this.store.filterByLicense(tenantId, license, buildContext(request));
|
|
5613
7112
|
}
|
|
5614
7113
|
/**
|
|
5615
|
-
* Guard against mutating a
|
|
7114
|
+
* Guard against mutating a built-in or tenant-plugin skill.
|
|
7115
|
+
* Message style mirrors SandboxSkillStore built-in errors so the controller's
|
|
7116
|
+
* existing "built-in skill" -> 403 mapping applies. Runs before any store write.
|
|
7117
|
+
*/
|
|
7118
|
+
async assertMutable(tenantId, id3, action) {
|
|
7119
|
+
this.assertNotPluginSkill(id3, action);
|
|
7120
|
+
if ((await this.tenantPluginSkills(tenantId)).some((skill) => skill.id === id3)) {
|
|
7121
|
+
throw new Error(`Skill "${id3}" is a built-in skill and cannot be ${action}`);
|
|
7122
|
+
}
|
|
7123
|
+
}
|
|
7124
|
+
/**
|
|
7125
|
+
* Guard against mutating a globally registered plugin skill.
|
|
5616
7126
|
* Message style mirrors SandboxSkillStore built-in errors so the controller's
|
|
5617
7127
|
* existing "built-in skill" -> 403 mapping applies.
|
|
5618
7128
|
*/
|
|
@@ -5818,169 +7328,8 @@ async function filterSkillsByLicense(request, reply) {
|
|
|
5818
7328
|
}
|
|
5819
7329
|
}
|
|
5820
7330
|
|
|
5821
|
-
// src/services/collection_service.ts
|
|
5822
|
-
var import_uuid2 = require("uuid");
|
|
5823
|
-
var import_documents = require("@langchain/core/documents");
|
|
5824
|
-
var import_core11 = require("@axiom-lattice/core");
|
|
5825
|
-
function getTenantId5(request) {
|
|
5826
|
-
return request.user?.tenantId || request.headers["x-tenant-id"] || "default";
|
|
5827
|
-
}
|
|
5828
|
-
var CollectionService = class {
|
|
5829
|
-
// ─── Collection CRUD ──────────────────────────────────────────
|
|
5830
|
-
async getAllCollections(request) {
|
|
5831
|
-
const tenantId = getTenantId5(request);
|
|
5832
|
-
const collections = await import_core11.collectionLatticeManager.getAllCollections(tenantId);
|
|
5833
|
-
for (const c2 of collections) {
|
|
5834
|
-
try {
|
|
5835
|
-
c2._entryCount = await (0, import_core11.getCollectionEntryCount)(c2.name, c2.embeddingKey, c2.tenantId);
|
|
5836
|
-
} catch {
|
|
5837
|
-
c2._entryCount = 0;
|
|
5838
|
-
}
|
|
5839
|
-
}
|
|
5840
|
-
return collections;
|
|
5841
|
-
}
|
|
5842
|
-
async getCollectionByName(request, name) {
|
|
5843
|
-
const tenantId = getTenantId5(request);
|
|
5844
|
-
return import_core11.collectionLatticeManager.getCollection(tenantId, name);
|
|
5845
|
-
}
|
|
5846
|
-
async createCollection(request, data) {
|
|
5847
|
-
const tenantId = getTenantId5(request);
|
|
5848
|
-
const collection = await import_core11.collectionLatticeManager.registerCollection(tenantId, data);
|
|
5849
|
-
try {
|
|
5850
|
-
await (0, import_core11.getOrCreateCollectionVectorStore)(data.name, data.embeddingKey, tenantId);
|
|
5851
|
-
} catch (err) {
|
|
5852
|
-
console.warn(`[CollectionService] Failed to init vector store for ${data.name}:`, err);
|
|
5853
|
-
}
|
|
5854
|
-
return collection;
|
|
5855
|
-
}
|
|
5856
|
-
async updateCollection(request, name, updates) {
|
|
5857
|
-
const tenantId = getTenantId5(request);
|
|
5858
|
-
return import_core11.collectionLatticeManager.updateCollection(tenantId, name, updates);
|
|
5859
|
-
}
|
|
5860
|
-
async deleteCollection(request, name) {
|
|
5861
|
-
const tenantId = getTenantId5(request);
|
|
5862
|
-
await (0, import_core11.removeCollectionVectorStore)(name, tenantId);
|
|
5863
|
-
return import_core11.collectionLatticeManager.removeCollection(tenantId, name);
|
|
5864
|
-
}
|
|
5865
|
-
// ─── Entry CRUD ───────────────────────────────────────────────
|
|
5866
|
-
async getEntries(request, collectionName) {
|
|
5867
|
-
const collection = await this.getCollectionByName(request, collectionName);
|
|
5868
|
-
if (!collection) throw new Error(`Collection "${collectionName}" not found`);
|
|
5869
|
-
const docs = await (0, import_core11.listCollectionEntries)(collectionName, collection.embeddingKey, collection.tenantId);
|
|
5870
|
-
return docs.map((doc) => ({
|
|
5871
|
-
id: doc.metadata._id || "",
|
|
5872
|
-
content: doc.pageContent,
|
|
5873
|
-
metadata: Object.fromEntries(
|
|
5874
|
-
Object.entries(doc.metadata).filter(([k]) => !k.startsWith("_"))
|
|
5875
|
-
)
|
|
5876
|
-
}));
|
|
5877
|
-
}
|
|
5878
|
-
async createEntry(request, collectionName, data) {
|
|
5879
|
-
const collection = await this.getCollectionByName(request, collectionName);
|
|
5880
|
-
if (!collection) throw new Error(`Collection "${collectionName}" not found`);
|
|
5881
|
-
const vectorStore = await (0, import_core11.getOrCreateCollectionVectorStore)(
|
|
5882
|
-
collectionName,
|
|
5883
|
-
collection.embeddingKey,
|
|
5884
|
-
collection.tenantId
|
|
5885
|
-
);
|
|
5886
|
-
const entryId = (0, import_uuid2.v4)();
|
|
5887
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
5888
|
-
const doc = new import_documents.Document({
|
|
5889
|
-
pageContent: data.content,
|
|
5890
|
-
metadata: {
|
|
5891
|
-
_id: entryId,
|
|
5892
|
-
_created_at: now,
|
|
5893
|
-
_updated_at: now,
|
|
5894
|
-
...data.metadata || {}
|
|
5895
|
-
}
|
|
5896
|
-
});
|
|
5897
|
-
await vectorStore.addDocuments([doc]);
|
|
5898
|
-
return { id: entryId, content: data.content, metadata: data.metadata || {} };
|
|
5899
|
-
}
|
|
5900
|
-
async getEntry(request, collectionName, entryId) {
|
|
5901
|
-
const collection = await this.getCollectionByName(request, collectionName);
|
|
5902
|
-
if (!collection) throw new Error(`Collection "${collectionName}" not found`);
|
|
5903
|
-
const docs = await (0, import_core11.listCollectionEntries)(collectionName, collection.embeddingKey, collection.tenantId);
|
|
5904
|
-
const doc = docs.find((d) => d.metadata._id === entryId);
|
|
5905
|
-
if (!doc) return null;
|
|
5906
|
-
return {
|
|
5907
|
-
id: entryId,
|
|
5908
|
-
content: doc.pageContent,
|
|
5909
|
-
metadata: Object.fromEntries(
|
|
5910
|
-
Object.entries(doc.metadata).filter(([k]) => !k.startsWith("_"))
|
|
5911
|
-
)
|
|
5912
|
-
};
|
|
5913
|
-
}
|
|
5914
|
-
async updateEntry(request, collectionName, entryId, data) {
|
|
5915
|
-
const existing = await this.getEntry(request, collectionName, entryId);
|
|
5916
|
-
if (!existing) return null;
|
|
5917
|
-
const collection = await this.getCollectionByName(request, collectionName);
|
|
5918
|
-
if (!collection) throw new Error(`Collection "${collectionName}" not found`);
|
|
5919
|
-
const vectorStore = await (0, import_core11.getOrCreateCollectionVectorStore)(
|
|
5920
|
-
collectionName,
|
|
5921
|
-
collection.embeddingKey,
|
|
5922
|
-
collection.tenantId
|
|
5923
|
-
);
|
|
5924
|
-
try {
|
|
5925
|
-
await vectorStore.delete({ filter: { _id: entryId } });
|
|
5926
|
-
} catch {
|
|
5927
|
-
}
|
|
5928
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
5929
|
-
const mergedMetadata = { ...existing.metadata, ...data.metadata || {} };
|
|
5930
|
-
const doc = new import_documents.Document({
|
|
5931
|
-
pageContent: data.content ?? existing.content,
|
|
5932
|
-
metadata: { _id: entryId, _created_at: now, _updated_at: now, ...mergedMetadata }
|
|
5933
|
-
});
|
|
5934
|
-
await vectorStore.addDocuments([doc]);
|
|
5935
|
-
return { id: entryId, content: data.content ?? existing.content, metadata: mergedMetadata };
|
|
5936
|
-
}
|
|
5937
|
-
async deleteEntry(request, collectionName, entryId) {
|
|
5938
|
-
const collection = await this.getCollectionByName(request, collectionName);
|
|
5939
|
-
if (!collection) throw new Error(`Collection "${collectionName}" not found`);
|
|
5940
|
-
const vectorStore = await (0, import_core11.getOrCreateCollectionVectorStore)(
|
|
5941
|
-
collectionName,
|
|
5942
|
-
collection.embeddingKey,
|
|
5943
|
-
collection.tenantId
|
|
5944
|
-
);
|
|
5945
|
-
try {
|
|
5946
|
-
await vectorStore.delete({ filter: { _id: entryId } });
|
|
5947
|
-
return true;
|
|
5948
|
-
} catch {
|
|
5949
|
-
return false;
|
|
5950
|
-
}
|
|
5951
|
-
}
|
|
5952
|
-
async searchEntries(request, collectionName, params) {
|
|
5953
|
-
const collection = await this.getCollectionByName(request, collectionName);
|
|
5954
|
-
if (!collection) throw new Error(`Collection "${collectionName}" not found`);
|
|
5955
|
-
const vectorStore = await (0, import_core11.getOrCreateCollectionVectorStore)(
|
|
5956
|
-
collectionName,
|
|
5957
|
-
collection.embeddingKey,
|
|
5958
|
-
collection.tenantId
|
|
5959
|
-
);
|
|
5960
|
-
let embeddings;
|
|
5961
|
-
try {
|
|
5962
|
-
embeddings = import_core11.embeddingsLatticeManager.getEmbeddingsClient(collection.embeddingKey);
|
|
5963
|
-
} catch {
|
|
5964
|
-
embeddings = import_core11.embeddingsLatticeManager.getEmbeddingsClient("default");
|
|
5965
|
-
}
|
|
5966
|
-
const queryVector = await embeddings.embedQuery(params.query);
|
|
5967
|
-
const results = await vectorStore.similaritySearchVectorWithScore(
|
|
5968
|
-
queryVector,
|
|
5969
|
-
params.top_k || 5,
|
|
5970
|
-
params.filter
|
|
5971
|
-
);
|
|
5972
|
-
return results.map(([doc, score]) => ({
|
|
5973
|
-
id: doc.metadata._id || (0, import_uuid2.v4)(),
|
|
5974
|
-
content: doc.pageContent,
|
|
5975
|
-
metadata: Object.fromEntries(
|
|
5976
|
-
Object.entries(doc.metadata).filter(([k]) => !k.startsWith("_"))
|
|
5977
|
-
),
|
|
5978
|
-
score
|
|
5979
|
-
}));
|
|
5980
|
-
}
|
|
5981
|
-
};
|
|
5982
|
-
|
|
5983
7331
|
// src/controllers/collections.ts
|
|
7332
|
+
init_collection_service();
|
|
5984
7333
|
var collectionService = new CollectionService();
|
|
5985
7334
|
function serializeCollection(collection) {
|
|
5986
7335
|
return {
|
|
@@ -6120,6 +7469,7 @@ async function listEmbeddings(_request, _reply) {
|
|
|
6120
7469
|
}
|
|
6121
7470
|
|
|
6122
7471
|
// src/controllers/entries.ts
|
|
7472
|
+
init_collection_service();
|
|
6123
7473
|
var collectionService2 = new CollectionService();
|
|
6124
7474
|
async function listEntries(request, reply) {
|
|
6125
7475
|
try {
|
|
@@ -7989,10 +9339,20 @@ async function importApply(request, reply) {
|
|
|
7989
9339
|
|
|
7990
9340
|
// src/controllers/middleware-types.ts
|
|
7991
9341
|
var import_core19 = require("@axiom-lattice/core");
|
|
9342
|
+
async function collectMiddlewareMetas(tenantId) {
|
|
9343
|
+
let tenantPlugins = [];
|
|
9344
|
+
try {
|
|
9345
|
+
tenantPlugins = (await (0, import_core19.getSandboxPluginCatalog)().ensureLoaded(tenantId)).plugins;
|
|
9346
|
+
} catch {
|
|
9347
|
+
tenantPlugins = [];
|
|
9348
|
+
}
|
|
9349
|
+
const globalPlugins = import_core19.PluginRegistry.list().map((type) => import_core19.PluginRegistry.get(type)).filter((p) => Boolean(p));
|
|
9350
|
+
return (0, import_core19.mergePluginSources)(globalPlugins, tenantPlugins).map(import_core19.serializePluginMeta);
|
|
9351
|
+
}
|
|
7992
9352
|
function middlewareTypesRoutes(fastify2) {
|
|
7993
|
-
fastify2.get("/api/middleware-types", async (
|
|
7994
|
-
const
|
|
7995
|
-
return reply.send(
|
|
9353
|
+
fastify2.get("/api/middleware-types", async (request, reply) => {
|
|
9354
|
+
const tenantId = request.user?.tenantId || request.headers["x-tenant-id"] || "default";
|
|
9355
|
+
return reply.send(await collectMiddlewareMetas(tenantId));
|
|
7996
9356
|
});
|
|
7997
9357
|
}
|
|
7998
9358
|
|
|
@@ -8714,6 +10074,7 @@ var import_core25 = require("@axiom-lattice/core");
|
|
|
8714
10074
|
var import_core26 = require("@axiom-lattice/core");
|
|
8715
10075
|
var import_uuid3 = require("uuid");
|
|
8716
10076
|
init_mime();
|
|
10077
|
+
init_previewToken();
|
|
8717
10078
|
init_workspace_file_service();
|
|
8718
10079
|
init_path_containment();
|
|
8719
10080
|
|
|
@@ -9666,7 +11027,7 @@ var WorkspaceController = class {
|
|
|
9666
11027
|
workspaceId,
|
|
9667
11028
|
projectId,
|
|
9668
11029
|
timestamp: Date.now()
|
|
9669
|
-
})};</script
|
|
11030
|
+
})};</script>` + buildPreviewTokenScript({ tenantId, workspaceId, projectId });
|
|
9670
11031
|
if (content2.toLowerCase().includes("</head>")) {
|
|
9671
11032
|
content2 = content2.replace(/<\/head>/i, `${contextScript}</head>`);
|
|
9672
11033
|
console.log(`[viewFile] Context script injected before </head>`);
|
|
@@ -9697,7 +11058,7 @@ var WorkspaceController = class {
|
|
|
9697
11058
|
workspaceId,
|
|
9698
11059
|
projectId,
|
|
9699
11060
|
timestamp: Date.now()
|
|
9700
|
-
})};</script
|
|
11061
|
+
})};</script>` + buildPreviewTokenScript({ tenantId, workspaceId, projectId });
|
|
9701
11062
|
if (content.toLowerCase().includes("</head>")) {
|
|
9702
11063
|
finalContent = content.replace(/<\/head>/i, `${contextScript}</head>`);
|
|
9703
11064
|
console.log(`[viewFile] Context script injected before </head>`);
|
|
@@ -10020,13 +11381,17 @@ var ProjectAccessService = class {
|
|
|
10020
11381
|
this.requireCapability(membership, input.capability);
|
|
10021
11382
|
return { project, membership };
|
|
10022
11383
|
}
|
|
10023
|
-
/**
|
|
11384
|
+
/**
|
|
11385
|
+
* Authorizes roster visibility for any active participant (owner/admin/member/viewer).
|
|
11386
|
+
* Mutating the roster requires `manage` separately; reading it never does, because every
|
|
11387
|
+
* room participant needs the member list to render the room and derive their own capabilities.
|
|
11388
|
+
*/
|
|
10024
11389
|
async requireRosterAccess(input) {
|
|
10025
11390
|
const project = await this.deps.projectStore.getProjectById(input.tenantId, input.projectId);
|
|
10026
11391
|
if (!project) throw new ProjectCollaborationError("PROJECT_NOT_FOUND", 404, "Project not found");
|
|
10027
11392
|
return this.requireProjectAccess({
|
|
10028
11393
|
...input,
|
|
10029
|
-
capability:
|
|
11394
|
+
capability: "read"
|
|
10030
11395
|
});
|
|
10031
11396
|
}
|
|
10032
11397
|
async requirePublicProjectAccess(project, input) {
|
|
@@ -10111,7 +11476,7 @@ var ProjectAccessService = class {
|
|
|
10111
11476
|
|
|
10112
11477
|
// src/controllers/database-configs.ts
|
|
10113
11478
|
var import_core27 = require("@axiom-lattice/core");
|
|
10114
|
-
var
|
|
11479
|
+
var import_crypto6 = require("crypto");
|
|
10115
11480
|
function getTenantId9(request) {
|
|
10116
11481
|
const userTenantId = request.user?.tenantId;
|
|
10117
11482
|
if (userTenantId) {
|
|
@@ -10189,7 +11554,7 @@ async function createDatabaseConfig(request, reply) {
|
|
|
10189
11554
|
message: "Database configuration with this key already exists"
|
|
10190
11555
|
};
|
|
10191
11556
|
}
|
|
10192
|
-
const id3 = body.id || (0,
|
|
11557
|
+
const id3 = body.id || (0, import_crypto6.randomUUID)();
|
|
10193
11558
|
const config = await store2.createConfig(tenantId, id3, body);
|
|
10194
11559
|
try {
|
|
10195
11560
|
import_core27.sqlDatabaseManager.registerDatabase(tenantId, config.key, config.config);
|
|
@@ -10390,7 +11755,7 @@ function registerDatabaseConfigRoutes(app2) {
|
|
|
10390
11755
|
|
|
10391
11756
|
// src/controllers/metrics-configs.ts
|
|
10392
11757
|
var import_core28 = require("@axiom-lattice/core");
|
|
10393
|
-
var
|
|
11758
|
+
var import_crypto7 = require("crypto");
|
|
10394
11759
|
function getTenantId10(request) {
|
|
10395
11760
|
const userTenantId = request.user?.tenantId;
|
|
10396
11761
|
if (userTenantId) {
|
|
@@ -10471,7 +11836,7 @@ async function createMetricsServerConfig(request, reply) {
|
|
|
10471
11836
|
message: "selectedDataSources is required for semantic metrics servers"
|
|
10472
11837
|
};
|
|
10473
11838
|
}
|
|
10474
|
-
const id3 = body.id || (0,
|
|
11839
|
+
const id3 = body.id || (0, import_crypto7.randomUUID)();
|
|
10475
11840
|
const configData = {
|
|
10476
11841
|
key: body.key,
|
|
10477
11842
|
name: body.name,
|
|
@@ -10992,6 +12357,17 @@ function getTenant(request) {
|
|
|
10992
12357
|
}
|
|
10993
12358
|
return request.headers["x-tenant-id"] || "default";
|
|
10994
12359
|
}
|
|
12360
|
+
async function getTenantPlugin(request, type) {
|
|
12361
|
+
const tenantId = getTenant(request);
|
|
12362
|
+
let tenantPlugins = [];
|
|
12363
|
+
try {
|
|
12364
|
+
tenantPlugins = (await (0, import_core29.getSandboxPluginCatalog)().ensureLoaded(tenantId)).plugins;
|
|
12365
|
+
} catch {
|
|
12366
|
+
tenantPlugins = [];
|
|
12367
|
+
}
|
|
12368
|
+
const globalPlugins = import_core29.PluginRegistry.list().map((t2) => import_core29.PluginRegistry.get(t2)).filter((p) => Boolean(p));
|
|
12369
|
+
return (0, import_core29.mergePluginSources)(globalPlugins, tenantPlugins).find((p) => p.meta.type === type);
|
|
12370
|
+
}
|
|
10995
12371
|
function maskSecrets(config) {
|
|
10996
12372
|
const sensitive = /* @__PURE__ */ new Set([
|
|
10997
12373
|
"password",
|
|
@@ -11075,7 +12451,7 @@ function connectionRoutes(fastify2) {
|
|
|
11075
12451
|
fastify2.post("/api/connections/test", async (request, reply) => {
|
|
11076
12452
|
const { type } = request.query;
|
|
11077
12453
|
if (!type) return reply.status(400).send({ error: "query 'type' required" });
|
|
11078
|
-
const plugin =
|
|
12454
|
+
const plugin = await getTenantPlugin(request, type);
|
|
11079
12455
|
if (!plugin?.connection?.test) {
|
|
11080
12456
|
return reply.status(400).send({ error: "plugin does not support connection testing" });
|
|
11081
12457
|
}
|
|
@@ -11103,7 +12479,7 @@ function connectionRoutes(fastify2) {
|
|
|
11103
12479
|
fastify2.post("/api/connections/discover", async (request, reply) => {
|
|
11104
12480
|
const { type } = request.query;
|
|
11105
12481
|
if (!type) return reply.status(400).send({ error: "query 'type' required" });
|
|
11106
|
-
const plugin =
|
|
12482
|
+
const plugin = await getTenantPlugin(request, type);
|
|
11107
12483
|
if (!plugin?.connection?.discover) {
|
|
11108
12484
|
return reply.status(400).send({ error: "plugin does not support resource discovery" });
|
|
11109
12485
|
}
|
|
@@ -12526,9 +13902,9 @@ function resolveConsoleTokenSecret(_authRequired) {
|
|
|
12526
13902
|
return devSessionSecret;
|
|
12527
13903
|
}
|
|
12528
13904
|
var devSessionSecret;
|
|
12529
|
-
function createConsoleSessionToken(payload,
|
|
13905
|
+
function createConsoleSessionToken(payload, secret2) {
|
|
12530
13906
|
const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
12531
|
-
const signature = (0, import_node_crypto4.createHmac)("sha256",
|
|
13907
|
+
const signature = (0, import_node_crypto4.createHmac)("sha256", secret2).update(encodedPayload).digest("base64url");
|
|
12532
13908
|
return `${encodedPayload}.${signature}`;
|
|
12533
13909
|
}
|
|
12534
13910
|
function isConsoleSessionPayload(value) {
|
|
@@ -12536,17 +13912,17 @@ function isConsoleSessionPayload(value) {
|
|
|
12536
13912
|
const payload = value;
|
|
12537
13913
|
return typeof payload.userId === "string" && payload.userId.length > 0 && typeof payload.exp === "number" && (payload.tenantId === void 0 || typeof payload.tenantId === "string");
|
|
12538
13914
|
}
|
|
12539
|
-
function extractUserFromAuthHeader(authHeader,
|
|
12540
|
-
const session = verifySignedConsoleSession(authHeader,
|
|
13915
|
+
function extractUserFromAuthHeader(authHeader, secret2) {
|
|
13916
|
+
const session = verifySignedConsoleSession(authHeader, secret2);
|
|
12541
13917
|
return session ? { id: session.id, tenantId: session.tenantId } : void 0;
|
|
12542
13918
|
}
|
|
12543
|
-
function verifyConsoleSessionAuthHeader(authHeader,
|
|
12544
|
-
const session = verifySignedConsoleSession(authHeader,
|
|
13919
|
+
function verifyConsoleSessionAuthHeader(authHeader, secret2) {
|
|
13920
|
+
const session = verifySignedConsoleSession(authHeader, secret2);
|
|
12545
13921
|
if (!session?.tenantId || session.tenantId.trim() !== session.tenantId) return void 0;
|
|
12546
13922
|
return { id: session.id, tenantId: session.tenantId, expiresAt: session.expiresAt };
|
|
12547
13923
|
}
|
|
12548
|
-
function verifySignedConsoleSession(authHeader,
|
|
12549
|
-
if (!
|
|
13924
|
+
function verifySignedConsoleSession(authHeader, secret2) {
|
|
13925
|
+
if (!secret2 || !authHeader?.startsWith("Bearer ")) return void 0;
|
|
12550
13926
|
const token = authHeader.substring(7);
|
|
12551
13927
|
const parts = token.split(".");
|
|
12552
13928
|
if (parts.length !== 2) return void 0;
|
|
@@ -12555,7 +13931,7 @@ function verifySignedConsoleSession(authHeader, secret) {
|
|
|
12555
13931
|
try {
|
|
12556
13932
|
const actualSignature = Buffer.from(encodedSignature, "base64url");
|
|
12557
13933
|
if (actualSignature.toString("base64url") !== encodedSignature) return void 0;
|
|
12558
|
-
const expectedSignature = (0, import_node_crypto4.createHmac)("sha256",
|
|
13934
|
+
const expectedSignature = (0, import_node_crypto4.createHmac)("sha256", secret2).update(encodedPayload).digest();
|
|
12559
13935
|
if (actualSignature.length !== expectedSignature.length || !(0, import_node_crypto4.timingSafeEqual)(actualSignature, expectedSignature)) {
|
|
12560
13936
|
return void 0;
|
|
12561
13937
|
}
|
|
@@ -12588,7 +13964,7 @@ function isStaleConsoleSessionCredential(authHeader) {
|
|
|
12588
13964
|
function bypassesConsoleAuth(request) {
|
|
12589
13965
|
const path7 = request.url.split("?")[0];
|
|
12590
13966
|
const method = request.method;
|
|
12591
|
-
if (method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/bootstrap$/.test(path7) || (method === "GET" || method === "POST") && /^\/api\/web-apps\/[^/]+\/runtime\/threads$/.test(path7) || (method === "PATCH" || method === "DELETE") && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+$/.test(path7) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/messages$/.test(path7) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/files\/(viewfile|downloadfile)$/.test(path7) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/api\/assistants\/[^/]+\/threads\/[^/]+\/sandbox\/(viewfile|downloadfile)$/.test(path7) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/(messages\/stream|abort|attachments)$/.test(path7) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/interrupts\/[^/]+\/resume$/.test(path7) || method === "GET" && /^\/api\/web-apps\/[^/]+\/chat$/.test(path7) || method === "GET" && /^\/embed\/[^/]+$/.test(path7) || (method === "POST" || method === "DELETE") && path7 === "/open/mcp") return true;
|
|
13967
|
+
if (method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/bootstrap$/.test(path7) || (method === "GET" || method === "POST") && /^\/api\/web-apps\/[^/]+\/runtime\/threads$/.test(path7) || (method === "PATCH" || method === "DELETE") && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+$/.test(path7) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/messages$/.test(path7) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/files\/(viewfile|downloadfile)$/.test(path7) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/api\/assistants\/[^/]+\/threads\/[^/]+\/sandbox\/(viewfile|downloadfile)$/.test(path7) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/(messages\/stream|abort|attachments)$/.test(path7) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/interrupts\/[^/]+\/resume$/.test(path7) || method === "GET" && /^\/api\/web-apps\/[^/]+\/chat$/.test(path7) || method === "GET" && /^\/embed\/[^/]+$/.test(path7) || (method === "POST" || method === "DELETE") && path7 === "/open/mcp" || method === "POST" && path7 === "/open/session" || (method === "GET" || method === "POST") && path7.startsWith("/open/sandbox/files/")) return true;
|
|
12592
13968
|
if (request.method === "GET" && /^\/api\/a2a\/agents\/[^/]+\/\.well-known\/agent-card\.json$/.test(path7)) {
|
|
12593
13969
|
return true;
|
|
12594
13970
|
}
|
|
@@ -12596,8 +13972,8 @@ function bypassesConsoleAuth(request) {
|
|
|
12596
13972
|
}
|
|
12597
13973
|
function registerConsoleAuthHook(app2, options) {
|
|
12598
13974
|
app2.addHook("preHandler", async (request, reply) => {
|
|
12599
|
-
const
|
|
12600
|
-
const session = verifySignedConsoleSession(request.headers.authorization,
|
|
13975
|
+
const secret2 = options.tokenSecret ?? resolveConsoleTokenSecret(options.authRequired);
|
|
13976
|
+
const session = verifySignedConsoleSession(request.headers.authorization, secret2);
|
|
12601
13977
|
if (session) {
|
|
12602
13978
|
const user = { id: session.id, tenantId: session.tenantId, tokenExpiresAt: session.expiresAt };
|
|
12603
13979
|
request.user = user;
|
|
@@ -12850,7 +14226,7 @@ var larkChannelAdapter = {
|
|
|
12850
14226
|
};
|
|
12851
14227
|
|
|
12852
14228
|
// src/channels/lark/verification.ts
|
|
12853
|
-
var
|
|
14229
|
+
var import_crypto9 = __toESM(require("crypto"));
|
|
12854
14230
|
function parseLarkRequestBody(body, encryptKey) {
|
|
12855
14231
|
const parsed = body || {};
|
|
12856
14232
|
if (encryptKey && typeof parsed.encrypt === "string") {
|
|
@@ -12859,11 +14235,11 @@ function parseLarkRequestBody(body, encryptKey) {
|
|
|
12859
14235
|
return parsed;
|
|
12860
14236
|
}
|
|
12861
14237
|
function decryptLarkPayload(encryptKey, encryptedPayload) {
|
|
12862
|
-
const key =
|
|
14238
|
+
const key = import_crypto9.default.createHash("sha256").update(encryptKey).digest();
|
|
12863
14239
|
const buffer = Buffer.from(encryptedPayload, "base64");
|
|
12864
14240
|
const iv = buffer.subarray(0, 16);
|
|
12865
14241
|
const ciphertext = buffer.subarray(16);
|
|
12866
|
-
const decipher =
|
|
14242
|
+
const decipher = import_crypto9.default.createDecipheriv("aes-256-cbc", key, iv);
|
|
12867
14243
|
const plaintext = Buffer.concat([
|
|
12868
14244
|
decipher.update(ciphertext),
|
|
12869
14245
|
decipher.final()
|
|
@@ -12980,7 +14356,7 @@ function registerChannelRoutes(app2, dependencies) {
|
|
|
12980
14356
|
}
|
|
12981
14357
|
|
|
12982
14358
|
// src/controllers/channel-installations.ts
|
|
12983
|
-
var
|
|
14359
|
+
var import_crypto10 = require("crypto");
|
|
12984
14360
|
var import_protocols5 = require("@axiom-lattice/protocols");
|
|
12985
14361
|
var _adapterRegistry;
|
|
12986
14362
|
var _router;
|
|
@@ -13105,8 +14481,8 @@ function snapshotPlainObject(value) {
|
|
|
13105
14481
|
}
|
|
13106
14482
|
}
|
|
13107
14483
|
async function getInstallationStore() {
|
|
13108
|
-
const { getStoreLattice:
|
|
13109
|
-
const store2 =
|
|
14484
|
+
const { getStoreLattice: getStoreLattice37 } = await import("@axiom-lattice/core");
|
|
14485
|
+
const store2 = getStoreLattice37("default", "channelInstallation").store;
|
|
13110
14486
|
if (store2) return store2;
|
|
13111
14487
|
const { PostgreSQLChannelInstallationStore } = await import("@axiom-lattice/pg-stores");
|
|
13112
14488
|
const databaseUrl = process.env.DATABASE_URL;
|
|
@@ -13182,7 +14558,7 @@ async function createChannelInstallation(request, reply) {
|
|
|
13182
14558
|
};
|
|
13183
14559
|
}
|
|
13184
14560
|
const store2 = await getInstallationStore();
|
|
13185
|
-
const installationId = (0,
|
|
14561
|
+
const installationId = (0, import_crypto10.randomUUID)();
|
|
13186
14562
|
const createInput = {
|
|
13187
14563
|
channel: body.channel,
|
|
13188
14564
|
name: body.name,
|
|
@@ -16510,6 +17886,7 @@ function isMultipartRequestError(error) {
|
|
|
16510
17886
|
var import_node_fs2 = require("fs");
|
|
16511
17887
|
var import_promises2 = require("fs/promises");
|
|
16512
17888
|
var import_node_path2 = __toESM(require("path"));
|
|
17889
|
+
var import_node_url = require("url");
|
|
16513
17890
|
var import_zod7 = require("zod");
|
|
16514
17891
|
var idSchema2 = import_zod7.z.string().min(1).max(128).regex(/^[A-Za-z0-9._:@-]+$/);
|
|
16515
17892
|
var JS_CONTENT_TYPE = "application/javascript; charset=utf-8";
|
|
@@ -16539,10 +17916,36 @@ async function listChunkCssFiles(assetsDir) {
|
|
|
16539
17916
|
}
|
|
16540
17917
|
}
|
|
16541
17918
|
var BUNDLED_MARKER = "agent-chat-loader.js";
|
|
17919
|
+
function selfModuleDir() {
|
|
17920
|
+
try {
|
|
17921
|
+
const target = {};
|
|
17922
|
+
const originalPrepare = Error.prepareStackTrace;
|
|
17923
|
+
Error.captureStackTrace(target, selfModuleDir);
|
|
17924
|
+
Error.prepareStackTrace = (error, frames2) => frames2;
|
|
17925
|
+
const frames = target.stack;
|
|
17926
|
+
Error.prepareStackTrace = originalPrepare;
|
|
17927
|
+
if (!Array.isArray(frames)) return null;
|
|
17928
|
+
for (const frame of frames) {
|
|
17929
|
+
const callSite = frame;
|
|
17930
|
+
if (typeof callSite.getFileName !== "function") continue;
|
|
17931
|
+
const fileName = callSite.getFileName();
|
|
17932
|
+
if (typeof fileName !== "string" || fileName.length === 0) continue;
|
|
17933
|
+
const filePath = fileName.startsWith("file://") ? (0, import_node_url.fileURLToPath)(fileName) : fileName;
|
|
17934
|
+
return import_node_path2.default.dirname(filePath);
|
|
17935
|
+
}
|
|
17936
|
+
} catch {
|
|
17937
|
+
}
|
|
17938
|
+
return null;
|
|
17939
|
+
}
|
|
16542
17940
|
function resolveBundledEmbedDir() {
|
|
17941
|
+
const candidates = [];
|
|
16543
17942
|
if (typeof __dirname === "string") {
|
|
16544
|
-
|
|
16545
|
-
|
|
17943
|
+
candidates.push(import_node_path2.default.resolve(__dirname, "embed"));
|
|
17944
|
+
}
|
|
17945
|
+
const selfDir = selfModuleDir();
|
|
17946
|
+
if (selfDir !== null) candidates.push(import_node_path2.default.resolve(selfDir, "embed"));
|
|
17947
|
+
for (const candidate of candidates) {
|
|
17948
|
+
if ((0, import_node_fs2.existsSync)(import_node_path2.default.join(candidate, BUNDLED_MARKER))) return candidate;
|
|
16546
17949
|
}
|
|
16547
17950
|
let dir = import_node_path2.default.dirname(import_node_path2.default.resolve(process.argv[1] ?? process.cwd()));
|
|
16548
17951
|
for (let depth = 0; depth < 8; depth += 1) {
|
|
@@ -16612,10 +18015,10 @@ function resolveAgentWebAppAttachmentSecret(consoleSecret) {
|
|
|
16612
18015
|
return process.env.WEB_APP_ATTACHMENT_SECRET || process.env.AUTH_TOKEN_SECRET || process.env.JWT_SECRET || consoleSecret;
|
|
16613
18016
|
}
|
|
16614
18017
|
var AgentWebAppAttachmentRefService = class {
|
|
16615
|
-
constructor(
|
|
18018
|
+
constructor(secret2, now = Date.now) {
|
|
16616
18019
|
this.now = now;
|
|
16617
|
-
if (!
|
|
16618
|
-
this.key = (0, import_node_crypto9.createHash)("sha256").update(
|
|
18020
|
+
if (!secret2) throw new Error("Attachment signing secret is required");
|
|
18021
|
+
this.key = (0, import_node_crypto9.createHash)("sha256").update(secret2, "utf8").digest();
|
|
16619
18022
|
}
|
|
16620
18023
|
sign(input) {
|
|
16621
18024
|
const payload = {
|
|
@@ -17875,7 +19278,14 @@ function registerProjectRoomRoutes(app2, deps) {
|
|
|
17875
19278
|
await deps.readStateService.mark(actor(request, params.projectId));
|
|
17876
19279
|
return { data: { marked: true } };
|
|
17877
19280
|
}));
|
|
17878
|
-
app2.get("/api/projects/:projectId/members", async (request, reply) => run(reply, async () =>
|
|
19281
|
+
app2.get("/api/projects/:projectId/members", async (request, reply) => run(reply, async () => {
|
|
19282
|
+
const memberships = await deps.membershipService.list(actor(request, projectRoomParamsSchema.parse(request.params).projectId));
|
|
19283
|
+
const enriched = await Promise.all(memberships.map(async (membership) => {
|
|
19284
|
+
const user = await deps.userDirectory.getUserById(membership.userId);
|
|
19285
|
+
return user === null ? membership : { ...membership, name: user.name };
|
|
19286
|
+
}));
|
|
19287
|
+
return { data: enriched };
|
|
19288
|
+
}));
|
|
17879
19289
|
app2.post("/api/projects/:projectId/members", async (request, reply) => run(reply, async () => {
|
|
17880
19290
|
const p = projectRoomParamsSchema.parse(request.params);
|
|
17881
19291
|
return { statusCode: 201, data: await deps.membershipService.add(actor(request, p.projectId), addProjectMemberSchema.parse(request.body)) };
|
|
@@ -18047,13 +19457,16 @@ function registerCoSpaceRoutes(app2, deps) {
|
|
|
18047
19457
|
project.id
|
|
18048
19458
|
);
|
|
18049
19459
|
const participantNames = [];
|
|
19460
|
+
const otherHumanNames = [];
|
|
18050
19461
|
for (const m of memberships) {
|
|
18051
19462
|
if (m.status !== "active") continue;
|
|
18052
19463
|
const user = await deps.userStore.getUserById(m.userId);
|
|
18053
19464
|
if (user) {
|
|
18054
19465
|
participantNames.push(user.name);
|
|
19466
|
+
if (m.userId !== actor2.userId) otherHumanNames.push(user.name);
|
|
18055
19467
|
}
|
|
18056
19468
|
}
|
|
19469
|
+
const displayName = project.kind === "personal" && otherHumanNames.length === 1 ? otherHumanNames[0] : void 0;
|
|
18057
19470
|
rooms.push({
|
|
18058
19471
|
project,
|
|
18059
19472
|
room,
|
|
@@ -18062,6 +19475,7 @@ function registerCoSpaceRoutes(app2, deps) {
|
|
|
18062
19475
|
(m) => m.status === "active"
|
|
18063
19476
|
).length,
|
|
18064
19477
|
participantNames,
|
|
19478
|
+
...displayName === void 0 ? {} : { displayName },
|
|
18065
19479
|
unreadCount: await computeUnread(
|
|
18066
19480
|
deps,
|
|
18067
19481
|
actor2.tenantId,
|
|
@@ -18079,41 +19493,45 @@ function registerCoSpaceRoutes(app2, deps) {
|
|
|
18079
19493
|
const bTime = b.lastMessage ? Date.parse(b.lastMessage.createdAt) : 0;
|
|
18080
19494
|
return bTime - aTime;
|
|
18081
19495
|
});
|
|
18082
|
-
|
|
18083
|
-
|
|
18084
|
-
|
|
18085
|
-
|
|
18086
|
-
|
|
18087
|
-
|
|
18088
|
-
|
|
18089
|
-
|
|
18090
|
-
|
|
18091
|
-
|
|
18092
|
-
|
|
18093
|
-
|
|
18094
|
-
|
|
18095
|
-
|
|
18096
|
-
|
|
18097
|
-
|
|
18098
|
-
|
|
18099
|
-
|
|
19496
|
+
try {
|
|
19497
|
+
const publicRoom = await deps.publicRoom.ensure(actor2.tenantId, params.workspaceId);
|
|
19498
|
+
if (publicRoom) {
|
|
19499
|
+
const publicMessages = await deps.messageStore.list({
|
|
19500
|
+
tenantId: actor2.tenantId,
|
|
19501
|
+
roomId: publicRoom.room.id,
|
|
19502
|
+
limit: 1
|
|
19503
|
+
});
|
|
19504
|
+
const publicLastMessage = publicMessages[0];
|
|
19505
|
+
const publicMemberships = await deps.membershipStore.list(
|
|
19506
|
+
actor2.tenantId,
|
|
19507
|
+
publicRoom.project.id
|
|
19508
|
+
);
|
|
19509
|
+
const publicParticipantNames = [];
|
|
19510
|
+
for (const m of publicMemberships) {
|
|
19511
|
+
if (m.status !== "active") continue;
|
|
19512
|
+
const user = await deps.userStore.getUserById(m.userId);
|
|
19513
|
+
if (user) {
|
|
19514
|
+
publicParticipantNames.push(user.name);
|
|
19515
|
+
}
|
|
18100
19516
|
}
|
|
19517
|
+
rooms.unshift({
|
|
19518
|
+
project: publicRoom.project,
|
|
19519
|
+
room: publicRoom.room,
|
|
19520
|
+
lastMessage: publicLastMessage === void 0 ? void 0 : (0, import_protocols15.toProjectRoomPublicMessage)(publicLastMessage),
|
|
19521
|
+
participantCount: publicMemberships.filter((m) => m.status === "active").length,
|
|
19522
|
+
participantNames: publicParticipantNames,
|
|
19523
|
+
isPublic: true,
|
|
19524
|
+
unreadCount: await computeUnread(
|
|
19525
|
+
deps,
|
|
19526
|
+
actor2.tenantId,
|
|
19527
|
+
actor2.userId,
|
|
19528
|
+
publicRoom.room.id,
|
|
19529
|
+
publicLastMessage
|
|
19530
|
+
)
|
|
19531
|
+
});
|
|
18101
19532
|
}
|
|
18102
|
-
|
|
18103
|
-
|
|
18104
|
-
room: publicRoom.room,
|
|
18105
|
-
lastMessage: publicLastMessage === void 0 ? void 0 : (0, import_protocols15.toProjectRoomPublicMessage)(publicLastMessage),
|
|
18106
|
-
participantCount: publicMemberships.filter((m) => m.status === "active").length,
|
|
18107
|
-
participantNames: publicParticipantNames,
|
|
18108
|
-
isPublic: true,
|
|
18109
|
-
unreadCount: await computeUnread(
|
|
18110
|
-
deps,
|
|
18111
|
-
actor2.tenantId,
|
|
18112
|
-
actor2.userId,
|
|
18113
|
-
publicRoom.room.id,
|
|
18114
|
-
publicLastMessage
|
|
18115
|
-
)
|
|
18116
|
-
});
|
|
19533
|
+
} catch (e) {
|
|
19534
|
+
console.error("[CoSpace] Failed to assemble public room:", e);
|
|
18117
19535
|
}
|
|
18118
19536
|
return { data: { rooms } };
|
|
18119
19537
|
});
|
|
@@ -18138,7 +19556,6 @@ function registerCoSpaceRoutes(app2, deps) {
|
|
|
18138
19556
|
);
|
|
18139
19557
|
}
|
|
18140
19558
|
let projectId;
|
|
18141
|
-
let otherPartyId;
|
|
18142
19559
|
if (body.type === "human") {
|
|
18143
19560
|
projectId = (0, import_core44.generateDirectHumanProjectId)(
|
|
18144
19561
|
actor2.tenantId,
|
|
@@ -18146,7 +19563,6 @@ function registerCoSpaceRoutes(app2, deps) {
|
|
|
18146
19563
|
actor2.userId,
|
|
18147
19564
|
body.targetUserId
|
|
18148
19565
|
);
|
|
18149
|
-
otherPartyId = body.targetUserId;
|
|
18150
19566
|
} else {
|
|
18151
19567
|
projectId = (0, import_core44.generateDirectBotProjectId)(
|
|
18152
19568
|
actor2.tenantId,
|
|
@@ -18154,14 +19570,24 @@ function registerCoSpaceRoutes(app2, deps) {
|
|
|
18154
19570
|
actor2.userId,
|
|
18155
19571
|
body.assistantId
|
|
18156
19572
|
);
|
|
18157
|
-
otherPartyId = body.assistantId;
|
|
18158
19573
|
}
|
|
18159
19574
|
let project = await deps.projectStore.getProjectById(
|
|
18160
19575
|
actor2.tenantId,
|
|
18161
19576
|
projectId
|
|
18162
19577
|
);
|
|
18163
19578
|
if (!project) {
|
|
18164
|
-
|
|
19579
|
+
let displayName;
|
|
19580
|
+
if (body.type === "human") {
|
|
19581
|
+
const targetUser = await deps.userStore.getUserById(body.targetUserId);
|
|
19582
|
+
displayName = targetUser?.name ?? body.targetUserId;
|
|
19583
|
+
} else {
|
|
19584
|
+
const targetAssistant = await deps.assistantStore.getAssistantById(
|
|
19585
|
+
actor2.tenantId,
|
|
19586
|
+
body.assistantId
|
|
19587
|
+
);
|
|
19588
|
+
displayName = targetAssistant?.name ?? body.assistantId;
|
|
19589
|
+
}
|
|
19590
|
+
const name = body.type === "human" ? `Direct with ${displayName}` : `Chat with ${displayName}`;
|
|
18165
19591
|
project = await deps.projectStore.createProject(
|
|
18166
19592
|
actor2.tenantId,
|
|
18167
19593
|
params.workspaceId,
|
|
@@ -18354,12 +19780,28 @@ function registerCoSpaceRoutes(app2, deps) {
|
|
|
18354
19780
|
actor2.tenantId,
|
|
18355
19781
|
directProjectId
|
|
18356
19782
|
);
|
|
18357
|
-
|
|
19783
|
+
const bot = {
|
|
18358
19784
|
assistantId: assistant.id,
|
|
18359
19785
|
name: assistant.name,
|
|
18360
19786
|
description: assistant.description,
|
|
18361
19787
|
hasDirectRoom: existingProject !== null
|
|
18362
|
-
}
|
|
19788
|
+
};
|
|
19789
|
+
if (assistant.createdAt) bot.createdAt = assistant.createdAt.toISOString();
|
|
19790
|
+
if (existingProject) {
|
|
19791
|
+
const membership = await deps.botMembershipStore.findByAssistant(
|
|
19792
|
+
actor2.tenantId,
|
|
19793
|
+
directProjectId,
|
|
19794
|
+
assistant.id
|
|
19795
|
+
);
|
|
19796
|
+
if (membership) {
|
|
19797
|
+
if (membership.role) bot.role = membership.role;
|
|
19798
|
+
if (membership.mentionName) bot.mentionName = membership.mentionName;
|
|
19799
|
+
if (membership.responsibility) bot.responsibility = membership.responsibility;
|
|
19800
|
+
bot.status = membership.status;
|
|
19801
|
+
if (membership.joinedAt) bot.joinedAt = membership.joinedAt.toISOString();
|
|
19802
|
+
}
|
|
19803
|
+
}
|
|
19804
|
+
bots.push(bot);
|
|
18363
19805
|
}
|
|
18364
19806
|
return { data: { bots } };
|
|
18365
19807
|
});
|
|
@@ -18400,13 +19842,15 @@ function registerCoSpaceRoutes(app2, deps) {
|
|
|
18400
19842
|
actor2.tenantId,
|
|
18401
19843
|
directProjectId
|
|
18402
19844
|
);
|
|
18403
|
-
|
|
19845
|
+
const member = {
|
|
18404
19846
|
userId: link.userId,
|
|
18405
19847
|
name: user.name,
|
|
18406
19848
|
email: user.email,
|
|
18407
19849
|
role: link.role,
|
|
18408
19850
|
hasDirectRoom: existingProject !== null
|
|
18409
|
-
}
|
|
19851
|
+
};
|
|
19852
|
+
if (link.joinedAt) member.joinedAt = link.joinedAt.toISOString();
|
|
19853
|
+
members.push(member);
|
|
18410
19854
|
}
|
|
18411
19855
|
return { data: { members } };
|
|
18412
19856
|
});
|
|
@@ -22252,7 +23696,15 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
|
|
|
22252
23696
|
});
|
|
22253
23697
|
}
|
|
22254
23698
|
};
|
|
22255
|
-
registerProjectRoomRoutes(app2, {
|
|
23699
|
+
registerProjectRoomRoutes(app2, {
|
|
23700
|
+
roomService,
|
|
23701
|
+
membershipService,
|
|
23702
|
+
messageService,
|
|
23703
|
+
readStateService,
|
|
23704
|
+
userDirectory: {
|
|
23705
|
+
getUserById: (id3) => (0, import_core51.getStoreLattice)("default", "user").store.getUserById(id3).then((u) => u ? { name: u.name } : null)
|
|
23706
|
+
}
|
|
23707
|
+
});
|
|
22256
23708
|
registerProjectRosterRoutes(app2, { service: rosterService });
|
|
22257
23709
|
registerCoSpaceRoutes(app2, {
|
|
22258
23710
|
projectStore: {
|
|
@@ -23617,7 +25069,7 @@ var collectionRegistration = {
|
|
|
23617
25069
|
|
|
23618
25070
|
// src/export_registrations/channel-installation.registration.ts
|
|
23619
25071
|
var import_core59 = require("@axiom-lattice/core");
|
|
23620
|
-
var
|
|
25072
|
+
var import_crypto11 = require("crypto");
|
|
23621
25073
|
var UUID_PATTERN2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
23622
25074
|
var PUBLIC_CHANNELS = /* @__PURE__ */ new Set(["lark", "email", "slack", "wechat"]);
|
|
23623
25075
|
function isPublicChannel(channel) {
|
|
@@ -23776,7 +25228,7 @@ var channelInstallationRegistration = {
|
|
|
23776
25228
|
}
|
|
23777
25229
|
id3 = sourceId;
|
|
23778
25230
|
} else {
|
|
23779
|
-
id3 = (0,
|
|
25231
|
+
id3 = (0, import_crypto11.randomUUID)();
|
|
23780
25232
|
}
|
|
23781
25233
|
await store2.createInstallation(tenantId, id3, createInput);
|
|
23782
25234
|
return { newId: id3 };
|
|
@@ -24323,7 +25775,7 @@ function createAuditLoggerMiddleware() {
|
|
|
24323
25775
|
}
|
|
24324
25776
|
|
|
24325
25777
|
// src/index.ts
|
|
24326
|
-
var
|
|
25778
|
+
var import_core78 = require("@axiom-lattice/core");
|
|
24327
25779
|
|
|
24328
25780
|
// src/swagger.ts
|
|
24329
25781
|
var import_swagger = __toESM(require("@fastify/swagger"));
|
|
@@ -24640,7 +26092,7 @@ _AgentTaskConsumer.agent_run_endpoint = "http://localhost:4001/api/runs";
|
|
|
24640
26092
|
var AgentTaskConsumer = _AgentTaskConsumer;
|
|
24641
26093
|
|
|
24642
26094
|
// src/index.ts
|
|
24643
|
-
var
|
|
26095
|
+
var import_core79 = require("@axiom-lattice/core");
|
|
24644
26096
|
|
|
24645
26097
|
// src/channels/ChannelInfrastructure.ts
|
|
24646
26098
|
var import_core65 = require("@axiom-lattice/core");
|
|
@@ -24648,7 +26100,7 @@ var import_core65 = require("@axiom-lattice/core");
|
|
|
24648
26100
|
// src/router/MessageRouter.ts
|
|
24649
26101
|
var import_core64 = require("@axiom-lattice/core");
|
|
24650
26102
|
var import_protocols27 = require("@axiom-lattice/protocols");
|
|
24651
|
-
var
|
|
26103
|
+
var import_crypto12 = require("crypto");
|
|
24652
26104
|
var BindingNotFoundError = class extends Error {
|
|
24653
26105
|
constructor(message) {
|
|
24654
26106
|
super(message);
|
|
@@ -24963,7 +26415,7 @@ var MessageRouter = class {
|
|
|
24963
26415
|
}
|
|
24964
26416
|
if (!threadId) {
|
|
24965
26417
|
const threadStore = (0, import_core64.getStoreLattice)("default", "thread").store;
|
|
24966
|
-
const newThreadId = (0,
|
|
26418
|
+
const newThreadId = (0, import_crypto12.randomUUID)();
|
|
24967
26419
|
console.log({
|
|
24968
26420
|
event: "dispatch:thread:create",
|
|
24969
26421
|
agentId,
|
|
@@ -25009,7 +26461,7 @@ var MessageRouter = class {
|
|
|
25009
26461
|
workspace_id: binding?.workspaceId || "",
|
|
25010
26462
|
project_id: binding?.projectId || ""
|
|
25011
26463
|
});
|
|
25012
|
-
const inputMessageId = (0,
|
|
26464
|
+
const inputMessageId = (0, import_crypto12.randomUUID)();
|
|
25013
26465
|
const replyTarget = internalRoom ? correlatedRoomReplyTarget(message.replyTarget, inputMessageId) : message.replyTarget;
|
|
25014
26466
|
const replyAdapter = replyTarget ? this.adapterRegistry.get(replyTarget.adapterChannel) : void 0;
|
|
25015
26467
|
if (options.trustedMessageOptions && (!this.trustedDispatcher || !replyTarget || !replyAdapter)) {
|
|
@@ -25207,25 +26659,25 @@ async function prepareProjectTaskRuntime(runtime, log2) {
|
|
|
25207
26659
|
}
|
|
25208
26660
|
|
|
25209
26661
|
// src/index.ts
|
|
25210
|
-
var
|
|
26662
|
+
var import_protocols35 = require("@axiom-lattice/protocols");
|
|
25211
26663
|
process.on("unhandledRejection", (reason, promise) => {
|
|
25212
26664
|
console.error("\u672A\u5904\u7406\u7684Promise\u62D2\u7EDD:", reason);
|
|
25213
26665
|
});
|
|
25214
26666
|
var DEFAULT_LOGGER_CONFIG = {
|
|
25215
26667
|
name: "default",
|
|
25216
26668
|
description: "Default logger for lattice-gateway service",
|
|
25217
|
-
type:
|
|
26669
|
+
type: import_protocols35.LoggerType.PINO,
|
|
25218
26670
|
serviceName: "lattice/gateway",
|
|
25219
26671
|
loggerName: "lattice/gateway"
|
|
25220
26672
|
};
|
|
25221
26673
|
var loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);
|
|
25222
26674
|
var logger6 = loggerLattice.client;
|
|
25223
26675
|
function initializeLogger(config) {
|
|
25224
|
-
if (
|
|
25225
|
-
|
|
26676
|
+
if (import_core79.loggerLatticeManager.hasLattice("default")) {
|
|
26677
|
+
import_core79.loggerLatticeManager.removeLattice("default");
|
|
25226
26678
|
}
|
|
25227
|
-
(0,
|
|
25228
|
-
return (0,
|
|
26679
|
+
(0, import_core79.registerLoggerLattice)("default", config);
|
|
26680
|
+
return (0, import_core79.getLoggerLattice)("default");
|
|
25229
26681
|
}
|
|
25230
26682
|
var app = (0, import_fastify.default)({
|
|
25231
26683
|
logger: false,
|
|
@@ -25322,7 +26774,7 @@ app.setErrorHandler((error, request, reply) => {
|
|
|
25322
26774
|
});
|
|
25323
26775
|
function getConfiguredSandboxProvider() {
|
|
25324
26776
|
const sandboxProviderType = process.env.SANDBOX_PROVIDER_TYPE || "microsandbox-remote";
|
|
25325
|
-
return (0,
|
|
26777
|
+
return (0, import_core79.createSandboxProvider)({
|
|
25326
26778
|
type: sandboxProviderType,
|
|
25327
26779
|
remoteBaseURL: process.env.SANDBOX_BASE_URL,
|
|
25328
26780
|
microsandboxServiceBaseURL: process.env.MICROSANDBOX_SERVICE_BASE_URL,
|
|
@@ -25338,7 +26790,7 @@ function getConfiguredSandboxProvider() {
|
|
|
25338
26790
|
}
|
|
25339
26791
|
async function restoreMcpConnections() {
|
|
25340
26792
|
try {
|
|
25341
|
-
const storeLattice = (0,
|
|
26793
|
+
const storeLattice = (0, import_core79.getStoreLattice)("default", "mcp");
|
|
25342
26794
|
const store2 = storeLattice.store;
|
|
25343
26795
|
if (!store2) {
|
|
25344
26796
|
logger6.info("MCP store not configured, skipping connection restoration");
|
|
@@ -25352,15 +26804,15 @@ async function restoreMcpConnections() {
|
|
|
25352
26804
|
for (const config of connectedConfigs) {
|
|
25353
26805
|
try {
|
|
25354
26806
|
const connection = convertToConnection2(config.config);
|
|
25355
|
-
|
|
26807
|
+
import_core79.mcpManager.addServer(config.key, connection);
|
|
25356
26808
|
} catch (err) {
|
|
25357
26809
|
logger6.warn(`Failed to prepare MCP server "${config.key}" for restoration`, { error: err });
|
|
25358
26810
|
}
|
|
25359
26811
|
}
|
|
25360
|
-
await
|
|
26812
|
+
await import_core79.mcpManager.connect();
|
|
25361
26813
|
for (const config of connectedConfigs) {
|
|
25362
26814
|
try {
|
|
25363
|
-
await
|
|
26815
|
+
await import_core79.mcpManager.registerToolsToToolLattice(config.key, config.selectedTools);
|
|
25364
26816
|
logger6.info(`MCP server "${config.key}" restored with ${config.selectedTools.length} tools`);
|
|
25365
26817
|
} catch (err) {
|
|
25366
26818
|
logger6.warn(`Failed to register tools for MCP server "${config.key}"`, { error: err });
|
|
@@ -25388,9 +26840,9 @@ var start = async (config) => {
|
|
|
25388
26840
|
let projectRoomRealtimeRuntime;
|
|
25389
26841
|
if (projectRoomRealtimeMode === "single-gateway") {
|
|
25390
26842
|
projectRoomRealtimeRuntime = createProjectRoomRealtimeRuntime({
|
|
25391
|
-
tasks: (0,
|
|
25392
|
-
rooms: (0,
|
|
25393
|
-
memberships: (0,
|
|
26843
|
+
tasks: (0, import_core79.getStoreLattice)("default", "task").store,
|
|
26844
|
+
rooms: (0, import_core79.getStoreLattice)("default", "projectRoom").store,
|
|
26845
|
+
memberships: (0, import_core79.getStoreLattice)("default", "projectBotMembership").store,
|
|
25394
26846
|
log: { warn: (message, context) => logger6.warn(message, context) }
|
|
25395
26847
|
});
|
|
25396
26848
|
}
|
|
@@ -25404,7 +26856,7 @@ var start = async (config) => {
|
|
|
25404
26856
|
const infrastructure = createChannelInfrastructure({
|
|
25405
26857
|
adapterRegistry,
|
|
25406
26858
|
getStore: ((kind) => getStore11("default", kind).store),
|
|
25407
|
-
trustedDispatcher: (0,
|
|
26859
|
+
trustedDispatcher: (0, import_core79.createTrustedAgentMessageDispatcher)((scope) => import_core79.agentInstanceManager.getAgent(scope)),
|
|
25408
26860
|
middlewares: [
|
|
25409
26861
|
createDeduplicationMiddleware(),
|
|
25410
26862
|
createRateLimitMiddleware(),
|
|
@@ -25415,7 +26867,7 @@ var start = async (config) => {
|
|
|
25415
26867
|
});
|
|
25416
26868
|
const bindingStore = infrastructure.bindingRegistry;
|
|
25417
26869
|
const installationStore = infrastructure.installationStore;
|
|
25418
|
-
(0,
|
|
26870
|
+
(0, import_core78.setBindingRegistry)(bindingStore);
|
|
25419
26871
|
const router = infrastructure.router;
|
|
25420
26872
|
app.addHook("onClose", async () => router.dispose());
|
|
25421
26873
|
channelDeps = {
|
|
@@ -25431,10 +26883,10 @@ var start = async (config) => {
|
|
|
25431
26883
|
error: err instanceof Error ? err.message : String(err)
|
|
25432
26884
|
});
|
|
25433
26885
|
}
|
|
25434
|
-
(0,
|
|
26886
|
+
(0, import_core78.setEvalRunService)(evalRunner);
|
|
25435
26887
|
try {
|
|
25436
|
-
const menuStore = (0,
|
|
25437
|
-
(0,
|
|
26888
|
+
const menuStore = (0, import_core79.getStoreLattice)("default", "menu").store;
|
|
26889
|
+
(0, import_core78.setMenuRegistry)(menuStore);
|
|
25438
26890
|
logger6.info("Menu registry initialized");
|
|
25439
26891
|
} catch {
|
|
25440
26892
|
}
|
|
@@ -25451,10 +26903,10 @@ var start = async (config) => {
|
|
|
25451
26903
|
const { A2AAuthService: A2AAuthService2, parseEnvKeys: parseEnvKeys2 } = await Promise.resolve().then(() => (init_A2AAuthService(), A2AAuthService_exports));
|
|
25452
26904
|
const { registerA2AStandardRoutes: registerA2AStandardRoutes2 } = await Promise.resolve().then(() => (init_a2a_standard(), a2a_standard_exports));
|
|
25453
26905
|
const a2a = await Promise.resolve().then(() => (init_a2a(), a2a_exports));
|
|
25454
|
-
const a2aKeyStore = (0,
|
|
25455
|
-
const assistantStore = (0,
|
|
25456
|
-
const projectStore = (0,
|
|
25457
|
-
const taskStore = (0,
|
|
26906
|
+
const a2aKeyStore = (0, import_core79.getStoreLattice)("default", "a2aApiKey").store;
|
|
26907
|
+
const assistantStore = (0, import_core79.getStoreLattice)("default", "assistant").store;
|
|
26908
|
+
const projectStore = (0, import_core79.getStoreLattice)("default", "project").store;
|
|
26909
|
+
const taskStore = (0, import_core79.getStoreLattice)("default", "task").store;
|
|
25458
26910
|
const authService = new A2AAuthService2({
|
|
25459
26911
|
keyStore: a2aKeyStore,
|
|
25460
26912
|
assistantStore,
|
|
@@ -25480,24 +26932,54 @@ var start = async (config) => {
|
|
|
25480
26932
|
}
|
|
25481
26933
|
try {
|
|
25482
26934
|
const { registerOpenRoutes: registerOpenRoutes2 } = await Promise.resolve().then(() => (init_open(), open_exports));
|
|
26935
|
+
const { registerOpenSessionRoutes: registerOpenSessionRoutes2 } = await Promise.resolve().then(() => (init_open_session(), open_session_exports));
|
|
26936
|
+
const { registerOpenCatalogRoutes: registerOpenCatalogRoutes2 } = await Promise.resolve().then(() => (init_open_catalog(), open_catalog_exports));
|
|
26937
|
+
const { registerOpenFilesRoutes: registerOpenFilesRoutes2 } = await Promise.resolve().then(() => (init_open_files(), open_files_exports));
|
|
26938
|
+
const { registerOpenAuditRoutes: registerOpenAuditRoutes2 } = await Promise.resolve().then(() => (init_open_audit(), open_audit_exports));
|
|
26939
|
+
const { registerOpenExposureRoutes: registerOpenExposureRoutes2 } = await Promise.resolve().then(() => (init_open_exposure(), open_exposure_exports));
|
|
26940
|
+
const { openLattice: openLattice2 } = await Promise.resolve().then(() => (init_openLattice(), openLattice_exports));
|
|
26941
|
+
const { createKbProvider: createKbProvider2 } = await Promise.resolve().then(() => (init_kbProvider(), kbProvider_exports));
|
|
26942
|
+
const { createOpenSandboxProvider: createOpenSandboxProvider2 } = await Promise.resolve().then(() => (init_sandboxProvider(), sandboxProvider_exports));
|
|
26943
|
+
const { createAgentProvider: createAgentProvider2 } = await Promise.resolve().then(() => (init_agentProvider(), agentProvider_exports));
|
|
26944
|
+
const { registerExposedPluginTools: registerExposedPluginTools2 } = await Promise.resolve().then(() => (init_registerExposedPlugins(), registerExposedPlugins_exports));
|
|
26945
|
+
const { CollectionService: CollectionService2 } = await Promise.resolve().then(() => (init_collection_service(), collection_service_exports));
|
|
26946
|
+
openLattice2.register(createKbProvider2(new CollectionService2()));
|
|
26947
|
+
openLattice2.register(createOpenSandboxProvider2());
|
|
26948
|
+
const threadStore = (0, import_core79.getStoreLattice)("default", "thread").store;
|
|
26949
|
+
const assistantStore = (0, import_core79.getStoreLattice)("default", "assistant").store;
|
|
26950
|
+
openLattice2.register(
|
|
26951
|
+
createAgentProvider2({
|
|
26952
|
+
threadStore,
|
|
26953
|
+
resolveAssistant: async (tenantId, assistantId) => {
|
|
26954
|
+
const assistant = await assistantStore.getAssistantById(tenantId, assistantId);
|
|
26955
|
+
return assistant ? { name: assistant.name, description: assistant.description } : null;
|
|
26956
|
+
}
|
|
26957
|
+
})
|
|
26958
|
+
);
|
|
26959
|
+
await registerExposedPluginTools2();
|
|
25483
26960
|
registerOpenRoutes2(app);
|
|
25484
|
-
|
|
26961
|
+
registerOpenSessionRoutes2(app);
|
|
26962
|
+
registerOpenCatalogRoutes2(app);
|
|
26963
|
+
registerOpenFilesRoutes2(app);
|
|
26964
|
+
registerOpenAuditRoutes2(app);
|
|
26965
|
+
registerOpenExposureRoutes2(app);
|
|
26966
|
+
logger6.info("Open API routes registered (kb + sandbox providers, session exchange)");
|
|
25485
26967
|
} catch (err) {
|
|
25486
|
-
logger6.warn("Open
|
|
26968
|
+
logger6.warn("Open API routes unavailable", {
|
|
25487
26969
|
error: err instanceof Error ? err.message : String(err)
|
|
25488
26970
|
});
|
|
25489
26971
|
}
|
|
25490
|
-
if (!
|
|
25491
|
-
|
|
26972
|
+
if (!import_core79.sandboxLatticeManager.hasLattice("default")) {
|
|
26973
|
+
import_core79.sandboxLatticeManager.registerLattice("default", getConfiguredSandboxProvider());
|
|
25492
26974
|
logger6.info("Registered sandbox manager from env configuration");
|
|
25493
26975
|
}
|
|
25494
26976
|
try {
|
|
25495
26977
|
const { ResourceController: ResourceController2 } = await Promise.resolve().then(() => (init_resources(), resources_exports));
|
|
25496
|
-
const sharedResourceStore = (0,
|
|
25497
|
-
const cache = new
|
|
26978
|
+
const sharedResourceStore = (0, import_core79.getStoreLattice)("default", "sharedResource").store;
|
|
26979
|
+
const cache = new import_core79.TokenCache();
|
|
25498
26980
|
const resourceController = new ResourceController2({
|
|
25499
26981
|
store: sharedResourceStore,
|
|
25500
|
-
sandboxManager:
|
|
26982
|
+
sandboxManager: import_core79.sandboxLatticeManager,
|
|
25501
26983
|
cache,
|
|
25502
26984
|
logger: logger6
|
|
25503
26985
|
});
|
|
@@ -25536,7 +27018,7 @@ var start = async (config) => {
|
|
|
25536
27018
|
}
|
|
25537
27019
|
}
|
|
25538
27020
|
if (process.env.AXIOM_RESTORE_PENDING_ON_STARTUP === "true") {
|
|
25539
|
-
|
|
27021
|
+
import_core79.agentInstanceManager.restore().then((stats) => {
|
|
25540
27022
|
logger6.info(`Agent recovery complete: ${stats.restored} threads restored, ${stats.errors} errors`);
|
|
25541
27023
|
}).catch((error) => {
|
|
25542
27024
|
logger6.error("Agent recovery failed", { error });
|