@lastbrain/ai-ui-react 1.0.28 → 1.0.30

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 (37) hide show
  1. package/dist/components/AiChipLabel.d.ts.map +1 -1
  2. package/dist/components/AiChipLabel.js +2 -0
  3. package/dist/components/AiContextButton.d.ts.map +1 -1
  4. package/dist/components/AiContextButton.js +5 -35
  5. package/dist/components/AiImageButton.d.ts.map +1 -1
  6. package/dist/components/AiImageButton.js +5 -25
  7. package/dist/components/AiInput.d.ts.map +1 -1
  8. package/dist/components/AiInput.js +5 -2
  9. package/dist/components/AiPromptPanel.d.ts.map +1 -1
  10. package/dist/components/AiPromptPanel.js +19 -5
  11. package/dist/components/AiSelect.d.ts.map +1 -1
  12. package/dist/components/AiSelect.js +2 -1
  13. package/dist/components/AiTextarea.d.ts.map +1 -1
  14. package/dist/components/AiTextarea.js +2 -1
  15. package/dist/components/ErrorToast.d.ts +18 -0
  16. package/dist/components/ErrorToast.d.ts.map +1 -0
  17. package/dist/components/ErrorToast.js +123 -0
  18. package/dist/hooks/useModelManagement.d.ts.map +1 -1
  19. package/dist/hooks/useModelManagement.js +3 -1
  20. package/dist/index.d.ts +2 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +3 -0
  23. package/dist/utils/errorHandler.d.ts +30 -0
  24. package/dist/utils/errorHandler.d.ts.map +1 -0
  25. package/dist/utils/errorHandler.js +135 -0
  26. package/package.json +2 -2
  27. package/src/components/AiChipLabel.tsx +2 -0
  28. package/src/components/AiContextButton.tsx +11 -34
  29. package/src/components/AiImageButton.tsx +11 -25
  30. package/src/components/AiInput.tsx +5 -2
  31. package/src/components/AiPromptPanel.tsx +24 -7
  32. package/src/components/AiSelect.tsx +2 -1
  33. package/src/components/AiTextarea.tsx +2 -1
  34. package/src/components/ErrorToast.tsx +181 -0
  35. package/src/hooks/useModelManagement.ts +21 -8
  36. package/src/index.ts +4 -0
  37. package/src/utils/errorHandler.ts +189 -0
@@ -1 +1 @@
1
- {"version":3,"file":"AiChipLabel.d.ts","sourceRoot":"","sources":["../../src/components/AiChipLabel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA0C,MAAM,OAAO,CAAC;AAQ/D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,OAAmB,EACnB,SAAS,EACT,KAAK,EAAE,WAAW,GACnB,EAAE,gBAAgB,2CAgClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAU,EACV,QAAQ,EACR,WAAoE,EACpE,OAAO,EACP,QAAQ,EACR,eAAuB,EACvB,SAAS,EACT,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,YAAY,GACvB,EAAE,gBAAgB,2CA2LlB"}
1
+ {"version":3,"file":"AiChipLabel.d.ts","sourceRoot":"","sources":["../../src/components/AiChipLabel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA0C,MAAM,OAAO,CAAC;AAS/D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,OAAmB,EACnB,SAAS,EACT,KAAK,EAAE,WAAW,GACnB,EAAE,gBAAgB,2CAgClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAU,EACV,QAAQ,EACR,WAAoE,EACpE,OAAO,EACP,QAAQ,EACR,eAAuB,EACvB,SAAS,EACT,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,YAAY,GACvB,EAAE,gBAAgB,2CA4LlB"}
@@ -7,6 +7,7 @@ import { AiPromptPanel } from "./AiPromptPanel";
7
7
  import { useAiCallText } from "../hooks/useAiCallText";
8
8
  import { useAiModels } from "../hooks/useAiModels";
9
9
  import { useAiContext } from "../context/AiProvider";
10
+ import { handleAIError } from "../utils/errorHandler";
10
11
  export function AiChipLabel({ children, variant = "default", className, style: customStyle, }) {
11
12
  const variantStyles = {
12
13
  default: {},
@@ -96,6 +97,7 @@ Exemple de réponse attendue: javascript, react, frontend, api, development`;
96
97
  }
97
98
  catch (error) {
98
99
  console.error("Erreur lors de la génération des chips:", error);
100
+ handleAIError(error, undefined);
99
101
  setShowPromptPanel(false);
100
102
  }
101
103
  };
@@ -1 +1 @@
1
- {"version":3,"file":"AiContextButton.d.ts","sourceRoot":"","sources":["../../src/components/AiContextButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAQ5C,MAAM,WAAW,oBACf,SACE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC,EACrC,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IAEvE,WAAW,EAAE,GAAG,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CACT,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAC7C,IAAI,CAAC;IACV,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,YAAY,EACtB,MAAgB,EAChB,WAAW,EACX,kBAAyC,EACzC,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,gBAA0C,EAC1C,YAAY,EACZ,aAAa,EACb,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,EACf,GAAG,WAAW,EACf,EAAE,oBAAoB,2CAshBtB"}
1
+ {"version":3,"file":"AiContextButton.d.ts","sourceRoot":"","sources":["../../src/components/AiContextButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAU5C,MAAM,WAAW,oBACf,SACE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC,EACrC,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IAEvE,WAAW,EAAE,GAAG,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CACT,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAC7C,IAAI,CAAC;IACV,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,YAAY,EACtB,MAAgB,EAChB,WAAW,EACX,kBAAyC,EACzC,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,gBAA0C,EAC1C,YAAY,EACZ,aAAa,EACb,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,EACf,GAAG,WAAW,EACf,EAAE,oBAAoB,2CA6ftB"}
@@ -6,13 +6,16 @@ import { useAiCallText } from "../hooks/useAiCallText";
6
6
  import { useAiModels } from "../hooks/useAiModels";
7
7
  import { AiPromptPanel } from "./AiPromptPanel";
8
8
  import { useUsageToast } from "./UsageToast";
9
+ import { useErrorToast, ErrorToast } from "./ErrorToast";
9
10
  import { aiStyles } from "../styles/inline";
10
11
  import { useAiContext } from "../context/AiProvider";
12
+ import { handleAIError } from "../utils/errorHandler";
11
13
  export function AiContextButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode = "modal", contextData, contextDescription = "Données à analyser", onResult, onToast, disabled, className, children, resultModalTitle = "Résultat de l'analyse", storeOutputs, artifactTitle, context: _context, model: _model, prompt: _prompt, ...buttonProps }) {
12
14
  const [isOpen, setIsOpen] = useState(false);
13
15
  const [isResultOpen, setIsResultOpen] = useState(false);
14
16
  const [analysisResult, setAnalysisResult] = useState(null);
15
17
  const { showUsageToast, toastData, toastKey, clearToast } = useUsageToast();
18
+ const { showErrorToast, errorData, errorKey, clearError } = useErrorToast();
16
19
  // Récupérer le contexte AiProvider avec fallback sur les props
17
20
  const aiContext = useAiContext();
18
21
  const baseUrl = propBaseUrl ?? aiContext.baseUrl;
@@ -154,40 +157,7 @@ Analyse ces données et réponds de manière structurée et claire.`;
154
157
  }
155
158
  catch (error) {
156
159
  console.error("AiContextButton error:", error);
157
- // Gestion spécifique des erreurs d'API
158
- let errorMessage = "Erreur lors de l'analyse";
159
- let errorCode;
160
- if (error instanceof Error) {
161
- try {
162
- // Tenter de parser l'erreur JSON si c'est une erreur API
163
- const errorData = JSON.parse(error.message);
164
- if (errorData.error?.code === "INSUFFICIENT_TOKENS") {
165
- errorMessage =
166
- "Crédits insuffisants pour cette analyse. Veuillez recharger votre compte.";
167
- errorCode = "INSUFFICIENT_TOKENS";
168
- }
169
- else if (errorData.error?.message) {
170
- errorMessage = errorData.error.message;
171
- errorCode = errorData.error.code;
172
- }
173
- }
174
- catch {
175
- // Si ce n'est pas du JSON, utiliser le message d'erreur direct
176
- if (error.message.includes("INSUFFICIENT_TOKENS")) {
177
- errorMessage =
178
- "Crédits insuffisants pour cette analyse. Veuillez recharger votre compte.";
179
- errorCode = "INSUFFICIENT_TOKENS";
180
- }
181
- else {
182
- errorMessage = error.message;
183
- }
184
- }
185
- }
186
- onToast?.({
187
- type: "error",
188
- message: errorMessage,
189
- code: errorCode,
190
- });
160
+ handleAIError(error, onToast, showErrorToast);
191
161
  }
192
162
  finally {
193
163
  setIsOpen(false);
@@ -365,5 +335,5 @@ Analyse ces données et réponds de manière structurée et claire.`;
365
335
  ...getThemeStyles().content,
366
336
  }, children: [_jsxs("span", { children: ["Co\u00FBt: $", (apiKeyId?.includes("dev")
367
337
  ? 0
368
- : analysisResult.cost).toFixed(6)] }), _jsxs("span", { children: ["ID: ", analysisResult.requestId?.slice(-8) || "N/A"] })] }) })] })] }) }) }))] }));
338
+ : analysisResult.cost).toFixed(6)] }), _jsxs("span", { children: ["ID: ", analysisResult.requestId?.slice(-8) || "N/A"] })] }) })] })] }) }) })), _jsx(ErrorToast, { error: errorData, onComplete: clearError }, errorKey)] }));
369
339
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AiImageButton.d.ts","sourceRoot":"","sources":["../../src/components/AiImageButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAS5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAQ5C,MAAM,WAAW,kBACf,SACE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC,EACrC,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACvE,OAAO,CAAC,EAAE,CACR,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAC7C,IAAI,CAAC;IACV,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,YAAY,EACtB,MAAgB,EAChB,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,EACf,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,aAAoB,EACpB,WAAW,EACX,YAAY,EACZ,aAAa,EACb,GAAG,WAAW,EACf,EAAE,kBAAkB,2CA2ZpB"}
1
+ {"version":3,"file":"AiImageButton.d.ts","sourceRoot":"","sources":["../../src/components/AiImageButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAS5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAU5C,MAAM,WAAW,kBACf,SACE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC,EACrC,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACvE,OAAO,CAAC,EAAE,CACR,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAC7C,IAAI,CAAC;IACV,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,YAAY,EACtB,MAAgB,EAChB,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,EACf,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,aAAoB,EACpB,WAAW,EACX,YAAY,EACZ,aAAa,EACb,GAAG,WAAW,EACf,EAAE,kBAAkB,2CA2YpB"}
@@ -6,12 +6,15 @@ import { useAiCallImage } from "../hooks/useAiCallImage";
6
6
  import { useAiModels } from "../hooks/useAiModels";
7
7
  import { AiPromptPanel } from "./AiPromptPanel";
8
8
  import { useUsageToast } from "./UsageToast";
9
+ import { useErrorToast, ErrorToast } from "./ErrorToast";
9
10
  import { aiStyles } from "../styles/inline";
10
11
  import { useAiContext } from "../context/AiProvider";
12
+ import { handleAIError } from "../utils/errorHandler";
11
13
  export function AiImageButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode = "modal", context: _context, model: _model, prompt: _prompt, onImage, onToast, disabled, className, children, showImageCard = true, onImageSave, storeOutputs, artifactTitle, ...buttonProps }) {
12
14
  const [isOpen, setIsOpen] = useState(false);
13
15
  const [generatedImage, setGeneratedImage] = useState(null);
14
16
  const { showUsageToast, toastData, toastKey, clearToast } = useUsageToast();
17
+ const { showErrorToast, errorData, errorKey, clearError } = useErrorToast();
15
18
  // Récupérer le contexte AiProvider avec fallback sur les props
16
19
  const aiContext = useAiContext();
17
20
  const baseUrl = propBaseUrl ?? aiContext.baseUrl;
@@ -132,30 +135,7 @@ export function AiImageButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, ui
132
135
  }
133
136
  }
134
137
  catch (error) {
135
- let errorMessage = "Erreur lors de la génération de l'image";
136
- let errorCode;
137
- // Parse JSON error response for INSUFFICIENT_TOKENS
138
- if (error instanceof Error) {
139
- try {
140
- const errorData = JSON.parse(error.message);
141
- if (errorData.error?.code === "INSUFFICIENT_TOKENS") {
142
- errorMessage = `Solde insuffisant. ${errorData.error.message || "Veuillez recharger votre compte."}`;
143
- errorCode = "INSUFFICIENT_TOKENS";
144
- }
145
- }
146
- catch {
147
- // If parsing fails, check if error message contains the code
148
- if (error.message.includes("INSUFFICIENT_TOKENS")) {
149
- errorMessage = "Solde insuffisant. Veuillez recharger votre compte pour continuer.";
150
- errorCode = "INSUFFICIENT_TOKENS";
151
- }
152
- }
153
- }
154
- onToast?.({
155
- type: "error",
156
- message: errorMessage,
157
- code: errorCode || (error instanceof Error ? error.message : undefined),
158
- });
138
+ handleAIError(error, onToast, showErrorToast);
159
139
  }
160
140
  finally {
161
141
  setIsOpen(false);
@@ -264,5 +244,5 @@ export function AiImageButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, ui
264
244
  getThemeStyles().actionButton.color;
265
245
  }, title: "Copier l'URL", children: [_jsx(Copy, { size: 14 }), "Copier URL"] }), onImageSave && (_jsxs("button", { onClick: handleSave, className: "flex items-center gap-1 px-3 py-2 text-xs font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors", title: "Sauvegarder en base", children: [_jsx(ExternalLink, { size: 14 }), "Sauvegarder"] }))] }), _jsx("div", { className: "mt-3 pt-3 text-xs", style: {
266
246
  ...getThemeStyles().metadata,
267
- }, children: _jsx("div", { className: "flex justify-center", children: _jsxs("span", { children: ["ID: ", generatedImage.requestId.slice(-8)] }) }) })] }))] }));
247
+ }, children: _jsx("div", { className: "flex justify-center", children: _jsxs("span", { children: ["ID: ", generatedImage.requestId.slice(-8)] }) }) })] })), _jsx(ErrorToast, { error: errorData, onComplete: clearError }, errorKey)] }));
268
248
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AiInput.d.ts","sourceRoot":"","sources":["../../src/components/AiInput.tsx"],"names":[],"mappings":"AAEA,OAAc,EAAoB,KAAK,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAE1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAO5C,MAAM,WAAW,YACf,SACE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EACzB,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,SAAS,CAAC;IACxD,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC5B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,QAAQ,EACR,MAAgB,EAChB,OAAO,EACP,KAAK,EACL,MAAM,EACN,QAAgB,EAChB,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,EACT,qBAA6B,EAC7B,GAAG,UAAU,EACd,EAAE,YAAY,2CAyKd"}
1
+ {"version":3,"file":"AiInput.d.ts","sourceRoot":"","sources":["../../src/components/AiInput.tsx"],"names":[],"mappings":"AAEA,OAAc,EAAoB,KAAK,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAE1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAQ5C,MAAM,WAAW,YACf,SACE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EACzB,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,SAAS,CAAC;IACxD,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC5B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,QAAQ,EACR,MAAgB,EAChB,OAAO,EACP,KAAK,EACL,MAAM,EACN,QAAgB,EAChB,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,EACT,qBAA6B,EAC7B,GAAG,UAAU,EACd,EAAE,YAAY,2CA2Kd"}
@@ -7,6 +7,7 @@ import { useAiModels } from "../hooks/useAiModels";
7
7
  import { AiPromptPanel } from "./AiPromptPanel";
8
8
  import { UsageToast, useUsageToast } from "./UsageToast";
9
9
  import { aiStyles } from "../styles/inline";
10
+ import { handleAIError } from "../utils/errorHandler";
10
11
  export function AiInput({ baseUrl, apiKeyId, uiMode = "modal", context, model, prompt, editMode = false, onValue, onToast, disabled, className, enableModelManagement = false, ...inputProps }) {
11
12
  const [isOpen, setIsOpen] = useState(false);
12
13
  const [inputValue, setInputValue] = useState(inputProps.value?.toString() || inputProps.defaultValue?.toString() || "");
@@ -46,7 +47,8 @@ export function AiInput({ baseUrl, apiKeyId, uiMode = "modal", context, model, p
46
47
  }
47
48
  }
48
49
  catch (error) {
49
- onToast?.({ type: "error", message: "Failed to generate text" });
50
+ console.error("AiInput error:", error);
51
+ handleAIError(error, onToast);
50
52
  }
51
53
  finally {
52
54
  setIsOpen(false);
@@ -77,7 +79,8 @@ export function AiInput({ baseUrl, apiKeyId, uiMode = "modal", context, model, p
77
79
  }
78
80
  }
79
81
  catch (error) {
80
- onToast?.({ type: "error", message: "Failed to generate text" });
82
+ console.error("AiInput handleQuickGenerate error:", error);
83
+ handleAIError(error, onToast);
81
84
  }
82
85
  };
83
86
  const handleInputChange = (e) => {
@@ -1 +1 @@
1
- {"version":3,"file":"AiPromptPanel.d.ts","sourceRoot":"","sources":["../../src/components/AiPromptPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAOvC,OAAO,EAAsB,KAAK,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAG/E,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,SAAS,CAAC;IAE1D,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,IAAI,CAAC;IAExB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CActD"}
1
+ {"version":3,"file":"AiPromptPanel.d.ts","sourceRoot":"","sources":["../../src/components/AiPromptPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAQvC,OAAO,EAAsB,KAAK,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAG/E,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,SAAS,CAAC;IAE1D,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,IAAI,CAAC;IAExB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CActD"}
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  import { useState, useEffect, useRef, useLayoutEffect, } from "react";
4
4
  import { BookOpen, Search, Sparkles, Star, Tag, Settings } from "lucide-react";
5
5
  import { aiStyles } from "../styles/inline";
6
+ import { handleAIError } from "../utils/errorHandler";
6
7
  import { usePrompts, } from "../hooks/usePrompts";
7
8
  import { useModelManagement } from "../hooks/useModelManagement";
8
9
  import { AiProvider } from "../context/AiProvider";
@@ -36,17 +37,29 @@ function AiPromptPanelInternal({ isOpen, onClose, onSubmit, uiMode: _uiMode = "m
36
37
  const [isModelManagementOpen, setIsModelManagementOpen] = useState(false);
37
38
  const [loadingModels, setLoadingModels] = useState([]);
38
39
  const { prompts, loading: promptsLoading, fetchPrompts, incrementStat, } = usePrompts();
39
- // Hook de gestion des modèles (automatique si enableModelManagement et pas de props externes)
40
+ // Hook de gestion des modèles (automatique si enableModelManagement et pas de models/availableModels externes)
40
41
  const autoModelManagement = useModelManagement({
41
42
  apiKey,
42
43
  baseUrl,
43
44
  category: "text", // Par défaut pour AiPromptPanel
44
- autoFetch: enableModelManagement && availableModels.length === 0,
45
+ autoFetch: enableModelManagement &&
46
+ models.length === 0 &&
47
+ availableModels.length === 0,
45
48
  });
46
49
  // Utiliser soit les props externes soit la gestion automatique
47
- const effectiveAvailableModels = availableModels.length > 0
48
- ? availableModels
49
- : autoModelManagement.availableModels;
50
+ const effectiveAvailableModels = models.length > 0
51
+ ? models.map((m) => ({
52
+ id: m.id,
53
+ name: m.name,
54
+ category: m.type === "image" ? "image" : "text",
55
+ provider: m.provider,
56
+ description: `${m.provider} model`,
57
+ isPro: false,
58
+ isActive: true,
59
+ }))
60
+ : availableModels.length > 0
61
+ ? availableModels
62
+ : autoModelManagement.availableModels;
50
63
  const effectiveUserModels = userModels.length > 0 ? userModels : autoModelManagement.userModels;
51
64
  const effectiveToggleModel = onModelToggle || autoModelManagement.toggleModel;
52
65
  // Gestion des modèles
@@ -59,6 +72,7 @@ function AiPromptPanelInternal({ isOpen, onClose, onSubmit, uiMode: _uiMode = "m
59
72
  }
60
73
  catch (error) {
61
74
  console.error("Erreur lors du changement de modèle:", error);
75
+ handleAIError(error, undefined);
62
76
  }
63
77
  finally {
64
78
  setLoadingModels((prev) => prev.filter((id) => id !== modelId));
@@ -1 +1 @@
1
- {"version":3,"file":"AiSelect.d.ts","sourceRoot":"","sources":["../../src/components/AiSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAO5C,MAAM,WAAW,aACf,SACE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EACzB,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC1D,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC7B;AAED,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,QAAQ,EACR,MAAgB,EAChB,OAAO,EACP,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,GAAG,WAAW,EACf,EAAE,aAAa,2CA+Ef"}
1
+ {"version":3,"file":"AiSelect.d.ts","sourceRoot":"","sources":["../../src/components/AiSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAQ5C,MAAM,WAAW,aACf,SACE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EACzB,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC1D,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC7B;AAED,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,QAAQ,EACR,MAAgB,EAChB,OAAO,EACP,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,GAAG,WAAW,EACf,EAAE,aAAa,2CA+Ef"}
@@ -6,6 +6,7 @@ import { useAiModels } from "../hooks/useAiModels";
6
6
  import { AiPromptPanel } from "./AiPromptPanel";
7
7
  import { UsageToast, useUsageToast } from "./UsageToast";
8
8
  import { aiStyles } from "../styles/inline";
9
+ import { handleAIError } from "../utils/errorHandler";
9
10
  export function AiSelect({ baseUrl, apiKeyId, uiMode = "modal", context, model, prompt, onValue, onToast, disabled, className, children, ...selectProps }) {
10
11
  const [isOpen, setIsOpen] = useState(false);
11
12
  const [isFocused, setIsFocused] = useState(false);
@@ -33,7 +34,7 @@ export function AiSelect({ baseUrl, apiKeyId, uiMode = "modal", context, model,
33
34
  }
34
35
  }
35
36
  catch (error) {
36
- onToast?.({ type: "error", message: "Failed to generate suggestion" });
37
+ handleAIError(error, onToast);
37
38
  }
38
39
  finally {
39
40
  setIsOpen(false);
@@ -1 +1 @@
1
- {"version":3,"file":"AiTextarea.d.ts","sourceRoot":"","sources":["../../src/components/AiTextarea.tsx"],"names":[],"mappings":"AAEA,OAAc,EAIZ,KAAK,sBAAsB,EAC5B,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAO5C,MAAM,WAAW,eACf,SACE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EACzB,IAAI,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EAAE,SAAS,CAAC;IAC9D,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC7B;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,QAAQ,EACR,MAAgB,EAChB,OAAO,EACP,KAAK,EACL,MAAM,EACN,QAAgB,EAChB,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,EACT,GAAG,aAAa,EACjB,EAAE,eAAe,2CAyLjB"}
1
+ {"version":3,"file":"AiTextarea.d.ts","sourceRoot":"","sources":["../../src/components/AiTextarea.tsx"],"names":[],"mappings":"AAEA,OAAc,EAIZ,KAAK,sBAAsB,EAC5B,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAQ5C,MAAM,WAAW,eACf,SACE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EACzB,IAAI,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EAAE,SAAS,CAAC;IAC9D,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC7B;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,QAAQ,EACR,MAAgB,EAChB,OAAO,EACP,KAAK,EACL,MAAM,EACN,QAAgB,EAChB,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,EACT,GAAG,aAAa,EACjB,EAAE,eAAe,2CAyLjB"}
@@ -7,6 +7,7 @@ import { useAiModels } from "../hooks/useAiModels";
7
7
  import { AiPromptPanel } from "./AiPromptPanel";
8
8
  import { UsageToast, useUsageToast } from "./UsageToast";
9
9
  import { aiStyles } from "../styles/inline";
10
+ import { handleAIError } from "../utils/errorHandler";
10
11
  export function AiTextarea({ baseUrl, apiKeyId, uiMode = "modal", context, model, prompt, editMode = false, onValue, onToast, disabled, className, ...textareaProps }) {
11
12
  const [isOpen, setIsOpen] = useState(false);
12
13
  const [textareaValue, setTextareaValue] = useState(textareaProps.value?.toString() ||
@@ -81,7 +82,7 @@ export function AiTextarea({ baseUrl, apiKeyId, uiMode = "modal", context, model
81
82
  }
82
83
  }
83
84
  catch (error) {
84
- onToast?.({ type: "error", message: "Failed to generate text" });
85
+ handleAIError(error, onToast);
85
86
  }
86
87
  };
87
88
  const handleTextareaChange = (e) => {
@@ -0,0 +1,18 @@
1
+ interface ErrorToastData {
2
+ message: string;
3
+ code?: string;
4
+ }
5
+ interface ErrorToastProps {
6
+ error: ErrorToastData | null;
7
+ position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
8
+ onComplete?: () => void;
9
+ }
10
+ export declare function ErrorToast({ error, position, onComplete, }: ErrorToastProps): import("react/jsx-runtime").JSX.Element | null;
11
+ export declare function useErrorToast(): {
12
+ showErrorToast: (error: ErrorToastData) => void;
13
+ errorData: ErrorToastData | null;
14
+ errorKey: number;
15
+ clearError: () => void;
16
+ };
17
+ export {};
18
+ //# sourceMappingURL=ErrorToast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorToast.d.ts","sourceRoot":"","sources":["../../src/components/ErrorToast.tsx"],"names":[],"mappings":"AAKA,UAAU,cAAc;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,eAAe;IACvB,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,EAAE,cAAc,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAC;IACrE,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,QAAyB,EACzB,UAAU,GACX,EAAE,eAAe,kDA0IjB;AAED,wBAAgB,aAAa;4BAII,cAAc;;;;EAgB9C"}
@@ -0,0 +1,123 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { X, AlertCircle } from "lucide-react";
5
+ export function ErrorToast({ error, position = "bottom-right", onComplete, }) {
6
+ const [isVisible, setIsVisible] = useState(false);
7
+ const [isClosing, setIsClosing] = useState(false);
8
+ const fadeTimeoutRef = useRef(null);
9
+ const autoCloseTimeoutRef = useRef(null);
10
+ useEffect(() => {
11
+ if (error) {
12
+ // Show toast immediately
13
+ queueMicrotask(() => {
14
+ setIsVisible(true);
15
+ setIsClosing(false);
16
+ });
17
+ // Auto-close after 8 seconds for errors (longer than success messages)
18
+ autoCloseTimeoutRef.current = window.setTimeout(() => {
19
+ handleClose();
20
+ }, 8000);
21
+ }
22
+ return () => {
23
+ if (fadeTimeoutRef.current) {
24
+ window.clearTimeout(fadeTimeoutRef.current);
25
+ }
26
+ if (autoCloseTimeoutRef.current) {
27
+ window.clearTimeout(autoCloseTimeoutRef.current);
28
+ }
29
+ };
30
+ }, [error]);
31
+ const handleClose = () => {
32
+ if (isClosing)
33
+ return;
34
+ // Clear auto-close timeout if user closes manually
35
+ if (autoCloseTimeoutRef.current) {
36
+ window.clearTimeout(autoCloseTimeoutRef.current);
37
+ }
38
+ setIsClosing(true);
39
+ fadeTimeoutRef.current = window.setTimeout(() => {
40
+ setIsVisible(false);
41
+ onComplete?.();
42
+ }, 200);
43
+ };
44
+ if (!error)
45
+ return null;
46
+ const getPositionStyles = () => {
47
+ const baseStyles = {
48
+ position: "fixed",
49
+ zIndex: 9999,
50
+ pointerEvents: "auto",
51
+ };
52
+ switch (position) {
53
+ case "bottom-left":
54
+ return { ...baseStyles, bottom: "8px", left: "8px" };
55
+ case "top-right":
56
+ return { ...baseStyles, top: "8px", right: "8px" };
57
+ case "top-left":
58
+ return { ...baseStyles, top: "8px", left: "8px" };
59
+ default:
60
+ return { ...baseStyles, bottom: "8px", right: "8px" };
61
+ }
62
+ };
63
+ return (_jsxs("div", { style: {
64
+ ...getPositionStyles(),
65
+ opacity: isVisible && !isClosing ? 1 : 0,
66
+ transform: `translateY(${isVisible && !isClosing ? "0" : "8px"})`,
67
+ transition: "opacity 200ms ease, transform 200ms ease",
68
+ padding: "12px 16px",
69
+ borderRadius: "8px",
70
+ background: "rgba(239, 68, 68, 0.12)",
71
+ border: "1px solid rgba(239, 68, 68, 0.3)",
72
+ color: "#dc2626",
73
+ fontSize: "13px",
74
+ fontWeight: 500,
75
+ display: "flex",
76
+ alignItems: "flex-start",
77
+ gap: "10px",
78
+ boxShadow: "0 4px 12px -2px rgba(239, 68, 68, 0.2)",
79
+ backdropFilter: "blur(8px)",
80
+ WebkitBackdropFilter: "blur(8px)",
81
+ maxWidth: "400px",
82
+ minWidth: "280px",
83
+ }, children: [_jsx(AlertCircle, { size: 16, style: { marginTop: "2px", flexShrink: 0 } }), _jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [_jsxs("div", { style: { fontWeight: 600, marginBottom: "2px" }, children: ["Erreur", error.code && (_jsxs("span", { style: {
84
+ marginLeft: "8px",
85
+ fontSize: "10px",
86
+ opacity: 0.7,
87
+ fontFamily: "monospace",
88
+ }, children: ["[", error.code, "]"] }))] }), _jsx("div", { style: { fontSize: "12px", opacity: 0.9, wordBreak: "break-word" }, children: error.message })] }), _jsx("button", { onClick: handleClose, style: {
89
+ background: "transparent",
90
+ border: "none",
91
+ cursor: "pointer",
92
+ padding: "4px",
93
+ display: "flex",
94
+ alignItems: "center",
95
+ justifyContent: "center",
96
+ borderRadius: "4px",
97
+ transition: "background-color 150ms ease",
98
+ color: "inherit",
99
+ flexShrink: 0,
100
+ }, onMouseEnter: (e) => {
101
+ e.currentTarget.style.backgroundColor = "rgba(239, 68, 68, 0.2)";
102
+ }, onMouseLeave: (e) => {
103
+ e.currentTarget.style.backgroundColor = "transparent";
104
+ }, title: "Fermer", children: _jsx(X, { size: 14 }) })] }));
105
+ }
106
+ export function useErrorToast() {
107
+ const [errorData, setErrorData] = useState(null);
108
+ const [errorKey, setErrorKey] = useState(0);
109
+ const showErrorToast = (error) => {
110
+ // Replace any existing error toast with new one
111
+ setErrorKey((prev) => prev + 1);
112
+ setErrorData(error);
113
+ };
114
+ const clearError = () => {
115
+ setErrorData(null);
116
+ };
117
+ return {
118
+ showErrorToast,
119
+ errorData,
120
+ errorKey,
121
+ clearError,
122
+ };
123
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"useModelManagement.d.ts","sourceRoot":"","sources":["../../src/hooks/useModelManagement.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAQlC,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB;IACnE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;CACjD;AAED,MAAM,WAAW,wBAAwB;IAEvC,eAAe,EAAE,OAAO,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAGrB,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAGvC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,eAAe,EAAE,MAAM,OAAO,EAAE,CAAC;IACjC,iBAAiB,EAAE,MAAM,OAAO,EAAE,CAAC;CACpC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,yBAA8B,GACtC,wBAAwB,CAyN1B"}
1
+ {"version":3,"file":"useModelManagement.d.ts","sourceRoot":"","sources":["../../src/hooks/useModelManagement.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAQlC,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB;IACnE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;CACjD;AAED,MAAM,WAAW,wBAAwB;IAEvC,eAAe,EAAE,OAAO,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAGrB,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAGvC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,eAAe,EAAE,MAAM,OAAO,EAAE,CAAC;IACjC,iBAAiB,EAAE,MAAM,OAAO,EAAE,CAAC;CACpC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,yBAA8B,GACtC,wBAAwB,CAsO1B"}
@@ -152,7 +152,9 @@ export function useModelManagement(options = {}) {
152
152
  baseUrl: effectiveOptions.baseUrl || "none",
153
153
  });
154
154
  // Auto-fetch si autoFetch est activé ET qu'on a soit une apiKey soit un proxy externe ET API disponible
155
- if (autoFetch && !apiUnavailable && (effectiveOptions.apiKey || isExternalProxy)) {
155
+ if (autoFetch &&
156
+ !apiUnavailable &&
157
+ (effectiveOptions.apiKey || isExternalProxy)) {
156
158
  console.log("[useModelManagement] Starting auto-fetch...");
157
159
  Promise.all([refreshModels(), refreshUserModels()]);
158
160
  }
package/dist/index.d.ts CHANGED
@@ -17,6 +17,8 @@ export * from "./components/AiImageButton";
17
17
  export * from "./components/AiContextButton";
18
18
  export * from "./components/AiSettingsButton";
19
19
  export * from "./components/AiStatusButton";
20
+ export * from "./components/ErrorToast";
21
+ export * from "./components/UsageToast";
20
22
  export * from "./utils/modelManagement";
21
23
  export * from "./utils/cache";
22
24
  export * from "./examples/AiImageGenerator";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AAGxB,cAAc,sBAAsB,CAAC;AAGrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAG3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAG5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,eAAe,CAAC;AAG9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AACjD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AAGxB,cAAc,sBAAsB,CAAC;AAGrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAG3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAG5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,eAAe,CAAC;AAG9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AACjD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC"}
package/dist/index.js CHANGED
@@ -21,6 +21,9 @@ export * from "./components/AiImageButton";
21
21
  export * from "./components/AiContextButton";
22
22
  export * from "./components/AiSettingsButton";
23
23
  export * from "./components/AiStatusButton";
24
+ // Toast system
25
+ export * from "./components/ErrorToast";
26
+ export * from "./components/UsageToast";
24
27
  // Utils
25
28
  export * from "./utils/modelManagement";
26
29
  export * from "./utils/cache";
@@ -0,0 +1,30 @@
1
+ export interface ParsedError {
2
+ message: string;
3
+ code?: string;
4
+ isUserFriendly: boolean;
5
+ }
6
+ /**
7
+ * Parse et uniformise la gestion des erreurs des composants AI
8
+ */
9
+ export declare function parseAIError(error: any): ParsedError;
10
+ /**
11
+ * Interface pour la callback de gestion d'erreur uniforme
12
+ */
13
+ export interface ErrorToastCallback {
14
+ (toast: {
15
+ type: "error";
16
+ message: string;
17
+ code?: string;
18
+ }): void;
19
+ }
20
+ /**
21
+ * Gestionnaire d'erreur uniforme pour tous les composants AI
22
+ * @param error L'erreur à gérer
23
+ * @param onToast Callback externe optionnelle fournie par le parent
24
+ * @param showInternalToast Callback interne optionnelle pour afficher un toast dans le composant
25
+ */
26
+ export declare function handleAIError(error: any, onToast?: ErrorToastCallback, showInternalToast?: (error: {
27
+ message: string;
28
+ code?: string;
29
+ }) => void): void;
30
+ //# sourceMappingURL=errorHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/utils/errorHandler.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,GAAG,GAAG,WAAW,CA8CpD;AAyFD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAClE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,GAAG,EACV,OAAO,CAAC,EAAE,kBAAkB,EAC5B,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,GACtE,IAAI,CAuBN"}