aweshare 0.5.6 → 0.5.7

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.
Files changed (39) hide show
  1. package/README.ai.md +2 -2
  2. package/README.md +17 -3
  3. package/apps/agent/dist/doctor.js +52 -16
  4. package/apps/agent/dist/doctor.js.map +1 -1
  5. package/apps/agent/dist/table.d.ts +19 -2
  6. package/apps/agent/dist/table.js +28 -3
  7. package/apps/agent/dist/table.js.map +1 -1
  8. package/apps/consumer/dist/table.d.ts +17 -2
  9. package/apps/consumer/dist/table.js +18 -3
  10. package/apps/consumer/dist/table.js.map +1 -1
  11. package/apps/hub/dist/admin.d.ts +2 -0
  12. package/apps/hub/dist/admin.js +33 -1
  13. package/apps/hub/dist/admin.js.map +1 -1
  14. package/apps/hub/dist/cli.js +54 -15
  15. package/apps/hub/dist/cli.js.map +1 -1
  16. package/apps/hub/dist/config.d.ts +6 -1
  17. package/apps/hub/dist/config.js +42 -1
  18. package/apps/hub/dist/config.js.map +1 -1
  19. package/apps/hub/dist/consumer.d.ts +34 -3
  20. package/apps/hub/dist/consumer.js +99 -7
  21. package/apps/hub/dist/consumer.js.map +1 -1
  22. package/apps/hub/dist/db.d.ts +29 -1
  23. package/apps/hub/dist/db.js +70 -6
  24. package/apps/hub/dist/db.js.map +1 -1
  25. package/apps/hub/dist/meter.d.ts +6 -1
  26. package/apps/hub/dist/meter.js +14 -0
  27. package/apps/hub/dist/meter.js.map +1 -1
  28. package/apps/hub/dist/server.js +4 -2
  29. package/apps/hub/dist/server.js.map +1 -1
  30. package/apps/hub/dist/table.d.ts +20 -3
  31. package/apps/hub/dist/table.js +35 -10
  32. package/apps/hub/dist/table.js.map +1 -1
  33. package/package.json +1 -1
  34. package/packages/protocol/dist/index.d.ts +1 -0
  35. package/packages/protocol/dist/index.js +1 -0
  36. package/packages/protocol/dist/index.js.map +1 -1
  37. package/packages/protocol/dist/models.d.ts +23 -0
  38. package/packages/protocol/dist/models.js +72 -0
  39. package/packages/protocol/dist/models.js.map +1 -0
package/README.ai.md CHANGED
@@ -245,7 +245,7 @@ After setup:
245
245
  ```bash
246
246
  aweshare producer doctor # full diagnosis, ordered to find the first failing link
247
247
  aweshare producer list # registered offerings, live status, caps, occupancy, config drift
248
- aweshare hub status # rosters + offering health (admin context only)
248
+ aweshare hub status [--all] # offering health + capacity; --all adds rosters
249
249
  aweshare hub list usage # who used how much, aggregated per consumer × model
250
250
  aweshare self-update --check # installed vs npm latest
251
251
  ```
@@ -270,7 +270,7 @@ aweshare producer doctor [--status] # diagnosis (with --status: instant, no net
270
270
  aweshare producer list [--json] # this producer's offerings + drift
271
271
  aweshare producer usage [...] # who used this producer's models
272
272
  aweshare consumer list --hub URL --token asc_... # hub catalog view
273
- aweshare hub status # capacity, rosters, offering health
273
+ aweshare hub status [--all] # capacity + offering health; --all adds rosters
274
274
  aweshare hub list invites [--reveal|--token] # invite ledger / codes / minted tokens
275
275
  aweshare hub limits NAME # bare call views current overrides
276
276
  aweshare hub list usage [--details] [--group-by consumer|alias] [--since 7d]
package/README.md CHANGED
@@ -14,7 +14,7 @@
14
14
  <a href="https://ko-fi.com/mugpeng"><img src="https://img.shields.io/badge/Ko--fi-Buy%20me%20a%20coffee-FF5E5B?style=flat-square&logo=ko-fi&logoColor=white" alt="Ko-fi"></a>
15
15
  </p>
16
16
  <p>
17
- <a href="https://github.com/wehuman01/aweshare-source/releases"><img src="https://img.shields.io/badge/version-0.5.6-7C3AED?style=flat-square" alt="Version"></a>
17
+ <a href="https://github.com/wehuman01/aweshare-source/releases"><img src="https://img.shields.io/badge/version-0.5.7-7C3AED?style=flat-square" alt="Version"></a>
18
18
  <a href="https://github.com/wehuman01/aweshare"><img src="https://img.shields.io/badge/node-%E2%89%A522-0EA5E9?style=flat-square" alt="Node"></a>
19
19
  <a href="https://github.com/wehuman01/aweshare/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-proprietary-E34F26?style=flat-square" alt="License"></a>
20
20
  <a href="https://www.npmjs.com/package/aweshare"><img src="https://img.shields.io/badge/npm-aweshare-7C3AED?style=flat-square" alt="npm package"></a>
@@ -185,6 +185,16 @@ curl https://hub.example.com/v1/chat/completions \
185
185
 
186
186
  ## Consumer tool configuration
187
187
 
188
+ **Match the protocol to the tool first** — an alias speaks exactly one wire protocol and the hub never translates. Base URLs come in exactly two shapes: both OpenAI wires (`openai-chat` / `openai-responses`) point at `…/v1`, `anthropic` uses the bare hub address. The PROTOCOL column of `consumer list` / `GET /v1/catalog` shows these labels:
189
+
190
+ | PROTOCOL | Endpoint | base_url | Who can use it |
191
+ | --- | --- | --- | --- |
192
+ | `anthropic` | `/v1/messages` | `https://hub.example.com` | Claude Code, the Anthropic SDK |
193
+ | `openai-chat` | `/v1/chat/completions` | `https://hub.example.com/v1` | any OpenAI-compatible tool/SDK — opencode, zcode and other coding agents usually dial this |
194
+ | `openai-responses` | `/v1/responses` | `https://hub.example.com/v1` | Codex CLI (default `wire_api`), opencode, Cline (OpenAI Native) — not Codex-only |
195
+
196
+ A client may speak several wires (opencode speaks both OpenAI ones); pointing a chat-completions tool at an `openai-responses` alias (or vice versa) is a 404 (`unknown model alias … (no … offering under this alias)`).
197
+
188
198
  **OpenAI SDK / any OpenAI-compatible tool**
189
199
 
190
200
  ```ts
@@ -310,7 +320,7 @@ Honest limits: token-based caps count what upstreams report — Ollama streams r
310
320
 
311
321
  Error semantics: `401` invalid key · `401 TOKEN_REVOKED` suspended token (ask the operator to restore it) · `403 HUB_FULL` producer capacity reached · `404` unknown alias · `400 PROTOCOL_MISMATCH` protocol/alias mismatch · `429` rate limit, TPM or producer concurrency cap (`PRODUCER_MAX_USERS` = distinct-consumer cap; `QUOTA_EXCEEDED` = lifetime or daily token budget hit) · `502` upstream/tunnel failure (upstream 4xx/5xx passes through verbatim) · `503` producer offline / backend degraded · `504` timeout. Errors carry `{error:{code,message,requestId}}`; the requestId spans both sides' logs.
312
322
 
313
- Usage metering: one row per request (alias, real model, status, duration, byte counts, best-effort token counts), **zero content stored**. `aweshare hub list usage` (and `aweshare producer usage` on a producer's machine, scoped to its own models) answers "who used how much" by default: server-side aggregation on the hub's SQLite, one row per consumer × model — a person's rows stay together, busiest person and busiest model first — with request/error counts, best-effort token totals, an explicit unknown-token count (streaming backends that report no counts) and mean duration. The window defaults to 7 days and is printed with the table (`--since 30m\|12h\|7d\|…\|all`); `--group-by consumer` rolls up to per-person totals, `--group-by alias` to per-model totals. `--details` switches to the per-request log (`GET /admin/v1/usage`; admin sees everything, producers and consumers their own slice, rows carry the consumer/producer names).
323
+ Usage metering: one row per request (alias, declared upstream model, response-reported model when available, status, duration, byte counts, best-effort token counts), **zero content stored**. `aweshare hub list usage` (and `aweshare producer usage` on a producer's machine, scoped to its own models) answers "who used how much" by default: server-side aggregation on the hub's SQLite, one row per consumer × model — a person's rows stay together, busiest person and busiest model first — with request/error counts, best-effort token totals, an explicit unknown-token count (streaming backends that report no counts) and mean duration. The window defaults to 7 days and is printed with the table (`--since 30m\|12h\|7d\|…\|all`); `--group-by consumer` rolls up to per-person totals, `--group-by alias` to per-model totals. `--details` switches to the per-request log (`GET /admin/v1/usage`; admin sees everything, producers and consumers their own slice, rows carry the consumer/producer names).
314
324
 
315
325
  ## Command reference
316
326
 
@@ -325,10 +335,11 @@ Both sides at a glance — details in the sections above.
325
335
  | `aweshare hub produce [--host H] [--port N]` | run the hub with its own models attached — same as `serve`; the `[[backends]]`/`[[offerings]]` sections of `config.produce.toml` become `hub/…` offerings served in-process (keys in the data dir's secrets.json; edits hot-reload) |
326
336
  | `aweshare hub invite [--role producer\|consumer] [--name NAME] [--count N] [--expires-in D\|none]` | mint one-time invite codes (`asi_…`, printed once, expire after 7 d by default; re-view with `list invites --reveal`); `--expires-in` also bounds the lifetime of the token it mints — an expired key fails auth with 401 `TOKEN_EXPIRED` (`none` = code and identity never expire; identities minted before this change never expire); producer codes: bound (`--name`) or unbound (name + email at redeem, `--count` batches); consumer codes: always bound to one name |
327
337
  | `aweshare hub list invites [--reveal] [--token] [--json]` | the invite ledger: every code, the identity it minted and its lifecycle (pending/used/suspended/revoked/expired; a redeemed code shows `expired` once its identity's expiry passes); `--reveal` re-shows the codes, `--token` the minted tokens with last seen |
328
- | `aweshare hub status` | the hub's live state: producer slots, the producer and consumer rosters (status, ONLINE live-tunnel state, last seen), offerings counted per deduplicated alias (several protocols → one verdict, the worst), a per-alias table — the same columns as `consumer list` and `producer list`, worst status first — with live occupancy (`IN USE n/max`) and today's remaining daily tokens, and a last-5m requests/ok-rate/errors line from the usage summary (hub-admission 429s are not metered) |
338
+ | `aweshare hub status [--all]` | the hub's live state: producer slots, offerings counted per deduplicated alias (several protocols → one verdict, the worst), a per-alias table — the same columns as `consumer list` and `producer list`, worst status first — with live occupancy (`IN USE n/max`) and today's remaining daily tokens, and a last-5m requests/ok-rate/errors line from the usage summary (hub-admission 429s are not metered); identities appear as counts — `--all` prints the full producer/consumer rosters |
329
339
  | `aweshare hub limits NAME [--rps N] [--burst N] [--max-concurrent N] [--tpm N] [--max-total-tokens N] [--clear] [--json]` | show, merge or clear one consumer's limit overrides (unset keys keep the hub-wide defaults) |
330
340
  | `aweshare hub list usage [--details] [--consumer NAME] [--producer NAME] [--alias ns/model] [--group-by consumer-alias\|consumer\|alias] [--since 7d\|all] [--limit N] [--json]` | who used how much (default): aggregate per consumer × model, a person's rows together, busiest first — requests, errors, rate, best-effort token totals, unknown-token count, mean duration; window defaults to 7d and is printed with the table · `--details`: per-request log, newest first, zero content stored, each row naming its consumer |
331
341
  | `aweshare hub revoke --id N` · `aweshare hub restore --id N` | kill an invite / undo — a redeemed code suspends the producer it minted, restore revives both |
342
+ | `aweshare hub offering block ALIAS` · `aweshare hub offering restore ALIAS` | the per-alias scalpel between doing nothing and revoking a whole producer: block one offering (every protocol row of the alias) — new requests get 503 `OFFERING_BLOCKED`, status shows `blocked`, the producer's other offerings keep serving. Manual blocks survive re-registers; auto blocks (model mismatch, see `autoBlockModelMismatch`) clear once the producer re-declares a different `upstreamModel` |
332
343
 
333
344
  Token issuance runs through invites (both roles). `limits` and `list usage` are thin wrappers over the admin REST API (`/admin/v1/*`, see Endpoints and errors) — curl works too.
334
345
 
@@ -377,10 +388,13 @@ The hub reads `config.toml` from its data dir (`~/.aweshare-hub/config.toml`; Do
377
388
  | `AWESHARE_INVITE_REDEEM_PER_MIN` | 10 | redeem entry global insurance budget (valid-format attempts shared by every origin) |
378
389
  | `AWESHARE_INVITE_REDEEM_PER_IP_MIN` | 5 | redeem entry per-origin-IP bucket (`CF-Connecting-IP` behind a tunnel/proxy) — one visitor cannot monopolize admission; both keys reload via SIGHUP |
379
390
  | `AWESHARE_MAX_PRODUCERS` | 10 | max active producers — token issuance (admin API), invite redeem and restore refuse with `403 HUB_FULL` when full |
391
+ | `AWESHARE_AUTO_BLOCK_MODEL_MISMATCH` | false | auto-block an offering after 2 consecutive successful responses report a different model than declared. Off by default: mismatches are logged once (flip) and visible in `hub status` / `consumer list` / `list usage --details` either way — the hub is report-only until the operator opts in. An auto block clears when the producer re-declares a different `upstreamModel`; an explicit manual `offering block` takes precedence and always persists; reloads via SIGHUP |
380
392
  | `AWESHARE_NO_UPDATE_CHECK` | unset | set to `1` to disable the passive update reminder |
381
393
 
382
394
  Health: agent heartbeats every 15s, silent 45s = dead; backends with 2 consecutive AUTH/QUOTA failures auto-degrade (alias shows `degraded`, dispatch stops), 30s probes recover. A new connection with the same producer token replaces the old one (latest-wins).
383
395
 
396
+ Model honesty: an offering's `upstreamModel` is the producer's claim — the hub compares it with the bounded model id reported by each successful response (`model` / `message.model` / `response.model`). This is consistency evidence, not proof of the model's underlying weights: a producer or upstream router can still rewrite that metadata. The observation rides the existing usage meter, never rewrites the relayed response, and is scoped to the same alias, protocol and current declaration. It appears in the `OBSERVED MODEL` column, `list usage --details`, and `/v1/catalog` as `observedModel`, `observedAt`, `modelMatch` and the backward-compatible `modelVerified`. Comparison is token-aware: exact ids and explicit date/revision suffixes are affirmative; vendor prefixes are tolerated; adjacent variants such as `gpt-4`/`gpt-4o` and `gpt-4o`/`gpt-4o-mini` mismatch; a less-specific response is marked `?`/`insufficient`, not verified. Handling is tiered: default **report-only**, manual `hub offering block ALIAS` or whole-producer `hub revoke`, and opt-in auto-block after 2 consecutive mismatches. Manual blocks override automatic ones. `producer doctor` probes every distinct configured model and reports the response-named id with the same evidence boundary.
397
+
384
398
  Updating a npm install: `aweshare self-update` (asks before installing; `--check` only shows versions). The CLI also reminds you at most once a day when a newer npm release exists.
385
399
 
386
400
  Updating a Docker deployment: `docker compose pull && docker compose up -d`. State lives in the `./data` volume; producers redial automatically after the restart, and consumers see 503 only during the brief restart window.
@@ -1,4 +1,5 @@
1
1
  import { classifyStatus, codexNetworkHint, fetchUpstream, probeBody, probeTarget, readCodexCredentials, } from '../../../packages/producer-core/dist/index.js';
2
+ import { compareModels, selfReportedModel } from '../../../packages/protocol/dist/index.js';
2
3
  import { ConfigError, loadAgentConfig, } from './config.js';
3
4
  import { formatLogLine, isProducerAlive, logFileOf, readPid, tailLog, uptimeOf } from './daemon.js';
4
5
  import { assertWireCompatible, fetchOfferings, probeHub } from './hub.js';
@@ -139,8 +140,10 @@ async function checkBackend(backend, offerings, apiKey) {
139
140
  detail: `anthropic-style baseUrl must not include /v1 (the agent appends it), got ${backend.baseUrl}`,
140
141
  });
141
142
  }
142
- const offering = offerings.find((o) => o.backend === backend.id);
143
- if (!offering) {
143
+ const models = [
144
+ ...new Set(offerings.filter((o) => o.backend === backend.id).map((o) => o.upstreamModel)),
145
+ ];
146
+ if (models.length === 0) {
144
147
  checks.push({ name: label, ok: true, detail: 'no offerings — probe skipped' });
145
148
  return checks;
146
149
  }
@@ -172,21 +175,55 @@ async function checkBackend(backend, offerings, apiKey) {
172
175
  }
173
176
  const resolved = { ...backend, apiKey };
174
177
  const { url, headers } = probeTarget(resolved);
178
+ for (const model of models) {
179
+ checks.push(await probeModel(models.length === 1 ? `${label} probe` : `${label} probe '${model}'`, model, backend, resolved, url, headers));
180
+ }
181
+ return checks;
182
+ }
183
+ /** Probe every distinct model on a backend. A healthy first model says
184
+ * nothing about the other ids routed through the same upstream. */
185
+ async function probeModel(name, model, backend, resolved, url, headers) {
175
186
  try {
176
187
  const started = Date.now();
177
188
  const res = await fetchUpstream(resolved, url, {
178
189
  method: 'POST',
179
190
  headers,
180
- body: JSON.stringify(probeBody(offering.upstreamModel, backend.protocol, backend.login !== undefined)),
191
+ body: JSON.stringify(probeBody(model, backend.protocol, backend.login !== undefined)),
181
192
  signal: AbortSignal.timeout(30_000),
182
193
  });
183
194
  const reason = classifyStatus(res.status);
184
195
  if (reason === null) {
185
- checks.push({
186
- name: `${label} probe`,
196
+ // Response metadata is consistency evidence, not proof of the model's
197
+ // underlying weights.
198
+ let served = null;
199
+ try {
200
+ served = selfReportedModel(JSON.parse(await res.text()));
201
+ }
202
+ catch {
203
+ served = null; // non-JSON body: nothing self-reported to audit
204
+ }
205
+ if (served !== null) {
206
+ const comparison = compareModels(model, served);
207
+ if (comparison === 'mismatch') {
208
+ return {
209
+ name,
210
+ ok: false,
211
+ detail: `model '${model}' -> ${res.status}, but the response reports '${served}' — check the backend/proxy for model substitution`,
212
+ };
213
+ }
214
+ if (comparison === 'insufficient') {
215
+ return {
216
+ name,
217
+ ok: false,
218
+ detail: `model '${model}' -> ${res.status}, but the response only reports '${served}' — not specific enough to verify the declaration`,
219
+ };
220
+ }
221
+ }
222
+ return {
223
+ name,
187
224
  ok: true,
188
- detail: `model '${offering.upstreamModel}' -> ${res.status} (${Date.now() - started}ms)`,
189
- });
225
+ detail: `model '${model}' -> ${res.status} (${Date.now() - started}ms${served ? `, response reported '${served}'` : ''})`,
226
+ };
190
227
  }
191
228
  else {
192
229
  const hint = reason === 'AUTH'
@@ -196,21 +233,20 @@ async function checkBackend(backend, offerings, apiKey) {
196
233
  : reason === 'QUOTA'
197
234
  ? 'upstream balance or rate limit exhausted'
198
235
  : 'check that upstreamModel is a real model id on the backend (full `ollama list` tag)';
199
- checks.push({
200
- name: `${label} probe`,
236
+ await res.arrayBuffer().catch(() => undefined);
237
+ return {
238
+ name,
201
239
  ok: false,
202
- detail: `model '${offering.upstreamModel}' -> ${res.status} (${reason}): ${hint}`,
203
- });
240
+ detail: `model '${model}' -> ${res.status} (${reason}): ${hint}`,
241
+ };
204
242
  }
205
- await res.arrayBuffer().catch(() => undefined);
206
243
  }
207
244
  catch (err) {
208
- checks.push({
209
- name: `${label} probe`,
245
+ return {
246
+ name,
210
247
  ok: false,
211
248
  detail: `probe to ${url} failed: ${err instanceof Error ? err.message : err}${codexNetworkHint(resolved)}. Check local network and whether the service is running (inside Docker, 127.0.0.1 is the container itself)`,
212
- });
249
+ };
213
250
  }
214
- return checks;
215
251
  }
216
252
  //# sourceMappingURL=doctor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { type ModelComparison } from 'aweshare-protocol';
1
2
  /** Left-aligned columns with two-space gutters. */
2
3
  export declare function formatTable(headers: string[], rows: string[][]): string;
3
4
  /** '2026-08-01T10:00:00.123Z' → '2026-08-01 10:00Z' (UTC, minute precision). */
@@ -6,10 +7,16 @@ export declare function fmtTime(iso: string | null | undefined): string;
6
7
  export interface OfferingRow {
7
8
  alias: string;
8
9
  /** Owning producer's name; current hubs always send it. Rendered only in
9
- * the hub-wide view (`producer list --all`). */
10
+ * the hub-wide view (`producer list --all`). */
10
11
  producer?: string;
11
12
  protocol: string;
12
13
  status: string;
14
+ /** The model id reported in successful responses — consistency evidence
15
+ * for upstreamModel, not proof of underlying weights. Undefined on hubs
16
+ * that predate the audit, null before the first self-naming response. */
17
+ observedModel?: string | null;
18
+ modelVerified?: boolean | null;
19
+ modelMatch?: ModelComparison | null;
13
20
  maxConcurrencyPerUser: number;
14
21
  maxConcurrentUsers: number;
15
22
  /** Distinct consumers with a request in flight right now (snapshot at list
@@ -19,6 +26,11 @@ export interface OfferingRow {
19
26
  dailyTokens: number;
20
27
  usedDailyTokens: number;
21
28
  }
29
+ /** The OBSERVED MODEL cell — kept verbatim in apps/hub/src/table.ts and
30
+ * apps/consumer/src/table.ts with the shared headers: the observed id,
31
+ * '✗'-marked when it disagrees with the declaration, '-' when nothing was
32
+ * observed. */
33
+ export declare function observedCell(observedModel: string | null | undefined, modelVerified: boolean | null | undefined, modelMatch?: ModelComparison | null): string;
22
34
  export interface ProducerStatusInput {
23
35
  instance: string;
24
36
  hubUrl: string;
@@ -30,7 +42,9 @@ export interface ProducerStatusInput {
30
42
  /** Compact local overview; config secrets are deliberately never included. */
31
43
  export declare function renderProducerStatus(input: ProducerStatusInput): string;
32
44
  /** The offering table `producer list` renders — same column spec as the hub
33
- * status and consumer list tables (locked together by a cross-CLI test). */
45
+ * status and consumer list tables (locked together by a cross-CLI test).
46
+ * OBSERVED MODEL is what the upstream itself served: a '✗' marks a
47
+ * declaration that doesn't hold. */
34
48
  export declare function renderOfferings(rows: OfferingRow[], opts?: {
35
49
  producer?: boolean;
36
50
  }): string;
@@ -47,6 +61,9 @@ export interface UsageRow {
47
61
  producer_id: number;
48
62
  alias: string;
49
63
  upstream_model: string;
64
+ /** Model id the upstream named about itself; NULL when it named none.
65
+ * Absent on hubs that predate the model audit. */
66
+ observed_model?: string | null;
50
67
  protocol: string;
51
68
  streaming: number;
52
69
  status: number | null;
@@ -1,5 +1,5 @@
1
1
  // Aligned-column tables for list output; `--json` keeps the raw API shape.
2
- import { protocolLabel } from '../../../packages/protocol/dist/index.js';
2
+ import { compareModels, protocolLabel } from '../../../packages/protocol/dist/index.js';
3
3
  /** Left-aligned columns with two-space gutters. */
4
4
  export function formatTable(headers, rows) {
5
5
  const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => r[i]?.length ?? 0)));
@@ -13,6 +13,17 @@ export function formatTable(headers, rows) {
13
13
  export function fmtTime(iso) {
14
14
  return iso ? `${iso.slice(0, 16).replace('T', ' ')}Z` : '-';
15
15
  }
16
+ /** The OBSERVED MODEL cell — kept verbatim in apps/hub/src/table.ts and
17
+ * apps/consumer/src/table.ts with the shared headers: the observed id,
18
+ * '✗'-marked when it disagrees with the declaration, '-' when nothing was
19
+ * observed. */
20
+ export function observedCell(observedModel, modelVerified, modelMatch) {
21
+ if (observedModel === undefined || observedModel === null)
22
+ return '-';
23
+ if (modelMatch === 'mismatch' || modelVerified === false)
24
+ return `${observedModel} ✗`;
25
+ return modelMatch === 'insufficient' ? `${observedModel} ?` : observedModel;
26
+ }
16
27
  /** Compact local overview; config secrets are deliberately never included. */
17
28
  export function renderProducerStatus(input) {
18
29
  const countOfferings = (status) => input.offerings.filter((o) => o.status === status).length;
@@ -31,7 +42,9 @@ export function renderProducerStatus(input) {
31
42
  ].join('\n');
32
43
  }
33
44
  /** The offering table `producer list` renders — same column spec as the hub
34
- * status and consumer list tables (locked together by a cross-CLI test). */
45
+ * status and consumer list tables (locked together by a cross-CLI test).
46
+ * OBSERVED MODEL is what the upstream itself served: a '✗' marks a
47
+ * declaration that doesn't hold. */
35
48
  export function renderOfferings(rows, opts = {}) {
36
49
  if (rows.length === 0)
37
50
  return 'no offerings registered on this hub yet';
@@ -46,6 +59,7 @@ export function renderOfferings(rows, opts = {}) {
46
59
  return formatTable([
47
60
  ...(opts.producer ? ['PRODUCER'] : []),
48
61
  'ALIAS',
62
+ 'OBSERVED MODEL',
49
63
  'PROTOCOL',
50
64
  'STATUS',
51
65
  'MAX USERS',
@@ -59,6 +73,7 @@ export function renderOfferings(rows, opts = {}) {
59
73
  return [
60
74
  ...(opts.producer ? [join((r) => r.producer ?? '-')] : []),
61
75
  first?.alias ?? '',
76
+ join((r) => observedCell(r.observedModel, r.modelVerified, r.modelMatch)),
62
77
  join((r) => protocolLabel(r.protocol), ', '),
63
78
  join((r) => r.status),
64
79
  join((r) => String(r.maxConcurrentUsers)),
@@ -86,6 +101,16 @@ export function driftSummary(configAliases, hubAliases) {
86
101
  parts.push(`hub-only (config changed? run 'aweshare producer reload'): ${stale.join(', ')}`);
87
102
  return parts.length > 0 ? parts.join('\n') : null;
88
103
  }
104
+ /** The usage MODEL cell: the declaration, with the observed id appended when
105
+ * it disagrees (`glm-4.6≠step-2-16k`) — per-request evidence in one glance. */
106
+ function modelCell(r) {
107
+ if (r.observed_model == null)
108
+ return r.upstream_model;
109
+ const match = compareModels(r.upstream_model, r.observed_model);
110
+ if (match === 'mismatch')
111
+ return `${r.upstream_model}≠${r.observed_model}`;
112
+ return match === 'insufficient' ? `${r.upstream_model}?${r.observed_model}` : r.upstream_model;
113
+ }
89
114
  /** Newest-first usage log. Token counts are best-effort — NULL (e.g. Ollama
90
115
  * streams) renders as '-'. */
91
116
  export function renderUsage(rows, consumerName) {
@@ -95,7 +120,7 @@ export function renderUsage(rows, consumerName) {
95
120
  fmtTime(r.at),
96
121
  consumerName(r.consumer_id),
97
122
  r.alias,
98
- r.upstream_model,
123
+ modelCell(r),
99
124
  r.error_code ? `${r.status ?? '-'} ${r.error_code}` : String(r.status ?? '-'),
100
125
  `${r.duration_ms}ms`,
101
126
  r.prompt_tokens === null && r.completion_tokens === null
@@ -1 +1 @@
1
- {"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { type ModelComparison } from 'aweshare-protocol';
1
2
  /** Left-aligned columns with two-space gutters. */
2
3
  export declare function formatTable(headers: string[], rows: string[][]): string;
3
4
  export interface CatalogRow {
@@ -5,6 +6,13 @@ export interface CatalogRow {
5
6
  alias: string;
6
7
  protocol: string;
7
8
  status: string;
9
+ /** The model id reported in successful responses — consistency evidence
10
+ * for the producer's declaration, not proof of underlying model weights.
11
+ * Undefined on hubs that predate the audit, null before the first
12
+ * self-naming response. */
13
+ observedModel?: string | null;
14
+ modelVerified?: boolean | null;
15
+ modelMatch?: ModelComparison | null;
8
16
  /** Concurrent-requests cap per consumer; pre-v0.4.3 hubs don't report it. */
9
17
  maxConcurrencyPerUser?: number;
10
18
  maxConcurrentUsers: number;
@@ -18,8 +26,15 @@ export interface CatalogRow {
18
26
  }
19
27
  /** `consumer list` hides offline offerings by default — they can't be called,
20
28
  * so they're noise when picking a model; `--all` lists everything. Degraded
21
- * stays visible: the upstream is briefly failing but the producer is up. */
29
+ * stays visible: the upstream is briefly failing but the producer is up.
30
+ * Blocked offerings are hidden like offline ones — the operator closed them. */
22
31
  export declare function filterCatalog(rows: CatalogRow[], all: boolean): CatalogRow[];
32
+ /** The OBSERVED MODEL cell — kept verbatim in apps/hub/src/table.ts and
33
+ * apps/agent/src/table.ts with the shared headers: the observed id, '✗'-marked
34
+ * when it disagrees with the declaration, '-' when nothing was observed. */
35
+ export declare function observedCell(observedModel: string | null | undefined, modelVerified: boolean | null | undefined, modelMatch?: ModelComparison | null): string;
23
36
  /** The offering table every CLI renders — same column spec as hub status and
24
- * producer list (locked together by a cross-CLI test in apps/hub/test). */
37
+ * producer list (locked together by a cross-CLI test in apps/hub/test).
38
+ * OBSERVED MODEL is what the upstream itself served: a '✗' marks a
39
+ * declaration that doesn't hold. */
25
40
  export declare function renderCatalog(rows: CatalogRow[]): string;
@@ -11,9 +11,20 @@ export function formatTable(headers, rows) {
11
11
  }
12
12
  /** `consumer list` hides offline offerings by default — they can't be called,
13
13
  * so they're noise when picking a model; `--all` lists everything. Degraded
14
- * stays visible: the upstream is briefly failing but the producer is up. */
14
+ * stays visible: the upstream is briefly failing but the producer is up.
15
+ * Blocked offerings are hidden like offline ones — the operator closed them. */
15
16
  export function filterCatalog(rows, all) {
16
- return all ? rows : rows.filter((r) => r.status !== 'offline');
17
+ return all ? rows : rows.filter((r) => r.status !== 'offline' && r.status !== 'blocked');
18
+ }
19
+ /** The OBSERVED MODEL cell — kept verbatim in apps/hub/src/table.ts and
20
+ * apps/agent/src/table.ts with the shared headers: the observed id, '✗'-marked
21
+ * when it disagrees with the declaration, '-' when nothing was observed. */
22
+ export function observedCell(observedModel, modelVerified, modelMatch) {
23
+ if (observedModel === undefined || observedModel === null)
24
+ return '-';
25
+ if (modelMatch === 'mismatch' || modelVerified === false)
26
+ return `${observedModel} ✗`;
27
+ return modelMatch === 'insufficient' ? `${observedModel} ?` : observedModel;
17
28
  }
18
29
  /** One alias may speak several protocols (one hub row each); the table shows
19
30
  * one line per alias with the protocols joined. Other columns join differing
@@ -33,6 +44,7 @@ function mergeByAlias(rows) {
33
44
  return [
34
45
  first?.producer ?? '',
35
46
  first?.alias ?? '',
47
+ join((r) => observedCell(r.observedModel, r.modelVerified, r.modelMatch)),
36
48
  join((r) => protocolLabel(r.protocol), ', '),
37
49
  join((r) => r.status),
38
50
  join((r) => String(r.maxConcurrentUsers)),
@@ -44,13 +56,16 @@ function mergeByAlias(rows) {
44
56
  });
45
57
  }
46
58
  /** The offering table every CLI renders — same column spec as hub status and
47
- * producer list (locked together by a cross-CLI test in apps/hub/test). */
59
+ * producer list (locked together by a cross-CLI test in apps/hub/test).
60
+ * OBSERVED MODEL is what the upstream itself served: a '✗' marks a
61
+ * declaration that doesn't hold. */
48
62
  export function renderCatalog(rows) {
49
63
  if (rows.length === 0)
50
64
  return 'no offerings on this hub yet';
51
65
  return formatTable([
52
66
  'PRODUCER',
53
67
  'ALIAS',
68
+ 'OBSERVED MODEL',
54
69
  'PROTOCOL',
55
70
  'STATUS',
56
71
  'MAX USERS',
@@ -1 +1 @@
1
- {"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,OAAO,EAAwB,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEvE,mDAAmD;AACnD,MAAM,UAAU,WAAW,CAAC,OAAiB,EAAE,IAAgB;IAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IAC/F,MAAM,IAAI,GAAG,CAAC,KAAe,EAAU,EAAE,CACvC,KAAK;SACF,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;SACvC,IAAI,CAAC,IAAI,CAAC;SACV,OAAO,EAAE,CAAA;IACd,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACtD,CAAC;AA0BD;;;gFAGgF;AAChF,MAAM,UAAU,aAAa,CAAC,IAAkB,EAAE,GAAY;IAC5D,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAA;AAC1F,CAAC;AAED;;4EAE4E;AAC5E,MAAM,UAAU,YAAY,CAC1B,aAAwC,EACxC,aAAyC,EACzC,UAAmC;IAEnC,IAAI,aAAa,KAAK,SAAS,IAAI,aAAa,KAAK,IAAI;QAAE,OAAO,GAAG,CAAA;IACrE,IAAI,UAAU,KAAK,UAAU,IAAI,aAAa,KAAK,KAAK;QAAE,OAAO,GAAG,aAAa,IAAI,CAAA;IACrF,OAAO,UAAU,KAAK,cAAc,CAAC,CAAC,CAAC,GAAG,aAAa,IAAI,CAAC,CAAC,CAAC,aAAa,CAAA;AAC7E,CAAC;AAED;;;oDAGoD;AACpD,SAAS,YAAY,CAAC,IAAkB;IACtC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAA;IAC9C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,KAAK,EAAE,CAAA;QAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAA;QAClC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACd,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACvB,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QACrB,MAAM,IAAI,GAAG,CAAC,IAA+B,EAAE,GAAG,GAAG,GAAG,EAAU,EAAE,CAClE,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACxC,OAAO;YACL,KAAK,EAAE,QAAQ,IAAI,EAAE;YACrB,KAAK,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;YACzE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;YAC5C,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YACrB,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;YACzC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAC7F,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,qBAAqB,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC;YAC5F,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;YAChE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACT,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CACnF;SACF,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;oCAGoC;AACpC,MAAM,UAAU,aAAa,CAAC,IAAkB;IAC9C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,8BAA8B,CAAA;IAC5D,OAAO,WAAW,CAChB;QACE,UAAU;QACV,OAAO;QACP,gBAAgB;QAChB,UAAU;QACV,QAAQ;QACR,WAAW;QACX,QAAQ;QACR,UAAU;QACV,cAAc;QACd,WAAW;KACZ,EACD,YAAY,CAAC,IAAI,CAAC,CACnB,CAAA;AACH,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import type Database from 'better-sqlite3';
2
2
  import type { Logger } from 'pino';
3
3
  import type { AuthContext } from './auth.js';
4
+ import { type ModelWatch } from './consumer.js';
4
5
  import { type Router } from './http.js';
5
6
  import type { AliasSlots, AliasUsers } from './limiter.js';
6
7
  import type { LocalProducer } from './local.js';
@@ -15,6 +16,7 @@ export interface AdminDeps {
15
16
  * view reports in-flight occupancy from it. */
16
17
  slots: AliasSlots;
17
18
  users: AliasUsers;
19
+ watch: Pick<ModelWatch, 'reset'>;
18
20
  }
19
21
  /** Audit and governance: rosters, usage, per-consumer limits. Admission is
20
22
  * invite-only — see invites.ts; every identity therefore carries an invite
@@ -1,7 +1,7 @@
1
1
  import { roleForToken } from '../../../packages/protocol/dist/index.js';
2
2
  import { requireAdmin, requireConsumer, requireProducer } from './auth.js';
3
3
  import { offeringView, serializeOffering } from './consumer.js';
4
- import { getConsumerByName, getProducerByName, LOCAL_PRODUCER_ID, listOfferings, listTokens, queryUsage, setConsumerConfig, summarizeUsage, } from './db.js';
4
+ import { blockOffering, getConsumerByName, getProducerByName, LOCAL_PRODUCER_ID, listOfferings, listOfferingsByAlias, listTokens, queryUsage, restoreOffering, setConsumerConfig, summarizeUsage, } from './db.js';
5
5
  import { extractCredential, HttpError, readJson, sendJson } from './http.js';
6
6
  import { parseLimits, safeParseLimits } from './limits.js';
7
7
  /** Audit and governance: rosters, usage, per-consumer limits. Admission is
@@ -29,6 +29,18 @@ export function registerAdminRoutes(router, deps) {
29
29
  throw new HttpError(404, 'ALIAS_NOT_FOUND', `unknown producer: ${name}`);
30
30
  return producer.id;
31
31
  };
32
+ /** ?alias=ns/model for the block/restore endpoints — required, and it must
33
+ * name a registered offering (0 protocol rows = unknown alias). */
34
+ const offeringAliasFromQuery = (query) => {
35
+ const alias = query.get('alias');
36
+ if (!alias) {
37
+ throw new HttpError(400, 'ALIAS_REQUIRED', 'query parameter alias is required (ns/model)');
38
+ }
39
+ if (listOfferingsByAlias(db, alias).length === 0) {
40
+ throw new HttpError(404, 'ALIAS_NOT_FOUND', `unknown offering alias: ${alias}`);
41
+ }
42
+ return alias;
43
+ };
32
44
  router.add('GET', '/admin/v1/tokens', (ctx) => {
33
45
  requireAdmin(ctx.req, auth);
34
46
  const { producers, consumers } = listTokens(db);
@@ -60,6 +72,26 @@ export function registerAdminRoutes(router, deps) {
60
72
  requireAdmin(ctx.req, auth);
61
73
  sendJson(ctx.res, 200, offeringsPayload(deps));
62
74
  });
75
+ // The per-alias scalpel between "do nothing" and revoking the whole
76
+ // producer: block one offering (every protocol row of the alias) and its
77
+ // requests fail with 503 OFFERING_BLOCKED while the producer's honest
78
+ // offerings keep serving. Reversible. The alias rides the query string —
79
+ // it contains a '/', which path params can't carry.
80
+ router.add('POST', '/admin/v1/offerings/block', (ctx) => {
81
+ requireAdmin(ctx.req, auth);
82
+ const alias = offeringAliasFromQuery(ctx.query);
83
+ const rows = blockOffering(db, alias, 'manual');
84
+ deps.log.info({ alias, rows }, 'offering blocked (operator)');
85
+ sendJson(ctx.res, 200, { alias, blocked: true, offerings: rows });
86
+ });
87
+ router.add('POST', '/admin/v1/offerings/restore', (ctx) => {
88
+ requireAdmin(ctx.req, auth);
89
+ const alias = offeringAliasFromQuery(ctx.query);
90
+ const rows = restoreOffering(db, alias);
91
+ deps.watch.reset(alias);
92
+ deps.log.info({ alias, rows }, 'offering restored (operator)');
93
+ sendJson(ctx.res, 200, { alias, blocked: false, offerings: rows });
94
+ });
63
95
  // Detail log and aggregate summary share the same slice semantics: admin
64
96
  // sees everything, a producer key its own registrations, a consumer key its
65
97
  // own requests. Rows carry joined consumer/producer names so callers never