@gethelio/proxy 0.12.0 → 0.13.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/README.md +2 -1
- package/dist/cli.js +1435 -731
- package/dist/dashboard-assets/assets/index-BUdEZ-VN.js +128 -0
- package/dist/dashboard-assets/assets/index-DtnT1Y9r.css +1 -0
- package/dist/dashboard-assets/index.html +2 -2
- package/dist/index.d.ts +490 -24
- package/dist/index.js +1182 -672
- package/package.json +1 -1
- package/dist/dashboard-assets/assets/index-BBYXsIig.css +0 -1
- package/dist/dashboard-assets/assets/index-uJng9NyO.js +0 -128
package/dist/index.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ declare const policiesSchema: z.ZodObject<{
|
|
|
51
51
|
contains: z.ZodOptional<z.ZodString>;
|
|
52
52
|
regex: z.ZodOptional<z.ZodString>;
|
|
53
53
|
}, z.core.$strict>]>>>;
|
|
54
|
+
upstreams: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
54
55
|
}, z.core.$strict>;
|
|
55
56
|
action: z.ZodEnum<{
|
|
56
57
|
deny: "deny";
|
|
@@ -171,6 +172,7 @@ declare const budgetSchema: z.ZodObject<{
|
|
|
171
172
|
contains: z.ZodOptional<z.ZodString>;
|
|
172
173
|
regex: z.ZodOptional<z.ZodString>;
|
|
173
174
|
}, z.core.$strict>>>;
|
|
175
|
+
upstreams: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
174
176
|
}, z.core.$strict>;
|
|
175
177
|
field: z.ZodString;
|
|
176
178
|
}, z.core.$strict>>>;
|
|
@@ -190,11 +192,237 @@ declare const approvalChannelSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
190
192
|
type: z.ZodLiteral<"dashboard">;
|
|
191
193
|
name: z.ZodOptional<z.ZodString>;
|
|
192
194
|
}, z.core.$strict>], "type">;
|
|
193
|
-
|
|
194
|
-
|
|
195
|
+
declare const singularConfigSchema: z.ZodObject<{
|
|
196
|
+
listen: z.ZodPrefault<z.ZodObject<{
|
|
197
|
+
port: z.ZodDefault<z.ZodNumber>;
|
|
198
|
+
host: z.ZodDefault<z.ZodString>;
|
|
199
|
+
allowed_origins: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
200
|
+
}, z.core.$strict>>;
|
|
201
|
+
environment: z.ZodOptional<z.ZodString>;
|
|
202
|
+
session: z.ZodPrefault<z.ZodObject<{
|
|
203
|
+
identity: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
204
|
+
source: z.ZodLiteral<"header">;
|
|
205
|
+
name: z.ZodPipe<z.ZodDefault<z.ZodString>, z.ZodTransform<string, string>>;
|
|
206
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
207
|
+
source: z.ZodLiteral<"meta">;
|
|
208
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
209
|
+
source: z.ZodLiteral<"legacy_header">;
|
|
210
|
+
}, z.core.$strict>], "source">>>;
|
|
211
|
+
on_unresolved: z.ZodDefault<z.ZodEnum<{
|
|
212
|
+
deny: "deny";
|
|
213
|
+
anonymous: "anonymous";
|
|
214
|
+
}>>;
|
|
215
|
+
}, z.core.$strict>>;
|
|
216
|
+
policies: z.ZodPrefault<z.ZodObject<{
|
|
217
|
+
default: z.ZodDefault<z.ZodEnum<{
|
|
218
|
+
deny: "deny";
|
|
219
|
+
allow: "allow";
|
|
220
|
+
}>>;
|
|
221
|
+
flag_destructive: z.ZodOptional<z.ZodEnum<{
|
|
222
|
+
require_approval: "require_approval";
|
|
223
|
+
log: "log";
|
|
224
|
+
}>>;
|
|
225
|
+
dry_run: z.ZodDefault<z.ZodBoolean>;
|
|
226
|
+
rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
227
|
+
name: z.ZodOptional<z.ZodString>;
|
|
228
|
+
match: z.ZodObject<{
|
|
229
|
+
tool: z.ZodOptional<z.ZodString>;
|
|
230
|
+
annotations: z.ZodOptional<z.ZodObject<{
|
|
231
|
+
readOnlyHint: z.ZodOptional<z.ZodBoolean>;
|
|
232
|
+
destructiveHint: z.ZodOptional<z.ZodBoolean>;
|
|
233
|
+
idempotentHint: z.ZodOptional<z.ZodBoolean>;
|
|
234
|
+
openWorldHint: z.ZodOptional<z.ZodBoolean>;
|
|
235
|
+
}, z.core.$strict>>;
|
|
236
|
+
input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
237
|
+
eq: z.ZodOptional<z.ZodUnknown>;
|
|
238
|
+
neq: z.ZodOptional<z.ZodUnknown>;
|
|
239
|
+
gt: z.ZodOptional<z.ZodNumber>;
|
|
240
|
+
gte: z.ZodOptional<z.ZodNumber>;
|
|
241
|
+
lt: z.ZodOptional<z.ZodNumber>;
|
|
242
|
+
lte: z.ZodOptional<z.ZodNumber>;
|
|
243
|
+
contains: z.ZodOptional<z.ZodString>;
|
|
244
|
+
regex: z.ZodOptional<z.ZodString>;
|
|
245
|
+
}, z.core.$strict>>>;
|
|
246
|
+
environment: z.ZodOptional<z.ZodString>;
|
|
247
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
248
|
+
eq: z.ZodOptional<z.ZodString>;
|
|
249
|
+
neq: z.ZodOptional<z.ZodString>;
|
|
250
|
+
contains: z.ZodOptional<z.ZodString>;
|
|
251
|
+
regex: z.ZodOptional<z.ZodString>;
|
|
252
|
+
}, z.core.$strict>]>>>;
|
|
253
|
+
upstreams: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
254
|
+
}, z.core.$strict>;
|
|
255
|
+
action: z.ZodEnum<{
|
|
256
|
+
deny: "deny";
|
|
257
|
+
allow: "allow";
|
|
258
|
+
require_approval: "require_approval";
|
|
259
|
+
rate_limit: "rate_limit";
|
|
260
|
+
spend_limit: "spend_limit";
|
|
261
|
+
dry_run: "dry_run";
|
|
262
|
+
}>;
|
|
263
|
+
approval: z.ZodOptional<z.ZodObject<{
|
|
264
|
+
channel: z.ZodString;
|
|
265
|
+
timeout: z.ZodOptional<z.ZodString>;
|
|
266
|
+
delegates: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
267
|
+
escalation_after: z.ZodOptional<z.ZodString>;
|
|
268
|
+
}, z.core.$strict>>;
|
|
269
|
+
evidence: z.ZodOptional<z.ZodObject<{
|
|
270
|
+
requires: z.ZodArray<z.ZodString>;
|
|
271
|
+
}, z.core.$strict>>;
|
|
272
|
+
requires: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
273
|
+
requires_success: z.ZodOptional<z.ZodBoolean>;
|
|
274
|
+
limits: z.ZodOptional<z.ZodObject<{
|
|
275
|
+
max_calls: z.ZodOptional<z.ZodNumber>;
|
|
276
|
+
window: z.ZodOptional<z.ZodString>;
|
|
277
|
+
key: z.ZodOptional<z.ZodEnum<{
|
|
278
|
+
tool: "tool";
|
|
279
|
+
agent: "agent";
|
|
280
|
+
session: "session";
|
|
281
|
+
sender_id: "sender_id";
|
|
282
|
+
}>>;
|
|
283
|
+
max_spend: z.ZodOptional<z.ZodObject<{
|
|
284
|
+
field: z.ZodString;
|
|
285
|
+
limit: z.ZodNumber;
|
|
286
|
+
currency: z.ZodString;
|
|
287
|
+
window: z.ZodString;
|
|
288
|
+
key: z.ZodOptional<z.ZodEnum<{
|
|
289
|
+
tool: "tool";
|
|
290
|
+
agent: "agent";
|
|
291
|
+
session: "session";
|
|
292
|
+
sender_id: "sender_id";
|
|
293
|
+
}>>;
|
|
294
|
+
}, z.core.$strict>>;
|
|
295
|
+
}, z.core.$strict>>;
|
|
296
|
+
feedback: z.ZodOptional<z.ZodObject<{
|
|
297
|
+
message: z.ZodString;
|
|
298
|
+
suggestion: z.ZodOptional<z.ZodString>;
|
|
299
|
+
}, z.core.$strict>>;
|
|
300
|
+
}, z.core.$strict>>>;
|
|
301
|
+
install: z.ZodOptional<z.ZodObject<{
|
|
302
|
+
default: z.ZodDefault<z.ZodEnum<{
|
|
303
|
+
deny: "deny";
|
|
304
|
+
allow: "allow";
|
|
305
|
+
}>>;
|
|
306
|
+
rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
307
|
+
name: z.ZodOptional<z.ZodString>;
|
|
308
|
+
match: z.ZodObject<{
|
|
309
|
+
name: z.ZodOptional<z.ZodString>;
|
|
310
|
+
source: z.ZodOptional<z.ZodString>;
|
|
311
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
312
|
+
eq: z.ZodOptional<z.ZodString>;
|
|
313
|
+
neq: z.ZodOptional<z.ZodString>;
|
|
314
|
+
contains: z.ZodOptional<z.ZodString>;
|
|
315
|
+
regex: z.ZodOptional<z.ZodString>;
|
|
316
|
+
}, z.core.$strict>]>>>;
|
|
317
|
+
}, z.core.$strict>;
|
|
318
|
+
action: z.ZodEnum<{
|
|
319
|
+
allow: "allow";
|
|
320
|
+
deny_install: "deny_install";
|
|
321
|
+
}>;
|
|
322
|
+
feedback: z.ZodOptional<z.ZodObject<{
|
|
323
|
+
message: z.ZodString;
|
|
324
|
+
suggestion: z.ZodOptional<z.ZodString>;
|
|
325
|
+
}, z.core.$strict>>;
|
|
326
|
+
}, z.core.$strict>>>;
|
|
327
|
+
}, z.core.$strict>>;
|
|
328
|
+
on_tool_drift: z.ZodOptional<z.ZodEnum<{
|
|
329
|
+
require_approval: "require_approval";
|
|
330
|
+
log: "log";
|
|
331
|
+
block: "block";
|
|
332
|
+
}>>;
|
|
333
|
+
tool_revalidation: z.ZodOptional<z.ZodObject<{
|
|
334
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
335
|
+
interval: z.ZodDefault<z.ZodString>;
|
|
336
|
+
max_advertised_ttl: z.ZodOptional<z.ZodString>;
|
|
337
|
+
}, z.core.$strict>>;
|
|
338
|
+
hot_reload: z.ZodOptional<z.ZodBoolean>;
|
|
339
|
+
}, z.core.$strict>>;
|
|
340
|
+
budgets: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
341
|
+
name: z.ZodString;
|
|
342
|
+
limit: z.ZodNumber;
|
|
343
|
+
currency: z.ZodString;
|
|
344
|
+
window: z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"session">]>;
|
|
345
|
+
key: z.ZodDefault<z.ZodEnum<{
|
|
346
|
+
session: "session";
|
|
347
|
+
sender_id: "sender_id";
|
|
348
|
+
global: "global";
|
|
349
|
+
}>>;
|
|
350
|
+
on_exceed: z.ZodDefault<z.ZodEnum<{
|
|
351
|
+
deny: "deny";
|
|
352
|
+
require_approval: "require_approval";
|
|
353
|
+
}>>;
|
|
354
|
+
approval: z.ZodOptional<z.ZodObject<{
|
|
355
|
+
channel: z.ZodString;
|
|
356
|
+
timeout: z.ZodOptional<z.ZodString>;
|
|
357
|
+
delegates: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
358
|
+
escalation_after: z.ZodOptional<z.ZodString>;
|
|
359
|
+
}, z.core.$strict>>;
|
|
360
|
+
idle_ttl: z.ZodOptional<z.ZodString>;
|
|
361
|
+
contributors: z.ZodArray<z.ZodPipe<z.ZodUnknown, z.ZodObject<{
|
|
362
|
+
match: z.ZodObject<{
|
|
363
|
+
tool: z.ZodString;
|
|
364
|
+
input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
365
|
+
eq: z.ZodOptional<z.ZodUnknown>;
|
|
366
|
+
neq: z.ZodOptional<z.ZodUnknown>;
|
|
367
|
+
gt: z.ZodOptional<z.ZodNumber>;
|
|
368
|
+
gte: z.ZodOptional<z.ZodNumber>;
|
|
369
|
+
lt: z.ZodOptional<z.ZodNumber>;
|
|
370
|
+
lte: z.ZodOptional<z.ZodNumber>;
|
|
371
|
+
contains: z.ZodOptional<z.ZodString>;
|
|
372
|
+
regex: z.ZodOptional<z.ZodString>;
|
|
373
|
+
}, z.core.$strict>>>;
|
|
374
|
+
upstreams: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
375
|
+
}, z.core.$strict>;
|
|
376
|
+
field: z.ZodString;
|
|
377
|
+
}, z.core.$strict>>>;
|
|
378
|
+
}, z.core.$strict>>>;
|
|
379
|
+
approval: z.ZodPrefault<z.ZodObject<{
|
|
380
|
+
timeout: z.ZodDefault<z.ZodString>;
|
|
381
|
+
default_on_timeout: z.ZodDefault<z.ZodEnum<{
|
|
382
|
+
deny: "deny";
|
|
383
|
+
allow: "allow";
|
|
384
|
+
}>>;
|
|
385
|
+
channels: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
386
|
+
type: z.ZodLiteral<"slack">;
|
|
387
|
+
name: z.ZodOptional<z.ZodString>;
|
|
388
|
+
bot_token: z.ZodString;
|
|
389
|
+
signing_secret: z.ZodString;
|
|
390
|
+
channel: z.ZodString;
|
|
391
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
392
|
+
type: z.ZodLiteral<"webhook">;
|
|
393
|
+
name: z.ZodOptional<z.ZodString>;
|
|
394
|
+
url: z.ZodString;
|
|
395
|
+
secret: z.ZodOptional<z.ZodString>;
|
|
396
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
397
|
+
type: z.ZodLiteral<"dashboard">;
|
|
398
|
+
name: z.ZodOptional<z.ZodString>;
|
|
399
|
+
}, z.core.$strict>], "type">>>;
|
|
400
|
+
}, z.core.$strict>>;
|
|
401
|
+
audit: z.ZodPrefault<z.ZodObject<{
|
|
402
|
+
storage: z.ZodDefault<z.ZodEnum<{
|
|
403
|
+
sqlite: "sqlite";
|
|
404
|
+
}>>;
|
|
405
|
+
path: z.ZodDefault<z.ZodString>;
|
|
406
|
+
retention: z.ZodDefault<z.ZodString>;
|
|
407
|
+
include_responses: z.ZodDefault<z.ZodBoolean>;
|
|
408
|
+
}, z.core.$strict>>;
|
|
409
|
+
dashboard: z.ZodPrefault<z.ZodObject<{
|
|
410
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
411
|
+
port: z.ZodDefault<z.ZodNumber>;
|
|
412
|
+
host: z.ZodDefault<z.ZodString>;
|
|
413
|
+
api_secret: z.ZodOptional<z.ZodString>;
|
|
414
|
+
allow_open_mode: z.ZodDefault<z.ZodBoolean>;
|
|
415
|
+
sse_heartbeat_interval: z.ZodDefault<z.ZodString>;
|
|
416
|
+
}, z.core.$strict>>;
|
|
417
|
+
sdk: z.ZodPrefault<z.ZodObject<{
|
|
418
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
419
|
+
port: z.ZodDefault<z.ZodNumber>;
|
|
420
|
+
host: z.ZodDefault<z.ZodString>;
|
|
421
|
+
evaluation_ttl: z.ZodDefault<z.ZodString>;
|
|
422
|
+
}, z.core.$strict>>;
|
|
195
423
|
version: z.ZodLiteral<"1">;
|
|
196
424
|
upstream: z.ZodObject<{
|
|
197
|
-
url: z.ZodString
|
|
425
|
+
url: z.ZodOptional<z.ZodString>;
|
|
198
426
|
transport: z.ZodDefault<z.ZodEnum<{
|
|
199
427
|
"streamable-http": "streamable-http";
|
|
200
428
|
sse: "sse";
|
|
@@ -212,6 +440,8 @@ declare const helioConfigSchema: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.Z
|
|
|
212
440
|
forward_headers: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
213
441
|
headers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
214
442
|
}, z.core.$strict>;
|
|
443
|
+
}, z.core.$strict>;
|
|
444
|
+
declare const namedConfigSchema: z.ZodObject<{
|
|
215
445
|
listen: z.ZodPrefault<z.ZodObject<{
|
|
216
446
|
port: z.ZodDefault<z.ZodNumber>;
|
|
217
447
|
host: z.ZodDefault<z.ZodString>;
|
|
@@ -269,6 +499,7 @@ declare const helioConfigSchema: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.Z
|
|
|
269
499
|
contains: z.ZodOptional<z.ZodString>;
|
|
270
500
|
regex: z.ZodOptional<z.ZodString>;
|
|
271
501
|
}, z.core.$strict>]>>>;
|
|
502
|
+
upstreams: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
272
503
|
}, z.core.$strict>;
|
|
273
504
|
action: z.ZodEnum<{
|
|
274
505
|
deny: "deny";
|
|
@@ -389,6 +620,7 @@ declare const helioConfigSchema: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.Z
|
|
|
389
620
|
contains: z.ZodOptional<z.ZodString>;
|
|
390
621
|
regex: z.ZodOptional<z.ZodString>;
|
|
391
622
|
}, z.core.$strict>>>;
|
|
623
|
+
upstreams: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
392
624
|
}, z.core.$strict>;
|
|
393
625
|
field: z.ZodString;
|
|
394
626
|
}, z.core.$strict>>>;
|
|
@@ -437,9 +669,38 @@ declare const helioConfigSchema: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.Z
|
|
|
437
669
|
host: z.ZodDefault<z.ZodString>;
|
|
438
670
|
evaluation_ttl: z.ZodDefault<z.ZodString>;
|
|
439
671
|
}, z.core.$strict>>;
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
672
|
+
version: z.ZodLiteral<"1">;
|
|
673
|
+
upstreams: z.ZodArray<z.ZodObject<{
|
|
674
|
+
url: z.ZodOptional<z.ZodString>;
|
|
675
|
+
transport: z.ZodDefault<z.ZodEnum<{
|
|
676
|
+
"streamable-http": "streamable-http";
|
|
677
|
+
sse: "sse";
|
|
678
|
+
stdio: "stdio";
|
|
679
|
+
}>>;
|
|
680
|
+
protocol_version: z.ZodDefault<z.ZodEnum<{
|
|
681
|
+
auto: "auto";
|
|
682
|
+
"2025-06-18": "2025-06-18";
|
|
683
|
+
"2026-07-28": "2026-07-28";
|
|
684
|
+
}>>;
|
|
685
|
+
command: z.ZodOptional<z.ZodString>;
|
|
686
|
+
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
687
|
+
connect_timeout: z.ZodDefault<z.ZodString>;
|
|
688
|
+
request_timeout: z.ZodDefault<z.ZodString>;
|
|
689
|
+
forward_headers: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
690
|
+
headers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
691
|
+
name: z.ZodString;
|
|
692
|
+
}, z.core.$strict>>;
|
|
693
|
+
}, z.core.$strict>;
|
|
694
|
+
/** A fully validated and defaulted singular-mode (`upstream:`) configuration. */
|
|
695
|
+
type SingularHelioConfig = z.output<typeof singularConfigSchema>;
|
|
696
|
+
/** A fully validated and defaulted named-mode (`upstreams:`) configuration. */
|
|
697
|
+
type NamedHelioConfig = z.output<typeof namedConfigSchema>;
|
|
698
|
+
/** Fully validated and defaulted Helio configuration — one of the two mode arms. */
|
|
699
|
+
type HelioConfig = SingularHelioConfig | NamedHelioConfig;
|
|
700
|
+
/** Narrow a parsed config to the singular-mode (`upstream:`) arm. */
|
|
701
|
+
declare function isSingularConfig(config: HelioConfig): config is SingularHelioConfig;
|
|
702
|
+
/** Narrow a parsed config to the named-mode (`upstreams:`) arm. */
|
|
703
|
+
declare function isNamedConfig(config: HelioConfig): config is NamedHelioConfig;
|
|
443
704
|
/** An approval channel configuration (slack, webhook, or dashboard). */
|
|
444
705
|
type ApprovalChannel$1 = z.infer<typeof approvalChannelSchema>;
|
|
445
706
|
/** The policies section of the config. */
|
|
@@ -530,6 +791,8 @@ interface CompiledMatch {
|
|
|
530
791
|
readonly environment?: string;
|
|
531
792
|
/** Flattened list of metadata conditions (one entry per key+operator pair). */
|
|
532
793
|
readonly metadata?: readonly MetadataCondition[];
|
|
794
|
+
/** Configured upstream names the rule is scoped to, OR within the list (issue #293). */
|
|
795
|
+
readonly upstreams?: readonly string[];
|
|
533
796
|
}
|
|
534
797
|
/** Compiled approval configuration with durations as milliseconds. */
|
|
535
798
|
interface CompiledApproval {
|
|
@@ -673,6 +936,12 @@ interface MatchContext {
|
|
|
673
936
|
* request column) is merged in by the decision pipeline, not stored here twice.
|
|
674
937
|
*/
|
|
675
938
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
939
|
+
/**
|
|
940
|
+
* The governed door's configured upstream name (issue #295). A string only on
|
|
941
|
+
* the MCP path when a name is configured; undefined on the sideband and in
|
|
942
|
+
* singular mode, so upstream-scoped rules are inert there by construction.
|
|
943
|
+
*/
|
|
944
|
+
readonly upstream?: string;
|
|
676
945
|
}
|
|
677
946
|
|
|
678
947
|
/** One compiled contributor: which calls feed the budget, and from which field. */
|
|
@@ -682,6 +951,13 @@ interface CompiledBudgetContributor {
|
|
|
682
951
|
/** Flattened conditions (one per path+operator); absent when unconditioned. */
|
|
683
952
|
readonly input?: readonly InputCondition[];
|
|
684
953
|
};
|
|
954
|
+
/**
|
|
955
|
+
* Configured upstream names the contributor is scoped to (issue #293);
|
|
956
|
+
* absent means every door contributes. A scoped contributor never
|
|
957
|
+
* participates when the charge context carries no upstream (sideband,
|
|
958
|
+
* singular mode).
|
|
959
|
+
*/
|
|
960
|
+
readonly upstreams?: readonly string[];
|
|
685
961
|
/** Dot-path into the tool arguments (e.g. "$.amount"), resolved per call. */
|
|
686
962
|
readonly field: string;
|
|
687
963
|
}
|
|
@@ -836,6 +1112,47 @@ interface CreateAppOptions {
|
|
|
836
1112
|
* @param options - Optional sub-apps to mount.
|
|
837
1113
|
*/
|
|
838
1114
|
declare function createApp(config: HelioConfig, forwarder: McpForwarder, options?: CreateAppOptions): Hono;
|
|
1115
|
+
/**
|
|
1116
|
+
* Optional sub-apps and callbacks for the multi-upstream composition.
|
|
1117
|
+
* The main-port posture is `createApp`'s (see CreateAppOptions): only the
|
|
1118
|
+
* Slack webhook callback belongs beside the MCP doors.
|
|
1119
|
+
*/
|
|
1120
|
+
interface CreateMultiAppOptions {
|
|
1121
|
+
/** Slack interactive action handler (mounted at /slack/actions, global). */
|
|
1122
|
+
slackActionApp?: Hono;
|
|
1123
|
+
/**
|
|
1124
|
+
* Recorder for inbound header/body agreement rejections (issue #226),
|
|
1125
|
+
* called with the name of the door that rejected so the audit record can
|
|
1126
|
+
* attribute it. Enforcement does not depend on it.
|
|
1127
|
+
*/
|
|
1128
|
+
onHeaderMismatch?: (rejection: HeaderMismatchRejection, upstreamName: string) => void;
|
|
1129
|
+
/**
|
|
1130
|
+
* @internal Test seam for the per-door concurrent-session cap on the
|
|
1131
|
+
* `/sse/<name>` mounts (issue #232's cap, per-route by construction), so
|
|
1132
|
+
* tests need not mint 1024 real streams per door. The same value goes to
|
|
1133
|
+
* every door's route; the session maps stay per-route-instance. Not wired
|
|
1134
|
+
* to config — absent means the hardcoded 1024.
|
|
1135
|
+
*/
|
|
1136
|
+
sse?: {
|
|
1137
|
+
readonly maxConcurrentSessions?: number;
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
/**
|
|
1141
|
+
* Create a Hono app serving every named upstream at its own pair of mounts,
|
|
1142
|
+
* `/mcp/<name>` and `/sse/<name>`, each a fresh route stack wrapping that
|
|
1143
|
+
* entry's forwarder. `/healthz` and `/slack/actions` stay global. There is
|
|
1144
|
+
* NO bare-path default: bare `/mcp`, `/sse`, and unknown names get an
|
|
1145
|
+
* explicit 404 catch-all whose JSON-RPC envelope states the path shape and
|
|
1146
|
+
* never enumerates configured names.
|
|
1147
|
+
*
|
|
1148
|
+
* @param config - The validated named-mode Helio configuration.
|
|
1149
|
+
* @param forwarders - One forwarder per configured entry, keyed by name.
|
|
1150
|
+
* Must cover the configured names exactly; missing or extra keys throw
|
|
1151
|
+
* (a missing key would silently mount a dead door, an extra one means the
|
|
1152
|
+
* record drifted from the config — fail at composition, not per request).
|
|
1153
|
+
* @param options - Optional sub-apps and callbacks.
|
|
1154
|
+
*/
|
|
1155
|
+
declare function createMultiApp(config: HelioConfig, forwarders: Record<string, McpForwarder>, options?: CreateMultiAppOptions): Hono;
|
|
839
1156
|
/**
|
|
840
1157
|
* Start the HTTP server on the configured host and port.
|
|
841
1158
|
*
|
|
@@ -866,6 +1183,11 @@ interface StreamableHttpForwarderOptions {
|
|
|
866
1183
|
requestTimeoutMs?: number;
|
|
867
1184
|
/** `upstream.protocol_version`: `auto` (default) probes; a dated pin skips it. */
|
|
868
1185
|
protocolVersion?: UpstreamProtocolVersionPin;
|
|
1186
|
+
/**
|
|
1187
|
+
* The operator-chosen upstream entry name (issue #295), threaded to the
|
|
1188
|
+
* session manager's era lifecycle lines. Unset in singular mode.
|
|
1189
|
+
*/
|
|
1190
|
+
upstreamName?: string;
|
|
869
1191
|
}
|
|
870
1192
|
/**
|
|
871
1193
|
* Spec-compliant upstream MCP Streamable HTTP client.
|
|
@@ -984,6 +1306,11 @@ interface StdioForwarderOptions {
|
|
|
984
1306
|
retryDelayMs?: number;
|
|
985
1307
|
/** Timeout in milliseconds for individual requests. */
|
|
986
1308
|
requestTimeoutMs?: number;
|
|
1309
|
+
/**
|
|
1310
|
+
* The operator-chosen upstream entry name (multi-upstream mode). Unset in
|
|
1311
|
+
* singular mode — the death line then keeps its bare `[helio]` tag.
|
|
1312
|
+
*/
|
|
1313
|
+
upstreamName?: string;
|
|
987
1314
|
}
|
|
988
1315
|
/**
|
|
989
1316
|
* Forward MCP requests to an upstream server via stdio.
|
|
@@ -997,6 +1324,7 @@ declare class StdioForwarder implements McpForwarder {
|
|
|
997
1324
|
private readonly maxRetries;
|
|
998
1325
|
private readonly retryDelayMs;
|
|
999
1326
|
private readonly pending;
|
|
1327
|
+
private readonly logTag;
|
|
1000
1328
|
private child;
|
|
1001
1329
|
private buffer;
|
|
1002
1330
|
private retryCount;
|
|
@@ -1156,6 +1484,14 @@ interface AuditRecord {
|
|
|
1156
1484
|
* and on records with no MCP wire (drift events, sideband records).
|
|
1157
1485
|
*/
|
|
1158
1486
|
readonly protocol_version: string | null;
|
|
1487
|
+
/**
|
|
1488
|
+
* Name of the upstream MCP server this record is attributed to (issue
|
|
1489
|
+
* #292). Null in singular mode (no named upstreams configured), on
|
|
1490
|
+
* sideband records (no MCP door), and on rows that predate the column.
|
|
1491
|
+
* Required-nullable like session_source/protocol_version: a producer that
|
|
1492
|
+
* could silently omit it would exempt that door from attribution.
|
|
1493
|
+
*/
|
|
1494
|
+
readonly upstream: string | null;
|
|
1159
1495
|
/** ISO 8601 timestamp of when the record was persisted. */
|
|
1160
1496
|
readonly created_at: string;
|
|
1161
1497
|
}
|
|
@@ -1171,6 +1507,18 @@ interface AuditQueryFilters {
|
|
|
1171
1507
|
readonly blocked?: boolean;
|
|
1172
1508
|
/** Filter by session ID (exact match). */
|
|
1173
1509
|
readonly session_id?: string;
|
|
1510
|
+
/**
|
|
1511
|
+
* Filter by session identity source (exact match — the five-value
|
|
1512
|
+
* `header` / `meta` / `legacy_header` / `transport` / `sideband`
|
|
1513
|
+
* vocabulary, issue #250). SQL equality: rows whose session_source is
|
|
1514
|
+
* NULL never match any filter value.
|
|
1515
|
+
*/
|
|
1516
|
+
readonly session_source?: string;
|
|
1517
|
+
/**
|
|
1518
|
+
* Filter by upstream name (exact match). SQL equality: rows whose
|
|
1519
|
+
* upstream is NULL never match any filter value.
|
|
1520
|
+
*/
|
|
1521
|
+
readonly upstream?: string;
|
|
1174
1522
|
/** Filter by agent ID (exact match). */
|
|
1175
1523
|
readonly agent_id?: string;
|
|
1176
1524
|
/** Include only records created at or after this ISO 8601 timestamp. */
|
|
@@ -1239,9 +1587,15 @@ interface AuditAggregateStats {
|
|
|
1239
1587
|
readonly reason: string;
|
|
1240
1588
|
readonly count: number;
|
|
1241
1589
|
}>;
|
|
1242
|
-
/**
|
|
1590
|
+
/**
|
|
1591
|
+
* Top tools by call count (max 10 rows). Each row is a (tool, upstream)
|
|
1592
|
+
* pair (issue #297): same-named tools on different upstreams stay
|
|
1593
|
+
* distinct. Upstream is null in singular mode, so all-null groups reduce
|
|
1594
|
+
* to exactly the pre-#297 per-tool rows.
|
|
1595
|
+
*/
|
|
1243
1596
|
readonly top_tools: ReadonlyArray<{
|
|
1244
1597
|
readonly tool_name: string;
|
|
1598
|
+
readonly upstream: string | null;
|
|
1245
1599
|
readonly count: number;
|
|
1246
1600
|
}>;
|
|
1247
1601
|
/** Approval rate (approved / total require_approval decisions), or null if none. */
|
|
@@ -1364,8 +1718,15 @@ declare class AuditStore {
|
|
|
1364
1718
|
private query;
|
|
1365
1719
|
/** Count records matching the given filters. */
|
|
1366
1720
|
count(filters?: AuditQueryFilters): number;
|
|
1367
|
-
/**
|
|
1368
|
-
|
|
1721
|
+
/**
|
|
1722
|
+
* Get aggregate statistics for a time range. The optional upstream filter
|
|
1723
|
+
* scopes EVERY sub-aggregate (totals, by_decision, by_block_reason,
|
|
1724
|
+
* top_tools, approval_rate, per_hour) — "analytics for this door", not one
|
|
1725
|
+
* filtered chart. Exact match: null-upstream rows never match any value.
|
|
1726
|
+
*/
|
|
1727
|
+
aggregate(from?: string, to?: string, filters?: {
|
|
1728
|
+
upstream?: string;
|
|
1729
|
+
}): AuditAggregateStats;
|
|
1369
1730
|
/** Delete records older than the retention period. Returns the count of deleted records. */
|
|
1370
1731
|
purgeExpired(): number;
|
|
1371
1732
|
private purgeBefore;
|
|
@@ -1653,6 +2014,18 @@ interface ApprovalTicket {
|
|
|
1653
2014
|
readonly rule_index: number | null;
|
|
1654
2015
|
readonly channel_name: string;
|
|
1655
2016
|
readonly session_id: string | null;
|
|
2017
|
+
/**
|
|
2018
|
+
* Which identity strategy produced session_id (issue #251): the MCP
|
|
2019
|
+
* resolver's vocabulary on proxy tickets, `sideband` on adapter tickets.
|
|
2020
|
+
* OPTIONAL-ABSENT, not nullable: the ticket is the wire object, and an
|
|
2021
|
+
* unattributed ticket omits the key rather than emitting null.
|
|
2022
|
+
*/
|
|
2023
|
+
readonly session_source?: string;
|
|
2024
|
+
/**
|
|
2025
|
+
* Upstream attribution (issue #292). Absent in singular mode and on
|
|
2026
|
+
* native (sideband) tickets — same wire-additive optional spelling.
|
|
2027
|
+
*/
|
|
2028
|
+
readonly upstream?: string;
|
|
1656
2029
|
readonly requested_at: string;
|
|
1657
2030
|
readonly timeout_at: string;
|
|
1658
2031
|
readonly timeout_ms: number;
|
|
@@ -1748,6 +2121,10 @@ declare class ApprovalQueue {
|
|
|
1748
2121
|
timeout_ms: number;
|
|
1749
2122
|
/** Breached budget context on break-glass / merged tickets (issue #14). */
|
|
1750
2123
|
breached_budgets?: readonly BudgetBreachContext[];
|
|
2124
|
+
/** Identity-strategy attribution for session_id (issue #251). */
|
|
2125
|
+
session_source?: string | null;
|
|
2126
|
+
/** Upstream attribution (issue #292); absent in singular mode. */
|
|
2127
|
+
upstream?: string | null;
|
|
1751
2128
|
}): ApprovalTicket;
|
|
1752
2129
|
/** Get a ticket by ID. Returns undefined if not found. */
|
|
1753
2130
|
get(id: string): ApprovalTicket | undefined;
|
|
@@ -1803,6 +2180,13 @@ interface ApprovalSubmitParams {
|
|
|
1803
2180
|
readonly tool_input: Record<string, unknown>;
|
|
1804
2181
|
readonly matched_rule: CompiledPolicyRule | undefined;
|
|
1805
2182
|
readonly session_id: string | null;
|
|
2183
|
+
/**
|
|
2184
|
+
* Identity-strategy attribution for session_id (issue #251).
|
|
2185
|
+
* Required-nullable so no submit site can silently forget it.
|
|
2186
|
+
*/
|
|
2187
|
+
readonly session_source: string | null;
|
|
2188
|
+
/** Upstream attribution (issue #292); null in singular mode. */
|
|
2189
|
+
readonly upstream: string | null;
|
|
1806
2190
|
/** Breached budget context; marks the ticket as break-glass (issue #14). */
|
|
1807
2191
|
readonly breached_budgets?: readonly BudgetBreachContext[];
|
|
1808
2192
|
/**
|
|
@@ -2010,12 +2394,21 @@ declare class RateLimiter {
|
|
|
2010
2394
|
* Reconcile bucket state against a new policy's limit configuration.
|
|
2011
2395
|
*
|
|
2012
2396
|
* Walks every existing bucket and checks whether its last-seen
|
|
2013
|
-
* `{ maxCalls, windowMs }` tuple still appears
|
|
2397
|
+
* `{ maxCalls, windowMs }` tuple still appears in `validConfigs`.
|
|
2014
2398
|
* Buckets whose config is still present are left untouched — counters and
|
|
2015
2399
|
* elapsed-window progress are preserved across hot-reloads. Buckets whose
|
|
2016
2400
|
* config is gone (rule changed or removed) are evicted so the next check
|
|
2017
2401
|
* lazy-creates a fresh bucket under the new config.
|
|
2018
2402
|
*
|
|
2403
|
+
* Keys built by `ruleBucketKey` (bucket-key.ts) carry the owning rule's
|
|
2404
|
+
* index, and for those the tuple must match at THAT index
|
|
2405
|
+
* (`config.ruleIndex`): a reorder that shifts a rate rule's index evicts
|
|
2406
|
+
* its old-index bucket instead of leaving an orphan no rule reads again —
|
|
2407
|
+
* or worse, letting whatever rule now sits at that index adopt another
|
|
2408
|
+
* rule's accrued calls. Un-suffixed keys keep the tuple-anywhere match,
|
|
2409
|
+
* but only against index-less configs — a caller that passes only indexed
|
|
2410
|
+
* configs (as the proxy does) evicts every un-suffixed bucket, fail-closed.
|
|
2411
|
+
*
|
|
2019
2412
|
* This is the compare-and-evict semantic that replaces the old `reset()`
|
|
2020
2413
|
* call on every hot-reload, which wiped all state even when the matching
|
|
2021
2414
|
* rule was unchanged.
|
|
@@ -2023,6 +2416,7 @@ declare class RateLimiter {
|
|
|
2023
2416
|
reconcile(validConfigs: Iterable<{
|
|
2024
2417
|
maxCalls: number;
|
|
2025
2418
|
windowMs: number;
|
|
2419
|
+
ruleIndex?: number;
|
|
2026
2420
|
}>): void;
|
|
2027
2421
|
/** Stop the cleanup timer and mark as closed. */
|
|
2028
2422
|
/**
|
|
@@ -2151,12 +2545,14 @@ declare class SpendLimiter {
|
|
|
2151
2545
|
* whose config is gone (rule changed or removed) are evicted so the next
|
|
2152
2546
|
* check lazy-creates a fresh bucket under the new config.
|
|
2153
2547
|
*
|
|
2154
|
-
* Keys built by
|
|
2155
|
-
* for those the tuple must match at THAT index (`config.ruleIndex`): a
|
|
2548
|
+
* Keys built by `ruleBucketKey` (bucket-key.ts) carry the owning rule's
|
|
2549
|
+
* index, and for those the tuple must match at THAT index (`config.ruleIndex`): a
|
|
2156
2550
|
* reorder that shifts a spend rule's index evicts its old-index bucket
|
|
2157
2551
|
* instead of leaving an orphan no rule reads again — or worse, letting
|
|
2158
2552
|
* whatever rule now sits at that index adopt another rule's accrued spend.
|
|
2159
|
-
* Un-suffixed keys keep the tuple-anywhere match
|
|
2553
|
+
* Un-suffixed keys keep the tuple-anywhere match, but only against
|
|
2554
|
+
* index-less configs — a caller that passes only indexed configs (as the
|
|
2555
|
+
* proxy does) evicts every un-suffixed bucket, fail-closed.
|
|
2160
2556
|
*
|
|
2161
2557
|
* Currency is part of the tuple because a USD→EUR switch is a meaningful
|
|
2162
2558
|
* policy change — the same numeric limit buys a different amount of real
|
|
@@ -2205,6 +2601,13 @@ interface BudgetChargeContext {
|
|
|
2205
2601
|
readonly sessionId: GatedSession | null;
|
|
2206
2602
|
/** Adapter-supplied sender id (sideband only); null on the MCP path. */
|
|
2207
2603
|
readonly senderId: string | null;
|
|
2604
|
+
/**
|
|
2605
|
+
* The governed door's configured upstream name (issue #295); null on the
|
|
2606
|
+
* sideband and in singular mode. Required so every door states its
|
|
2607
|
+
* upstream: a silently-missing value would exempt that door's calls from
|
|
2608
|
+
* upstream-scoped contributors once those exist.
|
|
2609
|
+
*/
|
|
2610
|
+
readonly upstream: string | null;
|
|
2208
2611
|
}
|
|
2209
2612
|
/** One budget's share of a call: which bucket, how much. */
|
|
2210
2613
|
interface BudgetCharge {
|
|
@@ -2218,6 +2621,12 @@ interface BudgetCharge {
|
|
|
2218
2621
|
* NOT repopulate the new pot with old-config spend — recordAll skips it.
|
|
2219
2622
|
*/
|
|
2220
2623
|
readonly generation: number;
|
|
2624
|
+
/**
|
|
2625
|
+
* The charge context's upstream name, stamped only when the door set one
|
|
2626
|
+
* (issue #295). Optional is the honest type: `remintDeferredCharges`
|
|
2627
|
+
* rebuilds charges without it, so deferred commits snapshot null.
|
|
2628
|
+
*/
|
|
2629
|
+
readonly upstream?: string;
|
|
2221
2630
|
}
|
|
2222
2631
|
/** A budget whose contributor matched but whose amount was unusable. */
|
|
2223
2632
|
interface BudgetChargeFailure {
|
|
@@ -2242,6 +2651,11 @@ interface BudgetPeekEntry {
|
|
|
2242
2651
|
readonly remaining: number;
|
|
2243
2652
|
/** Epoch ms when the oldest entry ages out (duration); null for session pots. */
|
|
2244
2653
|
readonly resetAtMs: number | null;
|
|
2654
|
+
/**
|
|
2655
|
+
* The charge's upstream label, or null: sideband calls, singular mode, and
|
|
2656
|
+
* reminted deferred commits all snapshot null (issue #295).
|
|
2657
|
+
*/
|
|
2658
|
+
readonly upstream: string | null;
|
|
2245
2659
|
/**
|
|
2246
2660
|
* Set on recordAll snapshots for charges frozen before a tuple-changing
|
|
2247
2661
|
* reload: the executed spend was ledgered under its evaluate-time
|
|
@@ -2306,6 +2720,12 @@ interface BudgetCommitEvent {
|
|
|
2306
2720
|
readonly limit: number;
|
|
2307
2721
|
readonly currency: string;
|
|
2308
2722
|
readonly utilization: number;
|
|
2723
|
+
/**
|
|
2724
|
+
* Upstream attribution from the charge context (issue #292), or null.
|
|
2725
|
+
* Reminted frozen-plan charges drop the label by design, so deferred
|
|
2726
|
+
* sideband commits always emit null here.
|
|
2727
|
+
*/
|
|
2728
|
+
readonly upstream: string | null;
|
|
2309
2729
|
}
|
|
2310
2730
|
/**
|
|
2311
2731
|
* Payload for the per-budget breach callback (dashboard event bus). Fired
|
|
@@ -2322,6 +2742,8 @@ interface BudgetBreachEvent {
|
|
|
2322
2742
|
readonly spent: number;
|
|
2323
2743
|
readonly limit: number;
|
|
2324
2744
|
readonly currency: string;
|
|
2745
|
+
/** Upstream attribution from the peek entry's context (issue #292), or null. */
|
|
2746
|
+
readonly upstream: string | null;
|
|
2325
2747
|
}
|
|
2326
2748
|
/** Wire-ready bucket state for `GET /api/budgets` (snake_case DTO). */
|
|
2327
2749
|
interface BudgetBucketState {
|
|
@@ -2373,14 +2795,18 @@ declare class BudgetEngine {
|
|
|
2373
2795
|
/**
|
|
2374
2796
|
* Resolve which budgets a call feeds and how much it charges each.
|
|
2375
2797
|
*
|
|
2376
|
-
* A contributor participates when its
|
|
2377
|
-
*
|
|
2378
|
-
*
|
|
2379
|
-
*
|
|
2380
|
-
*
|
|
2381
|
-
*
|
|
2382
|
-
*
|
|
2383
|
-
*
|
|
2798
|
+
* A contributor participates when its upstream scope admits the call's
|
|
2799
|
+
* door (absent scope admits every door; a scoped contributor never
|
|
2800
|
+
* participates when `ctx.upstream` is null — sideband, singular mode) AND
|
|
2801
|
+
* its tool glob matches the tool name AND every `match.input` condition
|
|
2802
|
+
* holds (absent conditions means the glob alone decides); the FIRST
|
|
2803
|
+
* participating contributor (config order, over that combined predicate)
|
|
2804
|
+
* supplies the amount field. A call that matches the glob but not the
|
|
2805
|
+
* conditions or the scope simply does not feed the budget — no charge, no
|
|
2806
|
+
* failure — and a later contributor may still participate. Once a
|
|
2807
|
+
* contributor is selected, a missing, non-numeric, negative, or non-finite
|
|
2808
|
+
* amount fails closed as a `failures` entry — the caller must deny the
|
|
2809
|
+
* call.
|
|
2384
2810
|
*/
|
|
2385
2811
|
resolveCharges(ctx: BudgetChargeContext): {
|
|
2386
2812
|
charges: BudgetCharge[];
|
|
@@ -2533,6 +2959,13 @@ interface GovernedForwarderOptions {
|
|
|
2533
2959
|
* default chain (deny mode) for direct/library construction.
|
|
2534
2960
|
*/
|
|
2535
2961
|
session?: CompiledSessionIdentity;
|
|
2962
|
+
/**
|
|
2963
|
+
* The operator-chosen upstream entry name (issue #295, multi-upstream
|
|
2964
|
+
* substrate). Unset in singular mode — every governance surface then
|
|
2965
|
+
* behaves exactly as today. The multi-upstream composition loop (issue
|
|
2966
|
+
* #294) passes each entry's name.
|
|
2967
|
+
*/
|
|
2968
|
+
upstreamName?: string;
|
|
2536
2969
|
}
|
|
2537
2970
|
/** Result of attempting to prime the tool annotation cache. */
|
|
2538
2971
|
interface AnnotationCachePrimeResult {
|
|
@@ -2562,6 +2995,7 @@ declare class GovernedForwarder implements McpForwarder {
|
|
|
2562
2995
|
private readonly rateLimiter;
|
|
2563
2996
|
private readonly spendLimiter;
|
|
2564
2997
|
private readonly budgetEngine;
|
|
2998
|
+
private readonly upstreamName;
|
|
2565
2999
|
private readonly annotationCache;
|
|
2566
3000
|
private agentKeyWarned;
|
|
2567
3001
|
private senderKeyWarned;
|
|
@@ -2673,7 +3107,9 @@ declare class GovernedForwarder implements McpForwarder {
|
|
|
2673
3107
|
*/
|
|
2674
3108
|
private handleDryRun;
|
|
2675
3109
|
/**
|
|
2676
|
-
* Construct a non-session limit bucket key.
|
|
3110
|
+
* Construct a non-session limit bucket key. Tool-scope keys route through
|
|
3111
|
+
* the shared `toolLimitKey` leaf, which prefixes them with the configured
|
|
3112
|
+
* upstream name when one is set (issue #295). Session keys are deliberately
|
|
2677
3113
|
* NOT built here: they come only from the gate module's `sessionLimitKey`,
|
|
2678
3114
|
* whose `GatedSession` parameter makes skipping the identity gate a
|
|
2679
3115
|
* compile error (issue #218) — call sites branch on `key === 'session'`.
|
|
@@ -2730,6 +3166,13 @@ interface BudgetEventRecord {
|
|
|
2730
3166
|
readonly timestamp: string;
|
|
2731
3167
|
readonly timestamp_ms: number;
|
|
2732
3168
|
readonly created_at: string;
|
|
3169
|
+
/**
|
|
3170
|
+
* Upstream attribution read from the referenced audit record via LEFT
|
|
3171
|
+
* JOIN (issue #292) — never a stored ledger column. Null on singular-mode
|
|
3172
|
+
* records, dangling or null `audit_record_id`, and rows predating the
|
|
3173
|
+
* audit column; a null renders as empty/absent, never a made-up label.
|
|
3174
|
+
*/
|
|
3175
|
+
readonly upstream: string | null;
|
|
2733
3176
|
}
|
|
2734
3177
|
/** One page of a budget's event history plus the unpaginated total. */
|
|
2735
3178
|
interface BudgetEventsPage {
|
|
@@ -3020,7 +3463,7 @@ declare class GovernanceConfigError extends Error {
|
|
|
3020
3463
|
* reserved `'<header_mismatch>'` sentinel — either way `top_tools` already
|
|
3021
3464
|
* excludes rejected records, so these rows never pollute tool rankings.
|
|
3022
3465
|
*/
|
|
3023
|
-
declare function buildHeaderMismatchAuditRecord(rejection: HeaderMismatchRejection, environment?: string): Omit<AuditRecord, 'id' | 'created_at'>;
|
|
3466
|
+
declare function buildHeaderMismatchAuditRecord(rejection: HeaderMismatchRejection, environment?: string, upstream?: string): Omit<AuditRecord, 'id' | 'created_at'>;
|
|
3024
3467
|
|
|
3025
3468
|
/** @internal Exported for testing only. */
|
|
3026
3469
|
declare class QueueChannel implements ApprovalChannel {
|
|
@@ -3164,6 +3607,8 @@ interface ActionEvent {
|
|
|
3164
3607
|
readonly matched_rule_index: number | null;
|
|
3165
3608
|
readonly record_kind: AuditRecord['record_kind'];
|
|
3166
3609
|
readonly origin: string;
|
|
3610
|
+
/** Upstream attribution from the audit record (issue #292), or null. */
|
|
3611
|
+
readonly upstream: string | null;
|
|
3167
3612
|
}
|
|
3168
3613
|
/** Payload for an approval_requested event. */
|
|
3169
3614
|
interface ApprovalRequestedEvent {
|
|
@@ -3171,6 +3616,8 @@ interface ApprovalRequestedEvent {
|
|
|
3171
3616
|
readonly tool_name: string;
|
|
3172
3617
|
readonly channel: string;
|
|
3173
3618
|
readonly requested_at: string;
|
|
3619
|
+
/** Upstream attribution from the ticket (issue #292), or null. */
|
|
3620
|
+
readonly upstream: string | null;
|
|
3174
3621
|
}
|
|
3175
3622
|
/** Payload for an approval_resolved event. */
|
|
3176
3623
|
interface ApprovalResolvedEvent {
|
|
@@ -3186,6 +3633,11 @@ interface LimitWarningEvent {
|
|
|
3186
3633
|
readonly current: number;
|
|
3187
3634
|
readonly limit: number;
|
|
3188
3635
|
readonly utilization: number;
|
|
3636
|
+
/**
|
|
3637
|
+
* Upstream name parsed from a partitioned bucket key (issue #292), or
|
|
3638
|
+
* null — session keys, singular tool keys, and sideband keys have no door.
|
|
3639
|
+
*/
|
|
3640
|
+
readonly upstream: string | null;
|
|
3189
3641
|
}
|
|
3190
3642
|
/** Payload for approval notification delivery failures. */
|
|
3191
3643
|
interface ApprovalNotificationFailedEvent {
|
|
@@ -3289,6 +3741,20 @@ interface DashboardAppOptions {
|
|
|
3289
3741
|
readonly staticDir?: string;
|
|
3290
3742
|
/** SSE heartbeat interval in milliseconds. Defaults to 30 000 (30s). */
|
|
3291
3743
|
readonly sseHeartbeatMs?: number;
|
|
3744
|
+
/**
|
|
3745
|
+
* @internal Test seam for the concurrent-connection cap (issue #285), so
|
|
3746
|
+
* tests need not mint 256 real streams. Not wired to config — the cap is
|
|
3747
|
+
* a hardcoded invariant (see MAX_SSE_CONNECTIONS).
|
|
3748
|
+
*/
|
|
3749
|
+
readonly maxSseConnections?: number;
|
|
3750
|
+
/**
|
|
3751
|
+
* @internal Test seam for the stale-connection sweep cadence (issue
|
|
3752
|
+
* #327), so sweeper tests need not wait out the production floor. `0`
|
|
3753
|
+
* DISABLES the sweeper entirely (the repo-wide sweep-interval
|
|
3754
|
+
* convention). Not wired to config — the 10 s floor stays the
|
|
3755
|
+
* production default.
|
|
3756
|
+
*/
|
|
3757
|
+
readonly sweepIntervalMs?: number;
|
|
3292
3758
|
}
|
|
3293
3759
|
/**
|
|
3294
3760
|
* Create a Hono app for the dashboard REST + SSE API.
|
|
@@ -3298,4 +3764,4 @@ interface DashboardAppOptions {
|
|
|
3298
3764
|
*/
|
|
3299
3765
|
declare function createDashboardApp(deps: DashboardAppDeps, options?: DashboardAppOptions): Hono;
|
|
3300
3766
|
|
|
3301
|
-
export { type AdapterLivenessEntry, type ApprovalAppOptions, type ApprovalChannel, type ApprovalOutcome, ApprovalQueue, type ApprovalQueueOptions, ApprovalRouter, type ApprovalRouterOptions, type ApprovalStatus, type ApprovalTicket, type AuditAggregateStats, type AuditInput, type AuditListResult, type AuditPaginationOptions, type AuditQueryFilters, type AuditRecord, AuditStore, type AuditStoreOptions, type AuditTimeBucket, AuditWriter, type AuditWriterOptions, type BudgetBreachContext, type BudgetBreachEvent, type BudgetBucketState, type BudgetCommitEvent, BudgetEngine, type BudgetEventRecord, type BudgetEventsPage, type BudgetLedgerRow, type BudgetLedgerSink, BudgetParseError, type BudgetState, type CompilePoliciesResult, type CompiledBudget, type CompiledBudgetContributor, type CompiledBudgetWindow, type CompiledPolicy, type CompiledPolicyRule, ConfigError, type CreateAppOptions, type DashboardAppDeps, type DashboardAppOptions, DashboardEventBus, type DashboardEventType, type DashboardEvents, EXPORT_MAX_RECORDS, type EvaluateInput, type EvidenceEntry, EvidenceStore, type EvidenceStoreOptions, GovernanceConfigError, GovernanceService, type GovernanceServiceOptions, GovernedForwarder, type GovernedForwarderOptions, type HeaderMismatchRejection, type HelioConfig, type InstallScanInput, LIST_MAX_PAGE_SIZE, type MatchContext, type PolicyDecision, PolicyParseError, QueueChannel, type RateLimitCheckParams, type RateLimitKeyState, type RateLimitResult, RateLimiter, type RateLimiterOptions, type ResolveApprovalInput, type ServerHandle, type SessionState, type SlackActionAppOptions, SlackChannel, type SlackChannelOptions, type SpendLimitCheckParams, type SpendLimitKeyState, type SpendLimitResult, SpendLimiter, type SpendLimiterOptions, SseUpstreamForwarder, type SseUpstreamForwarderOptions, StdioForwarder, type StdioForwarderOptions, StreamableHttpForwarder, type StreamableHttpForwarderOptions, UpstreamForwarder, type UpstreamForwarderOptions, VERSION, WebhookChannel, type WebhookChannelOptions, type WireDecision, buildHeaderMismatchAuditRecord, compileBudgets, compilePolicies, createApp, createApprovalApp, createChannels, createDashboardApp, createSidebandApp, createSlackActionApp, evaluatePolicy, loadConfig, matchRule, startServer, startSidebandServer };
|
|
3767
|
+
export { type AdapterLivenessEntry, type ApprovalAppOptions, type ApprovalChannel, type ApprovalOutcome, ApprovalQueue, type ApprovalQueueOptions, ApprovalRouter, type ApprovalRouterOptions, type ApprovalStatus, type ApprovalTicket, type AuditAggregateStats, type AuditInput, type AuditListResult, type AuditPaginationOptions, type AuditQueryFilters, type AuditRecord, AuditStore, type AuditStoreOptions, type AuditTimeBucket, AuditWriter, type AuditWriterOptions, type BudgetBreachContext, type BudgetBreachEvent, type BudgetBucketState, type BudgetCommitEvent, BudgetEngine, type BudgetEventRecord, type BudgetEventsPage, type BudgetLedgerRow, type BudgetLedgerSink, BudgetParseError, type BudgetState, type CompilePoliciesResult, type CompiledBudget, type CompiledBudgetContributor, type CompiledBudgetWindow, type CompiledPolicy, type CompiledPolicyRule, ConfigError, type CreateAppOptions, type CreateMultiAppOptions, type DashboardAppDeps, type DashboardAppOptions, DashboardEventBus, type DashboardEventType, type DashboardEvents, EXPORT_MAX_RECORDS, type EvaluateInput, type EvidenceEntry, EvidenceStore, type EvidenceStoreOptions, GovernanceConfigError, GovernanceService, type GovernanceServiceOptions, GovernedForwarder, type GovernedForwarderOptions, type HeaderMismatchRejection, type HelioConfig, type InstallScanInput, LIST_MAX_PAGE_SIZE, type MatchContext, type NamedHelioConfig, type PolicyDecision, PolicyParseError, QueueChannel, type RateLimitCheckParams, type RateLimitKeyState, type RateLimitResult, RateLimiter, type RateLimiterOptions, type ResolveApprovalInput, type ServerHandle, type SessionState, type SingularHelioConfig, type SlackActionAppOptions, SlackChannel, type SlackChannelOptions, type SpendLimitCheckParams, type SpendLimitKeyState, type SpendLimitResult, SpendLimiter, type SpendLimiterOptions, SseUpstreamForwarder, type SseUpstreamForwarderOptions, StdioForwarder, type StdioForwarderOptions, StreamableHttpForwarder, type StreamableHttpForwarderOptions, UpstreamForwarder, type UpstreamForwarderOptions, VERSION, WebhookChannel, type WebhookChannelOptions, type WireDecision, buildHeaderMismatchAuditRecord, compileBudgets, compilePolicies, createApp, createApprovalApp, createChannels, createDashboardApp, createMultiApp, createSidebandApp, createSlackActionApp, evaluatePolicy, isNamedConfig, isSingularConfig, loadConfig, matchRule, startServer, startSidebandServer };
|