@lastbrain/ai-ui-react 1.0.14 → 1.0.16

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.
@@ -1 +1 @@
1
- {"version":3,"file":"useModelManagement.d.ts","sourceRoot":"","sources":["../../src/hooks/useModelManagement.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAElC,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,CAkK1B"}
1
+ {"version":3,"file":"useModelManagement.d.ts","sourceRoot":"","sources":["../../src/hooks/useModelManagement.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAElC,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,CA+K1B"}
@@ -103,23 +103,34 @@ export function useModelManagement(options = {}) {
103
103
  const getInactiveModels = useCallback(() => {
104
104
  return availableModels.filter((model) => !userModels.includes(model.id));
105
105
  }, [availableModels, userModels]);
106
- // Auto-fetch au mount - seulement si autoFetch ET apiKey sont présents
106
+ // Auto-fetch au mount - si autoFetch ET (apiKey OU baseUrl avec proxy externe)
107
107
  useEffect(() => {
108
+ const isExternalProxy = apiOptions.baseUrl && apiOptions.baseUrl.includes("/api/lastbrain");
108
109
  console.log("[useModelManagement] useEffect triggered:", {
109
110
  autoFetch,
110
111
  hasApiKey: !!apiOptions.apiKey,
112
+ hasBaseUrl: !!apiOptions.baseUrl,
113
+ isExternalProxy,
111
114
  apiKeyPreview: apiOptions.apiKey
112
115
  ? apiOptions.apiKey.substring(0, 10) + "..."
113
116
  : "none",
117
+ baseUrl: apiOptions.baseUrl || "none",
114
118
  });
115
- if (autoFetch && apiOptions.apiKey) {
119
+ // Auto-fetch si autoFetch est activé ET qu'on a soit une apiKey soit un proxy externe
120
+ if (autoFetch && (apiOptions.apiKey || isExternalProxy)) {
116
121
  console.log("[useModelManagement] Starting auto-fetch...");
117
122
  Promise.all([refreshModels(), refreshUserModels()]);
118
123
  }
119
- else if (autoFetch && !apiOptions.apiKey) {
120
- console.warn("[useModelManagement] autoFetch is enabled but no apiKey provided. Skipping automatic fetch.");
124
+ else if (autoFetch && !apiOptions.apiKey && !isExternalProxy) {
125
+ console.warn("[useModelManagement] autoFetch is enabled but no apiKey or baseUrl provided. Skipping automatic fetch.");
121
126
  }
122
- }, [autoFetch, refreshModels, refreshUserModels, apiOptions.apiKey]);
127
+ }, [
128
+ autoFetch,
129
+ refreshModels,
130
+ refreshUserModels,
131
+ apiOptions.apiKey,
132
+ apiOptions.baseUrl,
133
+ ]);
123
134
  return {
124
135
  availableModels,
125
136
  userModels,
@@ -1 +1 @@
1
- {"version":3,"file":"usePrompts.d.ts","sourceRoot":"","sources":["../../src/hooks/usePrompts.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAa,SAAQ,MAAM;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,EAAE,CAAC,OAAO,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,YAAY,EAAE,CACZ,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,GAAG,YAAY,GAAG,YAAY,CAAC,KACnD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5B,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5E,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,aAAa,EAAE,CACb,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,KAClC,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB;AAED,wBAAgB,UAAU,IAAI,gBAAgB,CA0I7C"}
1
+ {"version":3,"file":"usePrompts.d.ts","sourceRoot":"","sources":["../../src/hooks/usePrompts.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAa,SAAQ,MAAM;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,EAAE,CAAC,OAAO,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,YAAY,EAAE,CACZ,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,GAAG,YAAY,GAAG,YAAY,CAAC,KACnD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5B,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5E,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,aAAa,EAAE,CACb,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,KAClC,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB;AAED,wBAAgB,UAAU,IAAI,gBAAgB,CAgL7C"}
@@ -2,7 +2,7 @@
2
2
  import { useState, useCallback } from "react";
3
3
  import { useAiContext } from "../context/AiProvider";
4
4
  export function usePrompts() {
5
- const { apiKeyId } = useAiContext();
5
+ const { apiKeyId, baseUrl } = useAiContext();
6
6
  const [prompts, setPrompts] = useState([]);
7
7
  const [loading, setLoading] = useState(false);
8
8
  const [error, setError] = useState(null);
@@ -15,10 +15,21 @@ export function usePrompts() {
15
15
  params.append("type", options.type);
16
16
  if (options?.favorite !== undefined)
17
17
  params.append("favorite", String(options.favorite));
18
+ // Déterminer si on est dans un contexte externe (proxy nécessaire)
19
+ const isExternalProxy = baseUrl && baseUrl.includes("/api/lastbrain");
18
20
  // Use public route without auth if public=true, otherwise use auth route
19
- const endpoint = options?.public
20
- ? `/api/ai/public/prompts?${params}`
21
- : `/api/ai/auth/prompts?${params}`;
21
+ let endpoint;
22
+ if (options?.public) {
23
+ endpoint = isExternalProxy
24
+ ? `${baseUrl}/ai/public/prompts?${params}`
25
+ : `/api/ai/public/prompts?${params}`;
26
+ }
27
+ else {
28
+ endpoint = isExternalProxy
29
+ ? `${baseUrl}/ai/auth/prompts?${params}`
30
+ : `/api/ai/auth/prompts?${params}`;
31
+ }
32
+ console.log("[usePrompts] Fetching prompts from:", endpoint);
22
33
  const response = await fetch(endpoint);
23
34
  const data = await response.json();
24
35
  if (response.ok) {
@@ -34,11 +45,15 @@ export function usePrompts() {
34
45
  finally {
35
46
  setLoading(false);
36
47
  }
37
- }, []);
48
+ }, [baseUrl]);
38
49
  const createPrompt = useCallback(async (data) => {
39
50
  try {
40
51
  setError(null);
41
- const response = await fetch("/api/ai/auth/prompts", {
52
+ const isExternalProxy = baseUrl && baseUrl.includes("/api/lastbrain");
53
+ const endpoint = isExternalProxy
54
+ ? `${baseUrl}/ai/auth/prompts`
55
+ : "/api/ai/auth/prompts";
56
+ const response = await fetch(endpoint, {
42
57
  method: "POST",
43
58
  headers: { "Content-Type": "application/json" },
44
59
  body: JSON.stringify(data),
@@ -56,11 +71,15 @@ export function usePrompts() {
56
71
  setError(err instanceof Error ? err.message : "Unknown error");
57
72
  return null;
58
73
  }
59
- }, []);
74
+ }, [baseUrl]);
60
75
  const updatePrompt = useCallback(async (id, data) => {
61
76
  try {
62
77
  setError(null);
63
- const response = await fetch("/api/ai/auth/prompts", {
78
+ const isExternalProxy = baseUrl && baseUrl.includes("/api/lastbrain");
79
+ const endpoint = isExternalProxy
80
+ ? `${baseUrl}/ai/auth/prompts`
81
+ : "/api/ai/auth/prompts";
82
+ const response = await fetch(endpoint, {
64
83
  method: "PUT",
65
84
  headers: { "Content-Type": "application/json" },
66
85
  body: JSON.stringify({ id, ...data }),
@@ -78,11 +97,15 @@ export function usePrompts() {
78
97
  setError(err instanceof Error ? err.message : "Unknown error");
79
98
  return null;
80
99
  }
81
- }, []);
100
+ }, [baseUrl]);
82
101
  const deletePrompt = useCallback(async (id) => {
83
102
  try {
84
103
  setError(null);
85
- const response = await fetch(`/api/ai/auth/prompts?id=${id}`, {
104
+ const isExternalProxy = baseUrl && baseUrl.includes("/api/lastbrain");
105
+ const endpoint = isExternalProxy
106
+ ? `${baseUrl}/ai/auth/prompts?id=${id}`
107
+ : `/api/ai/auth/prompts?id=${id}`;
108
+ const response = await fetch(endpoint, {
86
109
  method: "DELETE",
87
110
  });
88
111
  const result = await response.json();
@@ -98,10 +121,14 @@ export function usePrompts() {
98
121
  setError(err instanceof Error ? err.message : "Unknown error");
99
122
  return false;
100
123
  }
101
- }, []);
124
+ }, [baseUrl]);
102
125
  const incrementStat = useCallback(async (promptId, statType) => {
103
126
  try {
104
- await fetch("/api/ai/auth/prompts/stats", {
127
+ const isExternalProxy = baseUrl && baseUrl.includes("/api/lastbrain");
128
+ const endpoint = isExternalProxy
129
+ ? `${baseUrl}/ai/auth/prompts/stats`
130
+ : "/api/ai/auth/prompts/stats";
131
+ await fetch(endpoint, {
105
132
  method: "POST",
106
133
  headers: { "Content-Type": "application/json" },
107
134
  body: JSON.stringify({ prompt_id: promptId, stat_type: statType }),
@@ -110,7 +137,7 @@ export function usePrompts() {
110
137
  catch (err) {
111
138
  // Silent fail for stats
112
139
  }
113
- }, []);
140
+ }, [baseUrl]);
114
141
  return {
115
142
  prompts,
116
143
  loading,
@@ -1 +1 @@
1
- {"version":3,"file":"modelManagement.d.ts","sourceRoot":"","sources":["../../src/utils/modelManagement.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,OAAO,EACjB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CACR,KAAK,CAAC;IACJ,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,CAAC,CACH,CAgCA;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,MAAM,EAAE,CAAC,CAgCnB"}
1
+ {"version":3,"file":"modelManagement.d.ts","sourceRoot":"","sources":["../../src/utils/modelManagement.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,OAAO,EACjB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CACR,KAAK,CAAC;IACJ,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,CAAC,CACH,CAqCA;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,MAAM,EAAE,CAAC,CAqCnB"}
@@ -45,7 +45,7 @@ export async function getAvailableModels(options = {}) {
45
45
  const response = await fetch(endpoint, {
46
46
  method: "GET",
47
47
  headers,
48
- credentials: isExternalProxy ? 'include' : 'same-origin',
48
+ credentials: isExternalProxy ? "include" : "same-origin",
49
49
  });
50
50
  if (!response.ok) {
51
51
  throw new Error(`Erreur lors de la récupération des modèles: ${response.status}`);
@@ -72,7 +72,7 @@ export async function getUserModels(options = {}) {
72
72
  const response = await fetch(endpoint, {
73
73
  method: "GET",
74
74
  headers,
75
- credentials: isExternalProxy ? 'include' : 'same-origin',
75
+ credentials: isExternalProxy ? "include" : "same-origin",
76
76
  });
77
77
  if (!response.ok) {
78
78
  throw new Error(`Erreur lors de la récupération des modèles utilisateur: ${response.status}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lastbrain/ai-ui-react",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "Headless React components for LastBrain AI UI Kit",
5
5
  "private": false,
6
6
  "type": "module",
@@ -48,7 +48,7 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "lucide-react": "^0.257.0",
51
- "@lastbrain/ai-ui-core": "1.0.8"
51
+ "@lastbrain/ai-ui-core": "1.0.16"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/react": "^19.2.0",
@@ -24,7 +24,7 @@ export function useAiStatus(options?: UseAiStatusOptions): UseAiStatusResult {
24
24
 
25
25
  const fetchStatus = useCallback(async () => {
26
26
  console.log("[useAiStatus] Starting status fetch");
27
-
27
+
28
28
  setLoading(true);
29
29
  setError(null);
30
30
  try {
@@ -175,25 +175,38 @@ export function useModelManagement(
175
175
  return availableModels.filter((model) => !userModels.includes(model.id));
176
176
  }, [availableModels, userModels]);
177
177
 
178
- // Auto-fetch au mount - seulement si autoFetch ET apiKey sont présents
178
+ // Auto-fetch au mount - si autoFetch ET (apiKey OU baseUrl avec proxy externe)
179
179
  useEffect(() => {
180
+ const isExternalProxy =
181
+ apiOptions.baseUrl && apiOptions.baseUrl.includes("/api/lastbrain");
182
+
180
183
  console.log("[useModelManagement] useEffect triggered:", {
181
184
  autoFetch,
182
185
  hasApiKey: !!apiOptions.apiKey,
186
+ hasBaseUrl: !!apiOptions.baseUrl,
187
+ isExternalProxy,
183
188
  apiKeyPreview: apiOptions.apiKey
184
189
  ? apiOptions.apiKey.substring(0, 10) + "..."
185
190
  : "none",
191
+ baseUrl: apiOptions.baseUrl || "none",
186
192
  });
187
193
 
188
- if (autoFetch && apiOptions.apiKey) {
194
+ // Auto-fetch si autoFetch est activé ET qu'on a soit une apiKey soit un proxy externe
195
+ if (autoFetch && (apiOptions.apiKey || isExternalProxy)) {
189
196
  console.log("[useModelManagement] Starting auto-fetch...");
190
197
  Promise.all([refreshModels(), refreshUserModels()]);
191
- } else if (autoFetch && !apiOptions.apiKey) {
198
+ } else if (autoFetch && !apiOptions.apiKey && !isExternalProxy) {
192
199
  console.warn(
193
- "[useModelManagement] autoFetch is enabled but no apiKey provided. Skipping automatic fetch."
200
+ "[useModelManagement] autoFetch is enabled but no apiKey or baseUrl provided. Skipping automatic fetch."
194
201
  );
195
202
  }
196
- }, [autoFetch, refreshModels, refreshUserModels, apiOptions.apiKey]);
203
+ }, [
204
+ autoFetch,
205
+ refreshModels,
206
+ refreshUserModels,
207
+ apiOptions.apiKey,
208
+ apiOptions.baseUrl,
209
+ ]);
197
210
 
198
211
  return {
199
212
  availableModels,
@@ -47,48 +47,68 @@ export interface UsePromptsReturn {
47
47
  }
48
48
 
49
49
  export function usePrompts(): UsePromptsReturn {
50
- const { apiKeyId } = useAiContext();
50
+ const { apiKeyId, baseUrl } = useAiContext();
51
51
  const [prompts, setPrompts] = useState<Prompt[] | PublicPrompt[]>([]);
52
52
  const [loading, setLoading] = useState(false);
53
53
  const [error, setError] = useState<string | null>(null);
54
54
 
55
- const fetchPrompts = useCallback(async (options?: UsePromptsOptions) => {
56
- try {
57
- setLoading(true);
58
- setError(null);
55
+ const fetchPrompts = useCallback(
56
+ async (options?: UsePromptsOptions) => {
57
+ try {
58
+ setLoading(true);
59
+ setError(null);
59
60
 
60
- const params = new URLSearchParams();
61
- if (options?.type) params.append("type", options.type);
62
- if (options?.favorite !== undefined)
63
- params.append("favorite", String(options.favorite));
61
+ const params = new URLSearchParams();
62
+ if (options?.type) params.append("type", options.type);
63
+ if (options?.favorite !== undefined)
64
+ params.append("favorite", String(options.favorite));
64
65
 
65
- // Use public route without auth if public=true, otherwise use auth route
66
- const endpoint = options?.public
67
- ? `/api/ai/public/prompts?${params}`
68
- : `/api/ai/auth/prompts?${params}`;
66
+ // Déterminer si on est dans un contexte externe (proxy nécessaire)
67
+ const isExternalProxy = baseUrl && baseUrl.includes("/api/lastbrain");
69
68
 
70
- const response = await fetch(endpoint);
69
+ // Use public route without auth if public=true, otherwise use auth route
70
+ let endpoint: string;
71
+ if (options?.public) {
72
+ endpoint = isExternalProxy
73
+ ? `${baseUrl}/ai/public/prompts?${params}`
74
+ : `/api/ai/public/prompts?${params}`;
75
+ } else {
76
+ endpoint = isExternalProxy
77
+ ? `${baseUrl}/ai/auth/prompts?${params}`
78
+ : `/api/ai/auth/prompts?${params}`;
79
+ }
71
80
 
72
- const data = await response.json();
81
+ console.log("[usePrompts] Fetching prompts from:", endpoint);
73
82
 
74
- if (response.ok) {
75
- setPrompts(data.prompts || []);
76
- } else {
77
- setError(data.error || "Failed to fetch prompts");
83
+ const response = await fetch(endpoint);
84
+
85
+ const data = await response.json();
86
+
87
+ if (response.ok) {
88
+ setPrompts(data.prompts || []);
89
+ } else {
90
+ setError(data.error || "Failed to fetch prompts");
91
+ }
92
+ } catch (err) {
93
+ setError(err instanceof Error ? err.message : "Unknown error");
94
+ } finally {
95
+ setLoading(false);
78
96
  }
79
- } catch (err) {
80
- setError(err instanceof Error ? err.message : "Unknown error");
81
- } finally {
82
- setLoading(false);
83
- }
84
- }, []);
97
+ },
98
+ [baseUrl]
99
+ );
85
100
 
86
101
  const createPrompt = useCallback(
87
102
  async (data: Omit<Prompt, "id" | "created_at" | "updated_at">) => {
88
103
  try {
89
104
  setError(null);
90
105
 
91
- const response = await fetch("/api/ai/auth/prompts", {
106
+ const isExternalProxy = baseUrl && baseUrl.includes("/api/lastbrain");
107
+ const endpoint = isExternalProxy
108
+ ? `${baseUrl}/ai/auth/prompts`
109
+ : "/api/ai/auth/prompts";
110
+
111
+ const response = await fetch(endpoint, {
92
112
  method: "POST",
93
113
  headers: { "Content-Type": "application/json" },
94
114
  body: JSON.stringify(data),
@@ -107,7 +127,7 @@ export function usePrompts(): UsePromptsReturn {
107
127
  return null;
108
128
  }
109
129
  },
110
- []
130
+ [baseUrl]
111
131
  );
112
132
 
113
133
  const updatePrompt = useCallback(
@@ -115,7 +135,12 @@ export function usePrompts(): UsePromptsReturn {
115
135
  try {
116
136
  setError(null);
117
137
 
118
- const response = await fetch("/api/ai/auth/prompts", {
138
+ const isExternalProxy = baseUrl && baseUrl.includes("/api/lastbrain");
139
+ const endpoint = isExternalProxy
140
+ ? `${baseUrl}/ai/auth/prompts`
141
+ : "/api/ai/auth/prompts";
142
+
143
+ const response = await fetch(endpoint, {
119
144
  method: "PUT",
120
145
  headers: { "Content-Type": "application/json" },
121
146
  body: JSON.stringify({ id, ...data }),
@@ -134,35 +159,48 @@ export function usePrompts(): UsePromptsReturn {
134
159
  return null;
135
160
  }
136
161
  },
137
- []
162
+ [baseUrl]
138
163
  );
139
164
 
140
- const deletePrompt = useCallback(async (id: string) => {
141
- try {
142
- setError(null);
165
+ const deletePrompt = useCallback(
166
+ async (id: string) => {
167
+ try {
168
+ setError(null);
143
169
 
144
- const response = await fetch(`/api/ai/auth/prompts?id=${id}`, {
145
- method: "DELETE",
146
- });
170
+ const isExternalProxy = baseUrl && baseUrl.includes("/api/lastbrain");
171
+ const endpoint = isExternalProxy
172
+ ? `${baseUrl}/ai/auth/prompts?id=${id}`
173
+ : `/api/ai/auth/prompts?id=${id}`;
147
174
 
148
- const result = await response.json();
175
+ const response = await fetch(endpoint, {
176
+ method: "DELETE",
177
+ });
149
178
 
150
- if (response.ok) {
151
- return true;
152
- } else {
153
- setError(result.error || "Failed to delete prompt");
179
+ const result = await response.json();
180
+
181
+ if (response.ok) {
182
+ return true;
183
+ } else {
184
+ setError(result.error || "Failed to delete prompt");
185
+ return false;
186
+ }
187
+ } catch (err) {
188
+ setError(err instanceof Error ? err.message : "Unknown error");
154
189
  return false;
155
190
  }
156
- } catch (err) {
157
- setError(err instanceof Error ? err.message : "Unknown error");
158
- return false;
159
- }
160
- }, []);
191
+ },
192
+ [baseUrl]
193
+ );
161
194
 
162
195
  const incrementStat = useCallback(
163
196
  async (promptId: string, statType: "views" | "used" | "picked") => {
164
197
  try {
165
- await fetch("/api/ai/auth/prompts/stats", {
198
+ const isExternalProxy = baseUrl && baseUrl.includes("/api/lastbrain");
199
+ const endpoint = isExternalProxy
200
+ ? `${baseUrl}/ai/auth/prompts/stats`
201
+ : "/api/ai/auth/prompts/stats";
202
+
203
+ await fetch(endpoint, {
166
204
  method: "POST",
167
205
  headers: { "Content-Type": "application/json" },
168
206
  body: JSON.stringify({ prompt_id: promptId, stat_type: statType }),
@@ -171,7 +209,7 @@ export function usePrompts(): UsePromptsReturn {
171
209
  // Silent fail for stats
172
210
  }
173
211
  },
174
- []
212
+ [baseUrl]
175
213
  );
176
214
 
177
215
  return {
@@ -65,11 +65,16 @@ export async function getAvailableModels(
65
65
 
66
66
  // Déterminer si on est dans un contexte externe (proxy nécessaire)
67
67
  const isExternalProxy = baseUrl && baseUrl.includes("/api/lastbrain");
68
- const endpoint = isExternalProxy
69
- ? `${baseUrl}/ai/auth/ai-models-available` // → /api/lastbrain/ai/auth/ai-models-available
70
- : `/api/public/v1/ai/models/available`; // → /api/public/v1/ai/models/available
71
-
72
- console.log("[getAvailableModels] isExternalProxy:", isExternalProxy, "endpoint:", endpoint);
68
+ const endpoint = isExternalProxy
69
+ ? `${baseUrl}/ai/auth/ai-models-available` // → /api/lastbrain/ai/auth/ai-models-available
70
+ : `/api/public/v1/ai/models/available`; // → /api/public/v1/ai/models/available
71
+
72
+ console.log(
73
+ "[getAvailableModels] isExternalProxy:",
74
+ isExternalProxy,
75
+ "endpoint:",
76
+ endpoint
77
+ );
73
78
 
74
79
  const headers: Record<string, string> = {};
75
80
 
@@ -81,7 +86,7 @@ export async function getAvailableModels(
81
86
  const response = await fetch(endpoint, {
82
87
  method: "GET",
83
88
  headers,
84
- credentials: isExternalProxy ? 'include' : 'same-origin',
89
+ credentials: isExternalProxy ? "include" : "same-origin",
85
90
  });
86
91
 
87
92
  if (!response.ok) {
@@ -104,11 +109,16 @@ export async function getUserModels(
104
109
 
105
110
  // Déterminer si on est dans un contexte externe (proxy nécessaire)
106
111
  const isExternalProxy = baseUrl && baseUrl.includes("/api/lastbrain");
107
- const endpoint = isExternalProxy
108
- ? `${baseUrl}/ai/auth/user-models` // → /api/lastbrain/ai/auth/user-models
109
- : `/api/public/v1/ai/user/models`; // → /api/public/v1/ai/user/models
110
-
111
- console.log("[getUserModels] isExternalProxy:", isExternalProxy, "endpoint:", endpoint);
112
+ const endpoint = isExternalProxy
113
+ ? `${baseUrl}/ai/auth/user-models` // → /api/lastbrain/ai/auth/user-models
114
+ : `/api/public/v1/ai/user/models`; // → /api/public/v1/ai/user/models
115
+
116
+ console.log(
117
+ "[getUserModels] isExternalProxy:",
118
+ isExternalProxy,
119
+ "endpoint:",
120
+ endpoint
121
+ );
112
122
 
113
123
  const headers: Record<string, string> = {};
114
124
 
@@ -120,7 +130,7 @@ export async function getUserModels(
120
130
  const response = await fetch(endpoint, {
121
131
  method: "GET",
122
132
  headers,
123
- credentials: isExternalProxy ? 'include' : 'same-origin',
133
+ credentials: isExternalProxy ? "include" : "same-origin",
124
134
  });
125
135
 
126
136
  if (!response.ok) {