recker 1.0.29 → 1.0.31

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 (68) hide show
  1. package/README.md +28 -1
  2. package/dist/ai/client-ai.d.ts +41 -0
  3. package/dist/ai/client-ai.js +391 -0
  4. package/dist/ai/index.d.ts +2 -0
  5. package/dist/ai/index.js +2 -0
  6. package/dist/ai/memory.d.ts +35 -0
  7. package/dist/ai/memory.js +136 -0
  8. package/dist/browser/ai/client-ai.d.ts +41 -0
  9. package/dist/browser/ai/client-ai.js +391 -0
  10. package/dist/browser/ai/memory.d.ts +35 -0
  11. package/dist/browser/ai/memory.js +136 -0
  12. package/dist/browser/core/client.d.ts +6 -1
  13. package/dist/browser/core/client.js +18 -0
  14. package/dist/browser/transport/undici.js +11 -2
  15. package/dist/browser/types/ai-client.d.ts +32 -0
  16. package/dist/browser/types/ai-client.js +1 -0
  17. package/dist/browser/types/ai.d.ts +1 -1
  18. package/dist/cli/index.js +402 -1
  19. package/dist/cli/tui/scroll-buffer.js +4 -4
  20. package/dist/cli/tui/shell.d.ts +3 -0
  21. package/dist/cli/tui/shell.js +166 -19
  22. package/dist/core/client.d.ts +6 -1
  23. package/dist/core/client.js +18 -0
  24. package/dist/mcp/server.js +15 -0
  25. package/dist/mcp/tools/scrape.d.ts +3 -0
  26. package/dist/mcp/tools/scrape.js +156 -0
  27. package/dist/mcp/tools/security.d.ts +3 -0
  28. package/dist/mcp/tools/security.js +471 -0
  29. package/dist/mcp/tools/seo.d.ts +3 -0
  30. package/dist/mcp/tools/seo.js +427 -0
  31. package/dist/presets/anthropic.d.ts +3 -1
  32. package/dist/presets/anthropic.js +11 -1
  33. package/dist/presets/azure-openai.d.ts +3 -1
  34. package/dist/presets/azure-openai.js +11 -1
  35. package/dist/presets/cohere.d.ts +3 -1
  36. package/dist/presets/cohere.js +8 -2
  37. package/dist/presets/deepseek.d.ts +3 -1
  38. package/dist/presets/deepseek.js +8 -2
  39. package/dist/presets/fireworks.d.ts +3 -1
  40. package/dist/presets/fireworks.js +8 -2
  41. package/dist/presets/gemini.d.ts +3 -1
  42. package/dist/presets/gemini.js +8 -1
  43. package/dist/presets/groq.d.ts +3 -1
  44. package/dist/presets/groq.js +8 -2
  45. package/dist/presets/huggingface.d.ts +3 -1
  46. package/dist/presets/huggingface.js +8 -1
  47. package/dist/presets/mistral.d.ts +3 -1
  48. package/dist/presets/mistral.js +8 -2
  49. package/dist/presets/openai.d.ts +3 -1
  50. package/dist/presets/openai.js +9 -2
  51. package/dist/presets/perplexity.d.ts +3 -1
  52. package/dist/presets/perplexity.js +8 -2
  53. package/dist/presets/registry.d.ts +4 -0
  54. package/dist/presets/registry.js +48 -0
  55. package/dist/presets/replicate.d.ts +3 -1
  56. package/dist/presets/replicate.js +8 -1
  57. package/dist/presets/together.d.ts +3 -1
  58. package/dist/presets/together.js +8 -2
  59. package/dist/presets/xai.d.ts +3 -1
  60. package/dist/presets/xai.js +8 -2
  61. package/dist/scrape/spider.js +1 -1
  62. package/dist/transport/undici.js +11 -2
  63. package/dist/types/ai-client.d.ts +32 -0
  64. package/dist/types/ai-client.js +1 -0
  65. package/dist/types/ai.d.ts +1 -1
  66. package/dist/utils/colors.d.ts +2 -0
  67. package/dist/utils/colors.js +4 -0
  68. package/package.json +1 -1
@@ -0,0 +1,427 @@
1
+ import { createClient } from '../../core/client.js';
2
+ import { analyzeSeo } from '../../seo/analyzer.js';
3
+ import { seoSpider } from '../../seo/seo-spider.js';
4
+ function formatCheck(check) {
5
+ const icon = check.status === 'pass' ? '✓' : check.status === 'fail' ? '✗' : '⚠';
6
+ let line = `${icon} [${check.status.toUpperCase()}] ${check.name}: ${check.message}`;
7
+ if (check.recommendation) {
8
+ line += `\n → ${check.recommendation}`;
9
+ }
10
+ return line;
11
+ }
12
+ function createIssueSummary(checks) {
13
+ const critical = checks.filter(c => c.status === 'fail');
14
+ const warnings = checks.filter(c => c.status === 'warn');
15
+ const passed = checks.filter(c => c.status === 'pass').length;
16
+ return { critical, warnings, passed, total: checks.length };
17
+ }
18
+ function extractCategory(name) {
19
+ const lowerName = name.toLowerCase();
20
+ const categories = [
21
+ 'meta', 'content', 'links', 'images', 'technical', 'security',
22
+ 'performance', 'mobile', 'accessibility', 'schema', 'structural',
23
+ 'i18n', 'pwa', 'social', 'ecommerce', 'local', 'cwv',
24
+ 'readability', 'crawl', 'internal-linking', 'best-practices'
25
+ ];
26
+ for (const cat of categories) {
27
+ if (lowerName.startsWith(cat) || lowerName.includes(cat)) {
28
+ return cat;
29
+ }
30
+ }
31
+ return 'general';
32
+ }
33
+ function generateQuickWins(report) {
34
+ const quickWins = [];
35
+ for (const check of report.checks) {
36
+ if (check.status === 'pass')
37
+ continue;
38
+ const category = extractCategory(check.name);
39
+ let priority = 'medium';
40
+ if (check.status === 'fail') {
41
+ priority = 'high';
42
+ }
43
+ else if (['meta', 'title', 'content'].includes(category)) {
44
+ priority = 'medium';
45
+ }
46
+ else {
47
+ priority = 'low';
48
+ }
49
+ if (check.name.toLowerCase().includes('title') && check.status === 'fail') {
50
+ priority = 'high';
51
+ }
52
+ if (check.name.toLowerCase().includes('meta description') && check.status === 'fail') {
53
+ priority = 'high';
54
+ }
55
+ if (check.name.toLowerCase().includes('h1') && check.status === 'fail') {
56
+ priority = 'high';
57
+ }
58
+ if (check.name.toLowerCase().includes('canonical') && check.status === 'fail') {
59
+ priority = 'high';
60
+ }
61
+ if (check.name.toLowerCase().includes('https') && check.status === 'fail') {
62
+ priority = 'high';
63
+ }
64
+ quickWins.push({
65
+ priority,
66
+ category,
67
+ issue: check.name,
68
+ action: check.recommendation || check.message,
69
+ impact: check.evidence?.impact || 'Improves SEO ranking and user experience',
70
+ });
71
+ }
72
+ const priorityOrder = { high: 0, medium: 1, low: 2 };
73
+ quickWins.sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority]);
74
+ return quickWins;
75
+ }
76
+ async function seoAnalyze(args) {
77
+ const url = String(args.url || '');
78
+ const categories = args.categories;
79
+ const verbose = Boolean(args.verbose);
80
+ if (!url) {
81
+ return {
82
+ content: [{ type: 'text', text: 'Error: url is required' }],
83
+ isError: true,
84
+ };
85
+ }
86
+ try {
87
+ const client = createClient({ timeout: 30000 });
88
+ const response = await client.get(url);
89
+ const html = await response.text();
90
+ const responseHeaders = {};
91
+ response.headers.forEach((val, key) => {
92
+ responseHeaders[key] = val;
93
+ });
94
+ const report = await analyzeSeo(html, {
95
+ baseUrl: url,
96
+ responseHeaders,
97
+ rules: categories ? { categories: categories } : undefined,
98
+ });
99
+ const summary = createIssueSummary(report.checks);
100
+ const output = {
101
+ url,
102
+ score: report.score,
103
+ grade: report.grade,
104
+ summary: {
105
+ critical: summary.critical.length,
106
+ warnings: summary.warnings.length,
107
+ passed: summary.passed,
108
+ total: summary.total,
109
+ },
110
+ timing: report.timing,
111
+ };
112
+ if (report.openGraph) {
113
+ output.openGraph = report.openGraph;
114
+ }
115
+ if (summary.critical.length > 0) {
116
+ output.criticalIssues = summary.critical.map(c => ({
117
+ name: c.name,
118
+ message: c.message,
119
+ recommendation: c.recommendation,
120
+ evidence: c.evidence,
121
+ }));
122
+ }
123
+ if (summary.warnings.length > 0) {
124
+ output.warnings = summary.warnings.slice(0, verbose ? undefined : 10).map(c => ({
125
+ name: c.name,
126
+ message: c.message,
127
+ recommendation: c.recommendation,
128
+ }));
129
+ if (!verbose && summary.warnings.length > 10) {
130
+ output.warningsNote = `Showing 10 of ${summary.warnings.length} warnings. Use verbose=true to see all.`;
131
+ }
132
+ }
133
+ if (verbose) {
134
+ output.detailedAnalysis = {
135
+ title: report.title,
136
+ metaDescription: report.metaDescription,
137
+ headings: report.headings,
138
+ content: report.content,
139
+ links: report.links,
140
+ images: report.images,
141
+ technical: report.technical,
142
+ };
143
+ }
144
+ return {
145
+ content: [{
146
+ type: 'text',
147
+ text: JSON.stringify(output, null, 2),
148
+ }],
149
+ };
150
+ }
151
+ catch (error) {
152
+ return {
153
+ content: [{
154
+ type: 'text',
155
+ text: `SEO analysis failed: ${error.message}`,
156
+ }],
157
+ isError: true,
158
+ };
159
+ }
160
+ }
161
+ async function seoSpiderCrawl(args) {
162
+ const url = String(args.url || '');
163
+ const maxPages = Number(args.maxPages) || 100;
164
+ const maxDepth = Number(args.maxDepth) || 5;
165
+ const concurrency = Number(args.concurrency) || 3;
166
+ if (!url) {
167
+ return {
168
+ content: [{ type: 'text', text: 'Error: url is required' }],
169
+ isError: true,
170
+ };
171
+ }
172
+ try {
173
+ const result = await seoSpider(url, {
174
+ seo: true,
175
+ maxPages,
176
+ maxDepth,
177
+ concurrency,
178
+ delay: 200,
179
+ });
180
+ const output = {
181
+ url,
182
+ crawlDuration: result.duration,
183
+ summary: result.summary,
184
+ };
185
+ if (result.siteWideIssues.length > 0) {
186
+ output.siteWideIssues = result.siteWideIssues.map(issue => ({
187
+ type: issue.type,
188
+ severity: issue.severity,
189
+ message: issue.message,
190
+ affectedUrls: issue.affectedUrls.slice(0, 5),
191
+ affectedCount: issue.affectedUrls.length,
192
+ value: issue.value,
193
+ }));
194
+ }
195
+ const pageResults = result.pages
196
+ .filter(p => p.seoReport)
197
+ .map(p => ({
198
+ url: p.url,
199
+ status: p.status,
200
+ score: p.seoReport?.score,
201
+ grade: p.seoReport?.grade,
202
+ criticalIssues: p.seoReport?.checks.filter(c => c.status === 'fail').length || 0,
203
+ warnings: p.seoReport?.checks.filter(c => c.status === 'warn').length || 0,
204
+ }))
205
+ .sort((a, b) => (a.score || 0) - (b.score || 0));
206
+ output.pages = pageResults;
207
+ const errorPages = result.pages.filter(p => p.error);
208
+ if (errorPages.length > 0) {
209
+ output.crawlErrors = errorPages.map(p => ({
210
+ url: p.url,
211
+ error: p.error,
212
+ }));
213
+ }
214
+ const recommendations = [];
215
+ if (result.summary.duplicateTitles > 0) {
216
+ recommendations.push(`Fix ${result.summary.duplicateTitles} pages with duplicate titles - each page should have a unique title`);
217
+ }
218
+ if (result.summary.duplicateDescriptions > 0) {
219
+ recommendations.push(`Fix ${result.summary.duplicateDescriptions} pages with duplicate meta descriptions`);
220
+ }
221
+ if (result.summary.duplicateH1s > 0) {
222
+ recommendations.push(`Fix ${result.summary.duplicateH1s} pages with duplicate H1 headings`);
223
+ }
224
+ if (result.summary.orphanPages > 0) {
225
+ recommendations.push(`Add internal links to ${result.summary.orphanPages} orphan pages that have no incoming links`);
226
+ }
227
+ if (result.summary.avgScore < 70) {
228
+ recommendations.push(`Overall site SEO score is ${result.summary.avgScore}/100 - focus on pages with lowest scores first`);
229
+ }
230
+ if (recommendations.length > 0) {
231
+ output.recommendations = recommendations;
232
+ }
233
+ return {
234
+ content: [{
235
+ type: 'text',
236
+ text: JSON.stringify(output, null, 2),
237
+ }],
238
+ };
239
+ }
240
+ catch (error) {
241
+ return {
242
+ content: [{
243
+ type: 'text',
244
+ text: `SEO spider failed: ${error.message}`,
245
+ }],
246
+ isError: true,
247
+ };
248
+ }
249
+ }
250
+ async function seoQuickWins(args) {
251
+ const url = String(args.url || '');
252
+ const limit = Number(args.limit) || 10;
253
+ if (!url) {
254
+ return {
255
+ content: [{ type: 'text', text: 'Error: url is required' }],
256
+ isError: true,
257
+ };
258
+ }
259
+ try {
260
+ const client = createClient({ timeout: 30000 });
261
+ const response = await client.get(url);
262
+ const html = await response.text();
263
+ const responseHeaders = {};
264
+ response.headers.forEach((val, key) => {
265
+ responseHeaders[key] = val;
266
+ });
267
+ const report = await analyzeSeo(html, {
268
+ baseUrl: url,
269
+ responseHeaders,
270
+ });
271
+ const quickWins = generateQuickWins(report).slice(0, limit);
272
+ const high = quickWins.filter(w => w.priority === 'high');
273
+ const medium = quickWins.filter(w => w.priority === 'medium');
274
+ const low = quickWins.filter(w => w.priority === 'low');
275
+ const output = {
276
+ url,
277
+ score: report.score,
278
+ grade: report.grade,
279
+ quickWins: {
280
+ high: high.map(w => ({
281
+ issue: w.issue,
282
+ action: w.action,
283
+ impact: w.impact,
284
+ category: w.category,
285
+ })),
286
+ medium: medium.map(w => ({
287
+ issue: w.issue,
288
+ action: w.action,
289
+ category: w.category,
290
+ })),
291
+ low: low.map(w => ({
292
+ issue: w.issue,
293
+ action: w.action,
294
+ category: w.category,
295
+ })),
296
+ },
297
+ summary: {
298
+ totalIssues: quickWins.length,
299
+ highPriority: high.length,
300
+ mediumPriority: medium.length,
301
+ lowPriority: low.length,
302
+ },
303
+ advice: high.length > 0
304
+ ? `Start with the ${high.length} high-priority issues first. These have the biggest impact on SEO.`
305
+ : medium.length > 0
306
+ ? `Good job! No critical issues. Focus on the ${medium.length} medium-priority improvements.`
307
+ : 'Excellent! Your page is well-optimized. Consider the minor improvements listed.',
308
+ };
309
+ return {
310
+ content: [{
311
+ type: 'text',
312
+ text: JSON.stringify(output, null, 2),
313
+ }],
314
+ };
315
+ }
316
+ catch (error) {
317
+ return {
318
+ content: [{
319
+ type: 'text',
320
+ text: `Quick wins analysis failed: ${error.message}`,
321
+ }],
322
+ isError: true,
323
+ };
324
+ }
325
+ }
326
+ export const seoTools = [
327
+ {
328
+ name: 'rek_seo_analyze',
329
+ description: `Analyze a single web page for SEO issues using 250+ rules across 21 categories.
330
+
331
+ Returns:
332
+ - SEO score (0-100) and grade (A-F)
333
+ - Critical issues that must be fixed
334
+ - Warnings and recommendations
335
+ - OpenGraph/social meta analysis
336
+ - Request timing breakdown
337
+
338
+ Perfect for analyzing your localhost dev server or any public URL. Categories include: meta, content, links, images, technical, security, performance, mobile, accessibility, schema, structural, i18n, PWA, social, e-commerce, local SEO, Core Web Vitals, readability, crawlability, internal linking, and best practices.`,
339
+ inputSchema: {
340
+ type: 'object',
341
+ properties: {
342
+ url: {
343
+ type: 'string',
344
+ description: 'URL to analyze (e.g., http://localhost:3000 or https://example.com)',
345
+ },
346
+ categories: {
347
+ type: 'array',
348
+ items: { type: 'string' },
349
+ description: 'Filter by specific categories (e.g., ["meta", "security", "performance"]). Leave empty for all.',
350
+ },
351
+ verbose: {
352
+ type: 'boolean',
353
+ description: 'Include detailed analysis (headings, links, images breakdown)',
354
+ default: false,
355
+ },
356
+ },
357
+ required: ['url'],
358
+ },
359
+ },
360
+ {
361
+ name: 'rek_seo_spider',
362
+ description: `Crawl an entire website and analyze SEO across all pages.
363
+
364
+ Detects site-wide issues:
365
+ - Duplicate titles, descriptions, and H1s
366
+ - Orphan pages (no internal links pointing to them)
367
+ - Pages with low SEO scores
368
+
369
+ Returns per-page scores and prioritized recommendations for improving overall site SEO. Great for auditing a full site before launch or finding issues across your dev environment.`,
370
+ inputSchema: {
371
+ type: 'object',
372
+ properties: {
373
+ url: {
374
+ type: 'string',
375
+ description: 'Starting URL to crawl (e.g., http://localhost:3000)',
376
+ },
377
+ maxPages: {
378
+ type: 'number',
379
+ description: 'Maximum pages to crawl',
380
+ default: 100,
381
+ },
382
+ maxDepth: {
383
+ type: 'number',
384
+ description: 'Maximum link depth to follow',
385
+ default: 5,
386
+ },
387
+ concurrency: {
388
+ type: 'number',
389
+ description: 'Parallel requests (be respectful to servers)',
390
+ default: 3,
391
+ },
392
+ },
393
+ required: ['url'],
394
+ },
395
+ },
396
+ {
397
+ name: 'rek_seo_quick_wins',
398
+ description: `Get prioritized, actionable SEO improvements for a page.
399
+
400
+ Returns issues sorted by priority (high/medium/low) with:
401
+ - What to fix
402
+ - How to fix it
403
+ - Expected impact
404
+
405
+ Use this when you want a focused list of what to work on next, rather than a full audit.`,
406
+ inputSchema: {
407
+ type: 'object',
408
+ properties: {
409
+ url: {
410
+ type: 'string',
411
+ description: 'URL to analyze',
412
+ },
413
+ limit: {
414
+ type: 'number',
415
+ description: 'Maximum number of quick wins to return',
416
+ default: 10,
417
+ },
418
+ },
419
+ required: ['url'],
420
+ },
421
+ },
422
+ ];
423
+ export const seoToolHandlers = {
424
+ rek_seo_analyze: seoAnalyze,
425
+ rek_seo_spider: seoSpiderCrawl,
426
+ rek_seo_quick_wins: seoQuickWins,
427
+ };
@@ -1,6 +1,8 @@
1
1
  import { ClientOptions } from '../types/index.js';
2
+ import type { ClientOptionsWithAI } from '../types/ai-client.js';
2
3
  export interface AnthropicPresetOptions {
3
4
  apiKey: string;
4
5
  version?: string;
6
+ model?: string;
5
7
  }
6
- export declare function anthropic(options: AnthropicPresetOptions): ClientOptions;
8
+ export declare function anthropic(options: AnthropicPresetOptions): ClientOptions & ClientOptionsWithAI;
@@ -1,4 +1,13 @@
1
1
  export function anthropic(options) {
2
+ const _aiConfig = {
3
+ provider: 'anthropic',
4
+ apiKey: options.apiKey,
5
+ model: options.model ?? 'claude-sonnet-4-5',
6
+ headers: {
7
+ 'anthropic-version': options.version || '2023-06-01',
8
+ },
9
+ memory: { maxPairs: 12 },
10
+ };
2
11
  return {
3
12
  baseUrl: 'https://api.anthropic.com/v1',
4
13
  headers: {
@@ -12,6 +21,7 @@ export function anthropic(options) {
12
21
  backoff: 'exponential',
13
22
  delay: 1000,
14
23
  statusCodes: [408, 429, 500, 502, 503, 504]
15
- }
24
+ },
25
+ _aiConfig,
16
26
  };
17
27
  }
@@ -1,8 +1,10 @@
1
1
  import { ClientOptions } from '../types/index.js';
2
+ import type { ClientOptionsWithAI } from '../types/ai-client.js';
2
3
  export interface AzureOpenAIPresetOptions {
3
4
  resourceName: string;
4
5
  apiKey: string;
5
6
  apiVersion?: string;
6
7
  deploymentName?: string;
8
+ model?: string;
7
9
  }
8
- export declare function azureOpenai(options: AzureOpenAIPresetOptions): ClientOptions;
10
+ export declare function azureOpenai(options: AzureOpenAIPresetOptions): ClientOptions & ClientOptionsWithAI;
@@ -3,6 +3,15 @@ export function azureOpenai(options) {
3
3
  const baseUrl = options.deploymentName
4
4
  ? `https://${options.resourceName}.openai.azure.com/openai/deployments/${options.deploymentName}`
5
5
  : `https://${options.resourceName}.openai.azure.com/openai`;
6
+ const _aiConfig = {
7
+ provider: 'azure-openai',
8
+ apiKey: options.apiKey,
9
+ model: options.model ?? options.deploymentName ?? 'gpt-4o',
10
+ resourceName: options.resourceName,
11
+ deploymentName: options.deploymentName,
12
+ apiVersion,
13
+ memory: { maxPairs: 12 },
14
+ };
6
15
  return {
7
16
  baseUrl,
8
17
  headers: {
@@ -20,6 +29,7 @@ export function azureOpenai(options) {
20
29
  backoff: 'exponential',
21
30
  delay: 1000,
22
31
  statusCodes: [408, 429, 500, 502, 503, 504]
23
- }
32
+ },
33
+ _aiConfig,
24
34
  };
25
35
  }
@@ -1,5 +1,7 @@
1
1
  import { ClientOptions } from '../types/index.js';
2
+ import type { ClientOptionsWithAI } from '../types/ai-client.js';
2
3
  export interface CoherePresetOptions {
3
4
  apiKey: string;
5
+ model?: string;
4
6
  }
5
- export declare function cohere(options: CoherePresetOptions): ClientOptions;
7
+ export declare function cohere(options: CoherePresetOptions): ClientOptions & ClientOptionsWithAI;
@@ -1,9 +1,14 @@
1
1
  export function cohere(options) {
2
+ const _aiConfig = {
3
+ provider: 'cohere',
4
+ apiKey: options.apiKey,
5
+ model: options.model ?? 'command-a-03-2025',
6
+ memory: { maxPairs: 12 },
7
+ };
2
8
  return {
3
9
  baseUrl: 'https://api.cohere.ai/v1',
4
10
  headers: {
5
11
  'Authorization': `Bearer ${options.apiKey}`,
6
- 'Content-Type': 'application/json',
7
12
  },
8
13
  timeout: 5 * 60 * 1000,
9
14
  retry: {
@@ -11,6 +16,7 @@ export function cohere(options) {
11
16
  backoff: 'exponential',
12
17
  delay: 1000,
13
18
  statusCodes: [408, 429, 500, 502, 503, 504]
14
- }
19
+ },
20
+ _aiConfig,
15
21
  };
16
22
  }
@@ -1,5 +1,7 @@
1
1
  import { ClientOptions } from '../types/index.js';
2
+ import type { ClientOptionsWithAI } from '../types/ai-client.js';
2
3
  export interface DeepSeekPresetOptions {
3
4
  apiKey: string;
5
+ model?: string;
4
6
  }
5
- export declare function deepseek(options: DeepSeekPresetOptions): ClientOptions;
7
+ export declare function deepseek(options: DeepSeekPresetOptions): ClientOptions & ClientOptionsWithAI;
@@ -1,9 +1,14 @@
1
1
  export function deepseek(options) {
2
+ const _aiConfig = {
3
+ provider: 'deepseek',
4
+ apiKey: options.apiKey,
5
+ model: options.model ?? 'deepseek-v3.2',
6
+ memory: { maxPairs: 12 },
7
+ };
2
8
  return {
3
9
  baseUrl: 'https://api.deepseek.com/v1',
4
10
  headers: {
5
11
  'Authorization': `Bearer ${options.apiKey}`,
6
- 'Content-Type': 'application/json',
7
12
  },
8
13
  timeout: 10 * 60 * 1000,
9
14
  retry: {
@@ -11,6 +16,7 @@ export function deepseek(options) {
11
16
  backoff: 'exponential',
12
17
  delay: 1000,
13
18
  statusCodes: [408, 429, 500, 502, 503, 504]
14
- }
19
+ },
20
+ _aiConfig,
15
21
  };
16
22
  }
@@ -1,5 +1,7 @@
1
1
  import { ClientOptions } from '../types/index.js';
2
+ import type { ClientOptionsWithAI } from '../types/ai-client.js';
2
3
  export interface FireworksPresetOptions {
3
4
  apiKey: string;
5
+ model?: string;
4
6
  }
5
- export declare function fireworks(options: FireworksPresetOptions): ClientOptions;
7
+ export declare function fireworks(options: FireworksPresetOptions): ClientOptions & ClientOptionsWithAI;
@@ -1,9 +1,14 @@
1
1
  export function fireworks(options) {
2
+ const _aiConfig = {
3
+ provider: 'fireworks',
4
+ apiKey: options.apiKey,
5
+ model: options.model ?? 'accounts/fireworks/models/llama-v3p3-70b-instruct',
6
+ memory: { maxPairs: 12 },
7
+ };
2
8
  return {
3
9
  baseUrl: 'https://api.fireworks.ai/inference/v1',
4
10
  headers: {
5
11
  'Authorization': `Bearer ${options.apiKey}`,
6
- 'Content-Type': 'application/json',
7
12
  },
8
13
  timeout: 5 * 60 * 1000,
9
14
  retry: {
@@ -11,6 +16,7 @@ export function fireworks(options) {
11
16
  backoff: 'exponential',
12
17
  delay: 500,
13
18
  statusCodes: [408, 429, 500, 502, 503, 504]
14
- }
19
+ },
20
+ _aiConfig,
15
21
  };
16
22
  }
@@ -1,5 +1,7 @@
1
1
  import { ClientOptions } from '../types/index.js';
2
+ import type { ClientOptionsWithAI } from '../types/ai-client.js';
2
3
  export interface GeminiPresetOptions {
3
4
  apiKey: string;
5
+ model?: string;
4
6
  }
5
- export declare function gemini(options: GeminiPresetOptions): ClientOptions;
7
+ export declare function gemini(options: GeminiPresetOptions): ClientOptions & ClientOptionsWithAI;
@@ -1,4 +1,10 @@
1
1
  export function gemini(options) {
2
+ const _aiConfig = {
3
+ provider: 'google',
4
+ apiKey: options.apiKey,
5
+ model: options.model ?? 'gemini-3-pro',
6
+ memory: { maxPairs: 12 },
7
+ };
2
8
  return {
3
9
  baseUrl: 'https://generativelanguage.googleapis.com/v1beta',
4
10
  headers: {
@@ -11,6 +17,7 @@ export function gemini(options) {
11
17
  backoff: 'exponential',
12
18
  delay: 1000,
13
19
  statusCodes: [408, 429, 500, 502, 503, 504]
14
- }
20
+ },
21
+ _aiConfig,
15
22
  };
16
23
  }
@@ -1,5 +1,7 @@
1
1
  import { ClientOptions } from '../types/index.js';
2
+ import type { ClientOptionsWithAI } from '../types/ai-client.js';
2
3
  export interface GroqPresetOptions {
3
4
  apiKey: string;
5
+ model?: string;
4
6
  }
5
- export declare function groq(options: GroqPresetOptions): ClientOptions;
7
+ export declare function groq(options: GroqPresetOptions): ClientOptions & ClientOptionsWithAI;
@@ -1,9 +1,14 @@
1
1
  export function groq(options) {
2
+ const _aiConfig = {
3
+ provider: 'groq',
4
+ apiKey: options.apiKey,
5
+ model: options.model ?? 'llama-3.3-70b-versatile',
6
+ memory: { maxPairs: 12 },
7
+ };
2
8
  return {
3
9
  baseUrl: 'https://api.groq.com/openai/v1',
4
10
  headers: {
5
11
  'Authorization': `Bearer ${options.apiKey}`,
6
- 'Content-Type': 'application/json',
7
12
  },
8
13
  timeout: 2 * 60 * 1000,
9
14
  retry: {
@@ -11,6 +16,7 @@ export function groq(options) {
11
16
  backoff: 'exponential',
12
17
  delay: 500,
13
18
  statusCodes: [408, 429, 500, 502, 503, 504]
14
- }
19
+ },
20
+ _aiConfig,
15
21
  };
16
22
  }
@@ -1,5 +1,7 @@
1
1
  import { ClientOptions } from '../types/index.js';
2
+ import type { ClientOptionsWithAI } from '../types/ai-client.js';
2
3
  export interface HuggingFacePresetOptions {
3
4
  apiKey: string;
5
+ model?: string;
4
6
  }
5
- export declare function huggingface(options: HuggingFacePresetOptions): ClientOptions;
7
+ export declare function huggingface(options: HuggingFacePresetOptions): ClientOptions & ClientOptionsWithAI;