@axiom-lattice/gateway 4.8.4 → 4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/a2a-BHBLACJV.mjs +17 -0
- package/dist/a2a-BHBLACJV.mjs.map +1 -0
- package/dist/{a2a-FGYX2HH3.mjs → chunk-HYYLYIMH.mjs} +59 -15
- package/dist/chunk-HYYLYIMH.mjs.map +1 -0
- package/dist/embed/{embed-page-AgentDetailSideApp-S5N76UPU.js → embed-page-AgentDetailSideApp-BVJK7WIS.js} +1 -1
- package/dist/embed/{embed-page-AgentGovernanceWorkbench-QFMP2M73.js → embed-page-AgentGovernanceWorkbench-L2YHPRNE.js} +1 -1
- package/dist/embed/{embed-page-MessageGraph-H3HPZKOH.js → embed-page-MessageGraph-JOQ46UE2.js} +1 -1
- package/dist/embed/{embed-page-ReactChart-ZFMANJCT.js → embed-page-ReactChart-I5AYTSII.js} +1 -1
- package/dist/embed/{embed-page-SkillFlow-HY7PD43P.js → embed-page-SkillFlow-YLB5XPFH.js} +1 -1
- package/dist/embed/{embed-page-TasksSideApp-QKEXMHCT.js → embed-page-TasksSideApp-QLJVB7UK.js} +1 -1
- package/dist/embed/{embed-page-TeamWorkspace-ZFVAFZXZ.js → embed-page-TeamWorkspace-BZZEAYSB.js} +1 -1
- package/dist/embed/{embed-page-TopologyRuntimeView-2BS4OYEZ.js → embed-page-TopologyRuntimeView-FRA3AXQQ.js} +1 -1
- package/dist/embed/{embed-page-WorkflowAutomationView-WUI7BSQP.js → embed-page-WorkflowAutomationView-D745PK3W.js} +1 -1
- package/dist/embed/{embed-page-chunk-5WYDCL3B.js → embed-page-chunk-4WBAN7QL.js} +7 -7
- package/dist/embed/{embed-page-chunk-4T4QMOUS.js → embed-page-chunk-FVMSMU4J.js} +1 -1
- package/dist/embed/{embed-page-chunk-VJTO6SG6.js → embed-page-chunk-FWGNJMXD.js} +1 -1
- package/dist/embed/{embed-page-chunk-MSHEVUK3.js → embed-page-chunk-K5YYUAPL.js} +1 -1
- package/dist/embed/{embed-page-chunk-6HM7ZERK.js → embed-page-chunk-M2PV36MX.js} +1 -1
- package/dist/embed/{embed-page-chunk-XKQ6YPUW.js → embed-page-chunk-P5PFV3N7.js} +1 -1
- package/dist/embed/{embed-page-chunk-7ZBZKXBU.js → embed-page-chunk-WMLR2GQK.js} +4 -4
- package/dist/embed/embed-page.js +1 -1
- package/dist/index.d.mts +383 -2
- package/dist/index.d.ts +383 -2
- package/dist/index.js +2557 -1091
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1498 -79
- package/dist/index.mjs.map +1 -1
- package/dist/{open-exposure-VU227IO3.mjs → open-exposure-27ESFWTB.mjs} +4 -4
- package/package.json +7 -7
- package/dist/a2a-FGYX2HH3.mjs.map +0 -1
- /package/dist/{open-exposure-VU227IO3.mjs.map → open-exposure-27ESFWTB.mjs.map} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as http from 'http';
|
|
2
|
-
import { ProjectRoomMessage, ProjectBotMembership, ProjectMembership, TaskItem, ChannelAdapter, InboundMessage, Binding, BindingRegistry, ChannelInstallationStore, DispatchResult, ProjectRoomEventScope, ProjectRoomBusinessEventDraft, ProjectRoomScopedBusinessEvent, ProjectRoomBusinessEvent, ProjectRoomEventSubscription, TaskStore, ProjectRoomStore, ProjectBotMembershipStore, ThreadStore, ProjectRoom, Thread, ProjectStore, TaskWorkItemStore, TenantStore, OutboxStore, LoggerType, PinoFileOptions } from '@axiom-lattice/protocols';
|
|
2
|
+
import { ProjectRoomMessage, ProjectBotMembership, ProjectMembership, TaskItem, ChannelAdapter, InboundMessage, Binding, BindingRegistry, ChannelInstallationStore, DispatchResult, ModelProviderStore, UserTenantLinkStore, LLMConfig, ModelProviderPublicEntry, TenantModelCatalog, CreateModelProviderRequest, UpdateModelProviderRequest, ModelDiscoveryResult, ModelProviderProbeRequest, ModelProviderProbeResult, ModelSelection, ProjectRoomEventScope, ProjectRoomBusinessEventDraft, ProjectRoomScopedBusinessEvent, ProjectRoomBusinessEvent, ProjectRoomEventSubscription, TaskStore, ProjectRoomStore, ProjectBotMembershipStore, ThreadStore, ProjectRoom, Thread, ProjectStore, TaskWorkItemStore, TenantStore, OutboxStore, A2AApiKeyStore, AssistantStore, A2AApiKeyEntry, A2AAuthContext, Assistant, OpenGrant, A2AApiKeyRecord, LoggerType, PinoFileOptions } from '@axiom-lattice/protocols';
|
|
3
3
|
import { TrustedAgentMessageDispatcher, TrustedMessageOptions, TaskLifecycleListener, TaskLifecycleService, IMessageQueueStore, Agent, TaskRunRegistry } from '@axiom-lattice/core';
|
|
4
4
|
import * as fastify from 'fastify';
|
|
5
|
+
import { RouteGenericInterface, FastifyRequest, FastifyReply } from 'fastify';
|
|
5
6
|
|
|
6
7
|
/** Public publisher surface for committed Project Room business facts. */
|
|
7
8
|
interface ProjectRoomRealtimePublisher {
|
|
@@ -166,6 +167,252 @@ declare class MessageRouter {
|
|
|
166
167
|
private projectRoomInterrupt;
|
|
167
168
|
}
|
|
168
169
|
|
|
170
|
+
/**
|
|
171
|
+
* Tenant model provider service.
|
|
172
|
+
*
|
|
173
|
+
* Owns provider configuration CRUD, upstream discovery, and the tenant-scoped
|
|
174
|
+
* model catalog. All tenant scoping decisions live here; the controller is a
|
|
175
|
+
* thin HTTP shell.
|
|
176
|
+
*/
|
|
177
|
+
|
|
178
|
+
/** Narrow persistence and registry dependencies of the service. */
|
|
179
|
+
interface ModelProviderServiceDeps {
|
|
180
|
+
providerStore: ModelProviderStore;
|
|
181
|
+
userTenantLinkStore: Pick<UserTenantLinkStore, "getLink">;
|
|
182
|
+
registry: {
|
|
183
|
+
register(tenantId: string, modelKey: string, config: LLMConfig): void;
|
|
184
|
+
has(tenantId: string, modelKey: string): boolean;
|
|
185
|
+
remove(tenantId: string, modelKey: string): boolean;
|
|
186
|
+
listRegistered(tenantId: string): string[];
|
|
187
|
+
};
|
|
188
|
+
idFactory?: () => string;
|
|
189
|
+
/**
|
|
190
|
+
* Best-effort local change notification for cross-replica invalidation.
|
|
191
|
+
* Called synchronously after a successful mutating operation.
|
|
192
|
+
*/
|
|
193
|
+
onChanged?: (tenantId: string, providerId: string) => void;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Service for tenant-scoped model provider configuration and discovery.
|
|
197
|
+
*/
|
|
198
|
+
declare class ModelProviderService {
|
|
199
|
+
private readonly deps;
|
|
200
|
+
private readonly idFactory;
|
|
201
|
+
constructor(deps: ModelProviderServiceDeps);
|
|
202
|
+
/**
|
|
203
|
+
* List the tenant's provider configurations.
|
|
204
|
+
*/
|
|
205
|
+
list(userId: string | undefined, tenantId: string): Promise<ModelProviderPublicEntry[]>;
|
|
206
|
+
/**
|
|
207
|
+
* Read one provider configuration.
|
|
208
|
+
*/
|
|
209
|
+
get(userId: string | undefined, tenantId: string, id: string): Promise<ModelProviderPublicEntry>;
|
|
210
|
+
/**
|
|
211
|
+
* The full model catalog visible to a tenant.
|
|
212
|
+
*/
|
|
213
|
+
catalog(userId: string | undefined, tenantId: string): Promise<TenantModelCatalog>;
|
|
214
|
+
/**
|
|
215
|
+
* Hydrates the runtime model registry from the persisted provider catalog.
|
|
216
|
+
*
|
|
217
|
+
* @returns The model keys registered in this process.
|
|
218
|
+
* @remarks Registers the Phase-1 (default tenant) enabled provider models so a
|
|
219
|
+
* replica that did not perform discovery — or that restarted — can execute
|
|
220
|
+
* them. Best-effort; the caller logs failures.
|
|
221
|
+
*/
|
|
222
|
+
hydrateRegistry(): Promise<string[]>;
|
|
223
|
+
/**
|
|
224
|
+
* Bring this replica's registry in line with one provider's current state.
|
|
225
|
+
*
|
|
226
|
+
* @param tenantId Tenant scope (only the default tenant registers).
|
|
227
|
+
* @param providerId Provider to reconcile; omit to re-hydrate the tenant.
|
|
228
|
+
* @remarks A missing provider removes every registry key under its
|
|
229
|
+
* `${providerId}/` prefix; legacy keys registered through `/api/models` are
|
|
230
|
+
* left untouched.
|
|
231
|
+
*/
|
|
232
|
+
reconcileProvider(tenantId: string, providerId?: string): Promise<void>;
|
|
233
|
+
/**
|
|
234
|
+
* Create a provider configuration. Does not run discovery.
|
|
235
|
+
*/
|
|
236
|
+
create(userId: string | undefined, tenantId: string, input: CreateModelProviderRequest): Promise<ModelProviderPublicEntry>;
|
|
237
|
+
/**
|
|
238
|
+
* Update a provider configuration.
|
|
239
|
+
* An omitted or empty `apiKey` keeps the stored key.
|
|
240
|
+
*/
|
|
241
|
+
update(userId: string | undefined, tenantId: string, id: string, updates: Partial<UpdateModelProviderRequest>): Promise<ModelProviderPublicEntry>;
|
|
242
|
+
/**
|
|
243
|
+
* Delete a provider configuration, its snapshot, and any registry entries
|
|
244
|
+
* that no other provider in the tenant still supplies.
|
|
245
|
+
*/
|
|
246
|
+
remove(userId: string | undefined, tenantId: string, id: string): Promise<void>;
|
|
247
|
+
/**
|
|
248
|
+
* Discover the provider's models and replace its snapshot.
|
|
249
|
+
*/
|
|
250
|
+
discover(userId: string | undefined, tenantId: string, id: string): Promise<ModelDiscoveryResult>;
|
|
251
|
+
/**
|
|
252
|
+
* Bring the execution registry in line with a provider's current state.
|
|
253
|
+
*
|
|
254
|
+
* Registration copies `apiKey` and `baseURL` by value, so a rotated
|
|
255
|
+
* credential or a changed endpoint only takes effect once the model is
|
|
256
|
+
* re-registered. Disabled models — and every model of a disabled provider —
|
|
257
|
+
* are removed instead.
|
|
258
|
+
*
|
|
259
|
+
* @returns The model keys left registered
|
|
260
|
+
*/
|
|
261
|
+
/**
|
|
262
|
+
* Probe an upstream without touching the store.
|
|
263
|
+
*
|
|
264
|
+
* Powers the provider form's "test latency" and "list models" actions, which
|
|
265
|
+
* validate a base URL and API key the user has typed but not yet saved. The
|
|
266
|
+
* URL is validated exactly as on create/update and is never persisted, so the
|
|
267
|
+
* "discover resolves its URL from the store" rule is not weakened — nothing
|
|
268
|
+
* a probe learns can reach the snapshot.
|
|
269
|
+
*/
|
|
270
|
+
probe(userId: string | undefined, tenantId: string, input: ModelProviderProbeRequest): Promise<ModelProviderProbeResult>;
|
|
271
|
+
/**
|
|
272
|
+
* Set exactly which models this provider contributes.
|
|
273
|
+
*
|
|
274
|
+
* This is the "add model" action: the caller passes the ids it picked from
|
|
275
|
+
* the live list, and the provider's model set becomes precisely those. Ids
|
|
276
|
+
* are expected to have come from a probe — model names cannot be guessed,
|
|
277
|
+
* since a wrong id surfaces later as "model not found" or an authorisation
|
|
278
|
+
* error rather than at configuration time.
|
|
279
|
+
*/
|
|
280
|
+
setModels(userId: string | undefined, tenantId: string, id: string, selection: ModelSelection[]): Promise<ModelProviderPublicEntry>;
|
|
281
|
+
private syncRegistry;
|
|
282
|
+
/** Best-effort local mutation notification; never affects the operation. */
|
|
283
|
+
private notifyChanged;
|
|
284
|
+
/**
|
|
285
|
+
* Enable or disable a single discovered model.
|
|
286
|
+
*/
|
|
287
|
+
setModelEnabled(userId: string | undefined, tenantId: string, id: string, modelId: string, enabled: boolean): Promise<ModelProviderPublicEntry>;
|
|
288
|
+
/**
|
|
289
|
+
* Whether discovered models should be registered for execution.
|
|
290
|
+
*/
|
|
291
|
+
private shouldRegister;
|
|
292
|
+
/**
|
|
293
|
+
* Build the runtime LLM config for a discovered model.
|
|
294
|
+
*
|
|
295
|
+
* `apiKeyEnvName`, `extra` and `modelKwargs` are deliberately omitted — they
|
|
296
|
+
* would let a tenant name an arbitrary process environment variable to read
|
|
297
|
+
* credentials from, or inject arbitrary constructor options.
|
|
298
|
+
*/
|
|
299
|
+
private toLlmConfig;
|
|
300
|
+
/**
|
|
301
|
+
* The sole projection from an internal provider entry to an API-safe shape.
|
|
302
|
+
*/
|
|
303
|
+
private toPublicEntry;
|
|
304
|
+
/**
|
|
305
|
+
* Reject a provider that would end up without a credential.
|
|
306
|
+
*
|
|
307
|
+
* @param apiKey - The key the provider would hold, if any
|
|
308
|
+
* @throws {ModelProviderServiceError} When no key is present
|
|
309
|
+
*/
|
|
310
|
+
private assertHasApiKey;
|
|
311
|
+
/**
|
|
312
|
+
* Load a provider or fail with 404.
|
|
313
|
+
*
|
|
314
|
+
* Callers always pass the session's tenant, so a provider belonging to
|
|
315
|
+
* another tenant is indistinguishable from a missing one.
|
|
316
|
+
*/
|
|
317
|
+
private requireProvider;
|
|
318
|
+
/**
|
|
319
|
+
* Require that the caller belongs to the tenant.
|
|
320
|
+
* An absent userId means the unauthenticated development fallback.
|
|
321
|
+
*/
|
|
322
|
+
private assertMember;
|
|
323
|
+
/**
|
|
324
|
+
* Require that the caller is a tenant owner or admin.
|
|
325
|
+
* Roles are read from the tenant link, never from the session token.
|
|
326
|
+
*/
|
|
327
|
+
private assertAdmin;
|
|
328
|
+
/**
|
|
329
|
+
* Validate the shape of an upstream URL and translate failures into service
|
|
330
|
+
* errors.
|
|
331
|
+
*
|
|
332
|
+
* Addresses are deliberately not restricted: other tenant-configured URLs in
|
|
333
|
+
* this platform (metrics servers, MCP servers) reach wherever they point, and
|
|
334
|
+
* self-hosted model servers normally sit on the gateway's own network.
|
|
335
|
+
*
|
|
336
|
+
* The mapping is explicit so the public error codes stay decoupled from the
|
|
337
|
+
* reasons the URL utility happens to use internally.
|
|
338
|
+
*/
|
|
339
|
+
private assertSafeUrl;
|
|
340
|
+
/**
|
|
341
|
+
* Translate a store-level unique violation into a stable service error.
|
|
342
|
+
*/
|
|
343
|
+
private mapStoreError;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* HTTP controller for tenant model providers.
|
|
348
|
+
*
|
|
349
|
+
* Thin shell: resolves the tenant scope from the authenticated session, parses
|
|
350
|
+
* the request, delegates to ModelProviderService, and renders service errors.
|
|
351
|
+
*/
|
|
352
|
+
|
|
353
|
+
type Request<T extends RouteGenericInterface = RouteGenericInterface> = FastifyRequest<T> & {
|
|
354
|
+
user?: {
|
|
355
|
+
id?: string;
|
|
356
|
+
tenantId?: string;
|
|
357
|
+
};
|
|
358
|
+
};
|
|
359
|
+
/** Controller for tenant-scoped model provider management. */
|
|
360
|
+
declare class ModelProviderController {
|
|
361
|
+
private readonly service;
|
|
362
|
+
private readonly authRequired;
|
|
363
|
+
constructor(deps: ModelProviderServiceDeps, options?: {
|
|
364
|
+
authRequired?: boolean;
|
|
365
|
+
});
|
|
366
|
+
/** GET /api/tenant-models */
|
|
367
|
+
getCatalog(request: Request, reply: FastifyReply): Promise<unknown>;
|
|
368
|
+
/** Hydrates the runtime model registry from persisted providers (startup). */
|
|
369
|
+
hydrateRegistry(): Promise<string[]>;
|
|
370
|
+
/** Reconciles one provider (or the tenant) after a foreign change. */
|
|
371
|
+
reconcileProvider(tenantId: string, providerId?: string): Promise<void>;
|
|
372
|
+
/** GET /api/model-providers */
|
|
373
|
+
listProviders(request: Request, reply: FastifyReply): Promise<unknown>;
|
|
374
|
+
/** GET /api/model-providers/:providerId */
|
|
375
|
+
getProvider(request: Request<{
|
|
376
|
+
Params: {
|
|
377
|
+
providerId: string;
|
|
378
|
+
};
|
|
379
|
+
}>, reply: FastifyReply): Promise<unknown>;
|
|
380
|
+
/** POST /api/model-providers */
|
|
381
|
+
createProvider(request: Request, reply: FastifyReply): Promise<unknown>;
|
|
382
|
+
/** PUT /api/model-providers/:providerId */
|
|
383
|
+
updateProvider(request: Request<{
|
|
384
|
+
Params: {
|
|
385
|
+
providerId: string;
|
|
386
|
+
};
|
|
387
|
+
}>, reply: FastifyReply): Promise<unknown>;
|
|
388
|
+
/** DELETE /api/model-providers/:providerId */
|
|
389
|
+
deleteProvider(request: Request<{
|
|
390
|
+
Params: {
|
|
391
|
+
providerId: string;
|
|
392
|
+
};
|
|
393
|
+
}>, reply: FastifyReply): Promise<unknown>;
|
|
394
|
+
/** POST /api/model-providers/probe */
|
|
395
|
+
probeProvider(request: Request, reply: FastifyReply): Promise<unknown>;
|
|
396
|
+
/** PUT /api/model-providers/:providerId/models */
|
|
397
|
+
setProviderModels(request: Request<{
|
|
398
|
+
Params: {
|
|
399
|
+
providerId: string;
|
|
400
|
+
};
|
|
401
|
+
}>, reply: FastifyReply): Promise<unknown>;
|
|
402
|
+
/** POST /api/model-providers/:providerId/discover */
|
|
403
|
+
discoverProvider(request: Request<{
|
|
404
|
+
Params: {
|
|
405
|
+
providerId: string;
|
|
406
|
+
};
|
|
407
|
+
}>, reply: FastifyReply): Promise<unknown>;
|
|
408
|
+
/** POST /api/model-providers/:providerId/models/enabled */
|
|
409
|
+
setModelEnabled(request: Request<{
|
|
410
|
+
Params: {
|
|
411
|
+
providerId: string;
|
|
412
|
+
};
|
|
413
|
+
}>, reply: FastifyReply): Promise<unknown>;
|
|
414
|
+
}
|
|
415
|
+
|
|
169
416
|
type Listener = (event: ProjectRoomBusinessEvent) => void | Promise<void>;
|
|
170
417
|
/** Construction options for the bounded process-local Project Room event broker. */
|
|
171
418
|
interface ProjectRoomEventBrokerOptions {
|
|
@@ -473,6 +720,12 @@ interface ProjectTaskExecutionDependencies {
|
|
|
473
720
|
dispatcher: TrustedAgentMessageDispatcher;
|
|
474
721
|
queue: IMessageQueueStore;
|
|
475
722
|
agentFor: (task: TaskItem, thread: Thread) => Agent;
|
|
723
|
+
/** JIT-materializes a public-project task owner so it has a room anchor to post/reply. */
|
|
724
|
+
ensurePublicOwner?: (input: {
|
|
725
|
+
tenantId: string;
|
|
726
|
+
projectId: string;
|
|
727
|
+
assistantId: string;
|
|
728
|
+
}) => Promise<unknown>;
|
|
476
729
|
}
|
|
477
730
|
/** Input for recovering exactly one persisted Project Task queue execution. */
|
|
478
731
|
interface RecoverProjectTaskExecutionInput {
|
|
@@ -704,6 +957,8 @@ interface LatticeRouteResult {
|
|
|
704
957
|
projectTaskUnavailableReason?: string;
|
|
705
958
|
/** Present only in exact single-Gateway realtime mode. */
|
|
706
959
|
projectRoomRealtimeRuntime?: ProjectRoomRealtimeRuntime;
|
|
960
|
+
/** Always-present controller used by the outbox poller to reconcile foreign changes. */
|
|
961
|
+
modelProviderController: ModelProviderController;
|
|
707
962
|
}
|
|
708
963
|
|
|
709
964
|
declare const defaultSwaggerConfig: {
|
|
@@ -1116,6 +1371,122 @@ declare function publishRoomEvent(outbox: OutboxStore, owner: string, scope: Pro
|
|
|
1116
1371
|
*/
|
|
1117
1372
|
declare function ingestRoomEvent(payload: unknown, broker: ProjectRoomEventBroker): boolean;
|
|
1118
1373
|
|
|
1374
|
+
/** Outbox topic carrying cross-replica A2A API-key invalidation. */
|
|
1375
|
+
declare const A2A_KEY_CHANGED_TOPIC = "a2a-key-changed";
|
|
1376
|
+
/**
|
|
1377
|
+
* Best-effort publish of an A2A key change to the durable outbox.
|
|
1378
|
+
*
|
|
1379
|
+
* @param outbox Shared outbox store.
|
|
1380
|
+
* @param owner This replica id (recorded as the event origin).
|
|
1381
|
+
* @param tenantId Tenant whose keys changed.
|
|
1382
|
+
* @remarks Never throws; peers fall back to startup load / the next change.
|
|
1383
|
+
*/
|
|
1384
|
+
declare function publishA2AKeyChanged(outbox: OutboxStore, owner: string, tenantId: string): Promise<void>;
|
|
1385
|
+
/**
|
|
1386
|
+
* Reloads this replica's key map after a foreign key change.
|
|
1387
|
+
*
|
|
1388
|
+
* @param payload Outbox payload, expected to carry a non-empty `tenantId`.
|
|
1389
|
+
* @param reload Store-backed reload callback (refreshes the global key map).
|
|
1390
|
+
*/
|
|
1391
|
+
declare function handleA2AKeyChanged(payload: unknown, reload: () => Promise<void>): Promise<void>;
|
|
1392
|
+
|
|
1393
|
+
/** Outbox topic carrying cross-replica model-provider invalidation. */
|
|
1394
|
+
declare const MODEL_PROVIDER_CHANGED_TOPIC = "model-provider-changed";
|
|
1395
|
+
/**
|
|
1396
|
+
* Best-effort publish of a model provider change to the durable outbox.
|
|
1397
|
+
*
|
|
1398
|
+
* @param outbox Shared outbox store.
|
|
1399
|
+
* @param owner This replica id (recorded as the event origin).
|
|
1400
|
+
* @param tenantId Tenant that owns the changed provider.
|
|
1401
|
+
* @param providerId Provider that changed; omitted to reconcile the tenant.
|
|
1402
|
+
* @remarks Never throws; startup hydration / the next change corrects a miss.
|
|
1403
|
+
*/
|
|
1404
|
+
declare function publishModelProviderChanged(outbox: OutboxStore, owner: string, tenantId: string, providerId?: string): Promise<void>;
|
|
1405
|
+
/**
|
|
1406
|
+
* Reconciles one provider (or the whole tenant) after a foreign change.
|
|
1407
|
+
*
|
|
1408
|
+
* @param payload Outbox payload, expected to carry a non-empty `tenantId`.
|
|
1409
|
+
* @param reconcile Store-backed reconcile callback.
|
|
1410
|
+
*/
|
|
1411
|
+
declare function handleModelProviderChanged(payload: unknown, reconcile: (tenantId: string, providerId?: string) => Promise<void>): Promise<void>;
|
|
1412
|
+
|
|
1413
|
+
/**
|
|
1414
|
+
* Dependencies injected into {@link A2AAuthService} so stores can be mocked in tests.
|
|
1415
|
+
*/
|
|
1416
|
+
interface A2AAuthServiceDeps {
|
|
1417
|
+
keyStore: A2AApiKeyStore;
|
|
1418
|
+
assistantStore: AssistantStore;
|
|
1419
|
+
projectStore: ProjectStore;
|
|
1420
|
+
envKeyMap?: Map<string, A2AApiKeyEntry>;
|
|
1421
|
+
/**
|
|
1422
|
+
* When true, requests with no key are allowed through when no keys are
|
|
1423
|
+
* configured (dev mode). Defaults to false — JSON-RPC stays locked until a
|
|
1424
|
+
* key is configured or this opt-in is explicitly enabled.
|
|
1425
|
+
*/
|
|
1426
|
+
allowUnauthenticated?: boolean;
|
|
1427
|
+
}
|
|
1428
|
+
interface UpdateKeyScopedInput {
|
|
1429
|
+
label?: string;
|
|
1430
|
+
projectId?: string;
|
|
1431
|
+
assistantIds?: string[];
|
|
1432
|
+
grants?: OpenGrant[];
|
|
1433
|
+
}
|
|
1434
|
+
/** Input for creating an API key scoped to a tenant + project. */
|
|
1435
|
+
interface CreateKeyScopedInput {
|
|
1436
|
+
tenantId: string;
|
|
1437
|
+
projectId?: string;
|
|
1438
|
+
assistantIds?: string[];
|
|
1439
|
+
/** Open-door grants (validated minimally; unknown domains simply never match). */
|
|
1440
|
+
grants?: OpenGrant[];
|
|
1441
|
+
label?: string;
|
|
1442
|
+
}
|
|
1443
|
+
/**
|
|
1444
|
+
* Parse an `A2A_API_KEYS="key:tenant:project,..."` env string into a lookup map.
|
|
1445
|
+
* Entries missing a key, tenant, or project segment are skipped.
|
|
1446
|
+
*/
|
|
1447
|
+
declare function parseEnvKeys(env: string): Map<string, A2AApiKeyEntry>;
|
|
1448
|
+
/**
|
|
1449
|
+
* Authenticates A2A requests against the key store + env key map,
|
|
1450
|
+
* enforces assistant whitelist / exposure, and validates key scope on creation.
|
|
1451
|
+
*/
|
|
1452
|
+
declare class A2AAuthService {
|
|
1453
|
+
private readonly keyStore;
|
|
1454
|
+
private readonly assistantStore;
|
|
1455
|
+
private readonly projectStore;
|
|
1456
|
+
private readonly envKeyMap;
|
|
1457
|
+
/** Lazily-populated store key map; reloaded via {@link refresh} after keys CRUD. */
|
|
1458
|
+
private storeKeyMapCache;
|
|
1459
|
+
private readonly allowUnauthenticated;
|
|
1460
|
+
constructor(deps: A2AAuthServiceDeps);
|
|
1461
|
+
/**
|
|
1462
|
+
* Reload the cached store key map. Call once at startup and after any keys
|
|
1463
|
+
* CRUD mutation so {@link authenticate} does not hit the store on every request.
|
|
1464
|
+
*/
|
|
1465
|
+
refresh(): Promise<void>;
|
|
1466
|
+
/** Return the cached store key map, loading it on first use. */
|
|
1467
|
+
private getStoreKeyMap;
|
|
1468
|
+
/**
|
|
1469
|
+
* Authenticate an incoming request header (authorization or x-api-key value).
|
|
1470
|
+
* Returns an auth context; `authenticated: false` means the caller must reject.
|
|
1471
|
+
*/
|
|
1472
|
+
authenticate(header: string | undefined): Promise<A2AAuthContext>;
|
|
1473
|
+
/**
|
|
1474
|
+
* Assert that the given assistant is reachable under the provided auth
|
|
1475
|
+
* context: authenticated, same tenant, and within the key's whitelist.
|
|
1476
|
+
*
|
|
1477
|
+
* Authorization is unified on the API key — the agent no longer carries an
|
|
1478
|
+
* exposure flag; the key's assistant whitelist / grants is the single source.
|
|
1479
|
+
*/
|
|
1480
|
+
assertAgentAccess(auth: A2AAuthContext, assistantId: string): Promise<Assistant>;
|
|
1481
|
+
/**
|
|
1482
|
+
* Create an API key scoped to a tenant + project, validating the project exists
|
|
1483
|
+
* in the tenant and every assistant belongs to the same tenant.
|
|
1484
|
+
*/
|
|
1485
|
+
createKeyScoped(input: CreateKeyScopedInput): Promise<A2AApiKeyRecord>;
|
|
1486
|
+
updateKeyScoped(id: string, tenantId: string, input: UpdateKeyScopedInput): Promise<A2AApiKeyRecord>;
|
|
1487
|
+
private extractToken;
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1119
1490
|
/**
|
|
1120
1491
|
* Logger configuration for gateway
|
|
1121
1492
|
*/
|
|
@@ -1135,6 +1506,16 @@ interface LatticeGatewayConfig {
|
|
|
1135
1506
|
defaultStartPollingQueue: boolean;
|
|
1136
1507
|
};
|
|
1137
1508
|
loggerConfig?: Partial<GatewayLoggerConfig>;
|
|
1509
|
+
/**
|
|
1510
|
+
* Install SIGTERM/SIGINT graceful-shutdown handlers (default `true`). On a
|
|
1511
|
+
* signal the gateway aborts in-flight thread runs (releasing their
|
|
1512
|
+
* cross-replica `thread-run` leases so a peer can take over immediately),
|
|
1513
|
+
* stops background jobs, and closes the HTTP server before exiting.
|
|
1514
|
+
* Set `false` when the host manages its own shutdown.
|
|
1515
|
+
*/
|
|
1516
|
+
gracefulShutdown?: boolean;
|
|
1517
|
+
/** Force-exit deadline for graceful shutdown in ms (default 10_000). */
|
|
1518
|
+
gracefulShutdownTimeoutMs?: number;
|
|
1138
1519
|
}
|
|
1139
1520
|
declare const LatticeGateway: {
|
|
1140
1521
|
startAsHttpEndpoint: (config?: LatticeGatewayConfig) => Promise<void>;
|
|
@@ -1146,4 +1527,4 @@ declare const LatticeGateway: {
|
|
|
1146
1527
|
AgentTaskConsumer: typeof AgentTaskConsumer;
|
|
1147
1528
|
};
|
|
1148
1529
|
|
|
1149
|
-
export { type GatewayLoggerConfig, LatticeGateway, type LatticeGatewayConfig, type OrphanRecoveryRuntime, type OrphanRecoveryRuntimeDeps, ProjectRoomEventBroker, ROOM_EVENT_TOPIC, type RecoverTaskDeps, type RecoverTaskResult, type TaskLivenessProbe, createOrphanRecoveryRuntime, createRecoveryCallerDeps, createTaskRunLiveness, ingestRoomEvent, publishRoomEvent, recoverTask, recoverTopCaller, resolveTopCaller, runOrphanRecovery };
|
|
1530
|
+
export { A2AAuthService, A2A_KEY_CHANGED_TOPIC, type GatewayLoggerConfig, LatticeGateway, type LatticeGatewayConfig, MODEL_PROVIDER_CHANGED_TOPIC, ModelProviderService, type ModelProviderServiceDeps, type OrphanRecoveryRuntime, type OrphanRecoveryRuntimeDeps, ProjectRoomEventBroker, ROOM_EVENT_TOPIC, type RecoverTaskDeps, type RecoverTaskResult, type TaskLivenessProbe, createOrphanRecoveryRuntime, createRecoveryCallerDeps, createTaskRunLiveness, handleA2AKeyChanged, handleModelProviderChanged, ingestRoomEvent, parseEnvKeys, publishA2AKeyChanged, publishModelProviderChanged, publishRoomEvent, recoverTask, recoverTopCaller, resolveTopCaller, runOrphanRecovery };
|