@hanzo/ui 8.27.60 → 8.27.61

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 (44) hide show
  1. package/dist/chat/Composer.cjs +1 -1
  2. package/dist/chat/Composer.d.ts +1 -1
  3. package/dist/chat/Composer.js +1 -1
  4. package/dist/gallery.cjs +4 -4
  5. package/dist/gallery.d.ts.map +1 -1
  6. package/dist/gallery.html +4 -5
  7. package/dist/gallery.js +5 -5
  8. package/dist/gallery.js.map +1 -1
  9. package/dist/index.cjs +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/index.node.cjs +1 -1
  12. package/dist/index.node.js +1 -1
  13. package/dist/models/ModelPicker.cjs +191 -0
  14. package/dist/models/ModelPicker.d.ts +27 -0
  15. package/dist/models/ModelPicker.d.ts.map +1 -0
  16. package/dist/models/ModelPicker.js +189 -0
  17. package/dist/models/ModelPicker.js.map +1 -0
  18. package/dist/models/catalog.cjs +313 -184
  19. package/dist/models/catalog.d.ts +101 -38
  20. package/dist/models/catalog.d.ts.map +1 -1
  21. package/dist/models/catalog.js +295 -179
  22. package/dist/models/catalog.js.map +1 -1
  23. package/dist/models/index.cjs +33 -12
  24. package/dist/models/index.d.ts +7 -4
  25. package/dist/models/index.d.ts.map +1 -1
  26. package/dist/models/index.js +7 -6
  27. package/dist/models/index.js.map +1 -1
  28. package/dist/models/picker.logic.cjs +83 -0
  29. package/dist/models/picker.logic.d.ts +51 -0
  30. package/dist/models/picker.logic.d.ts.map +1 -0
  31. package/dist/models/picker.logic.js +74 -0
  32. package/dist/models/picker.logic.js.map +1 -0
  33. package/dist/product/limits.cjs +14 -13
  34. package/dist/product/limits.d.ts +9 -10
  35. package/dist/product/limits.d.ts.map +1 -1
  36. package/dist/product/limits.js +14 -12
  37. package/dist/product/limits.js.map +1 -1
  38. package/dist/styles.css +1 -2
  39. package/package.json +1 -1
  40. package/dist/models/ModelSelector.cjs +0 -80
  41. package/dist/models/ModelSelector.d.ts +0 -44
  42. package/dist/models/ModelSelector.d.ts.map +0 -1
  43. package/dist/models/ModelSelector.js +0 -78
  44. package/dist/models/ModelSelector.js.map +0 -1
@@ -1,27 +1,49 @@
1
1
  /**
2
- * @hanzo/ui/models — Model catalog data layer
2
+ * @hanzo/ui/models — the model catalog, as `GET /v1/models` answers it.
3
3
  *
4
- * Pure, SSR-safe helpers shared by the unified ModelSelector. No React,
5
- * no browser globals — usable on the server, in edge runtimes, or the client.
4
+ * Pure and SSR-safe: no React, no browser globals. The picker and every host's
5
+ * explorer read the same rows through the same helpers, so a model is in the
6
+ * same group, with the same label and the same price, on every surface.
6
7
  *
7
- * ModelCatalogEntry is the gateway/OpenAI-shaped record ({ id, owned_by, ... })
8
- * returned by `${baseUrl}/models`. It is intentionally distinct from the
9
- * registry-shaped ZenModelLike in ./types (which drives the marketing cards).
8
+ * Every fact here is a field the gateway publishes — `class`, `family`,
9
+ * `inputs`, `outputs`, `supports_*`, `pricing`. Nothing is read from an id's
10
+ * spelling. A field the gateway leaves out is absent here too: a model with no
11
+ * price has no price, never a price of zero.
10
12
  */
13
+ import type { PausedModel } from '../product/limits.js';
14
+ /** The class a model is sold in, as the usage policy reads it. */
15
+ export type ModelClass = 'premium' | 'ours' | 'free';
16
+ /** Hanzo's own families. Every other model is grouped by who made it. */
17
+ export type ModelFamily = 'enso' | 'zen' | 'kai' | 'jev' | 'zoo';
18
+ /** What a model can be asked to do, from the modalities and capabilities it publishes. */
19
+ export type Capability = 'chat' | 'vision' | 'embeddings' | 'rerank' | 'image' | 'video' | 'audio' | 'decision' | 'tools' | 'reasoning';
20
+ /** List price, USD per 1M tokens, each side absent when the gateway lists none. */
21
+ export interface ModelPricing {
22
+ input_per_million?: number;
23
+ output_per_million?: number;
24
+ }
25
+ /** One row of `GET /v1/models`. */
11
26
  export interface ModelCatalogEntry {
12
- /** Gateway id, e.g. "claude-opus-4.8" */
13
27
  id: string;
14
- /** e.g. "anthropic" | "openai" | "hanzo" | "deepseek" */
28
+ /** Who made it: "anthropic", "openai", "zenlm", "hanzo", … */
15
29
  owned_by?: string;
16
- /** Optional explicit family label override */
17
- family?: string;
18
- /** Display label; defaults to id */
19
- label?: string;
30
+ name?: string;
31
+ description?: string;
32
+ class?: ModelClass;
33
+ family?: ModelFamily;
20
34
  premium?: boolean;
21
- /** "chat" (default) | "embedding" | "image" | ... */
22
- modality?: string;
35
+ /** Release time, Unix seconds. */
36
+ created?: number;
23
37
  context_window?: number;
24
- description?: string;
38
+ max_output_tokens?: number;
39
+ /** Input modalities: "text", "image", "audio", "file", "video". */
40
+ inputs?: string[];
41
+ /** What it answers with: "text", "image", "audio", "transcript", "embeddings", "rerank", "decision". */
42
+ outputs?: string[];
43
+ supports_vision?: boolean;
44
+ supports_tools?: boolean;
45
+ supports_reasoning?: boolean;
46
+ pricing?: ModelPricing;
25
47
  /** Absent, anyone may call it. `research`: it exists and nobody can call it yet. */
26
48
  access?: 'research';
27
49
  /** Where a person asks for access to a model they cannot call. */
@@ -30,38 +52,79 @@ export interface ModelCatalogEntry {
30
52
  /**
31
53
  * The models that exist and cannot be called, said once for every list of
32
54
  * models: a picker draws each one disabled, a catalogue page draws it muted.
33
- *
34
- * No gateway serves them, and that is the point: `/v1/models` never answers for
35
- * one, so nothing can route to it. A host that lists them appends these to what
36
- * the gateway said.
55
+ * `/v1/models` never answers for one, so nothing can route to it.
37
56
  */
38
57
  export declare const RESEARCH: ModelCatalogEntry[];
58
+ /** The catalog with the research models it does not already list, appended. */
59
+ export declare function withResearch(models: readonly ModelCatalogEntry[]): ModelCatalogEntry[];
60
+ /** One row, checked field by field: it is a network response. Null without an id. */
61
+ export declare function modelOf(v: unknown): ModelCatalogEntry | null;
39
62
  /**
40
- * Resolve the display family of a model.
41
- * Precedence: explicit `family` → enso id (house split, beats owned_by) →
42
- * owned_by map → llama id under any owner → capitalized owned_by → id prefix → "Other".
63
+ * The catalog from a `/v1/models` body (`{data: [...]}`) or its `data` array.
64
+ * Rows without an id are dropped; a repeated id keeps its first row.
43
65
  */
44
- export declare function familyOf(m: ModelCatalogEntry): string;
66
+ export declare function parseModels(body: unknown): ModelCatalogEntry[];
45
67
  /**
46
- * Group models by family, ordered house-then-marquee-then-alphabetical.
47
- * Model order within each family is the input order (stable).
68
+ * Fetch the catalog from an OpenAI-shaped `/models` endpoint. No caching, no
69
+ * state: the host owns both. Throws on a non-2xx answer.
48
70
  */
49
- export declare function groupModelsByFamily(models: ModelCatalogEntry[]): {
50
- family: string;
51
- models: ModelCatalogEntry[];
71
+ export declare function fetchModelCatalog(baseUrl?: string, token?: string): Promise<ModelCatalogEntry[]>;
72
+ /** The families, in the order every surface leads with them. */
73
+ export declare const FAMILIES: readonly {
74
+ id: ModelFamily;
75
+ label: string;
52
76
  }[];
77
+ export declare const CLASS_NAMES: Record<ModelClass, string>;
78
+ /** Who made a model, as the catalog keys it: `owned_by`, lowercased, without OpenRouter's `~` alias mark. */
79
+ export declare function makerOf(m: Pick<ModelCatalogEntry, 'owned_by'>): string;
80
+ /** A maker's display name. */
81
+ export declare function makerName(maker: string): string;
82
+ /** The name a model is shown by: the catalog's name, else its id. */
83
+ export declare function modelName(m: Pick<ModelCatalogEntry, 'id' | 'name'>): string;
84
+ /** The group a model is listed in: its Hanzo family, else its maker. */
85
+ export interface ModelGroup {
86
+ /** `family:zen`, `maker:anthropic`. */
87
+ key: string;
88
+ label: string;
89
+ family?: ModelFamily;
90
+ models: ModelCatalogEntry[];
91
+ }
92
+ export declare function groupKey(m: ModelCatalogEntry): string;
93
+ export declare function groupLabel(m: ModelCatalogEntry): string;
53
94
  /**
54
- * True when a model can be used for chat. Excludes embedding/image/video/
55
- * music/voice/tts/rerank/guard/foley/moderation/router by explicit modality
56
- * or by an id-segment heuristic.
95
+ * Models in groups: Hanzo's families first, in FAMILIES order, then every maker
96
+ * by name. Models keep the order they came in, so the caller sorts first.
57
97
  */
58
- export declare function isChatModel(m: ModelCatalogEntry): boolean;
59
- /** Keep only chat-capable models. */
60
- export declare function filterChatModels(models: ModelCatalogEntry[]): ModelCatalogEntry[];
98
+ export declare function groupModels(models: readonly ModelCatalogEntry[]): ModelGroup[];
61
99
  /**
62
- * Fetch a model catalog from an OpenAI-shaped `/models` endpoint.
63
- * SSR-safe: uses global fetch, no browser globals, no caching/state —
64
- * consumers own caching. Throws on a non-2xx response.
100
+ * What a model can do, read from what it publishes. A model that names no
101
+ * outputs is read as a text model, the way the gateway serves it.
65
102
  */
66
- export declare function fetchModelCatalog(baseUrl?: string, token?: string): Promise<ModelCatalogEntry[]>;
103
+ export declare function capabilitiesOf(m: ModelCatalogEntry): Capability[];
104
+ export declare function can(m: ModelCatalogEntry, c: Capability): boolean;
105
+ export declare const CAPABILITY_NAMES: Record<Capability, string>;
106
+ /** What `isPaused` reads of the payer's plan usage (`Limits` from `@hanzo/ui/product/limits`). */
107
+ export interface PauseSource {
108
+ classes: Partial<Record<ModelClass, {
109
+ state: string;
110
+ }>>;
111
+ paused?: readonly Pick<PausedModel, 'model'>[];
112
+ }
113
+ /** Whether `id` matches a paused entry: the same id, or a glob whose `*` stands for any run of characters. */
114
+ export declare function matchesPaused(id: string, pattern: string): boolean;
115
+ /**
116
+ * Whether the payer's plan has paused this model: its whole class is limited,
117
+ * or an entry in `paused` names it. It is still listed and still picked; the
118
+ * gateway refuses it or answers from Enso.
119
+ */
120
+ export declare function isPaused(m: Pick<ModelCatalogEntry, 'id' | 'class'>, limits: PauseSource | null | undefined): boolean;
121
+ /** Case-insensitive search: every word of the query appears in the model's id, name, maker, group or description. */
122
+ export declare function matchesModel(m: ModelCatalogEntry, query: string): boolean;
123
+ export type ModelSort = 'name' | 'newest' | 'context' | 'price';
124
+ /** A sorted copy. Context and price put models without the figure last. */
125
+ export declare function sortModels(models: readonly ModelCatalogEntry[], by?: ModelSort): ModelCatalogEntry[];
126
+ /** "200K", "1M", "1.5M"; "" when the catalog states no window. */
127
+ export declare function formatContext(n: number | undefined): string;
128
+ /** "$3.00" per 1M tokens, "Free" at zero, "" when the catalog lists no price. */
129
+ export declare function formatPrice(n: number | undefined): string;
67
130
  //# sourceMappingURL=catalog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/models/catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAA;IACV,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,oFAAoF;IACpF,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,EAAE,iBAAiB,EASvC,CAAA;AAsDD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAmBrD;AAaD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,iBAAiB,EAAE,GAC1B;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAAE,EAAE,CAWnD;AAkBD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAMzD;AAED,qCAAqC;AACrC,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAEjF;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA6B9B"}
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/models/catalog.ts"],"names":[],"mappings":"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"}