@umituz/web-ai 1.0.1 → 1.0.2
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/dist/content/index.cjs +116 -10
- package/dist/content/index.cjs.map +1 -1
- package/dist/content/index.d.cts +1 -1
- package/dist/content/index.d.ts +1 -1
- package/dist/content/index.js +116 -10
- package/dist/content/index.js.map +1 -1
- package/dist/core/index.cjs +10 -0
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +13 -3
- package/dist/core/index.d.ts +13 -3
- package/dist/core/index.js +9 -1
- package/dist/core/index.js.map +1 -1
- package/dist/{create-ai-DXEoke8-.d.ts → create-ai-9PW752z8.d.ts} +11 -1
- package/dist/{create-ai-DOI9jD3v.d.cts → create-ai-CXYKPK6G.d.cts} +11 -1
- package/dist/hooks/index.cjs +272 -10
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.cts +28 -2
- package/dist/hooks/index.d.ts +28 -2
- package/dist/hooks/index.js +272 -11
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +421 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +402 -11
- package/dist/index.js.map +1 -1
- package/dist/providers/index.cjs +696 -10
- package/dist/providers/index.cjs.map +1 -1
- package/dist/providers/index.d.cts +75 -8
- package/dist/providers/index.d.ts +75 -8
- package/dist/providers/index.js +679 -11
- package/dist/providers/index.js.map +1 -1
- package/dist/text-generation.service-BQO3Tvz2.d.cts +66 -0
- package/dist/text-generation.service-CcYQM6Ch.d.ts +66 -0
- package/package.json +6 -1
package/dist/hooks/index.cjs
CHANGED
|
@@ -117,6 +117,14 @@ var AIError = class _AIError extends Error {
|
|
|
117
117
|
}
|
|
118
118
|
};
|
|
119
119
|
|
|
120
|
+
// src/core/errors/groq-error.ts
|
|
121
|
+
var GroqError = class extends AIError {
|
|
122
|
+
constructor(type, message, cause, metadata = {}) {
|
|
123
|
+
super(type, message, cause, metadata);
|
|
124
|
+
this.name = "GroqError";
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
120
128
|
// src/core/errors/error-classifier.ts
|
|
121
129
|
var DEFAULT_RETRYABLE_TYPES = /* @__PURE__ */ new Set([
|
|
122
130
|
"NETWORK_ERROR" /* NETWORK_ERROR */,
|
|
@@ -1341,6 +1349,27 @@ var RequestDeduplicator = class {
|
|
|
1341
1349
|
}
|
|
1342
1350
|
};
|
|
1343
1351
|
|
|
1352
|
+
// src/core/utils/api-key-validator.ts
|
|
1353
|
+
var DEFAULT_API_KEY_RULE = {
|
|
1354
|
+
minLength: 10
|
|
1355
|
+
};
|
|
1356
|
+
function validateApiKey(apiKey, rule = DEFAULT_API_KEY_RULE) {
|
|
1357
|
+
if (!apiKey) {
|
|
1358
|
+
return { valid: false, reason: "API key is required" };
|
|
1359
|
+
}
|
|
1360
|
+
const trimmed = apiKey.trim();
|
|
1361
|
+
if (trimmed.length === 0) {
|
|
1362
|
+
return { valid: false, reason: "API key cannot be empty" };
|
|
1363
|
+
}
|
|
1364
|
+
if (trimmed.length < rule.minLength) {
|
|
1365
|
+
return {
|
|
1366
|
+
valid: false,
|
|
1367
|
+
reason: `API key must be at least ${rule.minLength} characters`
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1370
|
+
return { valid: true };
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1344
1373
|
// src/providers/groq/groq.constants.ts
|
|
1345
1374
|
var GROQ_MODELS = {
|
|
1346
1375
|
LLAMA_3_1_8B_INSTANT: "llama-3.1-8b-instant",
|
|
@@ -1357,11 +1386,13 @@ var DEFAULT_GENERATION_CONFIG = {
|
|
|
1357
1386
|
topP: 1
|
|
1358
1387
|
};
|
|
1359
1388
|
var GROQ_BASE_URL = "https://api.groq.com/openai/v1";
|
|
1389
|
+
var DEFAULT_BASE_URL = GROQ_BASE_URL;
|
|
1360
1390
|
var CHAT_COMPLETIONS_PATH = "/chat/completions";
|
|
1361
1391
|
var GROQ_TIMEOUTS = {
|
|
1362
1392
|
DEFAULT: 3e4,
|
|
1363
1393
|
STREAMING: 6e4
|
|
1364
1394
|
};
|
|
1395
|
+
var TIMEOUTS = GROQ_TIMEOUTS;
|
|
1365
1396
|
var HTTP_HEADERS = {
|
|
1366
1397
|
CONTENT_TYPE: "Content-Type",
|
|
1367
1398
|
APPLICATION_JSON: "application/json",
|
|
@@ -1420,13 +1451,65 @@ var GroqChatRequestBuilder = class _GroqChatRequestBuilder {
|
|
|
1420
1451
|
}
|
|
1421
1452
|
};
|
|
1422
1453
|
|
|
1454
|
+
// src/providers/groq/groq-config-store.ts
|
|
1455
|
+
var GroqConfigStore = class {
|
|
1456
|
+
config = null;
|
|
1457
|
+
initialize(config) {
|
|
1458
|
+
const validation = validateApiKey(config.apiKey, { minLength: 1 });
|
|
1459
|
+
if (!validation.valid) {
|
|
1460
|
+
throw new GroqError("INVALID_API_KEY" /* INVALID_API_KEY */, validation.reason ?? "Invalid API key");
|
|
1461
|
+
}
|
|
1462
|
+
const normalized = {
|
|
1463
|
+
apiKey: config.apiKey.trim(),
|
|
1464
|
+
baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,
|
|
1465
|
+
timeoutMs: config.timeoutMs ?? TIMEOUTS.DEFAULT,
|
|
1466
|
+
...config.models !== void 0 ? { models: config.models } : {},
|
|
1467
|
+
...config.textModel !== void 0 ? { textModel: config.textModel } : {}
|
|
1468
|
+
};
|
|
1469
|
+
this.config = normalized;
|
|
1470
|
+
return normalized;
|
|
1471
|
+
}
|
|
1472
|
+
get() {
|
|
1473
|
+
if (!this.config) {
|
|
1474
|
+
throw new GroqError(
|
|
1475
|
+
"MISSING_CONFIG" /* MISSING_CONFIG */,
|
|
1476
|
+
"Client not initialized. Call configureProvider first."
|
|
1477
|
+
);
|
|
1478
|
+
}
|
|
1479
|
+
return this.config;
|
|
1480
|
+
}
|
|
1481
|
+
getOrNull() {
|
|
1482
|
+
return this.config;
|
|
1483
|
+
}
|
|
1484
|
+
isInitialized() {
|
|
1485
|
+
return this.config !== null;
|
|
1486
|
+
}
|
|
1487
|
+
setApiKey(apiKey) {
|
|
1488
|
+
const current = this.get();
|
|
1489
|
+
const validation = validateApiKey(apiKey, { minLength: 1 });
|
|
1490
|
+
if (!validation.valid) {
|
|
1491
|
+
throw new GroqError("INVALID_API_KEY" /* INVALID_API_KEY */, validation.reason ?? "Invalid API key");
|
|
1492
|
+
}
|
|
1493
|
+
this.config = { ...current, apiKey: apiKey.trim() };
|
|
1494
|
+
}
|
|
1495
|
+
reset() {
|
|
1496
|
+
this.config = null;
|
|
1497
|
+
}
|
|
1498
|
+
};
|
|
1499
|
+
|
|
1423
1500
|
// src/providers/groq/groq-http-transport.ts
|
|
1424
1501
|
var GroqHttpTransport = class {
|
|
1425
|
-
constructor(
|
|
1426
|
-
this.
|
|
1502
|
+
constructor(configSource) {
|
|
1503
|
+
this.configSource = configSource;
|
|
1427
1504
|
}
|
|
1428
|
-
|
|
1505
|
+
configSource;
|
|
1429
1506
|
pendingAbortControllers = /* @__PURE__ */ new Set();
|
|
1507
|
+
getConfig() {
|
|
1508
|
+
if ("get" in this.configSource && typeof this.configSource.get === "function") {
|
|
1509
|
+
return this.configSource.get();
|
|
1510
|
+
}
|
|
1511
|
+
return this.configSource;
|
|
1512
|
+
}
|
|
1430
1513
|
cancelPendingRequests() {
|
|
1431
1514
|
for (const controller of this.pendingAbortControllers) {
|
|
1432
1515
|
controller.abort();
|
|
@@ -1441,7 +1524,7 @@ var GroqHttpTransport = class {
|
|
|
1441
1524
|
}
|
|
1442
1525
|
async streamChatCompletion(request, options = {}) {
|
|
1443
1526
|
const url = `${this.baseUrl()}${CHAT_COMPLETIONS_PATH}`;
|
|
1444
|
-
const timeout = this.
|
|
1527
|
+
const timeout = this.getConfig().timeoutMs ?? GROQ_TIMEOUTS.STREAMING;
|
|
1445
1528
|
const controller = new AbortController();
|
|
1446
1529
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1447
1530
|
const onExternalAbort = () => controller.abort();
|
|
@@ -1468,11 +1551,11 @@ var GroqHttpTransport = class {
|
|
|
1468
1551
|
}
|
|
1469
1552
|
}
|
|
1470
1553
|
baseUrl() {
|
|
1471
|
-
return this.
|
|
1554
|
+
return this.getConfig().baseUrl ?? GROQ_BASE_URL;
|
|
1472
1555
|
}
|
|
1473
1556
|
async request(endpoint, body) {
|
|
1474
1557
|
const url = `${this.baseUrl()}${endpoint}`;
|
|
1475
|
-
const timeout = this.
|
|
1558
|
+
const timeout = this.getConfig().timeoutMs ?? GROQ_TIMEOUTS.DEFAULT;
|
|
1476
1559
|
const controller = new AbortController();
|
|
1477
1560
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1478
1561
|
this.pendingAbortControllers.add(controller);
|
|
@@ -1495,7 +1578,7 @@ var GroqHttpTransport = class {
|
|
|
1495
1578
|
buildHeaders() {
|
|
1496
1579
|
return {
|
|
1497
1580
|
[HTTP_HEADERS.CONTENT_TYPE]: HTTP_HEADERS.APPLICATION_JSON,
|
|
1498
|
-
[HTTP_HEADERS.AUTHORIZATION]: `${HTTP_HEADERS.BEARER_PREFIX}${this.
|
|
1581
|
+
[HTTP_HEADERS.AUTHORIZATION]: `${HTTP_HEADERS.BEARER_PREFIX}${this.getConfig().apiKey}`
|
|
1499
1582
|
};
|
|
1500
1583
|
}
|
|
1501
1584
|
async throwFromErrorResponse(response) {
|
|
@@ -1597,21 +1680,40 @@ var CompositeExecutor = class {
|
|
|
1597
1680
|
|
|
1598
1681
|
// src/providers/groq/groq-http-client.ts
|
|
1599
1682
|
var GroqHttpClient = class {
|
|
1683
|
+
configStore;
|
|
1600
1684
|
transport;
|
|
1601
1685
|
executor;
|
|
1602
|
-
constructor(
|
|
1603
|
-
|
|
1686
|
+
constructor(configOrDeps, maybeDeps = {}) {
|
|
1687
|
+
const isConfig = typeof configOrDeps === "object" && configOrDeps !== null && "apiKey" in configOrDeps && typeof configOrDeps.apiKey === "string";
|
|
1688
|
+
const deps = isConfig ? maybeDeps : configOrDeps ?? {};
|
|
1689
|
+
this.configStore = deps.configStore ?? new GroqConfigStore();
|
|
1690
|
+
if (isConfig) {
|
|
1691
|
+
this.configStore.initialize(configOrDeps);
|
|
1692
|
+
}
|
|
1693
|
+
this.transport = deps.transport ?? new GroqHttpTransport(this.configStore);
|
|
1604
1694
|
const retryManager2 = deps.retryManager ?? new RetryManager();
|
|
1605
1695
|
const queue = deps.queue ?? new RequestQueue();
|
|
1606
1696
|
const deduplicator = deps.deduplicator ?? new RequestDeduplicator();
|
|
1607
1697
|
this.executor = new CompositeExecutor([
|
|
1608
1698
|
new DedupeExecutor(deduplicator, {
|
|
1609
|
-
generateKey: (request) => deduplicatorKey(request,
|
|
1699
|
+
generateKey: (request) => deduplicatorKey(request, this.configStore.isInitialized() ? this.configStore.get().apiKey : "")
|
|
1610
1700
|
}),
|
|
1611
1701
|
new RetryExecutor(retryManager2),
|
|
1612
1702
|
new QueueExecutor(queue, QUEUE_PRIORITY_USER_REQUEST)
|
|
1613
1703
|
]);
|
|
1614
1704
|
}
|
|
1705
|
+
initialize(config) {
|
|
1706
|
+
this.configStore.initialize(config);
|
|
1707
|
+
}
|
|
1708
|
+
isInitialized() {
|
|
1709
|
+
return this.configStore.isInitialized();
|
|
1710
|
+
}
|
|
1711
|
+
getApiKey() {
|
|
1712
|
+
return this.configStore.get().apiKey;
|
|
1713
|
+
}
|
|
1714
|
+
setApiKey(apiKey) {
|
|
1715
|
+
this.configStore.setApiKey(apiKey);
|
|
1716
|
+
}
|
|
1615
1717
|
cancelPendingRequests() {
|
|
1616
1718
|
this.transport.cancelPendingRequests();
|
|
1617
1719
|
}
|
|
@@ -1624,6 +1726,10 @@ var GroqHttpClient = class {
|
|
|
1624
1726
|
streamChatCompletion(request, options) {
|
|
1625
1727
|
return this.transport.streamChatCompletion(request, options);
|
|
1626
1728
|
}
|
|
1729
|
+
reset() {
|
|
1730
|
+
this.transport.cancelPendingRequests();
|
|
1731
|
+
this.configStore.reset();
|
|
1732
|
+
}
|
|
1627
1733
|
};
|
|
1628
1734
|
function deduplicatorKey(request, apiKey) {
|
|
1629
1735
|
const { model, messages, stream: _stream, ...rest } = request;
|
|
@@ -5232,12 +5338,168 @@ function useChat(options, deps) {
|
|
|
5232
5338
|
};
|
|
5233
5339
|
}
|
|
5234
5340
|
|
|
5341
|
+
// src/providers/groq/groq-container.ts
|
|
5342
|
+
var container = null;
|
|
5343
|
+
function getProvider() {
|
|
5344
|
+
return container;
|
|
5345
|
+
}
|
|
5346
|
+
|
|
5347
|
+
// src/hooks/use-groq.hook.ts
|
|
5348
|
+
function useGroq(options = {}, deps) {
|
|
5349
|
+
const textGeneration = deps?.textGeneration ?? getProvider()?.textGeneration;
|
|
5350
|
+
if (!textGeneration) {
|
|
5351
|
+
throw new Error(
|
|
5352
|
+
"useGroq requires a TextGenerationService dependency. Provide it via the second argument or wire it through configureProvider()."
|
|
5353
|
+
);
|
|
5354
|
+
}
|
|
5355
|
+
const [isLoading, setIsLoading] = react.useState(false);
|
|
5356
|
+
const [error, setError] = react.useState(null);
|
|
5357
|
+
const [result, setResult] = react.useState(null);
|
|
5358
|
+
const optionsRef = react.useRef(options);
|
|
5359
|
+
optionsRef.current = options;
|
|
5360
|
+
const abortControllerRef = react.useRef(null);
|
|
5361
|
+
const getOrCreateAbortController = react.useCallback(() => {
|
|
5362
|
+
if (!abortControllerRef.current || abortControllerRef.current.signal.aborted) {
|
|
5363
|
+
abortControllerRef.current = new AbortController();
|
|
5364
|
+
}
|
|
5365
|
+
return abortControllerRef.current;
|
|
5366
|
+
}, []);
|
|
5367
|
+
const stableConfig = react.useMemo(
|
|
5368
|
+
() => ({
|
|
5369
|
+
model: options.model,
|
|
5370
|
+
generationConfig: options.generationConfig
|
|
5371
|
+
}),
|
|
5372
|
+
[
|
|
5373
|
+
options.model,
|
|
5374
|
+
options.generationConfig?.temperature,
|
|
5375
|
+
options.generationConfig?.maxTokens,
|
|
5376
|
+
options.generationConfig?.topP
|
|
5377
|
+
]
|
|
5378
|
+
);
|
|
5379
|
+
react.useEffect(() => {
|
|
5380
|
+
abortControllerRef.current = new AbortController();
|
|
5381
|
+
return () => {
|
|
5382
|
+
abortControllerRef.current?.abort();
|
|
5383
|
+
abortControllerRef.current = null;
|
|
5384
|
+
};
|
|
5385
|
+
}, []);
|
|
5386
|
+
const runWithState = react.useCallback(
|
|
5387
|
+
async (task) => {
|
|
5388
|
+
const controller = getOrCreateAbortController();
|
|
5389
|
+
const { signal } = controller;
|
|
5390
|
+
if (signal.aborted) return null;
|
|
5391
|
+
setIsLoading(true);
|
|
5392
|
+
setError(null);
|
|
5393
|
+
setResult(null);
|
|
5394
|
+
const currentOptions = optionsRef.current;
|
|
5395
|
+
currentOptions.onStart?.();
|
|
5396
|
+
try {
|
|
5397
|
+
const value = await task(signal);
|
|
5398
|
+
return value;
|
|
5399
|
+
} catch (err) {
|
|
5400
|
+
if (signal.aborted) {
|
|
5401
|
+
return null;
|
|
5402
|
+
}
|
|
5403
|
+
const message = resolveUserFriendlyMessage(err);
|
|
5404
|
+
setError(message);
|
|
5405
|
+
currentOptions.onError?.(message);
|
|
5406
|
+
throw err;
|
|
5407
|
+
} finally {
|
|
5408
|
+
if (!signal.aborted) {
|
|
5409
|
+
setIsLoading(false);
|
|
5410
|
+
}
|
|
5411
|
+
}
|
|
5412
|
+
},
|
|
5413
|
+
[getOrCreateAbortController]
|
|
5414
|
+
);
|
|
5415
|
+
const generate = react.useCallback(
|
|
5416
|
+
(prompt, config) => runWithState(async () => {
|
|
5417
|
+
const response = await textGeneration.generateCompletion(prompt, {
|
|
5418
|
+
model: stableConfig.model,
|
|
5419
|
+
generationConfig: {
|
|
5420
|
+
...stableConfig.generationConfig,
|
|
5421
|
+
...config
|
|
5422
|
+
}
|
|
5423
|
+
});
|
|
5424
|
+
setResult(response);
|
|
5425
|
+
optionsRef.current.onSuccess?.(response);
|
|
5426
|
+
return response;
|
|
5427
|
+
}),
|
|
5428
|
+
[runWithState, textGeneration, stableConfig]
|
|
5429
|
+
);
|
|
5430
|
+
const generateJSON = react.useCallback(
|
|
5431
|
+
(prompt, config) => runWithState(async () => {
|
|
5432
|
+
const response = await textGeneration.generateStructured(prompt, {
|
|
5433
|
+
model: stableConfig.model,
|
|
5434
|
+
generationConfig: {
|
|
5435
|
+
...stableConfig.generationConfig,
|
|
5436
|
+
...config
|
|
5437
|
+
},
|
|
5438
|
+
...config?.schema !== void 0 ? { schema: config.schema } : {}
|
|
5439
|
+
});
|
|
5440
|
+
const json = JSON.stringify(response, null, 2);
|
|
5441
|
+
setResult(json);
|
|
5442
|
+
optionsRef.current.onSuccess?.(json);
|
|
5443
|
+
return response;
|
|
5444
|
+
}),
|
|
5445
|
+
[runWithState, textGeneration, stableConfig]
|
|
5446
|
+
);
|
|
5447
|
+
const stream = react.useCallback(
|
|
5448
|
+
(prompt, onChunk, config) => runWithState(async () => {
|
|
5449
|
+
const callbacks = {
|
|
5450
|
+
onChunk,
|
|
5451
|
+
onComplete: (text) => {
|
|
5452
|
+
setResult(text);
|
|
5453
|
+
optionsRef.current.onSuccess?.(text);
|
|
5454
|
+
}
|
|
5455
|
+
};
|
|
5456
|
+
return textGeneration.streamCompletion(
|
|
5457
|
+
prompt,
|
|
5458
|
+
callbacks,
|
|
5459
|
+
{
|
|
5460
|
+
model: stableConfig.model,
|
|
5461
|
+
generationConfig: {
|
|
5462
|
+
...stableConfig.generationConfig,
|
|
5463
|
+
...config
|
|
5464
|
+
}
|
|
5465
|
+
}
|
|
5466
|
+
);
|
|
5467
|
+
}),
|
|
5468
|
+
[runWithState, textGeneration, stableConfig]
|
|
5469
|
+
);
|
|
5470
|
+
const cancel = react.useCallback(() => {
|
|
5471
|
+
if (abortControllerRef.current) {
|
|
5472
|
+
abortControllerRef.current.abort();
|
|
5473
|
+
abortControllerRef.current = new AbortController();
|
|
5474
|
+
}
|
|
5475
|
+
setIsLoading(false);
|
|
5476
|
+
}, []);
|
|
5477
|
+
const reset = react.useCallback(() => {
|
|
5478
|
+
cancel();
|
|
5479
|
+
setError(null);
|
|
5480
|
+
setResult(null);
|
|
5481
|
+
}, [cancel]);
|
|
5482
|
+
const clearError = react.useCallback(() => setError(null), []);
|
|
5483
|
+
return {
|
|
5484
|
+
isLoading,
|
|
5485
|
+
error,
|
|
5486
|
+
result,
|
|
5487
|
+
generate,
|
|
5488
|
+
generateJSON,
|
|
5489
|
+
stream,
|
|
5490
|
+
cancel,
|
|
5491
|
+
reset,
|
|
5492
|
+
clearError
|
|
5493
|
+
};
|
|
5494
|
+
}
|
|
5495
|
+
|
|
5235
5496
|
exports.useAIContent = useAIContent;
|
|
5236
5497
|
exports.useAIGeneration = useAIGeneration;
|
|
5237
5498
|
exports.useBlogGenerator = useBlogGenerator;
|
|
5238
5499
|
exports.useCacheStats = useCacheStats;
|
|
5239
5500
|
exports.useChat = useChat;
|
|
5240
5501
|
exports.useContentWizard = useContentWizard;
|
|
5502
|
+
exports.useGroq = useGroq;
|
|
5241
5503
|
exports.useImageWizard = useImageWizard;
|
|
5242
5504
|
exports.useSocialContentGenerator = useSocialContentGenerator;
|
|
5243
5505
|
exports.useText = useText;
|