@data-club/ai-hub 0.0.8 → 0.0.10

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 (64) hide show
  1. package/dist/auth/locales/cs.d.ts +1 -1
  2. package/dist/auth/locales/cs.d.ts.map +1 -1
  3. package/dist/auth/locales/cs.js +1 -16
  4. package/dist/auth/locales/cs.js.map +1 -1
  5. package/dist/auth/locales/sk.d.ts +1 -1
  6. package/dist/auth/locales/sk.d.ts.map +1 -1
  7. package/dist/auth/locales/sk.js +1 -16
  8. package/dist/auth/locales/sk.js.map +1 -1
  9. package/dist/auth/texts.d.ts +0 -26
  10. package/dist/auth/texts.d.ts.map +1 -1
  11. package/dist/auth/texts.js +0 -15
  12. package/dist/auth/texts.js.map +1 -1
  13. package/dist/client/AIHubClient.d.ts +2 -39
  14. package/dist/client/AIHubClient.d.ts.map +1 -1
  15. package/dist/client/AIHubClient.js +2 -13
  16. package/dist/client/AIHubClient.js.map +1 -1
  17. package/dist/components/ChatShell/ShellHeader.d.ts +4 -4
  18. package/dist/components/ChatShell/UserMenu.d.ts +4 -10
  19. package/dist/components/ChatShell/UserMenu.d.ts.map +1 -1
  20. package/dist/components/ChatShell/UserMenu.js +8 -15
  21. package/dist/components/ChatShell/UserMenu.js.map +1 -1
  22. package/dist/components/DataClubAIHubAdmin/AgentsPage.d.ts +1 -1
  23. package/dist/components/DataClubAIHubAdmin/AgentsPage.d.ts.map +1 -1
  24. package/dist/components/DataClubAIHubAdmin/AgentsPage.js +2 -11
  25. package/dist/components/DataClubAIHubAdmin/AgentsPage.js.map +1 -1
  26. package/dist/components/DataClubAIHubAdmin/SettingsPage.d.ts +7 -8
  27. package/dist/components/DataClubAIHubAdmin/SettingsPage.d.ts.map +1 -1
  28. package/dist/components/DataClubAIHubAdmin/SettingsPage.js +8 -87
  29. package/dist/components/DataClubAIHubAdmin/SettingsPage.js.map +1 -1
  30. package/dist/components/DataClubAIHubAdmin/index.d.ts +1 -1
  31. package/dist/components/DataClubAIHubAdmin/index.js +1 -1
  32. package/dist/components/MessageList/index.d.ts.map +1 -1
  33. package/dist/components/MessageList/index.js +1 -2
  34. package/dist/components/MessageList/index.js.map +1 -1
  35. package/dist/context/AIHubProvider.d.ts.map +1 -1
  36. package/dist/context/AIHubProvider.js +1 -31
  37. package/dist/context/AIHubProvider.js.map +1 -1
  38. package/dist/index.d.ts +1 -3
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +0 -1
  41. package/dist/index.js.map +1 -1
  42. package/dist/state/stateReducer.d.ts.map +1 -1
  43. package/dist/state/stateReducer.js +0 -1
  44. package/dist/state/stateReducer.js.map +1 -1
  45. package/dist/types.d.ts +1 -73
  46. package/dist/types.d.ts.map +1 -1
  47. package/package.json +2 -1
  48. package/src/auth/locales/cs.ts +1 -23
  49. package/src/auth/locales/sk.ts +1 -23
  50. package/src/auth/texts.ts +0 -49
  51. package/src/client/AIHubClient.ts +2 -42
  52. package/src/components/ChatShell/ShellHeader.tsx +4 -4
  53. package/src/components/ChatShell/UserMenu.tsx +7 -27
  54. package/src/components/DataClubAIHubAdmin/AgentsPage.tsx +1 -21
  55. package/src/components/DataClubAIHubAdmin/SettingsPage.tsx +8 -197
  56. package/src/components/DataClubAIHubAdmin/index.tsx +1 -1
  57. package/src/components/MessageList/index.tsx +0 -4
  58. package/src/context/AIHubProvider.tsx +1 -32
  59. package/src/index.ts +0 -8
  60. package/src/state/stateReducer.ts +0 -1
  61. package/src/styles/CLASSES.md +1 -1
  62. package/src/styles/default.css +0 -67
  63. package/src/types.ts +0 -75
  64. package/src/components/CacheBadge/index.tsx +0 -245
@@ -2,20 +2,19 @@
2
2
  * `<AdminSettingsPage />` — the super_admin-only Settings sub-page mounted
3
3
  * inside `<DataClubAIHubAdmin />` ([08-admin-settings.md]).
4
4
  *
5
- * Five independent sections, each with its own Save button — per the spec,
6
- * "Don't make the user save all five sections together":
5
+ * Independent sections, each with its own Save button — per the spec,
6
+ * "Don't make the user save all sections together":
7
7
  *
8
- * 1. **Letta connection** — base URL, ADE URL, API key (masked + replaceable).
9
- * 2. **Theme** — default theme + switcher-enabled checkbox.
10
- * 3. **UI feature toggles** — the §8.4 toggle blob.
11
- * 4. **Signing key** — rotate with `ROTATE`-typing friction. Rotating
8
+ * 1. **Theme** — default theme + switcher-enabled checkbox.
9
+ * 2. **UI feature toggles** — the §8.4 toggle blob.
10
+ * 3. **Signing key** — rotate with `ROTATE`-typing friction. Rotating
12
11
  * invalidates every JWT, including the calling super-admin's.
13
- * 5. **Metrics scrape token** — rotate with the same friction. The new token
12
+ * 4. **Metrics scrape token** — rotate with the same friction. The new token
14
13
  * is shown ONCE via a reveal modal; subsequent settings reads no longer
15
14
  * expose it. Does NOT invalidate the calling JWT.
16
15
  *
17
16
  * Each section owns its own dirty-state and save handler; sibling sections
18
- * never share state. This means a half-typed Letta URL won't be pushed when
17
+ * never share state. This means a half-typed value won't be pushed when
19
18
  * the admin clicks `Save toggles` in a different section.
20
19
  *
21
20
  * Visible to `super_admin` only — the parent shell hides the nav item for
@@ -176,11 +175,6 @@ export function AdminSettingsPage(props: AdminSettingsPageProps): ReactNode {
176
175
  ) : null}
177
176
  {settings !== null ? (
178
177
  <>
179
- <LettaConnectionSection
180
- settings={settings}
181
- texts={props.texts}
182
- onSaved={handleSectionSaved}
183
- />
184
178
  <ThemeSection
185
179
  settings={settings}
186
180
  texts={props.texts}
@@ -230,7 +224,7 @@ export function AdminSettingsPage(props: AdminSettingsPageProps): ReactNode {
230
224
  }
231
225
 
232
226
  /* ────────────────────────────────────────────────────────────────────────── */
233
- /* Section: Letta connection */
227
+ /* Section: Theme */
234
228
  /* ────────────────────────────────────────────────────────────────────────── */
235
229
 
236
230
  interface SectionProps {
@@ -238,189 +232,6 @@ interface SectionProps {
238
232
  texts: AIHubAdminTexts;
239
233
  }
240
234
 
241
- interface LettaConnectionSectionProps extends SectionProps {
242
- onSaved: (next: AdminSettingsView) => void;
243
- }
244
-
245
- function LettaConnectionSection(props: LettaConnectionSectionProps): ReactNode {
246
- const { client } = useAIHub();
247
- const [baseUrl, setBaseUrl] = useState(props.settings.letta_base_url ?? "");
248
- const [adeUrl, setAdeUrl] = useState(props.settings.letta_ade_url ?? "");
249
- // Empty string = leave-as-is; non-empty = replace.
250
- const [apiKey, setApiKey] = useState("");
251
- const [saving, setSaving] = useState(false);
252
- const [flash, setFlash] = useState<{ tone: "success" | "error"; text: string } | null>(
253
- null,
254
- );
255
-
256
- async function handleSave(event: React.FormEvent): Promise<void> {
257
- event.preventDefault();
258
- setSaving(true);
259
- setFlash(null);
260
- try {
261
- const body: Parameters<typeof client.patchAdminSettings>[0] = {};
262
- // Compare against current to avoid stomping the existing value with the
263
- // identical one. The server treats null + value identically, but the
264
- // schema forbids `null + ""` so we coerce explicitly.
265
- if (baseUrl !== (props.settings.letta_base_url ?? "")) {
266
- body.lettaBaseUrl = baseUrl === "" ? null : baseUrl;
267
- }
268
- if (adeUrl !== (props.settings.letta_ade_url ?? "")) {
269
- body.lettaAdeUrl = adeUrl === "" ? null : adeUrl;
270
- }
271
- if (apiKey !== "") body.lettaApiKey = apiKey;
272
- const next = await client.patchAdminSettings(body);
273
- props.onSaved(next);
274
- setApiKey("");
275
- setFlash({ tone: "success", text: props.texts.settingsSaveSuccessFlash });
276
- } catch (err) {
277
- setFlash({
278
- tone: "error",
279
- text:
280
- err instanceof Error && err.message.length > 0
281
- ? err.message
282
- : props.texts.settingsSaveGenericError,
283
- });
284
- } finally {
285
- setSaving(false);
286
- }
287
- }
288
-
289
- // Clears the DB column (sends `letta_api_key: ""`), which makes the
290
- // server fall back to env.LETTA_API_KEY at runtime per the
291
- // resolveApiKey precedence in letta/client.ts. Same code path as the
292
- // base/ADE URL nulling — only it targets the API-key column.
293
- async function handleClearApiKeyOverride(): Promise<void> {
294
- setSaving(true);
295
- setFlash(null);
296
- try {
297
- const next = await client.patchAdminSettings({ lettaApiKey: "" });
298
- props.onSaved(next);
299
- setFlash({ tone: "success", text: props.texts.settingsSaveSuccessFlash });
300
- } catch (err) {
301
- setFlash({
302
- tone: "error",
303
- text:
304
- err instanceof Error && err.message.length > 0
305
- ? err.message
306
- : props.texts.settingsSaveGenericError,
307
- });
308
- } finally {
309
- setSaving(false);
310
- }
311
- }
312
-
313
- return (
314
- <section
315
- className="data-club-ai-hub-admin__settings-section"
316
- data-testid="admin-settings-letta-section"
317
- >
318
- <h2 className="data-club-ai-hub-admin__settings-section-heading">
319
- {props.texts.settingsLettaSectionHeading}
320
- </h2>
321
- <form onSubmit={(event) => void handleSave(event)} noValidate>
322
- <label className="data-club-ai-hub-admin__form-field">
323
- <span className="data-club-ai-hub-admin__form-label">
324
- {props.texts.settingsLettaBaseUrlLabel}
325
- </span>
326
- <input
327
- type="url"
328
- className="data-club-ai-hub-admin__form-input"
329
- data-testid="admin-settings-letta-base-url"
330
- value={baseUrl}
331
- onChange={(event) => setBaseUrl(event.target.value)}
332
- disabled={saving}
333
- />
334
- </label>
335
- <label className="data-club-ai-hub-admin__form-field">
336
- <span className="data-club-ai-hub-admin__form-label">
337
- {props.texts.settingsLettaAdeUrlLabel}
338
- </span>
339
- <input
340
- type="url"
341
- className="data-club-ai-hub-admin__form-input"
342
- data-testid="admin-settings-letta-ade-url"
343
- value={adeUrl}
344
- onChange={(event) => setAdeUrl(event.target.value)}
345
- disabled={saving}
346
- />
347
- <span className="data-club-ai-hub-admin__form-helper">
348
- {props.texts.settingsLettaAdeUrlHelper}
349
- </span>
350
- </label>
351
- <label className="data-club-ai-hub-admin__form-field">
352
- <span className="data-club-ai-hub-admin__form-label">
353
- {props.texts.settingsLettaApiKeyLabel}
354
- </span>
355
- <input
356
- type="password"
357
- className="data-club-ai-hub-admin__form-input"
358
- data-testid="admin-settings-letta-api-key"
359
- value={apiKey}
360
- placeholder={
361
- props.settings.letta_api_key_source === "db"
362
- ? props.texts.settingsLettaApiKeyPlaceholder
363
- : ""
364
- }
365
- onChange={(event) => setApiKey(event.target.value)}
366
- disabled={saving}
367
- autoComplete="new-password"
368
- />
369
- <span
370
- className="data-club-ai-hub-admin__form-helper"
371
- data-testid="admin-settings-letta-api-key-helper"
372
- data-source={props.settings.letta_api_key_source}
373
- >
374
- {props.settings.letta_api_key_source === "db"
375
- ? props.texts.settingsLettaApiKeyDbHelper
376
- : props.settings.letta_api_key_source === "env"
377
- ? props.texts.settingsLettaApiKeyEnvHelper
378
- : props.texts.settingsLettaApiKeyNoneHelper}
379
- </span>
380
- {props.settings.letta_api_key_source === "db" ? (
381
- <button
382
- type="button"
383
- className="data-club-ai-hub-admin__button"
384
- data-testid="admin-settings-letta-api-key-clear"
385
- onClick={() => void handleClearApiKeyOverride()}
386
- disabled={saving}
387
- >
388
- {props.texts.settingsLettaApiKeyClearOverrideButton}
389
- </button>
390
- ) : null}
391
- </label>
392
- {flash !== null ? (
393
- <div
394
- className={
395
- flash.tone === "success"
396
- ? "data-club-ai-hub-admin__flash data-club-ai-hub-admin__flash--success"
397
- : "data-club-ai-hub-admin__flash data-club-ai-hub-admin__flash--error"
398
- }
399
- data-testid="admin-settings-letta-flash"
400
- role={flash.tone === "error" ? "alert" : "status"}
401
- >
402
- {flash.text}
403
- </div>
404
- ) : null}
405
- <button
406
- type="submit"
407
- className="data-club-ai-hub-admin__button data-club-ai-hub-admin__button--primary"
408
- data-testid="admin-settings-letta-save"
409
- disabled={saving}
410
- >
411
- {saving
412
- ? props.texts.settingsSaveSavingButton
413
- : props.texts.settingsSaveLettaButton}
414
- </button>
415
- </form>
416
- </section>
417
- );
418
- }
419
-
420
- /* ────────────────────────────────────────────────────────────────────────── */
421
- /* Section: Theme */
422
- /* ────────────────────────────────────────────────────────────────────────── */
423
-
424
235
  interface ThemeSectionProps extends SectionProps {
425
236
  onSaved: (next: AdminSettingsView) => void;
426
237
  }
@@ -8,7 +8,7 @@
8
8
  * `user`-role caller the component returns `null` outright.
9
9
  *
10
10
  * The shell **renders its own `<ShellHeader />`** so the user-menu (log
11
- * out, theme toggle, Open Letta ADE, ← Back to chat) stays available
11
+ * out, theme toggle, ← Back to chat) stays available
12
12
  * from inside the admin view too — [00-shell.md] makes the shell header
13
13
  * part of every authenticated page. The component is identical to the
14
14
  * one ChatShell renders.
@@ -54,7 +54,6 @@ import type {
54
54
  AIHubMessageBubbleRenderer,
55
55
  } from "../../types.js";
56
56
 
57
- import { CacheBadge } from "../CacheBadge/index.js";
58
57
  import { MarkdownRenderer } from "../MarkdownRenderer/index.js";
59
58
  import { ReasoningView } from "../ReasoningView/index.js";
60
59
  import { ScrollToPresentButton } from "../ScrollToPresentButton/index.js";
@@ -713,9 +712,6 @@ function MessageBubble(props: {
713
712
  message.content.trim()
714
713
  )}
715
714
  </span>
716
- {isAssistant && message.usage ? (
717
- <CacheBadge usage={message.usage} />
718
- ) : null}
719
715
  {props.isFailedAssistant ? (
720
716
  <div className={cls.bubbleActions}>
721
717
  <span>{props.failedLabel}</span>
@@ -108,7 +108,7 @@ function mergeOptimisticAffordances(
108
108
  ): AIHubMessage[] {
109
109
  const optimisticById = new Map<string, AIHubMessage>();
110
110
  for (const m of optimistic) {
111
- if (m.role === "assistant" && (m.reasoning || m.tool_calls?.length || m.usage)) {
111
+ if (m.role === "assistant" && (m.reasoning || m.tool_calls?.length)) {
112
112
  optimisticById.set(m.id, m);
113
113
  }
114
114
  }
@@ -123,13 +123,6 @@ function mergeOptimisticAffordances(
123
123
  if ((!next.tool_calls || next.tool_calls.length === 0) && o.tool_calls?.length) {
124
124
  next.tool_calls = o.tool_calls;
125
125
  }
126
- // Usage rides through too — if the canonical refetch happens
127
- // before the server stamped `message_usage` (small race window),
128
- // the live `usage` event we already handled keeps the badge
129
- // rendered until the next refresh confirms it.
130
- if (!next.usage && o.usage) {
131
- next.usage = o.usage;
132
- }
133
126
  return next;
134
127
  });
135
128
  }
@@ -828,30 +821,6 @@ export function AIHubProvider(props: AIHubProviderProps): ReactNode {
828
821
  setStreamingReasoning(null);
829
822
  setStreamingToolCalls([]);
830
823
  sawAssistantOutput = true;
831
- } else if (event.event === "usage") {
832
- // Live usage stamp — the runner emits this right before
833
- // `stream_end{done}` carrying the cache-hit/write counts for
834
- // the turn. We attach it to the matching assistant bubble so
835
- // `<CacheBadge />` appears immediately (without waiting for
836
- // the post-stream `/messages` refetch). The refetch path
837
- // also stamps the same `usage` from the persisted
838
- // `message_usage` row, so refresh + history retrieval show
839
- // the badge too.
840
- const targetId = event.data.letta_message_id;
841
- if (typeof targetId === "string") {
842
- const usage = {
843
- input: event.data.input ?? null,
844
- output: event.data.output ?? null,
845
- cache_read: event.data.cache_read ?? null,
846
- cache_write: event.data.cache_write ?? null,
847
- reasoning: event.data.reasoning ?? null,
848
- context: event.data.context ?? null,
849
- total: event.data.total ?? null,
850
- };
851
- setMessages((prev) =>
852
- prev.map((m) => (m.id === targetId ? { ...m, usage } : m)),
853
- );
854
- }
855
824
  } else if (event.event === "error") {
856
825
  setLastTurnError(event.data.message);
857
826
  sawError = true;
package/src/index.ts CHANGED
@@ -26,7 +26,6 @@ export type {
26
26
  Session,
27
27
  AIHubMessage,
28
28
  AIHubMessageOverride,
29
- AIHubMessageUsage,
30
29
  AIHubToolCallRecord,
31
30
  TurnStatus,
32
31
  RunningPhase,
@@ -232,13 +231,6 @@ export type {
232
231
  } from "./components/ToolCallView/index.js";
233
232
  export { formatToolContentForDisplay } from "./components/ToolCallView/formatContent.js";
234
233
 
235
- export { CacheBadge, computeCacheHitRatio } from "./components/CacheBadge/index.js";
236
- export type {
237
- CacheBadgeProps,
238
- CacheBadgeClassNames,
239
- CacheBadgeTexts,
240
- } from "./components/CacheBadge/index.js";
241
-
242
234
  export { ScrollToPresentButton } from "./components/ScrollToPresentButton/index.js";
243
235
  export type {
244
236
  ScrollToPresentButtonProps,
@@ -125,7 +125,6 @@ export function reduceAIHubState(
125
125
  case "tool_call_dispatched":
126
126
  case "tool_call_progress":
127
127
  case "tool_call_result":
128
- case "usage":
129
128
  return next;
130
129
  }
131
130
  }
@@ -177,7 +177,7 @@ block and modifier.
177
177
  | `data-club-ai-hub__user-menu__header` | Header row inside the dropdown (username + role). |
178
178
  | `data-club-ai-hub__user-menu__username-large` | Larger username text in the dropdown header. |
179
179
  | `data-club-ai-hub__user-menu__role` | Role label below the username. |
180
- | `data-club-ai-hub__user-menu__item` | A menu item (Sign out today; Theme / Admin / Letta ADE in Steps 10–11). |
180
+ | `data-club-ai-hub__user-menu__item` | A menu item (Sign out today; Theme / Admin in Steps 10–11). |
181
181
 
182
182
  ### Agents picker — Step 9 (`ui-sketches/03-chat.md`)
183
183
 
@@ -660,10 +660,6 @@
660
660
  background-color: color-mix(in srgb, var(--dc-aih-accent) 12%, transparent);
661
661
  }
662
662
 
663
- .data-club-ai-hub__user-menu__item--link {
664
- text-decoration: none;
665
- }
666
-
667
663
  /* ── Language switcher (left of the user menu in the shell header) ────── */
668
664
 
669
665
  .data-club-ai-hub__language-switcher {
@@ -2264,69 +2260,6 @@
2264
2260
  letter-spacing: 0.04em;
2265
2261
  }
2266
2262
 
2267
- /* ─────────────────────────────────────────────────────────────────── */
2268
- /* Cache badge — per-assistant-message prompt-cache hit indicator */
2269
- /* */
2270
- /* Renders as a small chip in the bottom-right corner of the assistant */
2271
- /* bubble, showing the cache-hit % over the prompt-side tokens. The */
2272
- /* `data-cache-state` attribute (none|cold|warm|hot) drives the color */
2273
- /* so skinners can override per-state via the CSS-vars without */
2274
- /* duplicating the layout rules. */
2275
- /* ─────────────────────────────────────────────────────────────────── */
2276
- .data-club-ai-hub__cache-badge {
2277
- display: inline-flex;
2278
- align-items: center;
2279
- gap: 0.25em;
2280
- margin-top: 0.4em;
2281
- margin-left: auto;
2282
- align-self: flex-end;
2283
- padding: 0.1em 0.5em;
2284
- font-size: 0.75em;
2285
- line-height: 1.2;
2286
- border-radius: 999px;
2287
- background: var(--dc-aih-cache-badge-bg, rgba(127, 127, 127, 0.12));
2288
- color: var(--dc-aih-cache-badge-fg, var(--dc-aih-text-muted, #888));
2289
- border: 1px solid var(--dc-aih-cache-badge-border, transparent);
2290
- cursor: help; /* signals the title-attribute tooltip */
2291
- user-select: none;
2292
- transition: background 0.15s ease, border-color 0.15s ease;
2293
- }
2294
- .data-club-ai-hub__cache-badge[data-cache-state="hot"] {
2295
- background: var(--dc-aih-cache-badge-hot-bg, rgba(40, 180, 99, 0.14));
2296
- color: var(--dc-aih-cache-badge-hot-fg, #28b463);
2297
- }
2298
- .data-club-ai-hub__cache-badge[data-cache-state="warm"] {
2299
- background: var(--dc-aih-cache-badge-warm-bg, rgba(255, 142, 78, 0.14));
2300
- color: var(--dc-aih-cache-badge-warm-fg, #ff8e4e);
2301
- }
2302
- .data-club-ai-hub__cache-badge[data-cache-state="cold"] {
2303
- background: var(--dc-aih-cache-badge-cold-bg, rgba(160, 160, 160, 0.14));
2304
- color: var(--dc-aih-cache-badge-cold-fg, #888);
2305
- }
2306
- .data-club-ai-hub__cache-badge[data-cache-state="miss"] {
2307
- /* Full cache miss — provider had to reinitialize the whole prompt.
2308
- Red-tinted to signal "nothing cached this turn". */
2309
- background: var(--dc-aih-cache-badge-miss-bg, rgba(216, 44, 246, 0.12));
2310
- color: var(--dc-aih-cache-badge-miss-fg, #d82cf6);
2311
- }
2312
- .data-club-ai-hub__cache-badge[data-cache-state="priming"] {
2313
- /* This turn WROTE to the provider's cache. Next turn benefits.
2314
- Blue-tinted to distinguish from cold miss. */
2315
- background: var(--dc-aih-cache-badge-priming-bg, rgba(41, 189, 239, 0.14));
2316
- color: var(--dc-aih-cache-badge-priming-fg, #29bdef);
2317
- }
2318
- .data-club-ai-hub__cache-badge[data-cache-state="none"] {
2319
- font-style: italic;
2320
- opacity: 0.7;
2321
- }
2322
- .data-club-ai-hub__cache-badge__icon {
2323
- font-size: 0.9em;
2324
- }
2325
- .data-club-ai-hub__cache-badge__label {
2326
- font-variant-numeric: tabular-nums;
2327
- font-weight: 600;
2328
- }
2329
-
2330
2263
  /* ────────────────────────────────────────────────────────────────────────── */
2331
2264
  /* Step 12 — admin Agents / Sessions overview / Settings sub-pages */
2332
2265
  /* ────────────────────────────────────────────────────────────────────────── */
package/src/types.ts CHANGED
@@ -81,10 +81,6 @@ export interface AIHubUser {
81
81
  * `user.theme_preference + deployment.{theme_default, theme_switcher_enabled}`
82
82
  * per §7.6 (two lines in the React provider).
83
83
  *
84
- * `letta_ade_url` is included only when the caller's role is `power_user`
85
- * or higher; for `user`-role callers the field is absent — by design
86
- * (§6.3.4: the URL is an admin-surface concern).
87
- *
88
84
  * @see SPECIFICATIONS.md §6.3.4 — `GET /auth/me`
89
85
  * @see SPECIFICATIONS.md §7.6 — theme resolution
90
86
  */
@@ -123,11 +119,6 @@ export interface AIHubDeployment {
123
119
  * hidden. (Also hidden whenever only one agent exists, regardless of this.)
124
120
  */
125
121
  agent_switcher_enabled: boolean;
126
- /**
127
- * Browser-facing URL of the self-hosted Letta ADE — only present when the
128
- * caller's role is `power_user` or higher. Absent for `user`-role callers.
129
- */
130
- letta_ade_url?: string;
131
122
  }
132
123
 
133
124
  /**
@@ -261,16 +252,6 @@ export interface AIHubMessage {
261
252
  * @see ui-sketches/03-chat.md — tool_call_card
262
253
  */
263
254
  tool_calls?: AIHubToolCallRecord[] | null;
264
- /**
265
- * Provider-reported token usage for the turn that produced this
266
- * message. Set on the LAST assistant message of each turn (the
267
- * `usage_statistics` event is per-run, not per-message; we stamp it
268
- * on the visible final bubble). Renders as a small cache-status
269
- * badge in the chat UI; hover for the full breakdown.
270
- *
271
- * @see AIHubMessageUsage
272
- */
273
- usage?: AIHubMessageUsage | null;
274
255
  }
275
256
 
276
257
  /**
@@ -638,61 +619,6 @@ export interface AIHubSystemNoticeEvent extends AIHubEventBase {
638
619
  };
639
620
  }
640
621
 
641
- /**
642
- * System: per-turn token-usage counters propagated from Letta. Stamped
643
- * on the LAST assistant message of the turn — the React reducer uses
644
- * `letta_message_id` to attach the badge to the right bubble. Also
645
- * persisted server-side so a refresh keeps the badge.
646
- *
647
- * @see SPECIFICATIONS.md §9.4
648
- * @see docs/server/chat-sse.md
649
- */
650
- export interface AIHubSystemUsageEvent extends AIHubEventBase {
651
- event: "usage";
652
- data: {
653
- /**
654
- * Letta message id this usage attaches to (the turn's last assistant
655
- * message). The reducer joins this against the chat history to put
656
- * the cache badge on the right bubble. Optional for forward
657
- * compatibility with future per-message usage events.
658
- */
659
- letta_message_id?: string;
660
- /** Non-cached input-token count (prompt_tokens). */
661
- input?: number;
662
- /** Output-token count (completion_tokens). */
663
- output?: number;
664
- /** Cache-read-token count — Anthropic / OpenAI / Gemini all report. */
665
- cache_read?: number;
666
- /** Cache-write-token count — Anthropic only; null elsewhere. */
667
- cache_write?: number;
668
- /** Reasoning / thinking tokens for models that produce them. */
669
- reasoning?: number;
670
- /** Letta's rolling context-window-size estimate post-turn. */
671
- context?: number;
672
- /** Sum reported by provider (may differ from input+output when reasoning is counted separately). */
673
- total?: number;
674
- };
675
- }
676
-
677
- /**
678
- * Per-assistant-message cache + token usage, attached to the
679
- * historical chat record. Returned from `GET /sessions/{id}/messages`
680
- * via `AIHubMessage.usage`. Same shape as the live wire event's
681
- * `data` minus the `letta_message_id` (which is already the message
682
- * itself).
683
- *
684
- * @see AIHubSystemUsageEvent
685
- */
686
- export interface AIHubMessageUsage {
687
- input?: number | null;
688
- output?: number | null;
689
- cache_read?: number | null;
690
- cache_write?: number | null;
691
- reasoning?: number | null;
692
- context?: number | null;
693
- total?: number | null;
694
- }
695
-
696
622
  /**
697
623
  * System: non-recoverable error. Followed by `stream_end {reason: "error"}`.
698
624
  * The turn transitions to `failed`; the session remains usable.
@@ -734,7 +660,6 @@ export type AIHubEvent =
734
660
  | AIHubToolCallProgressEvent
735
661
  | AIHubToolCallResultEvent
736
662
  | AIHubSystemNoticeEvent
737
- | AIHubSystemUsageEvent
738
663
  | AIHubSystemErrorEvent;
739
664
 
740
665
  /* ────────────────────────────────────────────────────────────────────────── */