@burdenoff/fe-libs 2026.1027.13 → 2026.1028.1

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.
@@ -4,47 +4,49 @@ import { useAuth as n } from "../providers/shell/AuthProvider.js";
4
4
  import { useActiveContext as r } from "../providers/shell/ActiveContextProvider.js";
5
5
  import { MainLandmark as i } from "../components/SkipToContent.js";
6
6
  import { PermissionProvider as a, usePermissions as o, useSafePermissions as s } from "../providers/shell/PermissionProvider.js";
7
- import { MODELS as c, PROVIDERS as l, SUMMARY as u, catalog as d, sevenDays as f, summary as p } from "./ai/contracts.js";
8
- import { useAiTr as m } from "./ai/i18n.js";
9
- import { CatalogPanel as h } from "./ai/CatalogPanel.js";
10
- import { SummaryPanel as g } from "./ai/SummaryPanel.js";
11
- import { useAiRead as _ } from "./ai/useAiRead.js";
12
- import { useCallback as v, useMemo as y, useState as b } from "react";
13
- import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
7
+ import { BREAKDOWN as c, CREDITS as l, MODELS as u, PROVIDERS as d, SUMMARY as f, breakdown as p, catalog as m, credits as h, sevenDays as g, summary as _ } from "./ai/contracts.js";
8
+ import { useAiTr as v } from "./ai/i18n.js";
9
+ import { CatalogPanel as y } from "./ai/CatalogPanel.js";
10
+ import { SummaryPanel as b } from "./ai/SummaryPanel.js";
11
+ import { BreakdownPanel as x } from "./ai/BreakdownPanel.js";
12
+ import { CreditsPanel as S } from "./ai/CreditsPanel.js";
13
+ import { useAiRead as C } from "./ai/useAiRead.js";
14
+ import { useCallback as w, useMemo as T, useState as E } from "react";
15
+ import { Fragment as D, jsx as O, jsxs as k } from "react/jsx-runtime";
14
16
  //#region src/shared/pages/AiPage.tsx
15
- function w({ productName: t, productId: n }) {
16
- let r = m(), a = e("workspace");
17
- return /* @__PURE__ */ C(i, {
17
+ function A({ productName: t, productId: n }) {
18
+ let r = v(), a = e("workspace");
19
+ return /* @__PURE__ */ k(i, {
18
20
  className: "mx-auto w-full max-w-6xl space-y-6 px-4 py-6 sm:px-6",
19
21
  "data-product-id": n,
20
- children: [/* @__PURE__ */ C("header", {
22
+ children: [/* @__PURE__ */ k("header", {
21
23
  className: "space-y-2",
22
- children: [/* @__PURE__ */ S("h1", {
24
+ children: [/* @__PURE__ */ O("h1", {
23
25
  className: "text-2xl font-semibold text-foreground",
24
26
  children: r("title", "{product} AI operations", { product: t })
25
- }), /* @__PURE__ */ S("p", {
27
+ }), /* @__PURE__ */ O("p", {
26
28
  className: "max-w-3xl text-sm text-muted-foreground",
27
29
  children: r("intro", "Review the workspace model catalog and recorded AI usage.")
28
30
  })]
29
- }), a ? /* @__PURE__ */ S(T, { children: /* @__PURE__ */ S(E, {
31
+ }), a ? /* @__PURE__ */ O(j, { children: /* @__PURE__ */ O(M, {
30
32
  productId: n,
31
33
  client: a
32
- }) }) : /* @__PURE__ */ S("p", {
34
+ }) }) : /* @__PURE__ */ O("p", {
33
35
  role: "status",
34
36
  children: r("unavailable", "AI operations are unavailable in this context.")
35
37
  })]
36
38
  });
37
39
  }
38
- function T({ children: e }) {
40
+ function j({ children: e }) {
39
41
  let t = s(), { workspaceId: n } = r();
40
- return t ? e : /* @__PURE__ */ S(a, {
42
+ return t ? e : /* @__PURE__ */ O(a, {
41
43
  scopeId: n ?? null,
42
44
  gateway: "workspace",
43
45
  children: e
44
46
  });
45
47
  }
46
- function E({ productId: e, client: i }) {
47
- let a = n(), { workspaceId: s } = r(), w = o(), { locale: T } = t(), E = m(), D = y(() => ({
48
+ function M({ productId: e, client: i }) {
49
+ let a = n(), { workspaceId: s } = r(), A = o(), { locale: j } = t(), M = v(), N = T(() => ({
48
50
  workspaceId: s ?? "",
49
51
  actorId: a.user?.id ?? "",
50
52
  profileId: a.activeProfileId,
@@ -56,78 +58,102 @@ function E({ productId: e, client: i }) {
56
58
  a.activeProfileId,
57
59
  a.tokens?.accessToken,
58
60
  a.workspaceToken
59
- ]), [O, k] = b(f), [A, j] = b({
60
- scope: D,
61
+ ]), [P, F] = E(g), [I, L] = E({
62
+ scope: N,
61
63
  models: 0,
62
64
  providers: 0,
63
65
  revision: 0
64
- }), M = A.scope === D ? A.models : 0, N = A.scope === D ? A.providers : 0, P = A.scope === D ? A.revision : 0, F = (e) => a.isLoading ? "loading" : !a.isAuthenticated || !D.workspaceId || !D.actorId || !D.accessToken ? "unavailable" : w.isLoading || w.scopeId !== D.workspaceId ? "loading" : w.error ? "unavailable" : !w.isSuperAdmin && w.permissions?.actorId !== D.actorId ? "loading" : w.hasPermission(e) ? "ready" : "denied", I = y(() => ({ pagination: {
66
+ }), R = I.scope === N ? I.models : 0, z = I.scope === N ? I.providers : 0, B = I.scope === N ? I.revision : 0, V = (e) => a.isLoading ? "loading" : !a.isAuthenticated || !N.workspaceId || !N.actorId || !N.accessToken ? "unavailable" : A.isLoading || A.scopeId !== N.workspaceId ? "loading" : A.error ? "unavailable" : !A.isSuperAdmin && A.permissions?.actorId !== N.actorId ? "loading" : A.hasPermission(e) ? "ready" : "denied", H = T(() => ({ pagination: {
65
67
  limit: 20,
66
- offset: M
67
- } }), [M]), L = y(() => ({ pagination: {
68
+ offset: R
69
+ } }), [R]), U = T(() => ({ pagination: {
68
70
  limit: 20,
69
- offset: N
70
- } }), [N]), R = y(() => ({
71
- ...O,
71
+ offset: z
72
+ } }), [z]), W = T(() => ({
73
+ ...P,
72
74
  productKey: e
73
- }), [O, e]), z = v((e) => d(e, "models"), []), B = v((e) => d(e, "providers"), []), V = v((t) => p(t, D.workspaceId, e, O), [
74
- D.workspaceId,
75
+ }), [P, e]), G = w((e) => m(e, "models"), []), K = w((e) => m(e, "providers"), []), ee = w((t) => _(t, N.workspaceId, e, P), [
76
+ N.workspaceId,
75
77
  e,
76
- O
77
- ]), H = _(i, D, F("prompt-model:read"), c, I, z, P), U = _(i, D, F("prompt-provider:read"), l, L, B, P), W = _(i, D, F("prompt-invocation:read"), u, R, V, P);
78
- function G() {
79
- k(f()), j({
80
- scope: D,
81
- models: M,
82
- providers: N,
83
- revision: P + 1
78
+ P
79
+ ]), q = C(i, N, V("prompt-model:read"), u, H, G, B), J = C(i, N, V("prompt-provider:read"), d, U, K, B), Y = C(i, N, V("prompt-invocation:read"), f, W, ee, B), X = T(() => ({
80
+ ...P,
81
+ productKey: e,
82
+ groupBy: ["MODEL"]
83
+ }), [P, e]), Z = T(() => ({
84
+ ...P,
85
+ productKey: e,
86
+ groupBy: ["OPERATION"]
87
+ }), [P, e]), Q = T(() => ({
88
+ ...P,
89
+ productKey: e,
90
+ groupBy: ["TRIGGER"]
91
+ }), [P, e]), $ = w((t) => p(t, N.workspaceId, e, "MODEL"), [N.workspaceId, e]), te = w((t) => p(t, N.workspaceId, e, "OPERATION"), [N.workspaceId, e]), ne = w((t) => p(t, N.workspaceId, e, "TRIGGER"), [N.workspaceId, e]), re = T(() => ({ productKey: e }), [e]), ie = w((t) => h(t, e), [e]), ae = C(i, N, V("prompt-invocation:read"), c, X, $, B), oe = C(i, N, V("prompt-invocation:read"), c, Z, te, B), se = C(i, N, V("prompt-invocation:read"), c, Q, ne, B), ce = C(i, N, V("assistant:use"), l, re, ie, B);
92
+ function le() {
93
+ F(g()), L({
94
+ scope: N,
95
+ models: R,
96
+ providers: z,
97
+ revision: B + 1
84
98
  });
85
99
  }
86
- return /* @__PURE__ */ C(x, { children: [
87
- /* @__PURE__ */ C("div", {
100
+ return /* @__PURE__ */ k(D, { children: [
101
+ /* @__PURE__ */ k("div", {
88
102
  className: "flex flex-wrap items-center justify-between gap-3",
89
- children: [/* @__PURE__ */ S("p", {
103
+ children: [/* @__PURE__ */ O("p", {
90
104
  className: "text-sm text-muted-foreground",
91
- children: E("readonly", "Read-only workspace view")
92
- }), /* @__PURE__ */ S("button", {
105
+ children: M("readonly", "Read-only workspace view")
106
+ }), /* @__PURE__ */ O("button", {
93
107
  type: "button",
94
- onClick: G,
108
+ onClick: le,
95
109
  className: "rounded-md border border-border px-3 py-2 text-sm font-medium focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
96
- children: E("refresh", "Refresh")
110
+ children: M("refresh", "Refresh")
97
111
  })]
98
112
  }),
99
- /* @__PURE__ */ S(g, {
100
- state: W,
101
- window: O,
102
- locale: T
113
+ /* @__PURE__ */ O(S, {
114
+ state: ce,
115
+ locale: j
103
116
  }),
104
- /* @__PURE__ */ C("div", {
117
+ /* @__PURE__ */ O(b, {
118
+ state: Y,
119
+ window: P,
120
+ locale: j
121
+ }),
122
+ /* @__PURE__ */ O(x, {
123
+ states: {
124
+ MODEL: ae,
125
+ OPERATION: oe,
126
+ TRIGGER: se
127
+ },
128
+ locale: j
129
+ }),
130
+ /* @__PURE__ */ k("div", {
105
131
  className: "grid gap-6 lg:grid-cols-2",
106
- children: [/* @__PURE__ */ S(h, {
132
+ children: [/* @__PURE__ */ O(y, {
107
133
  kind: "models",
108
- state: H,
109
- offset: M,
110
- locale: T,
111
- onPage: (e) => j({
112
- scope: D,
134
+ state: q,
135
+ offset: R,
136
+ locale: j,
137
+ onPage: (e) => L({
138
+ scope: N,
113
139
  models: e,
114
- providers: N,
115
- revision: P
140
+ providers: z,
141
+ revision: B
116
142
  })
117
- }), /* @__PURE__ */ S(h, {
143
+ }), /* @__PURE__ */ O(y, {
118
144
  kind: "providers",
119
- state: U,
120
- offset: N,
121
- locale: T,
122
- onPage: (e) => j({
123
- scope: D,
124
- models: M,
145
+ state: J,
146
+ offset: z,
147
+ locale: j,
148
+ onPage: (e) => L({
149
+ scope: N,
150
+ models: R,
125
151
  providers: e,
126
- revision: P
152
+ revision: B
127
153
  })
128
154
  })]
129
155
  })
130
156
  ] });
131
157
  }
132
158
  //#endregion
133
- export { w as AiPage };
159
+ export { A as AiPage };
@@ -0,0 +1,6 @@
1
+ import { Breakdown, BreakdownDimension } from './contracts';
2
+ import { ReadState } from './useAiRead';
3
+ export declare function BreakdownPanel({ states, locale, }: {
4
+ states: Record<BreakdownDimension, ReadState<Breakdown>>;
5
+ locale: string;
6
+ }): import('react/jsx-runtime').JSX.Element;
@@ -0,0 +1,117 @@
1
+ import { exactInteger as e, exactUsd as t } from "./contracts.js";
2
+ import { useAiTr as n } from "./i18n.js";
3
+ import { ReadNotice as r } from "./ReadNotice.js";
4
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
5
+ //#region src/shared/pages/ai/BreakdownPanel.tsx
6
+ function o({ title: o, state: s, locale: c }) {
7
+ let l = n();
8
+ return /* @__PURE__ */ a("div", {
9
+ className: "min-w-0",
10
+ children: [/* @__PURE__ */ i("h3", {
11
+ className: "text-sm font-semibold",
12
+ children: o
13
+ }), /* @__PURE__ */ i("div", {
14
+ className: "mt-2",
15
+ "aria-live": "polite",
16
+ children: s.status === "ready" ? s.data.rows.length === 0 ? /* @__PURE__ */ i("p", {
17
+ className: "text-sm text-muted-foreground",
18
+ children: l("breakdownEmpty", "No recorded attempts in this window.")
19
+ }) : /* @__PURE__ */ a("div", {
20
+ className: "overflow-x-auto",
21
+ children: [/* @__PURE__ */ a("table", {
22
+ className: "w-full min-w-0 text-left text-sm",
23
+ children: [/* @__PURE__ */ i("thead", {
24
+ className: "text-xs text-muted-foreground",
25
+ children: /* @__PURE__ */ a("tr", { children: [
26
+ /* @__PURE__ */ i("th", {
27
+ scope: "col",
28
+ className: "py-1 pr-3 font-medium",
29
+ children: o
30
+ }),
31
+ /* @__PURE__ */ i("th", {
32
+ scope: "col",
33
+ className: "py-1 pr-3 text-right font-medium",
34
+ children: l("breakdownAttempts", "Attempts")
35
+ }),
36
+ /* @__PURE__ */ i("th", {
37
+ scope: "col",
38
+ className: "py-1 pr-3 text-right font-medium",
39
+ children: l("breakdownTokens", "Tokens")
40
+ }),
41
+ /* @__PURE__ */ i("th", {
42
+ scope: "col",
43
+ className: "py-1 text-right font-medium",
44
+ children: l("breakdownCost", "Est. cost")
45
+ })
46
+ ] })
47
+ }), /* @__PURE__ */ i("tbody", { children: s.data.rows.map((n, r) => /* @__PURE__ */ a("tr", {
48
+ className: "border-t border-border",
49
+ children: [
50
+ /* @__PURE__ */ i("td", {
51
+ className: "max-w-[16rem] break-all py-1 pr-3",
52
+ children: n.key ?? /* @__PURE__ */ i("span", {
53
+ className: "text-muted-foreground",
54
+ children: l("breakdownUnrecorded", "Not recorded")
55
+ })
56
+ }),
57
+ /* @__PURE__ */ i("td", {
58
+ className: "py-1 pr-3 text-right tabular-nums",
59
+ children: e(n.attempts, c)
60
+ }),
61
+ /* @__PURE__ */ i("td", {
62
+ className: "py-1 pr-3 text-right tabular-nums",
63
+ children: n.totalTokens === null ? l("unknown", "Unknown") : e(n.totalTokens, c)
64
+ }),
65
+ /* @__PURE__ */ i("td", {
66
+ className: "py-1 text-right tabular-nums",
67
+ children: n.costMicroUsd === null ? l("unknown", "Unknown") : t(n.costMicroUsd, c)
68
+ })
69
+ ]
70
+ }, `${n.key ?? ""}-${r}`)) })]
71
+ }), s.data.more && /* @__PURE__ */ i("p", {
72
+ className: "mt-1 text-xs text-muted-foreground",
73
+ children: l("breakdownMore", "Showing the highest-cost groups only.")
74
+ })]
75
+ }) : /* @__PURE__ */ i(r, { status: s.status })
76
+ })]
77
+ });
78
+ }
79
+ function s({ states: e, locale: t }) {
80
+ let r = n(), s = r("breakdown", "Where the spend went");
81
+ return /* @__PURE__ */ a("section", {
82
+ "aria-label": s,
83
+ className: "min-w-0 rounded-xl border border-border bg-card p-4 sm:p-5",
84
+ children: [
85
+ /* @__PURE__ */ i("h2", {
86
+ className: "text-lg font-semibold",
87
+ children: s
88
+ }),
89
+ /* @__PURE__ */ i("p", {
90
+ className: "mt-2 text-sm text-muted-foreground",
91
+ children: r("breakdownNotice", "Recorded attempts in the same window, grouped by model, AI surface and what started them. Costs are estimates.")
92
+ }),
93
+ /* @__PURE__ */ a("div", {
94
+ className: "mt-4 grid gap-6 xl:grid-cols-3",
95
+ children: [
96
+ /* @__PURE__ */ i(o, {
97
+ title: r("byModel", "Model"),
98
+ state: e.MODEL,
99
+ locale: t
100
+ }),
101
+ /* @__PURE__ */ i(o, {
102
+ title: r("bySurface", "AI surface"),
103
+ state: e.OPERATION,
104
+ locale: t
105
+ }),
106
+ /* @__PURE__ */ i(o, {
107
+ title: r("byTrigger", "Trigger"),
108
+ state: e.TRIGGER,
109
+ locale: t
110
+ })
111
+ ]
112
+ })
113
+ ]
114
+ });
115
+ }
116
+ //#endregion
117
+ export { s as BreakdownPanel };
@@ -0,0 +1,10 @@
1
+ import { CreditStatus } from './contracts';
2
+ import { ReadState } from './useAiRead';
3
+ /**
4
+ * The workspace's remaining AI credits for this product (BOFF-3732), so the
5
+ * balance is visible before an AI action rather than after a refusal.
6
+ */
7
+ export declare function CreditsPanel({ state, locale, }: {
8
+ state: ReadState<CreditStatus>;
9
+ locale: string;
10
+ }): import('react/jsx-runtime').JSX.Element;
@@ -0,0 +1,64 @@
1
+ import { useAiTr as e } from "./i18n.js";
2
+ import { ReadNotice as t } from "./ReadNotice.js";
3
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
+ //#region src/shared/pages/ai/CreditsPanel.tsx
5
+ function i({ state: i, locale: a }) {
6
+ let o = e(), s = o("credits", "AI credits this cycle"), c = new Intl.NumberFormat(a, { maximumFractionDigits: 0 });
7
+ return /* @__PURE__ */ r("section", {
8
+ "aria-label": s,
9
+ className: "min-w-0 rounded-xl border border-border bg-card p-4 sm:p-5",
10
+ children: [/* @__PURE__ */ n("h2", {
11
+ className: "text-lg font-semibold",
12
+ children: s
13
+ }), /* @__PURE__ */ r("div", {
14
+ className: "mt-3",
15
+ "aria-live": "polite",
16
+ children: [i.status === "ready" ? i.data.provisioned ? i.data.noLimit ? /* @__PURE__ */ n("p", {
17
+ className: "text-sm",
18
+ children: o("creditsUnlimited", "This plan has no AI credit limit.")
19
+ }) : /* @__PURE__ */ r("dl", {
20
+ className: "grid grid-cols-3 gap-3",
21
+ children: [
22
+ /* @__PURE__ */ r("div", {
23
+ className: "min-w-0",
24
+ children: [/* @__PURE__ */ n("dt", {
25
+ className: "text-xs text-muted-foreground",
26
+ children: o("creditsRemaining", "Remaining")
27
+ }), /* @__PURE__ */ n("dd", {
28
+ className: `break-all text-xl font-semibold tabular-nums ${i.data.exhausted ? "text-destructive" : ""}`,
29
+ children: c.format(i.data.remaining ?? 0)
30
+ })]
31
+ }),
32
+ /* @__PURE__ */ r("div", {
33
+ className: "min-w-0",
34
+ children: [/* @__PURE__ */ n("dt", {
35
+ className: "text-xs text-muted-foreground",
36
+ children: o("creditsUsed", "Used")
37
+ }), /* @__PURE__ */ n("dd", {
38
+ className: "break-all text-xl font-semibold tabular-nums",
39
+ children: c.format(i.data.used ?? 0)
40
+ })]
41
+ }),
42
+ /* @__PURE__ */ r("div", {
43
+ className: "min-w-0",
44
+ children: [/* @__PURE__ */ n("dt", {
45
+ className: "text-xs text-muted-foreground",
46
+ children: o("creditsLimit", "Limit")
47
+ }), /* @__PURE__ */ n("dd", {
48
+ className: "break-all text-xl font-semibold tabular-nums",
49
+ children: c.format(i.data.limit ?? 0)
50
+ })]
51
+ })
52
+ ]
53
+ }) : /* @__PURE__ */ n("p", {
54
+ className: "text-sm text-muted-foreground",
55
+ children: o("creditsNotMetered", "AI use is not metered against a credit budget in this workspace.")
56
+ }) : /* @__PURE__ */ n(t, { status: i.status }), i.status === "ready" && i.data.exhausted && /* @__PURE__ */ n("p", {
57
+ className: "mt-3 text-sm text-destructive",
58
+ children: o("creditsExhausted", "AI credits are used up. AI actions resume next cycle or after an upgrade.")
59
+ })]
60
+ })]
61
+ });
62
+ }
63
+ //#endregion
64
+ export { i as CreditsPanel };
@@ -43,3 +43,38 @@ export declare function summary(value: unknown, workspaceId: string, productKey:
43
43
  export declare function exactInteger(value: string, locale: string): string;
44
44
  export declare function exactUsd(value: string, locale: string): string;
45
45
  export declare function sevenDays(now?: Date): UsageWindow;
46
+ /**
47
+ * BOFF-3732: spend grouped by one dimension (BOFF-9935's promptUsageBreakdownV2),
48
+ * so an admin can tell a runaway workflow from the team asking the assistant.
49
+ */
50
+ export declare const BREAKDOWN: import('graphql').DocumentNode;
51
+ /** BOFF-3732: the workspace's remaining `<productKey>.ai.credits`. */
52
+ export declare const CREDITS: import('graphql').DocumentNode;
53
+ export type BreakdownDimension = 'MODEL' | 'OPERATION' | 'TRIGGER';
54
+ export declare const BREAKDOWN_DIMENSIONS: readonly BreakdownDimension[];
55
+ /** Rows shown per breakdown; the service orders by known cost, highest first. */
56
+ export declare const BREAKDOWN_ROWS = 10;
57
+ export interface BreakdownRow {
58
+ /** The group's value; null when the ledger rows did not record it (older rows have no trigger). */
59
+ key: string | null;
60
+ attempts: string;
61
+ totalTokens: string | null;
62
+ costMicroUsd: string | null;
63
+ costKnownAttempts: string;
64
+ }
65
+ export interface Breakdown {
66
+ dimension: BreakdownDimension;
67
+ rows: BreakdownRow[];
68
+ /** More groups exist than are shown. */
69
+ more: boolean;
70
+ }
71
+ export declare function breakdown(value: unknown, workspaceId: string, productKey: string, dimension: BreakdownDimension): Breakdown;
72
+ export interface CreditStatus {
73
+ provisioned: boolean;
74
+ noLimit: boolean;
75
+ exhausted: boolean;
76
+ used: number | null;
77
+ limit: number | null;
78
+ remaining: number | null;
79
+ }
80
+ export declare function credits(value: unknown, productKey: string): CreditStatus;
@@ -155,5 +155,97 @@ function f(e = /* @__PURE__ */ new Date()) {
155
155
  to: e.toISOString()
156
156
  };
157
157
  }
158
+ var p = e`
159
+ query AiOperationsBreakdown(
160
+ $from: DateTime!
161
+ $to: DateTime!
162
+ $productKey: String!
163
+ $groupBy: [PromptUsageDimensionV2!]!
164
+ ) {
165
+ promptUsageBreakdownV2(from: $from, to: $to, productKey: $productKey, groupBy: $groupBy) {
166
+ workspaceId
167
+ productKey
168
+ currency
169
+ costKind
170
+ truncated
171
+ rows {
172
+ providerKey
173
+ modelKey
174
+ operationKey
175
+ trigger
176
+ attempts
177
+ totalTokens {
178
+ knownSubtotal
179
+ knownAttempts
180
+ missingAttempts
181
+ }
182
+ costMicroUsd {
183
+ knownSubtotal
184
+ knownAttempts
185
+ missingAttempts
186
+ }
187
+ }
188
+ }
189
+ }
190
+ `, m = e`
191
+ query AiOperationsCredits($productKey: String!) {
192
+ aiCreditStatus(productKey: $productKey) {
193
+ productKey
194
+ quotaName
195
+ provisioned
196
+ noLimit
197
+ used
198
+ limit
199
+ remaining
200
+ exhausted
201
+ }
202
+ }
203
+ `;
204
+ function h(e) {
205
+ return e == null ? null : a(e);
206
+ }
207
+ function g(e, t) {
208
+ if (t === "MODEL") {
209
+ let t = h(e.providerKey), n = h(e.modelKey);
210
+ return n ? t ? `${t}/${n}` : n : null;
211
+ }
212
+ return h(t === "OPERATION" ? e.operationKey : e.trigger);
213
+ }
214
+ function _(e, t, n, r) {
215
+ let a = i(i(e).promptUsageBreakdownV2);
216
+ if (a.workspaceId !== t || a.productKey !== n || a.currency !== "USD" || a.costKind !== "ESTIMATE" || !Array.isArray(a.rows)) throw Error("AI_READ_SCOPE");
217
+ let c = a.rows.map((e) => {
218
+ let t = i(e), n = s(t.attempts), a = i(t.totalTokens), o = i(t.costMicroUsd);
219
+ return {
220
+ key: g(t, r),
221
+ attempts: n,
222
+ totalTokens: a.knownSubtotal === null ? null : s(a.knownSubtotal),
223
+ costMicroUsd: o.knownSubtotal === null ? null : s(o.knownSubtotal),
224
+ costKnownAttempts: s(o.knownAttempts)
225
+ };
226
+ });
227
+ return {
228
+ dimension: r,
229
+ rows: c.slice(0, 10),
230
+ more: o(a.truncated) || c.length > 10
231
+ };
232
+ }
233
+ function v(e) {
234
+ if (e === null) return null;
235
+ if (typeof e != "number" || !Number.isFinite(e) || e < 0) throw Error("AI_READ_SHAPE");
236
+ return e;
237
+ }
238
+ function y(e, t) {
239
+ let n = i(i(e).aiCreditStatus);
240
+ if (n.productKey !== t || n.quotaName !== `${t}.ai.credits`) throw Error("AI_READ_SCOPE");
241
+ return {
242
+ provisioned: o(n.provisioned),
243
+ noLimit: o(n.noLimit),
244
+ exhausted: o(n.exhausted),
245
+ used: v(n.used),
246
+ limit: v(n.limit),
247
+ remaining: v(n.remaining)
248
+ };
249
+ }
158
250
  //#endregion
159
- export { t as MODELS, n as PROVIDERS, r as SUMMARY, c as catalog, u as exactInteger, d as exactUsd, f as sevenDays, l as summary };
251
+ export { p as BREAKDOWN, m as CREDITS, t as MODELS, n as PROVIDERS, r as SUMMARY, _ as breakdown, c as catalog, y as credits, u as exactInteger, d as exactUsd, f as sevenDays, l as summary };
@@ -43,3 +43,10 @@ export declare function useAssistantChromeLabels(): {
43
43
  tokens: string;
44
44
  code: string;
45
45
  };
46
+ /**
47
+ * BOFF-3720 (AI_READINESS 5.3): the standing "AI can make mistakes" line shown
48
+ * under every assistant panel and on every write-proposal card. A platform
49
+ * shell label, so one seed of the `workspaces` dictionary translates it for
50
+ * every product.
51
+ */
52
+ export declare function useAssistantDisclaimerLabel(): string;
@@ -50,5 +50,8 @@ function n() {
50
50
  code: t("markdownEditor.placeholder.code", "code")
51
51
  };
52
52
  }
53
+ function r() {
54
+ return e()("assistantChrome.aiDisclaimer", "AI can make mistakes. Check important details.");
55
+ }
53
56
  //#endregion
54
- export { n as useAssistantChromeLabels, t as useWorkflowAssistantLabels };
57
+ export { n as useAssistantChromeLabels, r as useAssistantDisclaimerLabel, t as useWorkflowAssistantLabels };