@umituz/react-native-ai-groq-provider 1.0.24 → 1.0.26
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.
- package/package.json +1 -1
- package/src/application/use-cases/chat-session.usecase.ts +62 -14
- package/src/application/use-cases/streaming.usecase.ts +13 -7
- package/src/application/use-cases/structured-generation.usecase.ts +27 -10
- package/src/application/use-cases/text-generation.usecase.ts +4 -3
- package/src/domain/entities/error.types.ts +17 -2
- package/src/index.ts +24 -66
- package/src/infrastructure/http/groq-http-client.ts +68 -12
- package/src/infrastructure/http/streaming-client.ts +139 -87
- package/src/infrastructure/telemetry/TelemetryHooks.ts +39 -19
- package/src/infrastructure/utils/calculation.util.ts +59 -63
- package/src/infrastructure/utils/content-mapper.util.ts +1 -1
- package/src/presentation/hooks/use-groq.hook.ts +58 -41
- package/src/providers/ConfigBuilder.ts +2 -73
- package/src/providers/ProviderFactory.ts +7 -62
- package/src/shared/request-builder.ts +29 -10
- package/src/shared/response-handler.ts +93 -0
- package/src/types/react-native-global.d.ts +12 -0
- package/src/application/use-cases/index.ts +0 -19
- package/src/domain/entities/index.ts +0 -7
- package/src/infrastructure/http/index.ts +0 -7
- package/src/infrastructure/telemetry/index.ts +0 -5
- package/src/infrastructure/utils/async/index.ts +0 -6
- package/src/infrastructure/utils/index.ts +0 -8
- package/src/presentation/hooks/index.ts +0 -7
- package/src/presentation/hooks/useGroq.ts +0 -235
- package/src/presentation/hooks/useOperationManager.ts +0 -119
- package/src/presentation/index.ts +0 -6
- package/src/providers/index.ts +0 -16
- package/src/shared/index.ts +0 -16
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useGroq Hook
|
|
3
|
-
* Main React hook for Groq text generation
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { useState, useCallback, useRef, useMemo } from "react";
|
|
7
|
-
import type { GroqGenerationConfig } from "../../domain/entities";
|
|
8
|
-
import { textGeneration } from "../../infrastructure/services/TextGeneration";
|
|
9
|
-
import { structuredText } from "../../infrastructure/services/StructuredText";
|
|
10
|
-
import { streaming } from "../../infrastructure/services/Streaming";
|
|
11
|
-
import { getUserFriendlyError } from "../../infrastructure/utils/error-mapper.util";
|
|
12
|
-
import { telemetry } from "../../infrastructure/telemetry";
|
|
13
|
-
|
|
14
|
-
export interface UseGroqOptions {
|
|
15
|
-
/** Initial model to use */
|
|
16
|
-
model?: string;
|
|
17
|
-
/** Default generation config */
|
|
18
|
-
generationConfig?: GroqGenerationConfig;
|
|
19
|
-
/** Callback when generation starts */
|
|
20
|
-
onStart?: () => void;
|
|
21
|
-
/** Callback when generation completes */
|
|
22
|
-
onSuccess?: (result: string) => void;
|
|
23
|
-
/** Callback when generation fails */
|
|
24
|
-
onError?: (error: string) => void;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface UseGroqReturn {
|
|
28
|
-
/** Loading state */
|
|
29
|
-
isLoading: boolean;
|
|
30
|
-
/** Error message */
|
|
31
|
-
error: string | null;
|
|
32
|
-
/** Generated result */
|
|
33
|
-
result: string | null;
|
|
34
|
-
/** Generate text from a prompt */
|
|
35
|
-
generate: (prompt: string, options?: GroqGenerationConfig) => Promise<string>;
|
|
36
|
-
/** Generate structured JSON output */
|
|
37
|
-
generateJSON: <T = Record<string, unknown>>(
|
|
38
|
-
prompt: string,
|
|
39
|
-
options?: GroqGenerationConfig & { schema?: Record<string, unknown> }
|
|
40
|
-
) => Promise<T>;
|
|
41
|
-
/** Stream text generation */
|
|
42
|
-
stream: (
|
|
43
|
-
prompt: string,
|
|
44
|
-
onChunk: (chunk: string) => void,
|
|
45
|
-
options?: GroqGenerationConfig
|
|
46
|
-
) => Promise<void>;
|
|
47
|
-
/** Reset state */
|
|
48
|
-
reset: () => void;
|
|
49
|
-
/** Clear error */
|
|
50
|
-
clearError: () => void;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Hook for Groq text generation
|
|
55
|
-
* Optimized to prevent unnecessary re-renders and memory leaks
|
|
56
|
-
*/
|
|
57
|
-
export function useGroq(options: UseGroqOptions = {}): UseGroqReturn {
|
|
58
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
59
|
-
const [error, setError] = useState<string | null>(null);
|
|
60
|
-
const [result, setResult] = useState<string | null>(null);
|
|
61
|
-
const abortControllerRef = useRef<AbortController | null>(null);
|
|
62
|
-
|
|
63
|
-
// Memoize options to prevent unnecessary callback recreations
|
|
64
|
-
const stableOptions = useMemo(() => options, [
|
|
65
|
-
options.model,
|
|
66
|
-
options.generationConfig?.temperature,
|
|
67
|
-
options.generationConfig?.maxTokens,
|
|
68
|
-
options.generationConfig?.topP,
|
|
69
|
-
options.onStart,
|
|
70
|
-
options.onSuccess,
|
|
71
|
-
options.onError,
|
|
72
|
-
]);
|
|
73
|
-
|
|
74
|
-
const generate = useCallback(
|
|
75
|
-
async (prompt: string, config?: GroqGenerationConfig): Promise<string> => {
|
|
76
|
-
// Cancel any ongoing request
|
|
77
|
-
if (abortControllerRef.current) {
|
|
78
|
-
abortControllerRef.current.abort();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
abortControllerRef.current = new AbortController();
|
|
82
|
-
setIsLoading(true);
|
|
83
|
-
setError(null);
|
|
84
|
-
setResult(null);
|
|
85
|
-
|
|
86
|
-
telemetry.log("groq_generate_start", { prompt: prompt.substring(0, 100) });
|
|
87
|
-
stableOptions.onStart?.();
|
|
88
|
-
|
|
89
|
-
try {
|
|
90
|
-
const response = await textGeneration(prompt, {
|
|
91
|
-
model: stableOptions.model,
|
|
92
|
-
generationConfig: { ...stableOptions.generationConfig, ...config },
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
setResult(response);
|
|
96
|
-
stableOptions.onSuccess?.(response);
|
|
97
|
-
telemetry.log("groq_generate_success", { responseLength: response.length });
|
|
98
|
-
|
|
99
|
-
return response;
|
|
100
|
-
} catch (err) {
|
|
101
|
-
const errorMessage = getUserFriendlyError(err);
|
|
102
|
-
setError(errorMessage);
|
|
103
|
-
stableOptions.onError?.(errorMessage);
|
|
104
|
-
telemetry.log("groq_generate_error", { error: errorMessage });
|
|
105
|
-
throw err;
|
|
106
|
-
} finally {
|
|
107
|
-
setIsLoading(false);
|
|
108
|
-
abortControllerRef.current = null;
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
[stableOptions]
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
const generateJSON = useCallback(
|
|
115
|
-
async <T = Record<string, unknown>,>(
|
|
116
|
-
prompt: string,
|
|
117
|
-
config?: GroqGenerationConfig & { schema?: Record<string, unknown> }
|
|
118
|
-
): Promise<T> => {
|
|
119
|
-
// Cancel any ongoing request
|
|
120
|
-
if (abortControllerRef.current) {
|
|
121
|
-
abortControllerRef.current.abort();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
abortControllerRef.current = new AbortController();
|
|
125
|
-
setIsLoading(true);
|
|
126
|
-
setError(null);
|
|
127
|
-
setResult(null);
|
|
128
|
-
|
|
129
|
-
telemetry.log("groq_generate_json_start", { prompt: prompt.substring(0, 100) });
|
|
130
|
-
stableOptions.onStart?.();
|
|
131
|
-
|
|
132
|
-
try {
|
|
133
|
-
const response = await structuredText<T>(prompt, {
|
|
134
|
-
model: stableOptions.model,
|
|
135
|
-
generationConfig: { ...stableOptions.generationConfig, ...config },
|
|
136
|
-
schema: config?.schema,
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
setResult(JSON.stringify(response, null, 2));
|
|
140
|
-
stableOptions.onSuccess?.(JSON.stringify(response, null, 2));
|
|
141
|
-
telemetry.log("groq_generate_json_success");
|
|
142
|
-
|
|
143
|
-
return response;
|
|
144
|
-
} catch (err) {
|
|
145
|
-
const errorMessage = getUserFriendlyError(err);
|
|
146
|
-
setError(errorMessage);
|
|
147
|
-
stableOptions.onError?.(errorMessage);
|
|
148
|
-
telemetry.log("groq_generate_json_error", { error: errorMessage });
|
|
149
|
-
throw err;
|
|
150
|
-
} finally {
|
|
151
|
-
setIsLoading(false);
|
|
152
|
-
abortControllerRef.current = null;
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
[stableOptions]
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
const stream = useCallback(
|
|
159
|
-
async (
|
|
160
|
-
prompt: string,
|
|
161
|
-
onChunk: (chunk: string) => void,
|
|
162
|
-
config?: GroqGenerationConfig
|
|
163
|
-
): Promise<void> => {
|
|
164
|
-
// Cancel any ongoing request
|
|
165
|
-
if (abortControllerRef.current) {
|
|
166
|
-
abortControllerRef.current.abort();
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
abortControllerRef.current = new AbortController();
|
|
170
|
-
setIsLoading(true);
|
|
171
|
-
setError(null);
|
|
172
|
-
setResult(null);
|
|
173
|
-
|
|
174
|
-
let fullContent = "";
|
|
175
|
-
|
|
176
|
-
telemetry.log("groq_stream_start", { prompt: prompt.substring(0, 100) });
|
|
177
|
-
stableOptions.onStart?.();
|
|
178
|
-
|
|
179
|
-
try {
|
|
180
|
-
for await (const streamingResult of streaming(prompt, {
|
|
181
|
-
model: stableOptions.model,
|
|
182
|
-
generationConfig: { ...stableOptions.generationConfig, ...config },
|
|
183
|
-
callbacks: {
|
|
184
|
-
onChunk: (c) => {
|
|
185
|
-
fullContent += c;
|
|
186
|
-
onChunk(c);
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
})) {
|
|
190
|
-
// Consume the async iterator (streaming is handled via callbacks)
|
|
191
|
-
void streamingResult;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
setResult(fullContent);
|
|
195
|
-
stableOptions.onSuccess?.(fullContent);
|
|
196
|
-
telemetry.log("groq_stream_success", { contentLength: fullContent.length });
|
|
197
|
-
} catch (err) {
|
|
198
|
-
const errorMessage = getUserFriendlyError(err);
|
|
199
|
-
setError(errorMessage);
|
|
200
|
-
stableOptions.onError?.(errorMessage);
|
|
201
|
-
telemetry.log("groq_stream_error", { error: errorMessage });
|
|
202
|
-
throw err;
|
|
203
|
-
} finally {
|
|
204
|
-
setIsLoading(false);
|
|
205
|
-
abortControllerRef.current = null;
|
|
206
|
-
}
|
|
207
|
-
},
|
|
208
|
-
[stableOptions]
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
const reset = useCallback(() => {
|
|
212
|
-
if (abortControllerRef.current) {
|
|
213
|
-
abortControllerRef.current.abort();
|
|
214
|
-
abortControllerRef.current = null;
|
|
215
|
-
}
|
|
216
|
-
setIsLoading(false);
|
|
217
|
-
setError(null);
|
|
218
|
-
setResult(null);
|
|
219
|
-
}, []);
|
|
220
|
-
|
|
221
|
-
const clearError = useCallback(() => {
|
|
222
|
-
setError(null);
|
|
223
|
-
}, []);
|
|
224
|
-
|
|
225
|
-
return {
|
|
226
|
-
isLoading,
|
|
227
|
-
error,
|
|
228
|
-
result,
|
|
229
|
-
generate,
|
|
230
|
-
generateJSON,
|
|
231
|
-
stream,
|
|
232
|
-
reset,
|
|
233
|
-
clearError,
|
|
234
|
-
};
|
|
235
|
-
}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useOperationManager Hook
|
|
3
|
-
* Manages async operations with loading, error, and success states
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { useState, useCallback, useRef, useMemo } from "react";
|
|
7
|
-
import { getUserFriendlyError } from "../../infrastructure/utils/error-mapper.util";
|
|
8
|
-
import { telemetry } from "../../infrastructure/telemetry";
|
|
9
|
-
|
|
10
|
-
export interface OperationState<T> {
|
|
11
|
-
isLoading: boolean;
|
|
12
|
-
error: string | null;
|
|
13
|
-
data: T | null;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface UseOperationManagerOptions<T> {
|
|
17
|
-
/** Initial data */
|
|
18
|
-
initialData?: T | null;
|
|
19
|
-
/** Callback when operation starts */
|
|
20
|
-
onStart?: () => void;
|
|
21
|
-
/** Callback when operation succeeds */
|
|
22
|
-
onSuccess?: (data: T) => void;
|
|
23
|
-
/** Callback when operation fails */
|
|
24
|
-
onError?: (error: string) => void;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Hook for managing async operations
|
|
29
|
-
* Optimized to prevent unnecessary re-renders
|
|
30
|
-
*/
|
|
31
|
-
export function useOperationManager<T = unknown>(
|
|
32
|
-
options: UseOperationManagerOptions<T> = {}
|
|
33
|
-
) {
|
|
34
|
-
// Memoize options to prevent unnecessary callback recreations
|
|
35
|
-
const stableOptions = useMemo(() => options, [
|
|
36
|
-
options.initialData,
|
|
37
|
-
options.onStart,
|
|
38
|
-
options.onSuccess,
|
|
39
|
-
options.onError,
|
|
40
|
-
]);
|
|
41
|
-
|
|
42
|
-
const [state, setState] = useState<OperationState<T>>({
|
|
43
|
-
isLoading: false,
|
|
44
|
-
error: null,
|
|
45
|
-
data: stableOptions.initialData ?? null,
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
const abortControllerRef = useRef<AbortController | null>(null);
|
|
49
|
-
const operationNameRef = useRef<string>("");
|
|
50
|
-
|
|
51
|
-
const execute = useCallback(
|
|
52
|
-
async <R = T,>(
|
|
53
|
-
operationName: string,
|
|
54
|
-
asyncFn: (signal?: AbortSignal) => Promise<R>,
|
|
55
|
-
config?: { abortPrevious?: boolean }
|
|
56
|
-
): Promise<R> => {
|
|
57
|
-
// Cancel previous operation if configured
|
|
58
|
-
if (config?.abortPrevious && abortControllerRef.current) {
|
|
59
|
-
abortControllerRef.current.abort();
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
abortControllerRef.current = new AbortController();
|
|
63
|
-
operationNameRef.current = operationName;
|
|
64
|
-
|
|
65
|
-
setState((prev) => ({ ...prev, isLoading: true, error: null }));
|
|
66
|
-
|
|
67
|
-
telemetry.log(`${operationName}_start`);
|
|
68
|
-
stableOptions.onStart?.();
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
const result = await asyncFn(abortControllerRef.current.signal);
|
|
72
|
-
|
|
73
|
-
setState((prev) => ({ ...prev, isLoading: false, data: result as unknown as T }));
|
|
74
|
-
stableOptions.onSuccess?.(result as unknown as T);
|
|
75
|
-
telemetry.log(`${operationName}_success`);
|
|
76
|
-
|
|
77
|
-
return result;
|
|
78
|
-
} catch (error) {
|
|
79
|
-
const errorMessage = getUserFriendlyError(error);
|
|
80
|
-
setState((prev) => ({ ...prev, isLoading: false, error: errorMessage }));
|
|
81
|
-
stableOptions.onError?.(errorMessage);
|
|
82
|
-
telemetry.log(`${operationName}_error`, { error: errorMessage });
|
|
83
|
-
throw error;
|
|
84
|
-
} finally {
|
|
85
|
-
abortControllerRef.current = null;
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
[stableOptions]
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
const reset = useCallback(() => {
|
|
92
|
-
if (abortControllerRef.current) {
|
|
93
|
-
abortControllerRef.current.abort();
|
|
94
|
-
abortControllerRef.current = null;
|
|
95
|
-
}
|
|
96
|
-
setState((prev) => ({
|
|
97
|
-
...prev,
|
|
98
|
-
isLoading: false,
|
|
99
|
-
error: null,
|
|
100
|
-
data: stableOptions.initialData ?? null,
|
|
101
|
-
}));
|
|
102
|
-
}, [stableOptions.initialData]);
|
|
103
|
-
|
|
104
|
-
const clearError = useCallback(() => {
|
|
105
|
-
setState((prev) => ({ ...prev, error: null }));
|
|
106
|
-
}, []);
|
|
107
|
-
|
|
108
|
-
const setData = useCallback((data: T | null) => {
|
|
109
|
-
setState((prev) => ({ ...prev, data }));
|
|
110
|
-
}, []);
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
...state,
|
|
114
|
-
execute,
|
|
115
|
-
reset,
|
|
116
|
-
clearError,
|
|
117
|
-
setData,
|
|
118
|
-
};
|
|
119
|
-
}
|
package/src/providers/index.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Providers
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export { ConfigBuilder, GenerationConfigBuilder } from "./ConfigBuilder";
|
|
6
|
-
export {
|
|
7
|
-
providerFactory,
|
|
8
|
-
initializeProvider,
|
|
9
|
-
configureProvider,
|
|
10
|
-
resetProvider,
|
|
11
|
-
} from "./ProviderFactory";
|
|
12
|
-
|
|
13
|
-
export type {
|
|
14
|
-
ProviderConfig,
|
|
15
|
-
ProviderFactoryOptions,
|
|
16
|
-
} from "./ProviderFactory";
|
package/src/shared/index.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared Utilities
|
|
3
|
-
* Common utilities used across all layers
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export { logger, LogLevel } from "./logger";
|
|
7
|
-
export type { LogContext } from "./logger";
|
|
8
|
-
|
|
9
|
-
export { Timer } from "./timer";
|
|
10
|
-
export type { TimerResult } from "./timer";
|
|
11
|
-
|
|
12
|
-
export { RequestBuilder } from "./request-builder";
|
|
13
|
-
export type { RequestBuilderOptions } from "./request-builder";
|
|
14
|
-
|
|
15
|
-
export { ResponseHandler } from "./response-handler";
|
|
16
|
-
export type { ResponseHandlerResult } from "./response-handler";
|