@jeffusion/bungee-core 6.1.1 → 6.2.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/main.js +94 -65
- package/dist/observability-worker.js +21 -1
- package/dist/plugins/anthropic-request-sanitizer/index.js.map +3 -3
- package/dist/plugins/anthropic-tool-name-transformer/index.js.map +3 -3
- package/dist/plugins/chatgpt-oauth/control.js.map +1 -1
- package/dist/plugins/chatgpt-oauth/index.js.map +3 -3
- package/dist/plugins/codex-router/control.js.map +1 -1
- package/dist/plugins/codex-router/index.js.map +3 -3
- package/dist/plugins/deepseek-reasoning-fix/index.js.map +3 -3
- package/dist/plugins/key-access/control.js.map +1 -1
- package/dist/plugins/key-access/index.js.map +3 -3
- package/dist/plugins/key-access/ingress.js.map +1 -1
- package/dist/plugins/key-rate-limit/index.js.map +3 -3
- package/dist/plugins/llm-protocol-adapter/control.js.map +1 -1
- package/dist/plugins/llm-protocol-adapter/index.js.map +4 -4
- package/dist/plugins/llm-tps/control.js +212 -0
- package/dist/plugins/llm-tps/control.js.map +13 -0
- package/dist/plugins/llm-tps/index.js +286 -0
- package/dist/plugins/llm-tps/index.js.map +27 -0
- package/dist/plugins/llm-tps/manifest.json +115 -0
- package/dist/plugins/llm-tps/ui/TpsEndpoints.svelte +9 -0
- package/dist/plugins/llm-tps/ui/TpsOverview.svelte +9 -0
- package/dist/plugins/llm-tps/ui/TpsWidget.svelte +115 -0
- package/dist/plugins/llm-tps/ui/presentation.ts +16 -0
- package/dist/plugins/llm-tps/ui/stats-resource.ts +77 -0
- package/dist/plugins/llm-tps/ui/stats.ts +7 -0
- package/dist/plugins/model-mapping/index.js.map +3 -3
- package/dist/plugins/models-dev/index.js.map +3 -3
- package/dist/plugins/signature-repair/index.js.map +3 -3
- package/dist/plugins/token-budget/control.js.map +1 -1
- package/dist/plugins/token-budget/index.js.map +3 -3
- package/dist/plugins/token-metering/index.js +138 -11
- package/dist/plugins/token-metering/index.js.map +8 -7
- package/dist/plugins/token-stats/control.js.map +1 -1
- package/dist/plugins/token-stats/index.js.map +3 -3
- package/dist/plugins/user-auth/control.js.map +1 -1
- package/dist/plugins/user-auth/index.js.map +3 -3
- package/package.json +2 -2
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// plugins/llm-tps/contract.ts
|
|
3
|
+
var TPS_RETENTION_MS = 31 * 24 * 60 * 60 * 1000;
|
|
4
|
+
var TPS_REPORTING_INCOMPLETE_KEY = "reporting:incomplete";
|
|
5
|
+
|
|
6
|
+
// plugins/llm-tps/server/metrics.ts
|
|
7
|
+
function isUrlIdentity(value) {
|
|
8
|
+
return /^(?:[a-z][a-z\d+.-]*:)?\/\//i.test(value);
|
|
9
|
+
}
|
|
10
|
+
function safeCount(value, name) {
|
|
11
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
|
|
12
|
+
throw new RangeError(`invalid llm-tps ${name}`);
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
function identifier(value, name) {
|
|
16
|
+
if (typeof value !== "string" || !value.trim())
|
|
17
|
+
throw new TypeError(`invalid llm-tps ${name}`);
|
|
18
|
+
}
|
|
19
|
+
function validateSample(sample) {
|
|
20
|
+
for (const key of ["attemptId", "requestId", "routeId", "endpointId"])
|
|
21
|
+
identifier(sample[key], key);
|
|
22
|
+
if (isUrlIdentity(sample.endpointId))
|
|
23
|
+
throw new TypeError("llm-tps endpoint must be opaque");
|
|
24
|
+
safeCount(sample.finishedAtMs, "finishedAtMs");
|
|
25
|
+
safeCount(sample.outputTokens, "outputTokens");
|
|
26
|
+
if (!Number.isFinite(sample.generationDurationMs) || sample.generationDurationMs <= 0)
|
|
27
|
+
throw new RangeError("invalid llm-tps duration");
|
|
28
|
+
if (sample.outputSource !== "official" && sample.outputSource !== "estimated")
|
|
29
|
+
throw new TypeError("invalid llm-tps output source");
|
|
30
|
+
if (!Number.isFinite(sample.outputTokens / sample.generationDurationMs * 1000))
|
|
31
|
+
throw new RangeError("invalid llm-tps rate");
|
|
32
|
+
}
|
|
33
|
+
function rangeDuration(range) {
|
|
34
|
+
if (range === "1h")
|
|
35
|
+
return 3600000;
|
|
36
|
+
if (range === "12h")
|
|
37
|
+
return 43200000;
|
|
38
|
+
if (range === "24h")
|
|
39
|
+
return 86400000;
|
|
40
|
+
throw new RangeError("invalid llm-tps range");
|
|
41
|
+
}
|
|
42
|
+
function aggregate(row) {
|
|
43
|
+
const outputTokens = safeCount(row.outputTokens, "aggregate tokens");
|
|
44
|
+
const sampleCount = safeCount(row.sampleCount, "sample count");
|
|
45
|
+
const estimatedSampleCount = safeCount(row.estimatedSampleCount, "estimated sample count");
|
|
46
|
+
const duration = row.generationDurationMs;
|
|
47
|
+
if (typeof duration !== "number" || !Number.isFinite(duration) || duration < 0 || sampleCount > 0 && duration <= 0 || estimatedSampleCount > sampleCount || sampleCount === 0 && (outputTokens !== 0 || duration !== 0 || estimatedSampleCount !== 0))
|
|
48
|
+
throw new RangeError("invalid llm-tps aggregate");
|
|
49
|
+
const tps = sampleCount === 0 ? null : outputTokens / duration * 1000;
|
|
50
|
+
if (tps !== null && (!Number.isFinite(tps) || tps < 0))
|
|
51
|
+
throw new RangeError("invalid llm-tps aggregate rate");
|
|
52
|
+
return { tps, outputTokens, generationDurationMs: duration, sampleCount, estimatedSampleCount };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// plugins/llm-tps/server/storage.ts
|
|
56
|
+
function observationClient(storage) {
|
|
57
|
+
if (typeof storage.invokeObservation !== "function")
|
|
58
|
+
throw new Error("llm-tps observation storage is unavailable");
|
|
59
|
+
const invoke = storage.invokeObservation.bind(storage);
|
|
60
|
+
return {
|
|
61
|
+
recordSample: (sample) => invoke("recordSample", [sample]),
|
|
62
|
+
queryStats: (input) => invoke("queryStats", [input])
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
var metrics = `COALESCE(SUM(output_tokens), 0) AS outputTokens,
|
|
66
|
+
COALESCE(SUM(generation_duration_ms), 0) AS generationDurationMs,
|
|
67
|
+
COUNT(*) AS sampleCount, COALESCE(SUM(output_source = 'estimated'), 0) AS estimatedSampleCount,
|
|
68
|
+
COALESCE(SUM(CASE WHEN typeof(output_tokens) != 'integer' OR output_tokens < 0 OR output_tokens > 9007199254740991
|
|
69
|
+
OR typeof(generation_duration_ms) NOT IN ('integer', 'real') OR NOT(generation_duration_ms > 0)
|
|
70
|
+
OR generation_duration_ms > 1.7976931348623157e308 OR output_source NOT IN ('official','estimated')
|
|
71
|
+
OR typeof(finished_at_ms) != 'integer' OR finished_at_ms < 0 OR finished_at_ms > 9007199254740991
|
|
72
|
+
THEN 1 ELSE 0 END), 0) AS invalidSamples`;
|
|
73
|
+
function createObservationAdapter(observation) {
|
|
74
|
+
return Object.freeze({
|
|
75
|
+
async recordSample(sample) {
|
|
76
|
+
validateSample(sample);
|
|
77
|
+
observation.withDatabase((db) => {
|
|
78
|
+
db.transaction(() => {
|
|
79
|
+
db.query(`INSERT OR IGNORE INTO llm_tps_samples
|
|
80
|
+
(attempt_id, request_id, route_id, endpoint_id, finished_at_ms, output_tokens, generation_duration_ms, output_source)
|
|
81
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(sample.attemptId, sample.requestId, sample.routeId, sample.endpointId, sample.finishedAtMs, sample.outputTokens, sample.generationDurationMs, sample.outputSource);
|
|
82
|
+
db.query(`DELETE FROM llm_tps_samples WHERE attempt_id IN (
|
|
83
|
+
SELECT attempt_id FROM llm_tps_samples INDEXED BY idx_llm_tps_samples_finished
|
|
84
|
+
WHERE finished_at_ms < ? ORDER BY finished_at_ms LIMIT 500
|
|
85
|
+
)`).run(Date.now() - TPS_RETENTION_MS);
|
|
86
|
+
}).immediate();
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
async queryStats(input) {
|
|
90
|
+
safeCount(input.asOfMs, "asOfMs");
|
|
91
|
+
const start = input.asOfMs - rangeDuration(input.range);
|
|
92
|
+
return observation.withDatabase((db) => db.transaction(() => {
|
|
93
|
+
const where = "WHERE finished_at_ms >= ? AND finished_at_ms <= ?";
|
|
94
|
+
const totalRow = db.query(`SELECT ${metrics} FROM llm_tps_samples ${where}`).get(start, input.asOfMs);
|
|
95
|
+
const rows = db.query(`SELECT route_id AS routeId, endpoint_id AS endpointId, ${metrics}
|
|
96
|
+
FROM llm_tps_samples ${where} GROUP BY route_id, endpoint_id`).all(start, input.asOfMs);
|
|
97
|
+
const checked = (row) => {
|
|
98
|
+
if (safeCount(row.invalidSamples, "invalid sample count") !== 0)
|
|
99
|
+
throw new RangeError("invalid persisted llm-tps sample");
|
|
100
|
+
return aggregate(row);
|
|
101
|
+
};
|
|
102
|
+
const total = checked(totalRow);
|
|
103
|
+
const endpoints = rows.map((row) => {
|
|
104
|
+
identifier(row.routeId, "routeId");
|
|
105
|
+
identifier(row.endpointId, "endpointId");
|
|
106
|
+
if (isUrlIdentity(row.endpointId))
|
|
107
|
+
throw new TypeError("invalid persisted llm-tps endpoint");
|
|
108
|
+
return { routeId: row.routeId, endpointId: row.endpointId, ...checked(row) };
|
|
109
|
+
}).sort((a, b) => b.tps - a.tps || compare(a.routeId, b.routeId) || compare(a.endpointId, b.endpointId));
|
|
110
|
+
return { range: input.range, asOfMs: input.asOfMs, total, endpoints, reportingIncomplete: false };
|
|
111
|
+
})());
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function compare(a, b) {
|
|
116
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// plugins/llm-tps/server/control.ts
|
|
120
|
+
class ControlError extends Error {
|
|
121
|
+
code;
|
|
122
|
+
constructor(code) {
|
|
123
|
+
super(code);
|
|
124
|
+
this.code = code;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function abortable(operation, signals) {
|
|
128
|
+
return new Promise((resolve, reject) => {
|
|
129
|
+
const listeners = [];
|
|
130
|
+
const cleanup = () => signals.forEach((signal, index) => signal.removeEventListener("abort", listeners[index]));
|
|
131
|
+
const fail = (index) => {
|
|
132
|
+
cleanup();
|
|
133
|
+
reject(new ControlError(index < 3 ? "disposed" : "request_cancelled"));
|
|
134
|
+
};
|
|
135
|
+
signals.forEach((signal, index) => {
|
|
136
|
+
const listener = () => fail(index);
|
|
137
|
+
listeners.push(listener);
|
|
138
|
+
signal.addEventListener("abort", listener, { once: true });
|
|
139
|
+
});
|
|
140
|
+
const cancelled = signals.findIndex((signal) => signal.aborted);
|
|
141
|
+
if (cancelled !== -1)
|
|
142
|
+
fail(cancelled);
|
|
143
|
+
operation.then((value) => {
|
|
144
|
+
cleanup();
|
|
145
|
+
resolve(value);
|
|
146
|
+
}, (error) => {
|
|
147
|
+
cleanup();
|
|
148
|
+
reject(error);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function createControl(host) {
|
|
153
|
+
const client = observationClient(host.storage);
|
|
154
|
+
const disposal = new AbortController;
|
|
155
|
+
let disposed = false;
|
|
156
|
+
const assertAlive = (context) => {
|
|
157
|
+
if (disposed || host.signal.aborted || context?.signal.aborted)
|
|
158
|
+
throw new ControlError("disposed");
|
|
159
|
+
if (context?.requestSignal.aborted || context?.request.signal.aborted)
|
|
160
|
+
throw new ControlError("request_cancelled");
|
|
161
|
+
};
|
|
162
|
+
const dispose = () => {
|
|
163
|
+
disposed = true;
|
|
164
|
+
disposal.abort();
|
|
165
|
+
host.signal.removeEventListener("abort", dispose);
|
|
166
|
+
};
|
|
167
|
+
host.signal.addEventListener("abort", dispose, { once: true });
|
|
168
|
+
return {
|
|
169
|
+
api: [{ path: "/stats", methods: ["GET"], handler: "getStats", async invoke(context) {
|
|
170
|
+
try {
|
|
171
|
+
assertAlive(context);
|
|
172
|
+
if (context.request.method !== "GET")
|
|
173
|
+
return Response.json({ error: "method_not_allowed" }, { status: 405, headers: { allow: "GET" } });
|
|
174
|
+
const params = new URL(context.request.url).searchParams;
|
|
175
|
+
const range = params.get("range") ?? "24h";
|
|
176
|
+
if ([...params.keys()].some((key) => key !== "range") || params.getAll("range").length > 1 || !["1h", "12h", "24h"].includes(range))
|
|
177
|
+
throw new ControlError("invalid_input");
|
|
178
|
+
const readIncomplete = async () => {
|
|
179
|
+
const storage = host.storage;
|
|
180
|
+
const strict = storage.readStrict ? await storage.readStrict(TPS_REPORTING_INCOMPLETE_KEY) : null;
|
|
181
|
+
const value = strict === null ? await storage.get(TPS_REPORTING_INCOMPLETE_KEY) : strict.found ? strict.value : null;
|
|
182
|
+
if (value !== null && value !== false && value !== true)
|
|
183
|
+
throw new Error("invalid reporting status");
|
|
184
|
+
return value === true;
|
|
185
|
+
};
|
|
186
|
+
const [stats, incomplete] = await abortable(Promise.all([
|
|
187
|
+
client.queryStats({ range, asOfMs: Date.now() }),
|
|
188
|
+
readIncomplete()
|
|
189
|
+
]), [disposal.signal, host.signal, context.signal, context.requestSignal, context.request.signal]);
|
|
190
|
+
assertAlive(context);
|
|
191
|
+
return Response.json({ ...stats, reportingIncomplete: stats.reportingIncomplete || incomplete });
|
|
192
|
+
} catch (error) {
|
|
193
|
+
const code = error instanceof ControlError ? error.code : "storage_unavailable";
|
|
194
|
+
const status = code === "invalid_input" || code === "request_cancelled" ? 400 : code === "disposed" ? 409 : 503;
|
|
195
|
+
return Response.json({ error: code }, { status });
|
|
196
|
+
}
|
|
197
|
+
} }],
|
|
198
|
+
rpc: [],
|
|
199
|
+
start() {
|
|
200
|
+
assertAlive();
|
|
201
|
+
},
|
|
202
|
+
dispose
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
var control_default = { createControl };
|
|
206
|
+
export {
|
|
207
|
+
createControl,
|
|
208
|
+
createObservationAdapter,
|
|
209
|
+
control_default as default
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
//# debugId=6D69678B8F3EC90164756E2164756E21
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../plugins/llm-tps/contract.ts", "../../../../../plugins/llm-tps/server/metrics.ts", "../../../../../plugins/llm-tps/server/storage.ts", "../../../../../plugins/llm-tps/server/control.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"export type TpsRange = '1h' | '12h' | '24h';\n\nexport interface TpsSample {\n readonly attemptId: string;\n readonly requestId: string;\n readonly routeId: string;\n /** Configured endpoint ID, or an opaque hash when the host identity is a URL. */\n readonly endpointId: string;\n readonly finishedAtMs: number;\n readonly outputTokens: number;\n readonly generationDurationMs: number;\n readonly outputSource: 'official' | 'estimated';\n}\n\nexport interface TpsAggregate {\n readonly tps: number | null;\n readonly outputTokens: number;\n readonly generationDurationMs: number;\n readonly sampleCount: number;\n readonly estimatedSampleCount: number;\n}\n\nexport interface TpsEndpointStats extends TpsAggregate {\n readonly routeId: string;\n readonly endpointId: string;\n}\n\nexport interface TpsStatsResponse {\n readonly range: TpsRange;\n readonly asOfMs: number;\n readonly total: TpsAggregate;\n readonly endpoints: readonly TpsEndpointStats[];\n readonly reportingIncomplete: boolean;\n}\n\nexport const TPS_RETENTION_MS = 31 * 24 * 60 * 60 * 1000;\nexport const TPS_REPORTING_INCOMPLETE_KEY = 'reporting:incomplete';\n",
|
|
6
|
+
"import { createHash } from 'node:crypto';\nimport type { TokenMeteringResult } from '@jeffusion/bungee-core/plugin';\nimport type { TpsAggregate, TpsRange, TpsSample } from '../contract';\n\nexport function isUrlIdentity(value: string): boolean {\n return /^(?:[a-z][a-z\\d+.-]*:)?\\/\\//i.test(value);\n}\n\nexport function endpointIdentity(upstreamId: string): string {\n return isUrlIdentity(upstreamId)\n ? `endpoint-${createHash('sha256').update(upstreamId).digest('hex').slice(0, 16)}`\n : upstreamId;\n}\n\nexport function safeCount(value: unknown, name: string): number {\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) throw new RangeError(`invalid llm-tps ${name}`);\n return value;\n}\n\nexport function identifier(value: unknown, name: string): asserts value is string {\n if (typeof value !== 'string' || !value.trim()) throw new TypeError(`invalid llm-tps ${name}`);\n}\n\nexport function validateSample(sample: TpsSample): void {\n for (const key of ['attemptId', 'requestId', 'routeId', 'endpointId'] as const) identifier(sample[key], key);\n if (isUrlIdentity(sample.endpointId)) throw new TypeError('llm-tps endpoint must be opaque');\n safeCount(sample.finishedAtMs, 'finishedAtMs');\n safeCount(sample.outputTokens, 'outputTokens');\n if (!Number.isFinite(sample.generationDurationMs) || sample.generationDurationMs <= 0) throw new RangeError('invalid llm-tps duration');\n if (sample.outputSource !== 'official' && sample.outputSource !== 'estimated') throw new TypeError('invalid llm-tps output source');\n if (!Number.isFinite(sample.outputTokens / sample.generationDurationMs * 1000)) throw new RangeError('invalid llm-tps rate');\n}\n\n/** Unknown input usage does not invalidate observable output usage. */\nexport function sampleFromResult(result: TokenMeteringResult, routeId: string): TpsSample | null {\n const output = result.generationOutput;\n if (result.routeId !== routeId || !output\n || (output.source !== 'official' && output.source !== 'estimated')\n || !Number.isSafeInteger(output.tokens) || output.tokens < 0\n || !Number.isFinite(result.generationDurationMs) || result.generationDurationMs! <= 0) return null;\n const sample: TpsSample = {\n attemptId: result.attemptId, requestId: result.requestId, routeId: result.routeId,\n endpointId: endpointIdentity(result.upstreamId), finishedAtMs: result.finishedAtMs,\n outputTokens: output.tokens, generationDurationMs: result.generationDurationMs!, outputSource: output.source,\n };\n validateSample(sample);\n return sample;\n}\n\nexport function rangeDuration(range: TpsRange): number {\n if (range === '1h') return 3_600_000;\n if (range === '12h') return 43_200_000;\n if (range === '24h') return 86_400_000;\n throw new RangeError('invalid llm-tps range');\n}\n\nexport function aggregate(row: Record<string, unknown>): TpsAggregate {\n const outputTokens = safeCount(row.outputTokens, 'aggregate tokens');\n const sampleCount = safeCount(row.sampleCount, 'sample count');\n const estimatedSampleCount = safeCount(row.estimatedSampleCount, 'estimated sample count');\n const duration = row.generationDurationMs;\n if (typeof duration !== 'number' || !Number.isFinite(duration) || duration < 0\n || (sampleCount > 0 && duration <= 0) || estimatedSampleCount > sampleCount\n || (sampleCount === 0 && (outputTokens !== 0 || duration !== 0 || estimatedSampleCount !== 0))) throw new RangeError('invalid llm-tps aggregate');\n const tps = sampleCount === 0 ? null : outputTokens / duration * 1000;\n if (tps !== null && (!Number.isFinite(tps) || tps < 0)) throw new RangeError('invalid llm-tps aggregate rate');\n return { tps, outputTokens, generationDurationMs: duration, sampleCount, estimatedSampleCount };\n}\n",
|
|
7
|
+
"import type { PluginObservationStorage, PluginStorage } from '@jeffusion/bungee-core/plugin';\nimport { TPS_RETENTION_MS, type TpsRange, type TpsSample, type TpsStatsResponse } from '../contract';\nimport { aggregate, identifier, isUrlIdentity, rangeDuration, safeCount, validateSample } from './metrics';\n\nexport interface TpsObservationClient {\n recordSample(sample: TpsSample): Promise<void>;\n queryStats(input: { range: TpsRange; asOfMs: number }): Promise<TpsStatsResponse>;\n}\n\n/** Runtime and control use only the host's namespaced observation adapter. */\nexport function observationClient(storage: PluginStorage): TpsObservationClient {\n if (typeof storage.invokeObservation !== 'function') throw new Error('llm-tps observation storage is unavailable');\n const invoke = storage.invokeObservation.bind(storage);\n return {\n recordSample: sample => invoke<void>('recordSample', [sample]),\n queryStats: input => invoke<TpsStatsResponse>('queryStats', [input]),\n };\n}\n\nconst metrics = `COALESCE(SUM(output_tokens), 0) AS outputTokens,\n COALESCE(SUM(generation_duration_ms), 0) AS generationDurationMs,\n COUNT(*) AS sampleCount, COALESCE(SUM(output_source = 'estimated'), 0) AS estimatedSampleCount,\n COALESCE(SUM(CASE WHEN typeof(output_tokens) != 'integer' OR output_tokens < 0 OR output_tokens > 9007199254740991\n OR typeof(generation_duration_ms) NOT IN ('integer', 'real') OR NOT(generation_duration_ms > 0)\n OR generation_duration_ms > 1.7976931348623157e308 OR output_source NOT IN ('official','estimated')\n OR typeof(finished_at_ms) != 'integer' OR finished_at_ms < 0 OR finished_at_ms > 9007199254740991\n THEN 1 ELSE 0 END), 0) AS invalidSamples`;\n\n/** SQL is confined to the trusted access.db adapter callback. */\nexport function createObservationAdapter(observation: PluginObservationStorage): TpsObservationClient {\n return Object.freeze({\n async recordSample(sample: TpsSample): Promise<void> {\n validateSample(sample);\n observation.withDatabase(db => {\n db.transaction(() => {\n db.query(`INSERT OR IGNORE INTO llm_tps_samples\n (attempt_id, request_id, route_id, endpoint_id, finished_at_ms, output_tokens, generation_duration_ms, output_source)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(sample.attemptId, sample.requestId, sample.routeId, sample.endpointId,\n sample.finishedAtMs, sample.outputTokens, sample.generationDurationMs, sample.outputSource);\n db.query(`DELETE FROM llm_tps_samples WHERE attempt_id IN (\n SELECT attempt_id FROM llm_tps_samples INDEXED BY idx_llm_tps_samples_finished\n WHERE finished_at_ms < ? ORDER BY finished_at_ms LIMIT 500\n )`).run(Date.now() - TPS_RETENTION_MS);\n }).immediate();\n });\n },\n async queryStats(input: { range: TpsRange; asOfMs: number }): Promise<TpsStatsResponse> {\n safeCount(input.asOfMs, 'asOfMs');\n const start = input.asOfMs - rangeDuration(input.range);\n return observation.withDatabase(db => db.transaction(() => {\n const where = 'WHERE finished_at_ms >= ? AND finished_at_ms <= ?';\n const totalRow = db.query<Record<string, unknown>, [number, number]>(`SELECT ${metrics} FROM llm_tps_samples ${where}`).get(start, input.asOfMs)!;\n const rows = db.query<Record<string, unknown>, [number, number]>(`SELECT route_id AS routeId, endpoint_id AS endpointId, ${metrics}\n FROM llm_tps_samples ${where} GROUP BY route_id, endpoint_id`).all(start, input.asOfMs);\n const checked = (row: Record<string, unknown>) => {\n if (safeCount(row.invalidSamples, 'invalid sample count') !== 0) throw new RangeError('invalid persisted llm-tps sample');\n return aggregate(row);\n };\n const total = checked(totalRow);\n const endpoints = rows.map(row => {\n identifier(row.routeId, 'routeId'); identifier(row.endpointId, 'endpointId');\n if (isUrlIdentity(row.endpointId)) throw new TypeError('invalid persisted llm-tps endpoint');\n return { routeId: row.routeId, endpointId: row.endpointId, ...checked(row) };\n }).sort((a, b) => (b.tps! - a.tps!) || compare(a.routeId, b.routeId) || compare(a.endpointId, b.endpointId));\n return { range: input.range, asOfMs: input.asOfMs, total, endpoints, reportingIncomplete: false };\n })());\n },\n });\n}\n\nfunction compare(a: string, b: string): number { return a < b ? -1 : a > b ? 1 : 0; }\n",
|
|
8
|
+
"import type { ControlApiHandlerContext, ControlHostContext, ControlPlugin, PluginControl } from '@jeffusion/bungee-core/plugin';\nimport { TPS_REPORTING_INCOMPLETE_KEY, type TpsRange } from '../contract';\nimport { observationClient } from './storage';\nexport { createObservationAdapter } from './storage';\n\nclass ControlError extends Error {\n constructor(readonly code: 'disposed' | 'request_cancelled' | 'invalid_input') { super(code); }\n}\n\nfunction abortable<T>(operation: Promise<T>, signals: readonly AbortSignal[]): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const listeners: Array<() => void> = [];\n const cleanup = () => signals.forEach((signal, index) => signal.removeEventListener('abort', listeners[index]!));\n const fail = (index: number) => { cleanup(); reject(new ControlError(index < 3 ? 'disposed' : 'request_cancelled')); };\n signals.forEach((signal, index) => {\n const listener = () => fail(index); listeners.push(listener);\n signal.addEventListener('abort', listener, { once: true });\n });\n const cancelled = signals.findIndex(signal => signal.aborted);\n if (cancelled !== -1) fail(cancelled);\n operation.then(value => { cleanup(); resolve(value); }, error => { cleanup(); reject(error); });\n });\n}\n\nexport function createControl(host: ControlHostContext): PluginControl {\n const client = observationClient(host.storage);\n const disposal = new AbortController();\n let disposed = false;\n const assertAlive = (context?: ControlApiHandlerContext) => {\n if (disposed || host.signal.aborted || context?.signal.aborted) throw new ControlError('disposed');\n if (context?.requestSignal.aborted || context?.request.signal.aborted) throw new ControlError('request_cancelled');\n };\n const dispose = () => { disposed = true; disposal.abort(); host.signal.removeEventListener('abort', dispose); };\n host.signal.addEventListener('abort', dispose, { once: true });\n return {\n api: [{ path: '/stats', methods: ['GET'], handler: 'getStats', async invoke(context) {\n try {\n assertAlive(context);\n if (context.request.method !== 'GET') return Response.json({ error: 'method_not_allowed' }, { status: 405, headers: { allow: 'GET' } });\n const params = new URL(context.request.url).searchParams;\n const range = params.get('range') ?? '24h';\n if ([...params.keys()].some(key => key !== 'range') || params.getAll('range').length > 1\n || !['1h', '12h', '24h'].includes(range)) throw new ControlError('invalid_input');\n const readIncomplete = async () => {\n const storage = host.storage;\n const strict = storage.readStrict ? await storage.readStrict<unknown>(TPS_REPORTING_INCOMPLETE_KEY) : null;\n const value = strict === null ? await storage.get<unknown>(TPS_REPORTING_INCOMPLETE_KEY) : strict.found ? strict.value : null;\n if (value !== null && value !== false && value !== true) throw new Error('invalid reporting status');\n return value === true;\n };\n const [stats, incomplete] = await abortable(Promise.all([\n client.queryStats({ range: range as TpsRange, asOfMs: Date.now() }), readIncomplete(),\n ]), [disposal.signal, host.signal, context.signal, context.requestSignal, context.request.signal]);\n assertAlive(context);\n return Response.json({ ...stats, reportingIncomplete: stats.reportingIncomplete || incomplete });\n } catch (error) {\n const code = error instanceof ControlError ? error.code : 'storage_unavailable';\n const status = code === 'invalid_input' || code === 'request_cancelled' ? 400 : code === 'disposed' ? 409 : 503;\n return Response.json({ error: code }, { status });\n }\n } }],\n rpc: [],\n start() { assertAlive(); },\n dispose,\n };\n}\n\nexport default { createControl } satisfies ControlPlugin;\n"
|
|
9
|
+
],
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "6D69678B8F3EC90164756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/core/src/plugin-logger.ts
|
|
3
|
+
var sinkKey = Symbol.for("@jeffusion/bungee/plugin-log-sink");
|
|
4
|
+
function createLogger(bindings = {}) {
|
|
5
|
+
const method = (level) => (value, message) => {
|
|
6
|
+
const sink = globalThis[sinkKey];
|
|
7
|
+
if (sink) {
|
|
8
|
+
if (typeof value === "string")
|
|
9
|
+
sink[level](bindings, value);
|
|
10
|
+
else
|
|
11
|
+
sink[level]({ ...bindings, ...value }, message);
|
|
12
|
+
} else if (level !== "debug" || process.env.LOG_LEVEL === "debug") {
|
|
13
|
+
const write = level === "fatal" ? console.error : console[level];
|
|
14
|
+
write(message ?? (typeof value === "string" ? value : ""), typeof value === "string" ? bindings : { ...bindings, ...value });
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
return {
|
|
18
|
+
info: method("info"),
|
|
19
|
+
warn: method("warn"),
|
|
20
|
+
error: method("error"),
|
|
21
|
+
debug: method("debug"),
|
|
22
|
+
fatal: method("fatal"),
|
|
23
|
+
child: (extra) => createLogger({ ...bindings, ...extra })
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
var logger = createLogger();
|
|
27
|
+
|
|
28
|
+
// packages/core/src/hooks/impl.ts
|
|
29
|
+
var WATERFALL_VIEW_TRANSFORM = Symbol("waterfall-view-transform");
|
|
30
|
+
// packages/core/src/plugin.types.ts
|
|
31
|
+
function definePlugin(plugin) {
|
|
32
|
+
return plugin;
|
|
33
|
+
}
|
|
34
|
+
// packages/core/src/plugin-extensions.ts
|
|
35
|
+
var ANONYMOUS_PRINCIPAL = Object.freeze({ domain: "anonymous", keyId: "", credentialVersion: 0 });
|
|
36
|
+
// packages/core/src/plugin-durable-state.ts
|
|
37
|
+
var MAX_BYTES = 1024 * 1024;
|
|
38
|
+
// packages/core/src/plugin-services/host-rpc.ts
|
|
39
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
40
|
+
|
|
41
|
+
// packages/core/src/plugin-services/wire-contract.ts
|
|
42
|
+
var RPC_JSON_MAX_BYTES = 64 * 1024;
|
|
43
|
+
var RPC_CONTRACT_MAX_BYTES = 256 * 1024;
|
|
44
|
+
var RPC_CALL_PURPOSES = new Set(["bootstrap", "background", "management", "request", "attempt"]);
|
|
45
|
+
var RPC_COMMAND_DEDUPLICATION = new Set(["local-transaction", "external-contract", "none"]);
|
|
46
|
+
var RPC_COMMAND_POLICY_KEYS = new Set(["deduplication", "resultRetentionMs", "quotaBytes", "maxResultBytes"]);
|
|
47
|
+
|
|
48
|
+
// packages/core/src/plugin-services/rpc-runtime.ts
|
|
49
|
+
var PROCESSES = new Set(["control", "worker", "ingress"]);
|
|
50
|
+
var SCOPES = new Set(["global", "binding"]);
|
|
51
|
+
var PURPOSES = new Set(["bootstrap", "background", "management", "request", "attempt"]);
|
|
52
|
+
var ENDPOINTS = new WeakMap;
|
|
53
|
+
var REVOKED = new WeakMap;
|
|
54
|
+
|
|
55
|
+
// packages/core/src/plugin-services/host-rpc.ts
|
|
56
|
+
var SERVICE_ERROR_MESSAGES = {
|
|
57
|
+
unauthorized: "RPC call is not authorized",
|
|
58
|
+
not_ready: "RPC endpoint is not ready",
|
|
59
|
+
retired: "RPC endpoint is retiring",
|
|
60
|
+
revoked: "RPC endpoint generation was revoked",
|
|
61
|
+
unsupported_method: "RPC method is not published",
|
|
62
|
+
wrong_purpose: "RPC method is not published for this purpose",
|
|
63
|
+
invalid_input: "RPC input is not valid",
|
|
64
|
+
invalid_output: "RPC output is not valid",
|
|
65
|
+
invalid_operation_id: "RPC command operation id is invalid",
|
|
66
|
+
overloaded: "RPC runtime is at capacity",
|
|
67
|
+
cancelled: "RPC call was cancelled",
|
|
68
|
+
timeout: "RPC call deadline exceeded",
|
|
69
|
+
unknown: "RPC command outcome is unknown",
|
|
70
|
+
capability_unavailable: "RPC command execution is unavailable",
|
|
71
|
+
closed: "RPC runtime is closed",
|
|
72
|
+
failed: "RPC call failed",
|
|
73
|
+
conflict: "RPC command identity conflicts with an existing record",
|
|
74
|
+
expired: "RPC command result has expired",
|
|
75
|
+
pending: "RPC command is still pending",
|
|
76
|
+
rejected: "RPC command was rejected",
|
|
77
|
+
missing: "RPC command has no stored result",
|
|
78
|
+
storage_failure: "RPC command storage failed",
|
|
79
|
+
deadlock: "RPC call chain would deadlock",
|
|
80
|
+
call_depth_exceeded: "RPC call depth exceeded",
|
|
81
|
+
undeclared: "RPC service is not declared by the manifest",
|
|
82
|
+
unavailable: "RPC service is unavailable",
|
|
83
|
+
ambiguous_placement: "RPC service placement is ambiguous",
|
|
84
|
+
invalid_registration: "RPC registration is invalid"
|
|
85
|
+
};
|
|
86
|
+
var SERVICE_ERROR_CODES = new Set(Object.keys(SERVICE_ERROR_MESSAGES));
|
|
87
|
+
var EMPTY_OPTIONS = Object.freeze({});
|
|
88
|
+
var FRAME_STORE = new AsyncLocalStorage;
|
|
89
|
+
var CALLEE_INFO = new WeakMap;
|
|
90
|
+
// packages/core/src/plugin-services/peer-channel-protocol.ts
|
|
91
|
+
var CHANNEL_REQUEST_MAX_BYTES = 4 * 1024;
|
|
92
|
+
var CHANNEL_RESULT_MAX_BYTES = 60 * 1024;
|
|
93
|
+
var CHANNEL_MAX_CHUNK_BYTES = 60 * 1024;
|
|
94
|
+
var PLUGIN_CHANNEL_LANES = Object.freeze(["event", "snapshot", "stream"]);
|
|
95
|
+
var ERROR_CODES = new Set([
|
|
96
|
+
"unavailable",
|
|
97
|
+
"ambiguous",
|
|
98
|
+
"unauthorized",
|
|
99
|
+
"invalid",
|
|
100
|
+
"overloaded",
|
|
101
|
+
"expired",
|
|
102
|
+
"conflict",
|
|
103
|
+
"gap",
|
|
104
|
+
"truncated",
|
|
105
|
+
"rejected",
|
|
106
|
+
"cancelled",
|
|
107
|
+
"closed",
|
|
108
|
+
"unknown",
|
|
109
|
+
"failed"
|
|
110
|
+
]);
|
|
111
|
+
var RPC_CALL_PURPOSES2 = new Set(["bootstrap", "background", "management", "request", "attempt"]);
|
|
112
|
+
|
|
113
|
+
// packages/core/src/plugin-services/peer-channel-hub.ts
|
|
114
|
+
var CHANNEL_MAX_TRANSFER_BUFFER_BYTES = 4 * CHANNEL_MAX_CHUNK_BYTES;
|
|
115
|
+
var CHANNEL_MAX_TOTAL_BUFFER_BYTES = 16 * CHANNEL_MAX_CHUNK_BYTES;
|
|
116
|
+
var CHANNEL_STREAM_MAX_TOTAL_BYTES = 64 * 1024 * 1024;
|
|
117
|
+
var CHANNEL_STREAM_MAX_CREDIT_BYTES = 8 * CHANNEL_MAX_CHUNK_BYTES;
|
|
118
|
+
var CHANNEL_STREAM_DEFAULT_CREDIT_BYTES = 4 * CHANNEL_MAX_CHUNK_BYTES;
|
|
119
|
+
var CHANNEL_SNAPSHOT_MAX_BYTES = 64 * 1024 * 1024;
|
|
120
|
+
var CHANNEL_EVENT_MAX_PAYLOAD_BYTES = 60 * 1024;
|
|
121
|
+
var EMPTY = new Uint8Array(0);
|
|
122
|
+
var HANDLE_REGISTRATIONS = new WeakMap;
|
|
123
|
+
|
|
124
|
+
// packages/core/src/plugin-services/snapshot-store.ts
|
|
125
|
+
var DEFAULT_CHUNK_BYTES = 60 * 1024;
|
|
126
|
+
var SNAPSHOT_FAMILY_REFS = new Map;
|
|
127
|
+
|
|
128
|
+
// packages/core/src/plugin-services.ts
|
|
129
|
+
var CHANNEL_KINDS = new Set(["events", "snapshot", "stream"]);
|
|
130
|
+
var TOKEN_METERING_SERVICE_ID = "token-metering.v1";
|
|
131
|
+
var TOKEN_METERING_CONTRACT_VERSION = 1;
|
|
132
|
+
// packages/core/src/gateway/retry-action.ts
|
|
133
|
+
var retryActionBrand = Symbol.for("@jeffusion/bungee/request-retry-action");
|
|
134
|
+
// packages/core/src/token-stats-window.ts
|
|
135
|
+
var HOUR = 3600000;
|
|
136
|
+
var TOKEN_STATS_RETENTION_MS = 31 * 24 * HOUR;
|
|
137
|
+
// plugins/llm-tps/contract.ts
|
|
138
|
+
var TPS_RETENTION_MS = 31 * 24 * 60 * 60 * 1000;
|
|
139
|
+
var TPS_REPORTING_INCOMPLETE_KEY = "reporting:incomplete";
|
|
140
|
+
|
|
141
|
+
// plugins/llm-tps/server/metrics.ts
|
|
142
|
+
import { createHash } from "crypto";
|
|
143
|
+
function isUrlIdentity(value) {
|
|
144
|
+
return /^(?:[a-z][a-z\d+.-]*:)?\/\//i.test(value);
|
|
145
|
+
}
|
|
146
|
+
function endpointIdentity(upstreamId) {
|
|
147
|
+
return isUrlIdentity(upstreamId) ? `endpoint-${createHash("sha256").update(upstreamId).digest("hex").slice(0, 16)}` : upstreamId;
|
|
148
|
+
}
|
|
149
|
+
function safeCount(value, name) {
|
|
150
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
|
|
151
|
+
throw new RangeError(`invalid llm-tps ${name}`);
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
function identifier(value, name) {
|
|
155
|
+
if (typeof value !== "string" || !value.trim())
|
|
156
|
+
throw new TypeError(`invalid llm-tps ${name}`);
|
|
157
|
+
}
|
|
158
|
+
function validateSample(sample) {
|
|
159
|
+
for (const key of ["attemptId", "requestId", "routeId", "endpointId"])
|
|
160
|
+
identifier(sample[key], key);
|
|
161
|
+
if (isUrlIdentity(sample.endpointId))
|
|
162
|
+
throw new TypeError("llm-tps endpoint must be opaque");
|
|
163
|
+
safeCount(sample.finishedAtMs, "finishedAtMs");
|
|
164
|
+
safeCount(sample.outputTokens, "outputTokens");
|
|
165
|
+
if (!Number.isFinite(sample.generationDurationMs) || sample.generationDurationMs <= 0)
|
|
166
|
+
throw new RangeError("invalid llm-tps duration");
|
|
167
|
+
if (sample.outputSource !== "official" && sample.outputSource !== "estimated")
|
|
168
|
+
throw new TypeError("invalid llm-tps output source");
|
|
169
|
+
if (!Number.isFinite(sample.outputTokens / sample.generationDurationMs * 1000))
|
|
170
|
+
throw new RangeError("invalid llm-tps rate");
|
|
171
|
+
}
|
|
172
|
+
function sampleFromResult(result, routeId) {
|
|
173
|
+
const output = result.generationOutput;
|
|
174
|
+
if (result.routeId !== routeId || !output || output.source !== "official" && output.source !== "estimated" || !Number.isSafeInteger(output.tokens) || output.tokens < 0 || !Number.isFinite(result.generationDurationMs) || result.generationDurationMs <= 0)
|
|
175
|
+
return null;
|
|
176
|
+
const sample = {
|
|
177
|
+
attemptId: result.attemptId,
|
|
178
|
+
requestId: result.requestId,
|
|
179
|
+
routeId: result.routeId,
|
|
180
|
+
endpointId: endpointIdentity(result.upstreamId),
|
|
181
|
+
finishedAtMs: result.finishedAtMs,
|
|
182
|
+
outputTokens: output.tokens,
|
|
183
|
+
generationDurationMs: result.generationDurationMs,
|
|
184
|
+
outputSource: output.source
|
|
185
|
+
};
|
|
186
|
+
validateSample(sample);
|
|
187
|
+
return sample;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// plugins/llm-tps/server/storage.ts
|
|
191
|
+
function observationClient(storage) {
|
|
192
|
+
if (typeof storage.invokeObservation !== "function")
|
|
193
|
+
throw new Error("llm-tps observation storage is unavailable");
|
|
194
|
+
const invoke = storage.invokeObservation.bind(storage);
|
|
195
|
+
return {
|
|
196
|
+
recordSample: (sample) => invoke("recordSample", [sample]),
|
|
197
|
+
queryStats: (input) => invoke("queryStats", [input])
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// plugins/llm-tps/server/index.ts
|
|
202
|
+
var MAX_PENDING = 256;
|
|
203
|
+
var LlmTpsPlugin = definePlugin(class {
|
|
204
|
+
static name = "llm-tps";
|
|
205
|
+
static version = "1.0.0";
|
|
206
|
+
unsubscribe;
|
|
207
|
+
accepting = false;
|
|
208
|
+
pending = 0;
|
|
209
|
+
writes = Promise.resolve();
|
|
210
|
+
reportingWrite;
|
|
211
|
+
reportingPersisted = false;
|
|
212
|
+
bodyRequirements() {
|
|
213
|
+
return { request: "none" };
|
|
214
|
+
}
|
|
215
|
+
register(_hooks) {}
|
|
216
|
+
async init(context) {
|
|
217
|
+
if (context.scope?.type !== "route" || !context.scope.routeId?.trim())
|
|
218
|
+
throw new Error("llm-tps requires a route binding");
|
|
219
|
+
if (!context.services)
|
|
220
|
+
throw new Error("llm-tps requires token-metering service");
|
|
221
|
+
const client = observationClient(context.storage);
|
|
222
|
+
const storage = context.storage.uncached?.() ?? context.storage;
|
|
223
|
+
const metering = context.services.consume("token-metering", TOKEN_METERING_SERVICE_ID, TOKEN_METERING_CONTRACT_VERSION);
|
|
224
|
+
const routeId = context.scope.routeId;
|
|
225
|
+
const incomplete = () => {
|
|
226
|
+
if (this.reportingPersisted || this.reportingWrite)
|
|
227
|
+
return;
|
|
228
|
+
this.reportingWrite = Promise.resolve().then(() => storage.set(TPS_REPORTING_INCOMPLETE_KEY, true)).then(() => {
|
|
229
|
+
this.reportingPersisted = true;
|
|
230
|
+
}).catch(() => {
|
|
231
|
+
try {
|
|
232
|
+
context.logger.error("llm-tps could not persist incomplete reporting status");
|
|
233
|
+
} catch {}
|
|
234
|
+
}).finally(() => {
|
|
235
|
+
this.reportingWrite = undefined;
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
this.accepting = true;
|
|
239
|
+
this.unsubscribe = metering.subscribe({
|
|
240
|
+
onResult: (result) => {
|
|
241
|
+
if (!this.accepting || result.routeId !== routeId)
|
|
242
|
+
return;
|
|
243
|
+
try {
|
|
244
|
+
if (result.observationIncomplete && result.generationDurationMs === undefined)
|
|
245
|
+
incomplete();
|
|
246
|
+
const sample = sampleFromResult(result, routeId);
|
|
247
|
+
if (!sample)
|
|
248
|
+
return;
|
|
249
|
+
if (this.pending >= MAX_PENDING) {
|
|
250
|
+
incomplete();
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
this.pending++;
|
|
254
|
+
this.writes = this.writes.then(() => client.recordSample(sample)).catch(incomplete).finally(() => {
|
|
255
|
+
this.pending--;
|
|
256
|
+
});
|
|
257
|
+
} catch {
|
|
258
|
+
incomplete();
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
onFailure: (_error, result) => {
|
|
262
|
+
if (this.accepting && result.routeId === routeId)
|
|
263
|
+
incomplete();
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
context.services.onDispose(() => this.stopAccepting());
|
|
267
|
+
}
|
|
268
|
+
stopAccepting() {
|
|
269
|
+
this.accepting = false;
|
|
270
|
+
const unsubscribe = this.unsubscribe;
|
|
271
|
+
this.unsubscribe = undefined;
|
|
272
|
+
unsubscribe?.();
|
|
273
|
+
}
|
|
274
|
+
async onDestroy() {
|
|
275
|
+
this.stopAccepting();
|
|
276
|
+
await this.writes;
|
|
277
|
+
await this.reportingWrite;
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
var server_default = LlmTpsPlugin;
|
|
281
|
+
export {
|
|
282
|
+
LlmTpsPlugin,
|
|
283
|
+
server_default as default
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
//# debugId=32378BFF08D1414E64756E2164756E21
|