@chai-ui/react 0.1.0

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 (66) hide show
  1. package/DESIGN.md +207 -0
  2. package/LICENSE +21 -0
  3. package/README.md +265 -0
  4. package/dist/ChaiProvider.d.ts +49 -0
  5. package/dist/ChaiProvider.d.ts.map +1 -0
  6. package/dist/ChaiProvider.js +54 -0
  7. package/dist/ChaiProvider.js.map +1 -0
  8. package/dist/Composer.d.ts +169 -0
  9. package/dist/Composer.d.ts.map +1 -0
  10. package/dist/Composer.js +389 -0
  11. package/dist/Composer.js.map +1 -0
  12. package/dist/MediaAnalyzer.d.ts +102 -0
  13. package/dist/MediaAnalyzer.d.ts.map +1 -0
  14. package/dist/MediaAnalyzer.js +250 -0
  15. package/dist/MediaAnalyzer.js.map +1 -0
  16. package/dist/ResultCard.d.ts +55 -0
  17. package/dist/ResultCard.d.ts.map +1 -0
  18. package/dist/ResultCard.js +409 -0
  19. package/dist/ResultCard.js.map +1 -0
  20. package/dist/index.d.ts +10 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +11 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/primitives/Pagination.d.ts +19 -0
  25. package/dist/primitives/Pagination.d.ts.map +1 -0
  26. package/dist/primitives/Pagination.js +13 -0
  27. package/dist/primitives/Pagination.js.map +1 -0
  28. package/dist/primitives/SearchMenu.d.ts +69 -0
  29. package/dist/primitives/SearchMenu.d.ts.map +1 -0
  30. package/dist/primitives/SearchMenu.js +88 -0
  31. package/dist/primitives/SearchMenu.js.map +1 -0
  32. package/dist/primitives/Toggle.d.ts +9 -0
  33. package/dist/primitives/Toggle.d.ts.map +1 -0
  34. package/dist/primitives/Toggle.js +28 -0
  35. package/dist/primitives/Toggle.js.map +1 -0
  36. package/dist/primitives/index.d.ts +4 -0
  37. package/dist/primitives/index.d.ts.map +1 -0
  38. package/dist/primitives/index.js +4 -0
  39. package/dist/primitives/index.js.map +1 -0
  40. package/dist/style.css +1860 -0
  41. package/dist/use-latest.d.ts +7 -0
  42. package/dist/use-latest.d.ts.map +1 -0
  43. package/dist/use-latest.js +17 -0
  44. package/dist/use-latest.js.map +1 -0
  45. package/dist/useComposer.d.ts +75 -0
  46. package/dist/useComposer.d.ts.map +1 -0
  47. package/dist/useComposer.js +191 -0
  48. package/dist/useComposer.js.map +1 -0
  49. package/dist/useMediaAnalyzer.d.ts +37 -0
  50. package/dist/useMediaAnalyzer.d.ts.map +1 -0
  51. package/dist/useMediaAnalyzer.js +114 -0
  52. package/dist/useMediaAnalyzer.js.map +1 -0
  53. package/package.json +88 -0
  54. package/src/ChaiProvider.tsx +88 -0
  55. package/src/Composer.tsx +961 -0
  56. package/src/MediaAnalyzer.tsx +527 -0
  57. package/src/ResultCard.tsx +980 -0
  58. package/src/index.ts +36 -0
  59. package/src/primitives/Pagination.tsx +41 -0
  60. package/src/primitives/SearchMenu.tsx +284 -0
  61. package/src/primitives/Toggle.tsx +43 -0
  62. package/src/primitives/index.ts +3 -0
  63. package/src/style.css +1860 -0
  64. package/src/use-latest.ts +18 -0
  65. package/src/useComposer.ts +289 -0
  66. package/src/useMediaAnalyzer.ts +157 -0
@@ -0,0 +1,88 @@
1
+ import { createContext, useContext, useMemo, type ReactNode } from "react";
2
+ import { createOpenRouterEngine, type DroppedMedia, type GenerationEngine, type MediaKind } from "@chai-ui/core";
3
+
4
+ /**
5
+ * The suggested reasoning model for text and images: prompt enhancement,
6
+ * auto-select routing and image analysis. A default, not a requirement —
7
+ * pass any model id `reasoningEngine` can run.
8
+ */
9
+ export const DEFAULT_REASONING_MODEL = "anthropic/claude-opus-5";
10
+
11
+ /**
12
+ * Suggested per-kind overrides for media Claude can't read. Gemini takes
13
+ * video and audio directly. For a cheaper option, swap in
14
+ * `"qwen/qwen3.8-omni-flash"`, which takes both too.
15
+ */
16
+ export const DEFAULT_REASONING_MODEL_BY_KIND: Partial<Record<MediaKind, string>> = {
17
+ video: "google/gemini-3.8-flash",
18
+ audio: "google/gemini-3.8-flash",
19
+ };
20
+
21
+ /** The reasoning engine and models every CHAI component shares. */
22
+ export interface Reasoning {
23
+ engine: GenerationEngine;
24
+ /** The model for text and any attachment kind without its own entry in `modelByKind`. */
25
+ model: string;
26
+ modelByKind: Partial<Record<MediaKind, string>>;
27
+ }
28
+
29
+ const ReasoningContext = createContext<Reasoning | undefined>(undefined);
30
+
31
+ export interface ChaiProviderProps {
32
+ /** Text, image and routing model. Defaults to `DEFAULT_REASONING_MODEL`. */
33
+ reasoningModel?: string;
34
+ /**
35
+ * Per-attachment-kind models, merged over `DEFAULT_REASONING_MODEL_BY_KIND`
36
+ * one kind at a time, e.g. `{ video: "qwen/qwen3.8-omni-flash" }` keeps
37
+ * the default for audio. Map a kind to `reasoningModel`'s value to use
38
+ * one model for everything.
39
+ */
40
+ reasoningModelByKind?: Partial<Record<MediaKind, string>>;
41
+ /**
42
+ * The engine the reasoning models run on. Defaults to OpenRouter,
43
+ * independent of the generation engine: Fal's own LLM access is an
44
+ * OpenRouter proxy, so defaulting to it would double-proxy.
45
+ */
46
+ reasoningEngine?: GenerationEngine;
47
+ children?: ReactNode;
48
+ }
49
+
50
+ export function ChaiProvider({ reasoningModel, reasoningModelByKind, reasoningEngine, children }: ChaiProviderProps) {
51
+ const engine = useMemo(() => reasoningEngine ?? createOpenRouterEngine(), [reasoningEngine]);
52
+ const model = reasoningModel ?? DEFAULT_REASONING_MODEL;
53
+ const video = reasoningModelByKind?.video;
54
+ const audio = reasoningModelByKind?.audio;
55
+ const image = reasoningModelByKind?.image;
56
+ const text = reasoningModelByKind?.text;
57
+ const value = useMemo(
58
+ () => ({
59
+ engine,
60
+ model,
61
+ modelByKind: { ...DEFAULT_REASONING_MODEL_BY_KIND, ...dropUndefined({ video, audio, image, text }) },
62
+ }),
63
+ [engine, model, video, audio, image, text]
64
+ );
65
+ return <ReasoningContext.Provider value={value}>{children}</ReasoningContext.Provider>;
66
+ }
67
+
68
+ function dropUndefined<T extends object>(obj: T): Partial<T> {
69
+ return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined)) as Partial<T>;
70
+ }
71
+
72
+ /** The nearest `ChaiProvider`'s reasoning engine and models, or `undefined` outside one. */
73
+ export function useReasoning(): Reasoning | undefined {
74
+ return useContext(ReasoningContext);
75
+ }
76
+
77
+ /**
78
+ * The reasoning model for a call with these attachments: the first
79
+ * attachment whose kind has its own model wins (a clip plus a still goes
80
+ * to the model that can read the clip), else `reasoning.model`.
81
+ */
82
+ export function reasoningModelFor(reasoning: Reasoning, attachments: DroppedMedia[] = []): string {
83
+ for (const { kind } of attachments) {
84
+ const model = reasoning.modelByKind[kind];
85
+ if (model) return model;
86
+ }
87
+ return reasoning.model;
88
+ }