@hanzo/ui 8.27.61 → 8.27.64

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 (51) hide show
  1. package/dist/auth/SignIn.cjs +2 -78
  2. package/dist/auth/SignIn.d.ts +1 -9
  3. package/dist/auth/SignIn.d.ts.map +1 -1
  4. package/dist/auth/SignIn.js +2 -78
  5. package/dist/auth/SignIn.js.map +1 -1
  6. package/dist/consent/Consent.cjs +8 -23
  7. package/dist/consent/Consent.d.ts.map +1 -1
  8. package/dist/consent/Consent.js +11 -26
  9. package/dist/consent/Consent.js.map +1 -1
  10. package/dist/gallery.cjs +2 -2
  11. package/dist/gallery.d.ts.map +1 -1
  12. package/dist/gallery.html +2 -2
  13. package/dist/gallery.js +2 -2
  14. package/dist/gallery.js.map +1 -1
  15. package/dist/marketing/Footer.cjs +1 -1
  16. package/dist/marketing/Footer.js +1 -1
  17. package/dist/models/catalog.cjs +22 -1
  18. package/dist/models/catalog.d.ts +9 -0
  19. package/dist/models/catalog.d.ts.map +1 -1
  20. package/dist/models/catalog.js +20 -0
  21. package/dist/models/catalog.js.map +1 -1
  22. package/dist/models/index.cjs +3 -3
  23. package/dist/models/index.d.ts +2 -2
  24. package/dist/models/index.d.ts.map +1 -1
  25. package/dist/models/index.js +2 -2
  26. package/dist/models/index.js.map +1 -1
  27. package/dist/models/picker.logic.cjs +3 -24
  28. package/dist/models/picker.logic.d.ts +1 -11
  29. package/dist/models/picker.logic.d.ts.map +1 -1
  30. package/dist/models/picker.logic.js +2 -22
  31. package/dist/models/picker.logic.js.map +1 -1
  32. package/dist/product/LimitedBanner.cjs +15 -9
  33. package/dist/product/LimitedBanner.d.ts +22 -2
  34. package/dist/product/LimitedBanner.d.ts.map +1 -1
  35. package/dist/product/LimitedBanner.js +14 -9
  36. package/dist/product/LimitedBanner.js.map +1 -1
  37. package/dist/product/PlanUsage.cjs +26 -13
  38. package/dist/product/PlanUsage.d.ts +12 -3
  39. package/dist/product/PlanUsage.d.ts.map +1 -1
  40. package/dist/product/PlanUsage.js +26 -13
  41. package/dist/product/PlanUsage.js.map +1 -1
  42. package/dist/product/UsageMeter.cjs +3 -5
  43. package/dist/product/UsageMeter.d.ts.map +1 -1
  44. package/dist/product/UsageMeter.js +3 -5
  45. package/dist/product/UsageMeter.js.map +1 -1
  46. package/dist/product/limits.cjs +43 -15
  47. package/dist/product/limits.d.ts +18 -5
  48. package/dist/product/limits.d.ts.map +1 -1
  49. package/dist/product/limits.js +41 -14
  50. package/dist/product/limits.js.map +1 -1
  51. package/package.json +2 -2
@@ -1,11 +1,8 @@
1
1
  /**
2
2
  * ModelPicker's decisions, as pure functions over plain values: which rows are
3
- * drawn, which slice of them a scrolled viewport shows, and which model a new
4
- * conversation starts on. Tested in node.
3
+ * drawn, and which slice of them a scrolled viewport shows. Tested in node.
5
4
  */
6
- import { can, FAMILIES, groupModels, matchesModel, sortModels, withResearch, } from './catalog.js';
7
- /** The house router: what a conversation is answered by until a model is picked. */
8
- export const ENSO = 'enso-auto';
5
+ import { can, ENSO, groupModels, matchesModel, sortModels, withResearch, } from './catalog.js';
9
6
  /** Whether a model may be picked: everything the gateway lists, never a research preview. */
10
7
  export const pickable = (m) => m.access !== 'research';
11
8
  /**
@@ -54,21 +51,4 @@ export function revealTop(i, top, height, row) {
54
51
  return y + row - height;
55
52
  return null;
56
53
  }
57
- /**
58
- * The model a new conversation, run or playground tab starts on: Enso for a
59
- * conversation, else the first of Hanzo's own models that does what the scope
60
- * asks, else the first free or Hanzo model that does. Never a premium model:
61
- * a person picks one of those. '' when nothing qualifies.
62
- */
63
- export function defaultModel(models, scope = 'chat') {
64
- const offered = models.filter((m) => pickable(m) && m.class !== 'premium' && can(m, scope));
65
- if (scope === 'chat' && offered.some((m) => m.id === ENSO))
66
- return ENSO;
67
- for (const f of FAMILIES) {
68
- const ours = sortModels(offered.filter((m) => m.family === f.id));
69
- if (ours.length)
70
- return ours[0].id;
71
- }
72
- return sortModels(offered)[0]?.id ?? '';
73
- }
74
54
  //# sourceMappingURL=picker.logic.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"picker.logic.js","sourceRoot":"","sources":["../../src/models/picker.logic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"picker.logic.js","sourceRoot":"","sources":["../../src/models/picker.logic.ts"],"names":[],"mappings":"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"}
@@ -1,23 +1,29 @@
1
1
  'use client';"use strict";
2
2
  'use client';
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.LimitActions = LimitActions;
4
5
  exports.LimitedBanner = LimitedBanner;
5
6
  const jsx_runtime_1 = require("react/jsx-runtime");
6
- /**
7
- * LimitedBanner — the reader's usage is paused or refused: the server's message,
8
- * the ways past it (Upgrade, Add prepaid credit) and, where the host has one, a
9
- * quiet "See usage" to its usage settings. One line where it fits. Neutral
10
- * chrome; the dot is the one status colour.
11
- */
12
7
  const gui_1 = require("@hanzo/gui");
13
8
  const lucide_icons_2_1 = require("@hanzogui/lucide-icons-2");
14
9
  const button_1 = require("../backends/gui/button.cjs");
15
10
  const slot_1 = require("../backends/gui/slot.cjs");
16
11
  const gesture_1 = require("../backends/gui/gesture.cjs");
12
+ const limits_1 = require("./limits.cjs");
17
13
  const go = (a) => {
18
- if (typeof window !== 'undefined')
14
+ if (a.url && typeof window !== 'undefined')
19
15
  window.location.assign(a.url);
20
16
  };
21
- function LimitedBanner({ message, actions = [], onAction = go, onUsage, onClose }) {
22
- return ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { role: "status", "aria-live": "polite", ...(0, slot_1.slot)('limited-banner'), width: "100%", items: "center", flexWrap: "wrap", gap: "$3", px: "$3", py: "$2.5", rounded: "$4", borderWidth: 1, borderColor: "$edge", bg: "$panel", children: [(0, jsx_runtime_1.jsxs)(gui_1.XStack, { flex: 1, minW: 200, items: "center", gap: "$2.5", children: [(0, jsx_runtime_1.jsx)(gui_1.View, { width: 8, height: 8, rounded: 4, bg: "$bad", shrink: 0, "aria-hidden": true }), (0, jsx_runtime_1.jsx)(gui_1.Text, { fontSize: "$2", color: "$ink", ...(0, slot_1.slot)('limited-banner-message'), children: message })] }), actions.length || onUsage ? ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { gap: "$2", shrink: 0, flexWrap: "wrap", items: "center", children: [actions.map((a) => ((0, jsx_runtime_1.jsx)(button_1.Button, { size: "sm", variant: a.kind === 'upgrade' ? 'default' : 'outline', "data-kind": a.kind, onPress: () => onAction(a), children: a.label }, `${a.kind}:${a.url}`))), onUsage ? ((0, jsx_runtime_1.jsx)(button_1.Button, { size: "sm", variant: "ghost", "data-kind": "usage", onPress: onUsage, children: "See usage" })) : null] })) : null, onClose ? ((0, jsx_runtime_1.jsx)(button_1.Button, { variant: "ghost", size: "icon", minH: 24, minW: 24, ...(0, gesture_1.touch)(24), "aria-label": "Dismiss", onPress: onClose, children: (0, jsx_runtime_1.jsx)(lucide_icons_2_1.X, { size: 14 }) })) : null] }));
17
+ /**
18
+ * The server's actions in the order it sent them: the first is the one filled
19
+ * control, the rest quiet. Only pages are offered when the host takes no action.
20
+ */
21
+ function LimitActions({ actions, onAction, children, }) {
22
+ const shown = onAction ? actions : actions.filter(limits_1.navigable);
23
+ if (!shown.length && !children)
24
+ return null;
25
+ return ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { gap: "$2", shrink: 0, flexWrap: "wrap", items: "center", children: [shown.map((a, i) => ((0, jsx_runtime_1.jsx)(button_1.Button, { size: "sm", variant: i === 0 ? 'primary' : 'default', "data-kind": a.kind, onPress: () => (onAction ?? go)(a), children: a.label }, `${a.kind}:${a.url ?? a.model ?? i}`))), children] }));
26
+ }
27
+ function LimitedBanner({ message, actions = [], onAction, onUsage, onClose }) {
28
+ return ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { role: "status", "aria-live": "polite", ...(0, slot_1.slot)('limited-banner'), width: "100%", items: "center", flexWrap: "wrap", gap: "$3", px: "$3", py: "$2.5", rounded: "$4", borderWidth: 1, borderColor: "$edge", bg: "$panel", children: [(0, jsx_runtime_1.jsxs)(gui_1.XStack, { flex: 1, minW: 200, items: "center", gap: "$2.5", children: [(0, jsx_runtime_1.jsx)(gui_1.View, { width: 8, height: 8, rounded: 4, bg: "$bad", shrink: 0, "aria-hidden": true }), (0, jsx_runtime_1.jsx)(gui_1.Text, { fontSize: "$2", color: "$ink", ...(0, slot_1.slot)('limited-banner-message'), children: message })] }), (0, jsx_runtime_1.jsx)(LimitActions, { actions: actions, onAction: onAction, children: onUsage ? ((0, jsx_runtime_1.jsx)(button_1.Button, { size: "sm", variant: "ghost", "data-kind": "usage", onPress: onUsage, children: "See usage" })) : null }), onClose ? ((0, jsx_runtime_1.jsx)(button_1.Button, { variant: "ghost", size: "icon", minH: 24, minW: 24, ...(0, gesture_1.touch)(24), "aria-label": "Dismiss", onPress: onClose, children: (0, jsx_runtime_1.jsx)(lucide_icons_2_1.X, { size: 14 }) })) : null] }));
23
29
  }
@@ -1,12 +1,32 @@
1
- import type { LimitAction } from './limits.js';
1
+ /**
2
+ * LimitedBanner — the reader's usage is paused or refused: the server's message,
3
+ * the ways past it (Upgrade, Add prepaid credit) and, where the host has one, a
4
+ * quiet "See usage" to its usage settings. One line where it fits. Neutral
5
+ * chrome; the dot is the one status colour.
6
+ */
7
+ import type { ReactNode } from 'react';
8
+ import { type LimitAction } from './limits.js';
2
9
  export interface LimitedBannerProps {
3
10
  message: string;
4
11
  actions?: readonly LimitAction[];
5
- /** Takes an action; by default the page goes to its URL. */
12
+ /**
13
+ * Takes an action. Without one only the pages (Upgrade, Add prepaid credit)
14
+ * are offered, and the browser goes to their URL: Continue with credits and a
15
+ * model switch need the host.
16
+ */
6
17
  onAction?: (action: LimitAction) => void;
7
18
  /** Opens the host's usage settings; draws "See usage" when given. */
8
19
  onUsage?: () => void;
9
20
  onClose?: () => void;
10
21
  }
22
+ /**
23
+ * The server's actions in the order it sent them: the first is the one filled
24
+ * control, the rest quiet. Only pages are offered when the host takes no action.
25
+ */
26
+ export declare function LimitActions({ actions, onAction, children, }: {
27
+ actions: readonly LimitAction[];
28
+ onAction?: (action: LimitAction) => void;
29
+ children?: ReactNode;
30
+ }): import("react").JSX.Element | null;
11
31
  export declare function LimitedBanner({ message, actions, onAction, onUsage, onClose }: LimitedBannerProps): import("react").JSX.Element;
12
32
  //# sourceMappingURL=LimitedBanner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LimitedBanner.d.ts","sourceRoot":"","sources":["../../src/product/LimitedBanner.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAChC,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAA;IACxC,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAMD,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,OAAY,EAAE,QAAa,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,kBAAkB,+BAkD3G"}
1
+ {"version":3,"file":"LimitedBanner.d.ts","sourceRoot":"","sources":["../../src/product/LimitedBanner.tsx"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AAEtD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAChC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAA;IACxC,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,OAAO,EAAE,SAAS,WAAW,EAAE,CAAA;IAC/B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAA;IACxC,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB,sCAmBA;AAED,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,OAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,kBAAkB,+BAqCtG"}
@@ -1,21 +1,26 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- /**
4
- * LimitedBanner — the reader's usage is paused or refused: the server's message,
5
- * the ways past it (Upgrade, Add prepaid credit) and, where the host has one, a
6
- * quiet "See usage" to its usage settings. One line where it fits. Neutral
7
- * chrome; the dot is the one status colour.
8
- */
9
3
  import { Text, View, XStack } from '@hanzo/gui';
10
4
  import { X } from '@hanzogui/lucide-icons-2';
11
5
  import { Button } from '../backends/gui/button.js';
12
6
  import { slot } from '../backends/gui/slot.js';
13
7
  import { touch } from '../backends/gui/gesture.js';
8
+ import { navigable } from './limits.js';
14
9
  const go = (a) => {
15
- if (typeof window !== 'undefined')
10
+ if (a.url && typeof window !== 'undefined')
16
11
  window.location.assign(a.url);
17
12
  };
18
- export function LimitedBanner({ message, actions = [], onAction = go, onUsage, onClose }) {
19
- return (_jsxs(XStack, { role: "status", "aria-live": "polite", ...slot('limited-banner'), width: "100%", items: "center", flexWrap: "wrap", gap: "$3", px: "$3", py: "$2.5", rounded: "$4", borderWidth: 1, borderColor: "$edge", bg: "$panel", children: [_jsxs(XStack, { flex: 1, minW: 200, items: "center", gap: "$2.5", children: [_jsx(View, { width: 8, height: 8, rounded: 4, bg: "$bad", shrink: 0, "aria-hidden": true }), _jsx(Text, { fontSize: "$2", color: "$ink", ...slot('limited-banner-message'), children: message })] }), actions.length || onUsage ? (_jsxs(XStack, { gap: "$2", shrink: 0, flexWrap: "wrap", items: "center", children: [actions.map((a) => (_jsx(Button, { size: "sm", variant: a.kind === 'upgrade' ? 'default' : 'outline', "data-kind": a.kind, onPress: () => onAction(a), children: a.label }, `${a.kind}:${a.url}`))), onUsage ? (_jsx(Button, { size: "sm", variant: "ghost", "data-kind": "usage", onPress: onUsage, children: "See usage" })) : null] })) : null, onClose ? (_jsx(Button, { variant: "ghost", size: "icon", minH: 24, minW: 24, ...touch(24), "aria-label": "Dismiss", onPress: onClose, children: _jsx(X, { size: 14 }) })) : null] }));
13
+ /**
14
+ * The server's actions in the order it sent them: the first is the one filled
15
+ * control, the rest quiet. Only pages are offered when the host takes no action.
16
+ */
17
+ export function LimitActions({ actions, onAction, children, }) {
18
+ const shown = onAction ? actions : actions.filter(navigable);
19
+ if (!shown.length && !children)
20
+ return null;
21
+ return (_jsxs(XStack, { gap: "$2", shrink: 0, flexWrap: "wrap", items: "center", children: [shown.map((a, i) => (_jsx(Button, { size: "sm", variant: i === 0 ? 'primary' : 'default', "data-kind": a.kind, onPress: () => (onAction ?? go)(a), children: a.label }, `${a.kind}:${a.url ?? a.model ?? i}`))), children] }));
22
+ }
23
+ export function LimitedBanner({ message, actions = [], onAction, onUsage, onClose }) {
24
+ return (_jsxs(XStack, { role: "status", "aria-live": "polite", ...slot('limited-banner'), width: "100%", items: "center", flexWrap: "wrap", gap: "$3", px: "$3", py: "$2.5", rounded: "$4", borderWidth: 1, borderColor: "$edge", bg: "$panel", children: [_jsxs(XStack, { flex: 1, minW: 200, items: "center", gap: "$2.5", children: [_jsx(View, { width: 8, height: 8, rounded: 4, bg: "$bad", shrink: 0, "aria-hidden": true }), _jsx(Text, { fontSize: "$2", color: "$ink", ...slot('limited-banner-message'), children: message })] }), _jsx(LimitActions, { actions: actions, onAction: onAction, children: onUsage ? (_jsx(Button, { size: "sm", variant: "ghost", "data-kind": "usage", onPress: onUsage, children: "See usage" })) : null }), onClose ? (_jsx(Button, { variant: "ghost", size: "icon", minH: 24, minW: 24, ...touch(24), "aria-label": "Dismiss", onPress: onClose, children: _jsx(X, { size: 14 }) })) : null] }));
20
25
  }
21
26
  //# sourceMappingURL=LimitedBanner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LimitedBanner.js","sourceRoot":"","sources":["../../src/product/LimitedBanner.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LimitedBanner.js","sourceRoot":"","sources":["../../src/product/LimitedBanner.tsx"],"names":[],"mappings":"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"}
@@ -1,45 +1,58 @@
1
1
  'use client';"use strict";
2
2
  'use client';
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.FREE_TERMS = exports.PLAN_TERMS = void 0;
4
+ exports.CREDITS_TERMS = exports.FREE_TERMS = exports.PLAN_TERMS = void 0;
5
5
  exports.PlanUsage = PlanUsage;
6
6
  const jsx_runtime_1 = require("react/jsx-runtime");
7
7
  /**
8
8
  * PlanUsage — the plan, its period, what it includes in plain words, a
9
- * UsageMeter, and the ways to more (Upgrade, Add prepaid credit). A paused class
10
- * leads with its LimitedBanner. Shares only, never an amount or a count.
9
+ * UsageMeter, the org's choice to keep paying from credits once included usage
10
+ * runs out, and the server's ways to more. A paused class leads with its
11
+ * LimitedBanner. Shares only, never an amount or a count.
11
12
  */
13
+ const react_1 = require("react");
12
14
  const gui_1 = require("@hanzo/gui");
13
- const button_1 = require("../backends/gui/button.cjs");
15
+ const gui_2 = require("../backends/gui/index.cjs");
16
+ const switch_1 = require("../backends/gui/switch.cjs");
14
17
  const slot_1 = require("../backends/gui/slot.cjs");
15
18
  const LimitedBanner_1 = require("./LimitedBanner.cjs");
16
19
  const UsageMeter_1 = require("./UsageMeter.cjs");
17
20
  /** What a paid plan includes, and what happens past it. */
18
21
  exports.PLAN_TERMS = [
19
22
  'Your plan includes usage of premium and Hanzo models each period.',
20
- 'Beyond it, prepaid credit pays.',
21
- 'Without prepaid credit, you continue in limited mode on free models.',
23
+ 'Beyond it, prepaid credit pays when you choose to continue with credits.',
24
+ 'Otherwise you continue in limited mode on free models.',
22
25
  ];
23
26
  /** What the free plan includes. */
24
27
  exports.FREE_TERMS = [
25
28
  'The free plan includes limited usage of free models.',
26
- 'Upgrade for premium and Hanzo models, or add prepaid credit to pay as you go.',
29
+ 'Upgrade for premium and Hanzo models, or add credits to pay as you go.',
27
30
  ];
31
+ /** The opt-in, in one sentence. */
32
+ exports.CREDITS_TERMS = "When your plan's included usage runs out, keep using any model and pay from your credits.";
28
33
  /** A slug as a name: "max-20x" reads "Max 20x". */
29
34
  const named = (slug) => slug.split('-').map((w) => (w ? w[0].toUpperCase() + w.slice(1) : w)).join(' ');
30
35
  const day = (iso) => {
31
36
  const t = iso ? Date.parse(iso) : NaN;
32
37
  return Number.isNaN(t) ? '' : new Date(t).toLocaleDateString('en-US', { timeZone: 'UTC', month: 'short', day: 'numeric' });
33
38
  };
34
- const go = (a) => {
35
- if (typeof window !== 'undefined')
36
- window.location.assign(a.url);
37
- };
38
- function PlanUsage({ limits, plan, notice, onAction = go, now }) {
39
+ function Credits({ on, onCredits, creditsHref, addCreditsHref, }) {
40
+ const [busy, setBusy] = (0, react_1.useState)(false);
41
+ const [wrong, setWrong] = (0, react_1.useState)('');
42
+ const flip = (next) => {
43
+ setBusy(true);
44
+ setWrong('');
45
+ onCredits(next)
46
+ .catch((e) => setWrong(e instanceof Error && e.message ? e.message : 'That did not save. Try again.'))
47
+ .finally(() => setBusy(false));
48
+ };
49
+ return ((0, jsx_runtime_1.jsxs)(gui_1.YStack, { gap: "$2", ...(0, slot_1.slot)('plan-usage-credits'), children: [(0, jsx_runtime_1.jsxs)(gui_1.XStack, { gap: "$3", items: "center", justify: "space-between", children: [(0, jsx_runtime_1.jsx)(gui_1.Text, { fontSize: "$2", color: "$ink", flex: 1, minW: 0, children: exports.CREDITS_TERMS }), (0, jsx_runtime_1.jsx)(switch_1.Switch, { checked: on, disabled: busy, onCheckedChange: flip, "aria-label": "Continue with credits" })] }), creditsHref || addCreditsHref ? ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { gap: "$4", flexWrap: "wrap", children: [creditsHref ? ((0, jsx_runtime_1.jsx)(gui_2.Anchor, { href: creditsHref, fontSize: "$2", color: "$soft", children: "Credits balance" })) : null, addCreditsHref ? ((0, jsx_runtime_1.jsx)(gui_2.Anchor, { href: addCreditsHref, fontSize: "$2", color: "$soft", children: "Add credits" })) : null] })) : null, wrong ? ((0, jsx_runtime_1.jsx)(gui_1.Text, { role: "alert", fontSize: "$2", color: "$bad", children: wrong })) : null] }));
50
+ }
51
+ function PlanUsage({ limits, plan, notice, onAction, onCredits, creditsHref, addCreditsHref, now }) {
39
52
  const free = !limits.plan;
40
53
  const name = plan || (free ? 'Free' : named(limits.plan));
41
54
  const from = day(limits.period_start);
42
55
  const to = day(limits.period_end);
43
56
  const terms = free ? exports.FREE_TERMS : exports.PLAN_TERMS;
44
- return ((0, jsx_runtime_1.jsxs)(gui_1.YStack, { gap: "$4", width: "100%", minW: 0, ...(0, slot_1.slot)('plan-usage'), children: [(0, jsx_runtime_1.jsxs)(gui_1.YStack, { gap: "$1", children: [(0, jsx_runtime_1.jsxs)(gui_1.Text, { fontSize: "$5", fontWeight: "600", color: "$ink", children: [name, " plan"] }), from && to ? ((0, jsx_runtime_1.jsxs)(gui_1.Text, { fontSize: "$2", color: "$soft", children: ["Current period ", from, " \u2013 ", to] })) : null] }), notice ? (0, jsx_runtime_1.jsx)(LimitedBanner_1.LimitedBanner, { message: notice.message, actions: notice.actions, onAction: onAction }) : null, (0, jsx_runtime_1.jsx)(UsageMeter_1.UsageMeter, { limits: limits, now: now }), (0, jsx_runtime_1.jsx)(gui_1.YStack, { gap: "$1", ...(0, slot_1.slot)('plan-usage-terms'), children: terms.map((line) => ((0, jsx_runtime_1.jsx)(gui_1.Text, { fontSize: "$2", color: "$soft", children: line }, line))) }), !notice && limits.actions.length ? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { gap: "$2", flexWrap: "wrap", children: limits.actions.map((a) => ((0, jsx_runtime_1.jsx)(button_1.Button, { size: "sm", variant: a.kind === 'upgrade' ? 'default' : 'outline', "data-kind": a.kind, onPress: () => onAction(a), children: a.label }, `${a.kind}:${a.url}`))) })) : null] }));
57
+ return ((0, jsx_runtime_1.jsxs)(gui_1.YStack, { gap: "$4", width: "100%", minW: 0, ...(0, slot_1.slot)('plan-usage'), children: [(0, jsx_runtime_1.jsxs)(gui_1.YStack, { gap: "$1", children: [(0, jsx_runtime_1.jsxs)(gui_1.Text, { fontSize: "$5", fontWeight: "600", color: "$ink", children: [name, " plan"] }), from && to ? ((0, jsx_runtime_1.jsxs)(gui_1.Text, { fontSize: "$2", color: "$soft", children: ["Current period ", from, " \u2013 ", to] })) : null] }), notice ? (0, jsx_runtime_1.jsx)(LimitedBanner_1.LimitedBanner, { message: notice.message, actions: notice.actions, onAction: onAction }) : null, (0, jsx_runtime_1.jsx)(UsageMeter_1.UsageMeter, { limits: limits, now: now }), (0, jsx_runtime_1.jsx)(gui_1.YStack, { gap: "$1", ...(0, slot_1.slot)('plan-usage-terms'), children: terms.map((line) => ((0, jsx_runtime_1.jsx)(gui_1.Text, { fontSize: "$2", color: "$soft", children: line }, line))) }), limits.creditsAfterAllowance !== undefined && onCredits ? ((0, jsx_runtime_1.jsx)(Credits, { on: limits.creditsAfterAllowance, onCredits: onCredits, creditsHref: creditsHref, addCreditsHref: addCreditsHref })) : null, !notice ? (0, jsx_runtime_1.jsx)(LimitedBanner_1.LimitActions, { actions: limits.actions, onAction: onAction }) : null] }));
45
58
  }
@@ -1,15 +1,24 @@
1
1
  import type { LimitAction, LimitNotice, Limits } from './limits.js';
2
2
  /** What a paid plan includes, and what happens past it. */
3
- export declare const PLAN_TERMS: readonly ['Your plan includes usage of premium and Hanzo models each period.', 'Beyond it, prepaid credit pays.', 'Without prepaid credit, you continue in limited mode on free models.'];
3
+ export declare const PLAN_TERMS: readonly ['Your plan includes usage of premium and Hanzo models each period.', 'Beyond it, prepaid credit pays when you choose to continue with credits.', 'Otherwise you continue in limited mode on free models.'];
4
4
  /** What the free plan includes. */
5
- export declare const FREE_TERMS: readonly ['The free plan includes limited usage of free models.', 'Upgrade for premium and Hanzo models, or add prepaid credit to pay as you go.'];
5
+ export declare const FREE_TERMS: readonly ['The free plan includes limited usage of free models.', 'Upgrade for premium and Hanzo models, or add credits to pay as you go.'];
6
+ /** The opt-in, in one sentence. */
7
+ export declare const CREDITS_TERMS = "When your plan's included usage runs out, keep using any model and pay from your credits.";
6
8
  export interface PlanUsageProps {
7
9
  limits: Limits;
8
10
  /** The plan's display name; the slug made readable when absent. */
9
11
  plan?: string;
10
12
  notice?: LimitNotice | null;
13
+ /** Takes an action; without one only the pages are offered. */
11
14
  onAction?: (action: LimitAction) => void;
15
+ /** Writes the org's continue-with-credits choice; the switch shows only when the limits carry it. */
16
+ onCredits?: (on: boolean) => Promise<void>;
17
+ /** Where the org's credits balance is read. */
18
+ creditsHref?: string;
19
+ /** Where credits are added. */
20
+ addCreditsHref?: string;
12
21
  now?: number;
13
22
  }
14
- export declare function PlanUsage({ limits, plan, notice, onAction, now }: PlanUsageProps): import("react").JSX.Element;
23
+ export declare function PlanUsage({ limits, plan, notice, onAction, onCredits, creditsHref, addCreditsHref, now }: PlanUsageProps): import("react").JSX.Element;
15
24
  //# sourceMappingURL=PlanUsage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlanUsage.d.ts","sourceRoot":"","sources":["../../src/product/PlanUsage.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEhE,2DAA2D;AAC3D,eAAO,MAAM,UAAU,YACrB,mEAAmE,EACnE,iCAAiC,EACjC,sEAAsE,CAC9D,CAAA;AAEV,mCAAmC;AACnC,eAAO,MAAM,UAAU,YACrB,sDAAsD,EACtD,+EAA+E,CACvE,CAAA;AAUV,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IAC3B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAA;IACxC,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAMD,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAa,EAAE,GAAG,EAAE,EAAE,cAAc,+BA4CrF"}
1
+ {"version":3,"file":"PlanUsage.d.ts","sourceRoot":"","sources":["../../src/product/PlanUsage.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEhE,2DAA2D;AAC3D,eAAO,MAAM,UAAU,YACrB,mEAAmE,EACnE,0EAA0E,EAC1E,wDAAwD,CAChD,CAAA;AAEV,mCAAmC;AACnC,eAAO,MAAM,UAAU,YACrB,sDAAsD,EACtD,wEAAwE,CAChE,CAAA;AAEV,mCAAmC;AACnC,eAAO,MAAM,aAAa,8FAA8F,CAAA;AAUxH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAA;IACxC,qGAAqG;IACrG,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,+BAA+B;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAqDD,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,EAAE,EAAE,cAAc,+BAiCxH"}
@@ -2,41 +2,54 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  /**
4
4
  * PlanUsage — the plan, its period, what it includes in plain words, a
5
- * UsageMeter, and the ways to more (Upgrade, Add prepaid credit). A paused class
6
- * leads with its LimitedBanner. Shares only, never an amount or a count.
5
+ * UsageMeter, the org's choice to keep paying from credits once included usage
6
+ * runs out, and the server's ways to more. A paused class leads with its
7
+ * LimitedBanner. Shares only, never an amount or a count.
7
8
  */
9
+ import { useState } from 'react';
8
10
  import { Text, XStack, YStack } from '@hanzo/gui';
9
- import { Button } from '../backends/gui/button.js';
11
+ import { Anchor } from '../backends/gui/index.js';
12
+ import { Switch } from '../backends/gui/switch.js';
10
13
  import { slot } from '../backends/gui/slot.js';
11
- import { LimitedBanner } from './LimitedBanner.js';
14
+ import { LimitActions, LimitedBanner } from './LimitedBanner.js';
12
15
  import { UsageMeter } from './UsageMeter.js';
13
16
  /** What a paid plan includes, and what happens past it. */
14
17
  export const PLAN_TERMS = [
15
18
  'Your plan includes usage of premium and Hanzo models each period.',
16
- 'Beyond it, prepaid credit pays.',
17
- 'Without prepaid credit, you continue in limited mode on free models.',
19
+ 'Beyond it, prepaid credit pays when you choose to continue with credits.',
20
+ 'Otherwise you continue in limited mode on free models.',
18
21
  ];
19
22
  /** What the free plan includes. */
20
23
  export const FREE_TERMS = [
21
24
  'The free plan includes limited usage of free models.',
22
- 'Upgrade for premium and Hanzo models, or add prepaid credit to pay as you go.',
25
+ 'Upgrade for premium and Hanzo models, or add credits to pay as you go.',
23
26
  ];
27
+ /** The opt-in, in one sentence. */
28
+ export const CREDITS_TERMS = "When your plan's included usage runs out, keep using any model and pay from your credits.";
24
29
  /** A slug as a name: "max-20x" reads "Max 20x". */
25
30
  const named = (slug) => slug.split('-').map((w) => (w ? w[0].toUpperCase() + w.slice(1) : w)).join(' ');
26
31
  const day = (iso) => {
27
32
  const t = iso ? Date.parse(iso) : NaN;
28
33
  return Number.isNaN(t) ? '' : new Date(t).toLocaleDateString('en-US', { timeZone: 'UTC', month: 'short', day: 'numeric' });
29
34
  };
30
- const go = (a) => {
31
- if (typeof window !== 'undefined')
32
- window.location.assign(a.url);
33
- };
34
- export function PlanUsage({ limits, plan, notice, onAction = go, now }) {
35
+ function Credits({ on, onCredits, creditsHref, addCreditsHref, }) {
36
+ const [busy, setBusy] = useState(false);
37
+ const [wrong, setWrong] = useState('');
38
+ const flip = (next) => {
39
+ setBusy(true);
40
+ setWrong('');
41
+ onCredits(next)
42
+ .catch((e) => setWrong(e instanceof Error && e.message ? e.message : 'That did not save. Try again.'))
43
+ .finally(() => setBusy(false));
44
+ };
45
+ return (_jsxs(YStack, { gap: "$2", ...slot('plan-usage-credits'), children: [_jsxs(XStack, { gap: "$3", items: "center", justify: "space-between", children: [_jsx(Text, { fontSize: "$2", color: "$ink", flex: 1, minW: 0, children: CREDITS_TERMS }), _jsx(Switch, { checked: on, disabled: busy, onCheckedChange: flip, "aria-label": "Continue with credits" })] }), creditsHref || addCreditsHref ? (_jsxs(XStack, { gap: "$4", flexWrap: "wrap", children: [creditsHref ? (_jsx(Anchor, { href: creditsHref, fontSize: "$2", color: "$soft", children: "Credits balance" })) : null, addCreditsHref ? (_jsx(Anchor, { href: addCreditsHref, fontSize: "$2", color: "$soft", children: "Add credits" })) : null] })) : null, wrong ? (_jsx(Text, { role: "alert", fontSize: "$2", color: "$bad", children: wrong })) : null] }));
46
+ }
47
+ export function PlanUsage({ limits, plan, notice, onAction, onCredits, creditsHref, addCreditsHref, now }) {
35
48
  const free = !limits.plan;
36
49
  const name = plan || (free ? 'Free' : named(limits.plan));
37
50
  const from = day(limits.period_start);
38
51
  const to = day(limits.period_end);
39
52
  const terms = free ? FREE_TERMS : PLAN_TERMS;
40
- return (_jsxs(YStack, { gap: "$4", width: "100%", minW: 0, ...slot('plan-usage'), children: [_jsxs(YStack, { gap: "$1", children: [_jsxs(Text, { fontSize: "$5", fontWeight: "600", color: "$ink", children: [name, " plan"] }), from && to ? (_jsxs(Text, { fontSize: "$2", color: "$soft", children: ["Current period ", from, " \u2013 ", to] })) : null] }), notice ? _jsx(LimitedBanner, { message: notice.message, actions: notice.actions, onAction: onAction }) : null, _jsx(UsageMeter, { limits: limits, now: now }), _jsx(YStack, { gap: "$1", ...slot('plan-usage-terms'), children: terms.map((line) => (_jsx(Text, { fontSize: "$2", color: "$soft", children: line }, line))) }), !notice && limits.actions.length ? (_jsx(XStack, { gap: "$2", flexWrap: "wrap", children: limits.actions.map((a) => (_jsx(Button, { size: "sm", variant: a.kind === 'upgrade' ? 'default' : 'outline', "data-kind": a.kind, onPress: () => onAction(a), children: a.label }, `${a.kind}:${a.url}`))) })) : null] }));
53
+ return (_jsxs(YStack, { gap: "$4", width: "100%", minW: 0, ...slot('plan-usage'), children: [_jsxs(YStack, { gap: "$1", children: [_jsxs(Text, { fontSize: "$5", fontWeight: "600", color: "$ink", children: [name, " plan"] }), from && to ? (_jsxs(Text, { fontSize: "$2", color: "$soft", children: ["Current period ", from, " \u2013 ", to] })) : null] }), notice ? _jsx(LimitedBanner, { message: notice.message, actions: notice.actions, onAction: onAction }) : null, _jsx(UsageMeter, { limits: limits, now: now }), _jsx(YStack, { gap: "$1", ...slot('plan-usage-terms'), children: terms.map((line) => (_jsx(Text, { fontSize: "$2", color: "$soft", children: line }, line))) }), limits.creditsAfterAllowance !== undefined && onCredits ? (_jsx(Credits, { on: limits.creditsAfterAllowance, onCredits: onCredits, creditsHref: creditsHref, addCreditsHref: addCreditsHref })) : null, !notice ? _jsx(LimitActions, { actions: limits.actions, onAction: onAction }) : null] }));
41
54
  }
42
55
  //# sourceMappingURL=PlanUsage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlanUsage.js","sourceRoot":"","sources":["../../src/product/PlanUsage.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PlanUsage.js","sourceRoot":"","sources":["../../src/product/PlanUsage.tsx"],"names":[],"mappings":"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"}
@@ -17,12 +17,10 @@ const limits_1 = require("./limits.cjs");
17
17
  exports.STATE_COLOR = { ok: '$good', near: '$yellow10', limited: '$bad' };
18
18
  /** What a class row says under its bar about who pays now. */
19
19
  function caption(c) {
20
- if (c.state === 'limited' && c.paying === 'none')
21
- return 'Paused';
22
- if (c.paying === 'prepaid')
23
- return 'Paid from prepaid credit';
24
20
  if (c.paying === 'credits')
25
- return 'Paid from credits';
21
+ return 'Paying from credits';
22
+ if (c.state === 'limited' && (c.paying === 'none' || c.paying === 'free'))
23
+ return 'Paused';
26
24
  if (c.state === 'near')
27
25
  return 'Almost used';
28
26
  return '';
@@ -1 +1 @@
1
- {"version":3,"file":"UsageMeter.d.ts","sourceRoot":"","sources":["../../src/product/UsageMeter.tsx"],"names":[],"mappings":"AAUA,OAAO,EAA+C,KAAK,UAAU,EAAqC,KAAK,MAAM,EAAE,MAAM,UAAU,CAAA;AAEvI,oDAAoD;AACpD,eAAO,MAAM,WAAW;iBAAS,OAAO;mBAAQ,WAAW;sBAAW,MAAM;CAAgD,CAAA;AAiC5H,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,iFAAiF;IACjF,OAAO,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;IAC/B,mDAAmD;IACnD,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;IAClB,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,OAAiB,EAAE,IAAW,EAAE,GAAG,EAAE,EAAE,eAAe,sCAgD1F"}
1
+ {"version":3,"file":"UsageMeter.d.ts","sourceRoot":"","sources":["../../src/product/UsageMeter.tsx"],"names":[],"mappings":"AAUA,OAAO,EAA+C,KAAK,UAAU,EAAqC,KAAK,MAAM,EAAE,MAAM,UAAU,CAAA;AAEvI,oDAAoD;AACpD,eAAO,MAAM,WAAW;iBAAS,OAAO;mBAAQ,WAAW;sBAAW,MAAM;CAAgD,CAAA;AAgC5H,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,iFAAiF;IACjF,OAAO,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;IAC/B,mDAAmD;IACnD,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;IAClB,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,OAAiB,EAAE,IAAW,EAAE,GAAG,EAAE,EAAE,eAAe,sCAgD1F"}
@@ -13,12 +13,10 @@ import { CLASSES, CLASS_LABEL, when } from './limits.js';
13
13
  export const STATE_COLOR = { ok: '$good', near: '$yellow10', limited: '$bad' };
14
14
  /** What a class row says under its bar about who pays now. */
15
15
  function caption(c) {
16
- if (c.state === 'limited' && c.paying === 'none')
17
- return 'Paused';
18
- if (c.paying === 'prepaid')
19
- return 'Paid from prepaid credit';
20
16
  if (c.paying === 'credits')
21
- return 'Paid from credits';
17
+ return 'Paying from credits';
18
+ if (c.state === 'limited' && (c.paying === 'none' || c.paying === 'free'))
19
+ return 'Paused';
22
20
  if (c.state === 'near')
23
21
  return 'Almost used';
24
22
  return '';
@@ -1 +1 @@
1
- {"version":3,"file":"UsageMeter.js","sourceRoot":"","sources":["../../src/product/UsageMeter.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UsageMeter.js","sourceRoot":"","sources":["../../src/product/UsageMeter.tsx"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@
10
10
  //
11
11
  // No React, no gui: this loads in Node and in a server component.
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.worst = exports.CLASS_LABEL = exports.CLASSES = void 0;
13
+ exports.worst = exports.CLASS_LABEL = exports.CLASSES = exports.navigable = void 0;
14
14
  exports.actionsOf = actionsOf;
15
15
  exports.limitsOf = limitsOf;
16
16
  exports.servedOf = servedOf;
@@ -20,6 +20,9 @@ exports.classesLabel = classesLabel;
20
20
  exports.when = when;
21
21
  exports.noticeOf = noticeOf;
22
22
  exports.nearOf = nearOf;
23
+ /** The actions that are pages a browser can simply open. */
24
+ const navigable = (a) => (a.kind === 'upgrade' || a.kind === 'topup') && Boolean(a.url);
25
+ exports.navigable = navigable;
23
26
  exports.CLASSES = ['premium', 'ours', 'free'];
24
27
  exports.CLASS_LABEL = {
25
28
  premium: 'Premium models',
@@ -27,8 +30,14 @@ exports.CLASS_LABEL = {
27
30
  free: 'Free models',
28
31
  };
29
32
  const STATES = ['ok', 'near', 'limited'];
30
- const PAYERS = ['plan', 'prepaid', 'credits', 'none'];
31
- const PAID = ['plan', 'prepaid', 'credits', 'free'];
33
+ const PAYERS = ['plan', 'credits', 'free', 'none'];
34
+ const KINDS = ['upgrade', 'topup', 'credits', 'switch'];
35
+ const LABEL = {
36
+ upgrade: 'Upgrade',
37
+ topup: 'Add prepaid credit',
38
+ credits: 'Continue with credits',
39
+ switch: 'Switch model',
40
+ };
32
41
  const RANK = { ok: 0, near: 1, limited: 2 };
33
42
  const text = (v) => (typeof v === 'string' ? v : null);
34
43
  const one = (set, v) => typeof v === 'string' && set.includes(v) ? v : null;
@@ -62,12 +71,18 @@ function actionsOf(v) {
62
71
  return [];
63
72
  return v.flatMap((a) => {
64
73
  const o = record(a);
65
- const kind = one(['upgrade', 'topup'], o?.kind);
66
- const url = text(o?.url);
67
- if (!kind || !url)
74
+ const kind = one(KINDS, o?.kind);
75
+ if (!kind)
76
+ return [];
77
+ const url = text(o?.url) ?? undefined;
78
+ const model = text(o?.model) ?? undefined;
79
+ const plan = text(o?.plan) ?? undefined;
80
+ // A page with no address, or a switch to no model, is not an action.
81
+ if ((kind === 'upgrade' || kind === 'topup') && !url)
82
+ return [];
83
+ if (kind === 'switch' && !model)
68
84
  return [];
69
- const plan = text(o?.plan);
70
- return [{ kind, label: text(o?.label) || (kind === 'upgrade' ? 'Upgrade' : 'Add prepaid credit'), url, ...(plan ? { plan } : {}) }];
85
+ return [{ kind, label: text(o?.label) || LABEL[kind], ...(url ? { url } : {}), ...(model ? { model } : {}), ...(plan ? { plan } : {}) }];
71
86
  });
72
87
  }
73
88
  const classList = (v) => Array.isArray(v) ? v.flatMap((c) => (one(exports.CLASSES, c) ? [c] : [])) : [];
@@ -117,6 +132,7 @@ function limitsOf(body) {
117
132
  ...(paused.length ? { paused } : {}),
118
133
  actions: actionsOf(o?.actions),
119
134
  upgrade: text(o?.upgrade) ?? undefined,
135
+ ...(typeof o?.credits_after_allowance === 'boolean' ? { creditsAfterAllowance: o.credits_after_allowance } : {}),
120
136
  };
121
137
  }
122
138
  /** The usage headers on a served call, or null when it carries none. */
@@ -128,7 +144,7 @@ function servedOf(headers) {
128
144
  return {
129
145
  state: usage ?? 'limited',
130
146
  class: one(exports.CLASSES, headers.get('x-hanzo-usage-class')),
131
- paidBy: one(PAID, headers.get('x-hanzo-paid-by')),
147
+ paidBy: one(PAYERS, headers.get('x-hanzo-paid-by')),
132
148
  fallback,
133
149
  reason: headers.get('x-hanzo-usage-reason') || null,
134
150
  };
@@ -202,8 +218,10 @@ function when(iso, now = Date.now()) {
202
218
  const PLAIN = {
203
219
  paid_plan_required: 'Premium models need a paid plan.',
204
220
  free_plan_cap: "You've used the free plan's usage for now.",
205
- insufficient_balance: 'Your prepaid credit has run out.',
221
+ insufficient_balance: 'Your credits have run out.',
206
222
  };
223
+ /** A paused model as a sentence names it: a glob reads as its family ("claude-opus models"). */
224
+ const modelWords = (model, name) => model.endsWith('*') ? `${model.slice(0, -1).split('/').pop()?.replace(/[-.]$/, '')} models` : name(model);
207
225
  /**
208
226
  * What to tell a reader whose usage is paused or refused, or null when nothing
209
227
  * is. A plan's included usage being used up reads as a pause until the reset;
@@ -223,14 +241,24 @@ function noticeOf(limits, heard, name = (id) => id, now = Date.now()) {
223
241
  classes.add(served.class);
224
242
  if (!refusal && !fallback && !limits?.limited && limits?.state !== 'limited')
225
243
  return null;
226
- const list = exports.CLASSES.filter((c) => classes.has(c));
227
244
  const reason = refusal?.code || limits?.limited?.reason || served?.reason || '';
228
- const resets = earliest([...list.map((c) => resetOf(limits?.classes[c])), refusal?.resets_at ?? null]);
245
+ // One model capped inside a class that is not: the class stays open, so it is not listed.
246
+ const capped = reason === 'model_cap'
247
+ ? (limits?.paused?.find((p) => fallback !== null && p.fallback === fallback) ?? limits?.paused?.[0] ?? null)
248
+ : null;
249
+ if (capped && served?.class)
250
+ classes.delete(served.class);
251
+ const list = exports.CLASSES.filter((c) => classes.has(c));
252
+ const resets = capped
253
+ ? (capped.resets_at ?? refusal?.resets_at ?? null)
254
+ : earliest([...list.map((c) => resetOf(limits?.classes[c])), refusal?.resets_at ?? null]);
229
255
  const paused = reason === 'plan_allowance_used' || (!reason && list.length > 0);
230
256
  const until = when(resets, now);
231
- const said = paused
232
- ? `${classesLabel(list)} are paused${until ? ` until ${until}` : ''}.`
233
- : refusal?.message || limits?.limited?.message || PLAIN[reason] || 'Usage is paused for now.';
257
+ const said = capped
258
+ ? `${modelWords(capped.model, name)} ${capped.model.endsWith('*') ? 'are' : 'is'} paused${until ? ` until ${until}` : ''}.`
259
+ : paused
260
+ ? `${classesLabel(list)} are paused${until ? ` until ${until}` : ''}.`
261
+ : refusal?.message || limits?.limited?.message || PLAIN[reason] || 'Usage is paused for now.';
234
262
  return {
235
263
  reason,
236
264
  classes: list,