aweshare 0.4.4 → 0.4.6
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 +19 -6
- package/apps/agent/dist/cli.js +33 -3
- package/apps/agent/dist/cli.js.map +1 -1
- package/apps/agent/dist/config.d.ts +5 -25
- package/apps/agent/dist/config.js +7 -110
- package/apps/agent/dist/config.js.map +1 -1
- package/apps/agent/dist/connection.d.ts +5 -11
- package/apps/agent/dist/connection.js +49 -128
- package/apps/agent/dist/connection.js.map +1 -1
- package/apps/agent/dist/doctor.js +1 -2
- package/apps/agent/dist/doctor.js.map +1 -1
- package/apps/agent/dist/hub.d.ts +3 -0
- package/apps/agent/dist/hub.js.map +1 -1
- package/apps/agent/dist/index.d.ts +1 -3
- package/apps/agent/dist/index.js +1 -3
- package/apps/agent/dist/index.js.map +1 -1
- package/apps/agent/dist/table.d.ts +14 -0
- package/apps/agent/dist/table.js +28 -1
- package/apps/agent/dist/table.js.map +1 -1
- package/apps/agent/package.json +2 -1
- package/apps/consumer/dist/cli.js +4 -2
- package/apps/consumer/dist/cli.js.map +1 -1
- package/apps/consumer/dist/table.d.ts +5 -0
- package/apps/consumer/dist/table.js +2 -0
- package/apps/consumer/dist/table.js.map +1 -1
- package/apps/consumer/package.json +1 -1
- package/apps/hub/dist/admin.d.ts +7 -0
- package/apps/hub/dist/admin.js +3 -2
- package/apps/hub/dist/admin.js.map +1 -1
- package/apps/hub/dist/cli.js +44 -3
- package/apps/hub/dist/cli.js.map +1 -1
- package/apps/hub/dist/config.d.ts +3 -1
- package/apps/hub/dist/config.js +27 -0
- package/apps/hub/dist/config.js.map +1 -1
- package/apps/hub/dist/consumer.d.ts +20 -4
- package/apps/hub/dist/consumer.js +42 -16
- package/apps/hub/dist/consumer.js.map +1 -1
- package/apps/hub/dist/db.d.ts +15 -1
- package/apps/hub/dist/db.js +34 -4
- package/apps/hub/dist/db.js.map +1 -1
- package/apps/hub/dist/limiter.d.ts +5 -0
- package/apps/hub/dist/limiter.js +15 -0
- package/apps/hub/dist/limiter.js.map +1 -1
- package/apps/hub/dist/local.d.ts +105 -0
- package/apps/hub/dist/local.js +414 -0
- package/apps/hub/dist/local.js.map +1 -0
- package/apps/hub/dist/server.d.ts +3 -0
- package/apps/hub/dist/server.js +15 -3
- package/apps/hub/dist/server.js.map +1 -1
- package/apps/hub/dist/table.d.ts +15 -0
- package/apps/hub/dist/table.js +19 -1
- package/apps/hub/dist/table.js.map +1 -1
- package/apps/hub/dist/tunnel.d.ts +23 -1
- package/apps/hub/dist/tunnel.js.map +1 -1
- package/apps/hub/package.json +2 -1
- package/bin/aweshare.mjs +1 -1
- package/package.json +3 -2
- package/packages/producer-core/dist/adapters.d.ts +23 -0
- package/{apps/agent → packages/producer-core}/dist/adapters.js +1 -1
- package/packages/producer-core/dist/adapters.js.map +1 -0
- package/packages/producer-core/dist/catalog.d.ts +39 -0
- package/packages/producer-core/dist/catalog.js +121 -0
- package/packages/producer-core/dist/catalog.js.map +1 -0
- package/packages/producer-core/dist/index.d.ts +5 -0
- package/packages/producer-core/dist/index.js +6 -0
- package/packages/producer-core/dist/index.js.map +1 -0
- package/packages/producer-core/dist/job.d.ts +44 -0
- package/packages/producer-core/dist/job.js +92 -0
- package/packages/producer-core/dist/job.js.map +1 -0
- package/packages/producer-core/dist/probe.d.ts +6 -0
- package/packages/producer-core/dist/probe.js +30 -0
- package/packages/producer-core/dist/probe.js.map +1 -0
- package/apps/agent/dist/adapters.d.ts +0 -15
- package/apps/agent/dist/adapters.js.map +0 -1
- /package/{apps/agent → packages/producer-core}/dist/health.d.ts +0 -0
- /package/{apps/agent → packages/producer-core}/dist/health.js +0 -0
- /package/{apps/agent → packages/producer-core}/dist/health.js.map +0 -0
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
3
|
+
import { existsSync, readFileSync, unwatchFile, watchFile } from 'node:fs';
|
|
4
|
+
import { classifyStatus, HealthGate, parseCatalog, probeBody, probeTarget, UpstreamJob, } from '../../../packages/producer-core/dist/index.js';
|
|
5
|
+
import { parse as parseToml } from 'smol-toml';
|
|
6
|
+
import { ensureLocalProducer, LOCAL_PRODUCER_ID, LOCAL_PRODUCER_NAME, upsertOfferings, } from './db.js';
|
|
7
|
+
import { HttpError } from './http.js';
|
|
8
|
+
import { statusForCode } from './tunnel.js';
|
|
9
|
+
const PROBE_INTERVAL_MS = 30_000;
|
|
10
|
+
const MAX_LOCAL_OFFERINGS = 256; // same cap the tunnel enforces per register
|
|
11
|
+
/**
|
|
12
|
+
* One in-process dispatched consumer request: shared upstream job + response
|
|
13
|
+
* pump. Same event, timer and buffering semantics as TunnelRequest, so
|
|
14
|
+
* handleInference treats the two relays identically. pauseInput/resumeInput
|
|
15
|
+
* gate the job's read loop — a held sink.chunk promise is backpressure.
|
|
16
|
+
*/
|
|
17
|
+
export class LocalRelay extends EventEmitter {
|
|
18
|
+
backend;
|
|
19
|
+
health;
|
|
20
|
+
init;
|
|
21
|
+
config;
|
|
22
|
+
log;
|
|
23
|
+
requestId = randomUUID().replaceAll('-', '');
|
|
24
|
+
startedAt = Date.now();
|
|
25
|
+
bytesOut = 0;
|
|
26
|
+
job = null;
|
|
27
|
+
result = {
|
|
28
|
+
status: null,
|
|
29
|
+
errorCode: null,
|
|
30
|
+
canceled: false,
|
|
31
|
+
durationMs: 0,
|
|
32
|
+
bytesOut: 0,
|
|
33
|
+
};
|
|
34
|
+
finished = false;
|
|
35
|
+
headArrived = false;
|
|
36
|
+
streamingStarted = false;
|
|
37
|
+
bufferedChunks = [];
|
|
38
|
+
pendingEnd = false;
|
|
39
|
+
headTimer = null;
|
|
40
|
+
idleTimer = null;
|
|
41
|
+
paused = false;
|
|
42
|
+
resumeWaiters = [];
|
|
43
|
+
headPromise;
|
|
44
|
+
resolveHead;
|
|
45
|
+
rejectHead;
|
|
46
|
+
finishedPromise;
|
|
47
|
+
settleFinished;
|
|
48
|
+
constructor(backend, health, init, config, log) {
|
|
49
|
+
super();
|
|
50
|
+
this.backend = backend;
|
|
51
|
+
this.health = health;
|
|
52
|
+
this.init = init;
|
|
53
|
+
this.config = config;
|
|
54
|
+
this.log = log;
|
|
55
|
+
this.headPromise = new Promise((resolve, reject) => {
|
|
56
|
+
this.resolveHead = resolve;
|
|
57
|
+
this.rejectHead = reject;
|
|
58
|
+
});
|
|
59
|
+
this.finishedPromise = new Promise((resolve) => {
|
|
60
|
+
this.settleFinished = resolve;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
dispatch() {
|
|
64
|
+
this.headTimer = setTimeout(() => this.fail('BACKEND_TIMEOUT', 'no response head from upstream', 504), this.config.headTimeoutMs);
|
|
65
|
+
// fire-and-forget: every settle path flows back through the sink
|
|
66
|
+
this.job = new UpstreamJob({
|
|
67
|
+
backend: this.backend,
|
|
68
|
+
health: this.health,
|
|
69
|
+
log: this.log,
|
|
70
|
+
id: this.requestId,
|
|
71
|
+
init: {
|
|
72
|
+
method: this.init.method,
|
|
73
|
+
path: this.init.path,
|
|
74
|
+
query: this.init.query,
|
|
75
|
+
headers: this.init.headers,
|
|
76
|
+
body: this.init.body,
|
|
77
|
+
},
|
|
78
|
+
sink: {
|
|
79
|
+
head: (status, headers) => this.handleHead(status, headers),
|
|
80
|
+
chunk: async (bytes) => {
|
|
81
|
+
this.handleChunk(bytes);
|
|
82
|
+
await this.waitWhilePaused();
|
|
83
|
+
},
|
|
84
|
+
end: () => this.handleEnd(),
|
|
85
|
+
error: (code, message) => this.handleError(code, message),
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
void this.job.execute();
|
|
89
|
+
return Promise.resolve();
|
|
90
|
+
}
|
|
91
|
+
waitHead() {
|
|
92
|
+
return this.headPromise;
|
|
93
|
+
}
|
|
94
|
+
startStreaming() {
|
|
95
|
+
this.streamingStarted = true;
|
|
96
|
+
for (const chunk of this.bufferedChunks)
|
|
97
|
+
this.emit('chunk', chunk);
|
|
98
|
+
this.bufferedChunks = [];
|
|
99
|
+
if (this.pendingEnd) {
|
|
100
|
+
this.pendingEnd = false;
|
|
101
|
+
this.emit('end');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
waitFinished() {
|
|
105
|
+
return this.finishedPromise;
|
|
106
|
+
}
|
|
107
|
+
cancel() {
|
|
108
|
+
if (this.finished)
|
|
109
|
+
return;
|
|
110
|
+
this.job?.abort();
|
|
111
|
+
this.finalize({ errorCode: 'REQUEST_CANCELED', canceled: true });
|
|
112
|
+
}
|
|
113
|
+
pauseInput() {
|
|
114
|
+
this.paused = true;
|
|
115
|
+
}
|
|
116
|
+
resumeInput() {
|
|
117
|
+
this.paused = false;
|
|
118
|
+
const waiters = this.resumeWaiters;
|
|
119
|
+
this.resumeWaiters = [];
|
|
120
|
+
for (const w of waiters)
|
|
121
|
+
w();
|
|
122
|
+
}
|
|
123
|
+
async waitWhilePaused() {
|
|
124
|
+
while (this.paused && !this.finished) {
|
|
125
|
+
await new Promise((resolve) => this.resumeWaiters.push(resolve));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
handleHead(status, headers) {
|
|
129
|
+
if (this.finished || this.headArrived)
|
|
130
|
+
return;
|
|
131
|
+
this.headArrived = true;
|
|
132
|
+
this.clearTimers();
|
|
133
|
+
this.result.status = status;
|
|
134
|
+
this.armIdleTimer();
|
|
135
|
+
this.resolveHead({ status, headers });
|
|
136
|
+
this.emit('head', status, headers);
|
|
137
|
+
}
|
|
138
|
+
handleChunk(payload) {
|
|
139
|
+
if (this.finished || !this.headArrived)
|
|
140
|
+
return;
|
|
141
|
+
this.bytesOut += payload.byteLength;
|
|
142
|
+
this.result.bytesOut = this.bytesOut;
|
|
143
|
+
this.armIdleTimer();
|
|
144
|
+
if (this.streamingStarted)
|
|
145
|
+
this.emit('chunk', payload);
|
|
146
|
+
else
|
|
147
|
+
this.bufferedChunks.push(payload);
|
|
148
|
+
}
|
|
149
|
+
handleEnd() {
|
|
150
|
+
if (this.finished)
|
|
151
|
+
return;
|
|
152
|
+
this.clearTimers();
|
|
153
|
+
if (!this.headArrived) {
|
|
154
|
+
// impossible from fetch (head resolves before the body iterates) — kept
|
|
155
|
+
// as a guard mirroring TunnelRequest
|
|
156
|
+
this.fail('TUNNEL_CLOSED', 'upstream ended request without a response head', 502);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
this.finalize({});
|
|
160
|
+
if (this.streamingStarted)
|
|
161
|
+
this.emit('end');
|
|
162
|
+
else
|
|
163
|
+
this.pendingEnd = true;
|
|
164
|
+
}
|
|
165
|
+
handleError(code, message) {
|
|
166
|
+
if (this.finished)
|
|
167
|
+
return;
|
|
168
|
+
this.fail(code, message, statusForCode(code));
|
|
169
|
+
}
|
|
170
|
+
fail(code, message, status) {
|
|
171
|
+
this.clearTimers();
|
|
172
|
+
this.job?.abort();
|
|
173
|
+
if (!this.headArrived) {
|
|
174
|
+
this.rejectHead({ code, message, status });
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
this.emit('error', { code, message, status });
|
|
178
|
+
}
|
|
179
|
+
this.finalize({ errorCode: code });
|
|
180
|
+
}
|
|
181
|
+
finalize(overrides) {
|
|
182
|
+
if (this.finished)
|
|
183
|
+
return;
|
|
184
|
+
this.finished = true;
|
|
185
|
+
this.clearTimers();
|
|
186
|
+
this.result.durationMs = Date.now() - this.startedAt;
|
|
187
|
+
if (overrides.errorCode !== undefined)
|
|
188
|
+
this.result.errorCode = overrides.errorCode;
|
|
189
|
+
if (overrides.canceled)
|
|
190
|
+
this.result.canceled = true;
|
|
191
|
+
// unblock a paused read loop so the job can wind down
|
|
192
|
+
this.resumeInput();
|
|
193
|
+
if (!this.headArrived) {
|
|
194
|
+
const code = this.result.errorCode ?? 'REQUEST_CANCELED';
|
|
195
|
+
this.rejectHead({
|
|
196
|
+
code,
|
|
197
|
+
message: `request ended before response head (${code})`,
|
|
198
|
+
status: statusForCode(code),
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
this.settleFinished(this.result);
|
|
202
|
+
}
|
|
203
|
+
armIdleTimer() {
|
|
204
|
+
if (this.idleTimer)
|
|
205
|
+
clearTimeout(this.idleTimer);
|
|
206
|
+
this.idleTimer = setTimeout(() => {
|
|
207
|
+
this.fail('STREAM_IDLE_TIMEOUT', 'response stream idle', statusForCode('STREAM_IDLE_TIMEOUT'));
|
|
208
|
+
}, this.config.idleTimeoutMs);
|
|
209
|
+
}
|
|
210
|
+
clearTimers() {
|
|
211
|
+
if (this.headTimer)
|
|
212
|
+
clearTimeout(this.headTimer);
|
|
213
|
+
if (this.idleTimer)
|
|
214
|
+
clearTimeout(this.idleTimer);
|
|
215
|
+
this.headTimer = null;
|
|
216
|
+
this.idleTimer = null;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* The hub's built-in producer: backends and offerings live in the hub's own
|
|
221
|
+
* config.toml ([[backends]]/[[offerings]] sections, producer format) with
|
|
222
|
+
* upstream keys in secrets.json. Catalog rows sit under the reserved producer
|
|
223
|
+
* id 0 / name 'hub', so caps, daily tokens, usage metering and the catalog
|
|
224
|
+
* apply unchanged; requests dispatch in-process — no tunnel, no self-dial.
|
|
225
|
+
* Config edits hot-reload (stat-poll, like every other config consumer).
|
|
226
|
+
*/
|
|
227
|
+
export class LocalProducer {
|
|
228
|
+
deps;
|
|
229
|
+
backends = new Map();
|
|
230
|
+
health = new HealthGate();
|
|
231
|
+
probeTimer = null;
|
|
232
|
+
reloadTimer = null;
|
|
233
|
+
watchers = [];
|
|
234
|
+
constructor(deps) {
|
|
235
|
+
this.deps = deps;
|
|
236
|
+
}
|
|
237
|
+
/** Load the catalog, register it, install the hot-reload watcher. Throws on
|
|
238
|
+
* a broken catalog (fail fast at startup); a no-op when the config carries
|
|
239
|
+
* no catalog sections. */
|
|
240
|
+
start() {
|
|
241
|
+
const seeded = ensureLocalProducer(this.deps.db);
|
|
242
|
+
const catalog = this.loadCatalog();
|
|
243
|
+
if (!seeded && catalog.offerings.length > 0) {
|
|
244
|
+
throw new Error(`the reserved name '${LOCAL_PRODUCER_NAME}' is taken by a real producer — rename that producer before serving hub-local offerings`);
|
|
245
|
+
}
|
|
246
|
+
this.apply(catalog);
|
|
247
|
+
if (catalog.offerings.length > 0 || catalog.backends.length > 0) {
|
|
248
|
+
this.deps.log.info({ offerings: catalog.offerings.length, backends: catalog.backends.length }, 'local producer ready — hub-local offerings served in-process');
|
|
249
|
+
}
|
|
250
|
+
this.installWatcher();
|
|
251
|
+
this.probeTimer = setInterval(() => void this.probeDegraded(), PROBE_INTERVAL_MS);
|
|
252
|
+
this.probeTimer.unref();
|
|
253
|
+
}
|
|
254
|
+
/** Status for hub-owned catalog rows — the local twin of Tunnel.offeringStatus. */
|
|
255
|
+
offeringStatus(offering) {
|
|
256
|
+
if (this.health.isDegraded(offering.backend_id))
|
|
257
|
+
return 'degraded';
|
|
258
|
+
return this.backends.has(offering.backend_id) ? 'online' : 'offline';
|
|
259
|
+
}
|
|
260
|
+
/** Admission-time check, the local twin of the tunnel session lookup:
|
|
261
|
+
* throws the same 503s a missing/degraded tunnel would. */
|
|
262
|
+
check(offering) {
|
|
263
|
+
if (this.health.isDegraded(offering.backend_id)) {
|
|
264
|
+
throw new HttpError(503, 'BACKEND_DEGRADED', `backend for ${offering.alias} is degraded`);
|
|
265
|
+
}
|
|
266
|
+
if (!this.backends.has(offering.backend_id)) {
|
|
267
|
+
throw new HttpError(503, 'PRODUCER_OFFLINE', `backend for ${offering.alias} is no longer configured`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
openRequest(offering, init) {
|
|
271
|
+
const backend = this.backends.get(offering.backend_id);
|
|
272
|
+
if (!backend) {
|
|
273
|
+
// check() ran at admission; a mid-flight catalog swap can still race us
|
|
274
|
+
throw new HttpError(503, 'PRODUCER_OFFLINE', `backend for ${offering.alias} is no longer configured`);
|
|
275
|
+
}
|
|
276
|
+
return new LocalRelay(backend, this.health, init, this.deps.config, this.deps.log);
|
|
277
|
+
}
|
|
278
|
+
/** Re-read config + secrets; valid -> swap in place, broken -> keep serving. */
|
|
279
|
+
reload(source) {
|
|
280
|
+
try {
|
|
281
|
+
const catalog = this.loadCatalog();
|
|
282
|
+
this.apply(catalog);
|
|
283
|
+
this.deps.log.info({ source, offerings: catalog.offerings.length }, `local catalog reloaded (${source})`);
|
|
284
|
+
}
|
|
285
|
+
catch (err) {
|
|
286
|
+
this.deps.log.error({ err }, 'local catalog reload failed — keeping previous values');
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
close() {
|
|
290
|
+
if (this.probeTimer)
|
|
291
|
+
clearInterval(this.probeTimer);
|
|
292
|
+
this.probeTimer = null;
|
|
293
|
+
if (this.reloadTimer)
|
|
294
|
+
clearTimeout(this.reloadTimer);
|
|
295
|
+
this.reloadTimer = null;
|
|
296
|
+
for (const [file, listener] of this.watchers)
|
|
297
|
+
unwatchFile(file, listener);
|
|
298
|
+
this.watchers = [];
|
|
299
|
+
}
|
|
300
|
+
/** Read + validate the catalog half of config.toml. Throws naming every
|
|
301
|
+
* problem (same rules as a producer's config). */
|
|
302
|
+
loadCatalog() {
|
|
303
|
+
const { paths } = this.deps;
|
|
304
|
+
let raw = {};
|
|
305
|
+
if (paths.configFile && existsSync(paths.configFile)) {
|
|
306
|
+
try {
|
|
307
|
+
raw = parseToml(readFileSync(paths.configFile, 'utf8'));
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
throw new Error(`${paths.configFile} is not valid TOML: ${err instanceof Error ? err.message : err}`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
let secrets = {};
|
|
314
|
+
if (paths.secretsFile && existsSync(paths.secretsFile)) {
|
|
315
|
+
try {
|
|
316
|
+
secrets = JSON.parse(readFileSync(paths.secretsFile, 'utf8'));
|
|
317
|
+
}
|
|
318
|
+
catch (err) {
|
|
319
|
+
throw new Error(`${paths.secretsFile} is not valid JSON: ${err instanceof Error ? err.message : err}`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (raw.backends === undefined && raw.offerings === undefined) {
|
|
323
|
+
return { offerings: [], backends: [] };
|
|
324
|
+
}
|
|
325
|
+
const { catalog, problems } = parseCatalog(raw, secrets);
|
|
326
|
+
const offerings = this.toRegistrations(catalog, problems);
|
|
327
|
+
if (problems.length > 0) {
|
|
328
|
+
throw new Error(`hub-local catalog has problems:\n - ${problems.join('\n - ')}`);
|
|
329
|
+
}
|
|
330
|
+
const backends = catalog.backends.map((b) => ({
|
|
331
|
+
...b,
|
|
332
|
+
apiKey: b.keyRef ? secrets[b.keyRef] : undefined,
|
|
333
|
+
}));
|
|
334
|
+
return { offerings, backends };
|
|
335
|
+
}
|
|
336
|
+
/** Namespace enforcement + Offering rows for the offerings cache. Bare
|
|
337
|
+
* names get the reserved 'hub/' prefix, like the tunnel does per producer. */
|
|
338
|
+
toRegistrations(catalog, problems) {
|
|
339
|
+
const protocolOf = new Map(catalog.backends.map((b) => [b.id, b.protocol]));
|
|
340
|
+
const rows = [];
|
|
341
|
+
for (const o of catalog.offerings) {
|
|
342
|
+
const alias = o.alias.includes('/') ? o.alias : `${LOCAL_PRODUCER_NAME}/${o.alias}`;
|
|
343
|
+
if (!alias.startsWith(`${LOCAL_PRODUCER_NAME}/`)) {
|
|
344
|
+
problems.push(`offering '${o.alias}': hub-local aliases must live under the reserved namespace '${LOCAL_PRODUCER_NAME}/'`);
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
const protocol = protocolOf.get(o.backend);
|
|
348
|
+
if (!protocol)
|
|
349
|
+
continue; // unknown backend — parseCatalog already flagged it
|
|
350
|
+
rows.push({
|
|
351
|
+
alias,
|
|
352
|
+
protocol,
|
|
353
|
+
upstreamModel: o.upstreamModel,
|
|
354
|
+
backendId: o.backend,
|
|
355
|
+
maxConcurrencyPerUser: o.maxConcurrencyPerUser,
|
|
356
|
+
...(o.maxConcurrentUsers !== undefined && { maxConcurrentUsers: o.maxConcurrentUsers }),
|
|
357
|
+
...(o.dailyTokens !== undefined && { dailyTokens: o.dailyTokens }),
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
if (rows.length > MAX_LOCAL_OFFERINGS) {
|
|
361
|
+
problems.push(`too many hub-local offerings (max ${MAX_LOCAL_OFFERINGS})`);
|
|
362
|
+
}
|
|
363
|
+
return rows;
|
|
364
|
+
}
|
|
365
|
+
apply(catalog) {
|
|
366
|
+
// register first, swap second: a request admitted between the two sees the
|
|
367
|
+
// row and the backend together or neither
|
|
368
|
+
upsertOfferings(this.deps.db, LOCAL_PRODUCER_ID, catalog.offerings);
|
|
369
|
+
this.backends = new Map(catalog.backends.map((b) => [b.id, b]));
|
|
370
|
+
}
|
|
371
|
+
installWatcher() {
|
|
372
|
+
// stat-poll (not inotify) so Docker bind mounts and network volumes work;
|
|
373
|
+
// debounce lets an editor's write-rename settle. Mirrors the agent's watcher.
|
|
374
|
+
for (const file of [this.deps.paths.configFile, this.deps.paths.secretsFile]) {
|
|
375
|
+
if (typeof file !== 'string')
|
|
376
|
+
continue;
|
|
377
|
+
const listener = (curr, prev) => {
|
|
378
|
+
if (prev.mtimeMs === 0 || curr.mtimeMs === prev.mtimeMs)
|
|
379
|
+
return;
|
|
380
|
+
if (this.reloadTimer !== null)
|
|
381
|
+
return;
|
|
382
|
+
this.reloadTimer = setTimeout(() => {
|
|
383
|
+
this.reloadTimer = null;
|
|
384
|
+
this.reload('file changed');
|
|
385
|
+
}, 500);
|
|
386
|
+
};
|
|
387
|
+
watchFile(file, { interval: 2000 }, listener);
|
|
388
|
+
this.watchers.push([file, listener]);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
/** Minimal live probe for degraded backends; success clears the state. */
|
|
392
|
+
async probeDegraded() {
|
|
393
|
+
for (const backend of this.backends.values()) {
|
|
394
|
+
if (!this.health.isDegraded(backend.id))
|
|
395
|
+
continue;
|
|
396
|
+
try {
|
|
397
|
+
const { url, headers } = probeTarget(backend);
|
|
398
|
+
const resp = await fetch(url, {
|
|
399
|
+
method: 'POST',
|
|
400
|
+
headers,
|
|
401
|
+
body: JSON.stringify(probeBody('ping', backend.protocol)),
|
|
402
|
+
signal: AbortSignal.timeout(10_000),
|
|
403
|
+
});
|
|
404
|
+
const reason = classifyStatus(resp.status);
|
|
405
|
+
this.health.record(backend.id, reason === null, reason ?? undefined);
|
|
406
|
+
await resp.arrayBuffer().catch(() => undefined);
|
|
407
|
+
}
|
|
408
|
+
catch {
|
|
409
|
+
this.health.record(backend.id, false, 'NETWORK');
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
//# sourceMappingURL=local.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.js","sourceRoot":"","sources":["../src/local.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import type { AuthContext } from './auth.js';
|
|
|
5
5
|
import { type HubConfig, type HubPaths } from './config.js';
|
|
6
6
|
import { Router } from './http.js';
|
|
7
7
|
import { FixedWindowLimiter } from './limiter.js';
|
|
8
|
+
import { LocalProducer } from './local.js';
|
|
8
9
|
import { Tunnel } from './tunnel.js';
|
|
9
10
|
export interface HubServer {
|
|
10
11
|
server: Server;
|
|
@@ -12,6 +13,8 @@ export interface HubServer {
|
|
|
12
13
|
router: Router;
|
|
13
14
|
auth: AuthContext;
|
|
14
15
|
tunnel: Tunnel;
|
|
16
|
+
/** The hub's built-in producer (config-driven hub-local offerings). */
|
|
17
|
+
local: LocalProducer;
|
|
15
18
|
paths: HubPaths;
|
|
16
19
|
config: HubConfig;
|
|
17
20
|
/** Rate limiter for the unauthenticated invite-redeem endpoint. */
|
package/apps/hub/dist/server.js
CHANGED
|
@@ -9,6 +9,7 @@ import { openDb } from './db.js';
|
|
|
9
9
|
import { Router, sendError, sendJson } from './http.js';
|
|
10
10
|
import { registerInviteRoutes } from './invites.js';
|
|
11
11
|
import { AliasSlots, AliasUsers, ConsumerLimiter, FixedWindowLimiter, TokenWindow, } from './limiter.js';
|
|
12
|
+
import { LocalProducer } from './local.js';
|
|
12
13
|
import { loadOrCreateAdminToken, loadOrCreatePepper } from './tokens.js';
|
|
13
14
|
import { Tunnel } from './tunnel.js';
|
|
14
15
|
const VERSION = JSON.parse(readFileSync(new URL('../../../package.json', import.meta.url), 'utf8')).version;
|
|
@@ -24,10 +25,18 @@ export function createHubServer(opts = {}) {
|
|
|
24
25
|
const auth = { db, pepper, adminToken };
|
|
25
26
|
const router = new Router();
|
|
26
27
|
const tunnel = new Tunnel(db, auth, config, log);
|
|
28
|
+
// hub-local offerings: backends/offerings sections of config.toml, served
|
|
29
|
+
// in-process; start() throws on a broken catalog so serve fails fast
|
|
30
|
+
const local = new LocalProducer({ db, paths, config, log });
|
|
31
|
+
local.start();
|
|
32
|
+
// per-alias admission state, shared by the consumer routes and the admin
|
|
33
|
+
// offerings view (live occupancy) — one source of truth for in-flight counts
|
|
34
|
+
const slots = new AliasSlots();
|
|
35
|
+
const users = new AliasUsers();
|
|
27
36
|
// {ok, version, wire} — agents preflight `join` against this and doctor
|
|
28
37
|
// reports hub identity; no auth, nothing secret.
|
|
29
38
|
router.add('GET', '/healthz', (ctx) => sendJson(ctx.res, 200, { ok: true, version: VERSION, wire: WIRE_VERSION }));
|
|
30
|
-
registerAdminRoutes(router, { db, auth, log, tunnel });
|
|
39
|
+
registerAdminRoutes(router, { db, auth, log, tunnel, local, slots, users });
|
|
31
40
|
const inviteLimiter = new FixedWindowLimiter(config.inviteRedeemPerMinute);
|
|
32
41
|
registerInviteRoutes(router, {
|
|
33
42
|
db,
|
|
@@ -42,10 +51,11 @@ export function createHubServer(opts = {}) {
|
|
|
42
51
|
auth,
|
|
43
52
|
config,
|
|
44
53
|
tunnel,
|
|
54
|
+
local,
|
|
45
55
|
limiter: new ConsumerLimiter(),
|
|
46
56
|
tpm: new TokenWindow(),
|
|
47
|
-
slots
|
|
48
|
-
users
|
|
57
|
+
slots,
|
|
58
|
+
users,
|
|
49
59
|
log,
|
|
50
60
|
});
|
|
51
61
|
const server = createServer(async (req, res) => {
|
|
@@ -80,11 +90,13 @@ export function createHubServer(opts = {}) {
|
|
|
80
90
|
router,
|
|
81
91
|
auth,
|
|
82
92
|
tunnel,
|
|
93
|
+
local,
|
|
83
94
|
paths,
|
|
84
95
|
config,
|
|
85
96
|
inviteLimiter,
|
|
86
97
|
log,
|
|
87
98
|
close: async () => {
|
|
99
|
+
local.close();
|
|
88
100
|
tunnel.close();
|
|
89
101
|
await new Promise((resolve) => server.close(() => resolve()));
|
|
90
102
|
db.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACjD,OAAO,EAAE,YAAY,EAAe,MAAM,WAAW,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,OAAO,MAAM,MAAM,MAAM,CAAA;AACzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAEhD,OAAO,EACL,cAAc,EACd,aAAa,EAGb,aAAa,EACb,cAAc,EACd,YAAY,GACb,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EACL,UAAU,EACV,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,WAAW,GACZ,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/apps/hub/dist/table.d.ts
CHANGED
|
@@ -44,6 +44,21 @@ export interface ConsumerListRow {
|
|
|
44
44
|
revoked_at: string | null;
|
|
45
45
|
last_seen_at: string | null;
|
|
46
46
|
}
|
|
47
|
+
export interface HubStatusInput {
|
|
48
|
+
maxProducers: number;
|
|
49
|
+
consumerRps: number;
|
|
50
|
+
consumerBurst: number;
|
|
51
|
+
consumerMaxConcurrent: number;
|
|
52
|
+
headTimeoutMs: number;
|
|
53
|
+
idleTimeoutMs: number;
|
|
54
|
+
producers: ProducerListRow[];
|
|
55
|
+
consumers: ConsumerListRow[];
|
|
56
|
+
offerings: {
|
|
57
|
+
status: string;
|
|
58
|
+
}[];
|
|
59
|
+
}
|
|
60
|
+
/** Compact read-only overview for operators; tokens and request contents stay absent. */
|
|
61
|
+
export declare function renderHubStatus(input: HubStatusInput): string;
|
|
47
62
|
export declare function renderProducers(rows: ProducerListRow[]): string;
|
|
48
63
|
export declare function renderConsumers(rows: ConsumerListRow[]): string;
|
|
49
64
|
/** Rows of GET /admin/v1/usage (one per proxied request; zero content stored). */
|
package/apps/hub/dist/table.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Aligned-column tables for the hub CLI's list output; `--json` keeps the raw API shape.
|
|
2
|
+
import { LOCAL_PRODUCER_ID } from './db.js';
|
|
2
3
|
/** Left-aligned columns with two-space gutters; null-ish cells render as '-'. */
|
|
3
4
|
export function formatTable(headers, rows) {
|
|
4
5
|
const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => r[i]?.length ?? 0)));
|
|
@@ -68,6 +69,23 @@ export function renderInvites(invites, reveal = false, tokens = false) {
|
|
|
68
69
|
...(reveal ? [i.code ?? '-'] : []),
|
|
69
70
|
]));
|
|
70
71
|
}
|
|
72
|
+
/** Compact read-only overview for operators; tokens and request contents stay absent. */
|
|
73
|
+
export function renderHubStatus(input) {
|
|
74
|
+
const producers = input.producers.filter((p) => p.id !== LOCAL_PRODUCER_ID);
|
|
75
|
+
const activeProducers = producers.filter((p) => p.revoked_at === null).length;
|
|
76
|
+
const suspendedProducers = producers.length - activeProducers;
|
|
77
|
+
const activeConsumers = input.consumers.filter((c) => c.revoked_at === null).length;
|
|
78
|
+
const suspendedConsumers = input.consumers.length - activeConsumers;
|
|
79
|
+
const countOfferings = (status) => input.offerings.filter((o) => o.status === status).length;
|
|
80
|
+
return [
|
|
81
|
+
'hub status',
|
|
82
|
+
` producer slots: ${activeProducers}/${input.maxProducers} active (${suspendedProducers} suspended)`,
|
|
83
|
+
` consumers: ${activeConsumers} active (${suspendedConsumers} suspended)`,
|
|
84
|
+
` offerings: ${countOfferings('online')} online, ${countOfferings('offline')} offline, ${countOfferings('degraded')} degraded`,
|
|
85
|
+
` consumer defaults: rps ${input.consumerRps}, burst ${input.consumerBurst}, max concurrent ${input.consumerMaxConcurrent}`,
|
|
86
|
+
` timeouts: head ${input.headTimeoutMs}ms, idle ${input.idleTimeoutMs}ms`,
|
|
87
|
+
].join('\n');
|
|
88
|
+
}
|
|
71
89
|
export function renderProducers(rows) {
|
|
72
90
|
if (rows.length === 0)
|
|
73
91
|
return 'no producers — mint invites with: aweshare hub invite --name NAME';
|
|
@@ -75,7 +93,7 @@ export function renderProducers(rows) {
|
|
|
75
93
|
String(p.id),
|
|
76
94
|
p.name,
|
|
77
95
|
p.email ?? '-',
|
|
78
|
-
p.revoked_at ? 'suspended' : 'active',
|
|
96
|
+
p.id === LOCAL_PRODUCER_ID ? 'built-in' : p.revoked_at ? 'suspended' : 'active',
|
|
79
97
|
fmtTime(p.last_seen_at),
|
|
80
98
|
fmtTime(p.created_at),
|
|
81
99
|
]));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"AAAA,yFAAyF;
|
|
1
|
+
{"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"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"}
|
|
@@ -39,12 +39,34 @@ export interface RelayFailure {
|
|
|
39
39
|
status: number;
|
|
40
40
|
}
|
|
41
41
|
export declare function statusForCode(code: string): number;
|
|
42
|
+
/**
|
|
43
|
+
* One dispatched consumer request, whichever way it leaves the hub: through a
|
|
44
|
+
* producer tunnel (TunnelRequest) or straight upstream in-process
|
|
45
|
+
* (local.ts LocalRelay). handleInference consumes only this surface — the
|
|
46
|
+
* timers, buffering and settle semantics are the same for both.
|
|
47
|
+
*/
|
|
48
|
+
export interface Relay extends EventEmitter {
|
|
49
|
+
readonly requestId: string;
|
|
50
|
+
dispatch(): Promise<void>;
|
|
51
|
+
waitHead(): Promise<{
|
|
52
|
+
status: number;
|
|
53
|
+
headers: Record<string, string>;
|
|
54
|
+
}>;
|
|
55
|
+
/** Flush chunks buffered between head and consumer attach; after this, chunks emit live. */
|
|
56
|
+
startStreaming(): void;
|
|
57
|
+
waitFinished(): Promise<RelayResult>;
|
|
58
|
+
/** Consumer went away; abort upstream. */
|
|
59
|
+
cancel(): void;
|
|
60
|
+
/** Stop reading upstream while a downstream HTTP response is saturated. */
|
|
61
|
+
pauseInput(): void;
|
|
62
|
+
resumeInput(): void;
|
|
63
|
+
}
|
|
42
64
|
/**
|
|
43
65
|
* One dispatched consumer request: ticket + dispatch + response pump.
|
|
44
66
|
* Emits: 'head' {status, headers}, 'chunk' (Uint8Array), 'end', 'error' (RelayFailure).
|
|
45
67
|
* waitFinished() always resolves — never rejects — with the final RelayResult.
|
|
46
68
|
*/
|
|
47
|
-
export declare class TunnelRequest extends EventEmitter {
|
|
69
|
+
export declare class TunnelRequest extends EventEmitter implements Relay {
|
|
48
70
|
private readonly session;
|
|
49
71
|
private readonly init;
|
|
50
72
|
private readonly config;
|