@sprqvntrs/llm 3.13.0
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/LICENSE +21 -0
- package/README.md +595 -0
- package/index.ts +53 -0
- package/package.json +56 -0
- package/src/clients/anthropic-client.ts +636 -0
- package/src/clients/openai-client.ts +548 -0
- package/src/clients/openrouter-client.ts +802 -0
- package/src/helpers.ts +185 -0
- package/src/llm.ts +107 -0
- package/src/model-types.ts +61 -0
- package/src/models.ts +98 -0
- package/src/pricing-data.json +1651 -0
- package/src/pricing.ts +36 -0
- package/src/types/client-interface.ts +222 -0
- package/src/utils/debug.ts +120 -0
- package/src/utils/errors.ts +508 -0
- package/src/utils/normalize-null-strings.ts +103 -0
- package/src/utils/resolve-refs.ts +91 -0
- package/src/utils/strip-json-artifacts.ts +98 -0
package/src/helpers.ts
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import type { LlmClientInterface } from './types/client-interface';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Simple schema for language validation response
|
|
6
|
+
*/
|
|
7
|
+
const LanguageCheckSchema = z.object({
|
|
8
|
+
isCorrectLanguage: z.boolean(),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Checks if content is in the expected language using an LLM
|
|
13
|
+
*
|
|
14
|
+
* @param {Object} params - The parameters for checking language
|
|
15
|
+
* @param {LlmClientInterface} params.llm - The LLM client to use for language detection
|
|
16
|
+
* @param {string} params.content - The content to check
|
|
17
|
+
* @param {string} params.expectedLanguage - The expected language of the content
|
|
18
|
+
* @returns {Promise<boolean>} - Whether the content is in the expected language
|
|
19
|
+
*/
|
|
20
|
+
export async function isContentInLanguage({
|
|
21
|
+
llm,
|
|
22
|
+
content,
|
|
23
|
+
expectedLanguage,
|
|
24
|
+
}: {
|
|
25
|
+
llm: LlmClientInterface;
|
|
26
|
+
content: string;
|
|
27
|
+
expectedLanguage: string;
|
|
28
|
+
}): Promise<boolean> {
|
|
29
|
+
try {
|
|
30
|
+
const prompt = `
|
|
31
|
+
<task>
|
|
32
|
+
Determine if the following content is written in ${expectedLanguage} language.
|
|
33
|
+
</task>
|
|
34
|
+
|
|
35
|
+
<instructions>
|
|
36
|
+
- Analyze the text and determine if it's written in ${expectedLanguage}
|
|
37
|
+
- Return true if the content is in ${expectedLanguage}
|
|
38
|
+
- Return false if the content is in any other language
|
|
39
|
+
- Ignore small phrases or individual words that might be in other languages
|
|
40
|
+
- Focus on the primary language of the text
|
|
41
|
+
</instructions>
|
|
42
|
+
|
|
43
|
+
<content>
|
|
44
|
+
${content}
|
|
45
|
+
</content>
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
const response = await llm.createStructuredResponse({
|
|
49
|
+
prompt,
|
|
50
|
+
schema: LanguageCheckSchema,
|
|
51
|
+
reasoningEffort: 'low', // Language detection doesn't need high reasoning
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return response.isCorrectLanguage;
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error('Error checking language:', error);
|
|
57
|
+
// In case of error, assume the language is correct to avoid blocking the flow
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Formats unstructured content into a structured format using an LLM
|
|
64
|
+
*
|
|
65
|
+
* This utility function takes unstructured content (typically from another LLM)
|
|
66
|
+
* and formats it according to a specified Zod schema. This is useful when working
|
|
67
|
+
* with LLMs that don't support structured outputs natively.
|
|
68
|
+
*
|
|
69
|
+
* @template T - The Zod schema type
|
|
70
|
+
* @param {Object} params - The parameters for formatting content
|
|
71
|
+
* @param {LlmClientInterface} params.llm - The LLM client to use for formatting
|
|
72
|
+
* @param {string} params.unstructuredContent - The unstructured content to format
|
|
73
|
+
* @param {T} params.schema - The Zod schema to validate against
|
|
74
|
+
* @param {string} [params.additionalInstructions] - Optional additional instructions for the formatting
|
|
75
|
+
* @returns {Promise<z.infer<T>>} - A promise that resolves to the structured content
|
|
76
|
+
*/
|
|
77
|
+
export async function formatContentToStructure<T extends z.ZodType>({
|
|
78
|
+
llm,
|
|
79
|
+
unstructuredContent,
|
|
80
|
+
schema,
|
|
81
|
+
additionalInstructions = '',
|
|
82
|
+
}: {
|
|
83
|
+
llm: LlmClientInterface;
|
|
84
|
+
unstructuredContent: string;
|
|
85
|
+
schema: T;
|
|
86
|
+
additionalInstructions?: string;
|
|
87
|
+
}): Promise<z.infer<T>> {
|
|
88
|
+
const conversionPrompt = `
|
|
89
|
+
This is the output of an AI model that is not able to respond in the format we need.
|
|
90
|
+
Please convert the output to the format we need. If you encounter any errors, return false on the success property (if applicable).
|
|
91
|
+
${additionalInstructions ? `\n${additionalInstructions}` : ''}
|
|
92
|
+
<output>
|
|
93
|
+
${JSON.stringify(unstructuredContent, null, 2)}
|
|
94
|
+
</output>
|
|
95
|
+
`;
|
|
96
|
+
|
|
97
|
+
const completion = await llm.createStructuredResponse({
|
|
98
|
+
prompt: conversionPrompt,
|
|
99
|
+
schema: schema,
|
|
100
|
+
reasoningEffort: 'low', // Formatting typically doesn't need high reasoning
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
return completion as z.infer<T>;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Attempts to generate and format content with language validation
|
|
108
|
+
*
|
|
109
|
+
* This function orchestrates the process of generating content with one LLM,
|
|
110
|
+
* checking if it's in the correct language, and formatting it with another LLM.
|
|
111
|
+
*
|
|
112
|
+
* @template T - The Zod schema type
|
|
113
|
+
* @param {Object} params - The parameters for generating and formatting
|
|
114
|
+
* @param {Function} params.generateContent - Function that generates the unstructured content
|
|
115
|
+
* @param {LlmClientInterface} params.languageCheckLlm - The LLM client to use for language validation
|
|
116
|
+
* @param {LlmClientInterface} params.formatterLlm - The LLM client to use for formatting
|
|
117
|
+
* @param {string} params.expectedLanguage - The expected language of the output
|
|
118
|
+
* @param {T} params.schema - The Zod schema to validate against
|
|
119
|
+
* @param {number} [params.maxAttempts=3] - Maximum number of attempts to get correct language
|
|
120
|
+
* @param {string} [params.additionalInstructions] - Optional additional instructions for formatting
|
|
121
|
+
* @returns {Promise<z.infer<T>>} - A promise that resolves to the structured content
|
|
122
|
+
*/
|
|
123
|
+
export async function generateAndFormatWithLanguageCheck<T extends z.ZodType>({
|
|
124
|
+
generateContent,
|
|
125
|
+
languageCheckLlm,
|
|
126
|
+
formatterLlm,
|
|
127
|
+
expectedLanguage,
|
|
128
|
+
schema,
|
|
129
|
+
maxAttempts = 3,
|
|
130
|
+
additionalInstructions,
|
|
131
|
+
}: {
|
|
132
|
+
generateContent: () => Promise<string>;
|
|
133
|
+
languageCheckLlm: LlmClientInterface;
|
|
134
|
+
formatterLlm: LlmClientInterface;
|
|
135
|
+
expectedLanguage: string;
|
|
136
|
+
schema: T;
|
|
137
|
+
maxAttempts?: number;
|
|
138
|
+
additionalInstructions?: string;
|
|
139
|
+
}): Promise<z.infer<T> & { languageCorrect: boolean }> {
|
|
140
|
+
let attempts = 0;
|
|
141
|
+
|
|
142
|
+
while (attempts < maxAttempts) {
|
|
143
|
+
attempts++;
|
|
144
|
+
|
|
145
|
+
// Step 1: Generate content
|
|
146
|
+
const unstructuredContent = await generateContent();
|
|
147
|
+
|
|
148
|
+
// Step 2: Check if content is in the expected language
|
|
149
|
+
const isLanguageCorrect = await isContentInLanguage({
|
|
150
|
+
llm: languageCheckLlm,
|
|
151
|
+
content: unstructuredContent,
|
|
152
|
+
expectedLanguage,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Step 3: Format the content regardless of language correctness
|
|
156
|
+
const formattedContent = await formatContentToStructure({
|
|
157
|
+
llm: formatterLlm,
|
|
158
|
+
unstructuredContent,
|
|
159
|
+
schema,
|
|
160
|
+
additionalInstructions,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Add language check result to the response
|
|
164
|
+
const result = {
|
|
165
|
+
...(formattedContent as object),
|
|
166
|
+
languageCorrect: isLanguageCorrect,
|
|
167
|
+
} as z.infer<T> & { languageCorrect: boolean };
|
|
168
|
+
|
|
169
|
+
// If language is correct, return immediately
|
|
170
|
+
if (isLanguageCorrect) {
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// If we've reached max attempts, return the last result anyway
|
|
175
|
+
if (attempts === maxAttempts) {
|
|
176
|
+
console.warn(`Max attempts reached. Language still incorrect after ${maxAttempts} tries.`);
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
console.info(`Incorrect language detected, retrying...`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// This should never be reached due to the while loop conditions
|
|
184
|
+
throw new Error('Unexpected end of content generation process');
|
|
185
|
+
}
|
package/src/llm.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { OpenAIClient } from './clients/openai-client';
|
|
2
|
+
import { AnthropicClient } from './clients/anthropic-client';
|
|
3
|
+
import { OpenRouterClient } from './clients/openrouter-client';
|
|
4
|
+
import type { LlmClientInterface } from './types/client-interface';
|
|
5
|
+
import type { AnthropicModel } from './model-types';
|
|
6
|
+
|
|
7
|
+
export type LlmProvider = 'openai' | 'anthropic' | 'openrouter';
|
|
8
|
+
|
|
9
|
+
export type LlmClientOptions = {
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Enable debug mode for development.
|
|
13
|
+
* - If true: always log debug messages
|
|
14
|
+
* - If false: never log debug messages
|
|
15
|
+
* - If undefined: auto-detect based on NODE_ENV (enabled in development)
|
|
16
|
+
*/
|
|
17
|
+
debug?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Some debug/testing contexts need to opt into reasoning endpoints explicitly (OpenAI only).
|
|
20
|
+
*/
|
|
21
|
+
useReasoningMode?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* OpenAI API key for structured formatting (used by Anthropic and OpenRouter clients).
|
|
24
|
+
* If provided, these clients will use OpenAI for reliable structured output formatting.
|
|
25
|
+
*/
|
|
26
|
+
openaiApiKey?: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Unified LLM client factory for all AI model interactions.
|
|
31
|
+
* Returns a client that implements the unified LlmClientInterface,
|
|
32
|
+
* providing consistent API across different providers.
|
|
33
|
+
*/
|
|
34
|
+
export class LLM {
|
|
35
|
+
/**
|
|
36
|
+
* Get an LLM client that implements the unified interface.
|
|
37
|
+
* Works with OpenAI, Anthropic, and OpenRouter providers transparently.
|
|
38
|
+
*
|
|
39
|
+
* @param provider - The LLM provider ('openai', 'anthropic', or 'openrouter')
|
|
40
|
+
* @param model - The model identifier (e.g., 'gpt-4o', 'claude-sonnet-4-20250514', 'openai/gpt-4o-mini')
|
|
41
|
+
* @param options - Optional configuration overrides
|
|
42
|
+
* @returns Client implementing LlmClientInterface
|
|
43
|
+
* @example
|
|
44
|
+
* const llm = LLM.getClient('openai', 'gpt-4o');
|
|
45
|
+
* const llm2 = LLM.getClient('openrouter', 'openai/gpt-4o-mini');
|
|
46
|
+
* const result = await llm.createStructuredResponse({ prompt, schema });
|
|
47
|
+
*/
|
|
48
|
+
static getClient(provider: LlmProvider, model: string, options?: LlmClientOptions): LlmClientInterface {
|
|
49
|
+
switch (provider) {
|
|
50
|
+
case 'openai':
|
|
51
|
+
return this._createOpenAIClient(model, options);
|
|
52
|
+
case 'anthropic':
|
|
53
|
+
return this._createAnthropicClient(model, options);
|
|
54
|
+
case 'openrouter':
|
|
55
|
+
return this._createOpenRouterClient(model, options);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Create an OpenAI client instance
|
|
61
|
+
*/
|
|
62
|
+
private static _createOpenAIClient(model: string, options?: LlmClientOptions): OpenAIClient {
|
|
63
|
+
const apiKey = options?.apiKey ?? process.env.OPENAI_API_KEY;
|
|
64
|
+
if (!apiKey) {
|
|
65
|
+
throw new Error('OPENAI_API_KEY is not set');
|
|
66
|
+
}
|
|
67
|
+
return new OpenAIClient({
|
|
68
|
+
apiKey,
|
|
69
|
+
model,
|
|
70
|
+
debug: options?.debug,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Create an Anthropic client instance
|
|
76
|
+
*/
|
|
77
|
+
private static _createAnthropicClient(model: string, options?: LlmClientOptions): AnthropicClient {
|
|
78
|
+
const apiKey = options?.apiKey ?? process.env.ANTHROPIC_API_KEY;
|
|
79
|
+
if (!apiKey) {
|
|
80
|
+
throw new Error('ANTHROPIC_API_KEY is not set');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return new AnthropicClient({
|
|
84
|
+
apiKey,
|
|
85
|
+
model: model as AnthropicModel,
|
|
86
|
+
openaiApiKey: options?.openaiApiKey,
|
|
87
|
+
debug: options?.debug,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Create an OpenRouter client instance
|
|
93
|
+
*/
|
|
94
|
+
private static _createOpenRouterClient(model: string, options?: LlmClientOptions): OpenRouterClient {
|
|
95
|
+
const apiKey = options?.apiKey ?? process.env.OPENROUTER_API_KEY;
|
|
96
|
+
if (!apiKey) {
|
|
97
|
+
throw new Error('OPENROUTER_API_KEY is not set');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return new OpenRouterClient({
|
|
101
|
+
apiKey,
|
|
102
|
+
model,
|
|
103
|
+
openaiApiKey: options?.openaiApiKey,
|
|
104
|
+
debug: options?.debug,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { ChatModel as OpenAIChatModel } from 'openai/resources/shared';
|
|
2
|
+
import type { Model as AnthropicModelType } from '@anthropic-ai/sdk/resources/messages/messages';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* OpenAI models released after the SDK's ChatModel union was last cut.
|
|
6
|
+
* Keep here until `openai` ships an SDK that includes them in `ChatModel`,
|
|
7
|
+
* then drop these literals.
|
|
8
|
+
*/
|
|
9
|
+
type OpenAINewerModel =
|
|
10
|
+
| 'gpt-5.5'
|
|
11
|
+
| 'gpt-5.5-pro'
|
|
12
|
+
| 'gpt-5.6-terra'
|
|
13
|
+
| 'gpt-5.6-terra-pro'
|
|
14
|
+
| 'gpt-5.6-luna'
|
|
15
|
+
| 'gpt-5.6-luna-pro'
|
|
16
|
+
| 'gpt-5.6-sol'
|
|
17
|
+
| 'gpt-5.6-sol-pro';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* OpenAI model types from the official SDK, plus newer models not yet in the
|
|
21
|
+
* SDK's `ChatModel` union and the embedding models we use directly.
|
|
22
|
+
*/
|
|
23
|
+
export type OpenAIModel =
|
|
24
|
+
| OpenAIChatModel
|
|
25
|
+
| OpenAINewerModel
|
|
26
|
+
| 'text-embedding-3-large'
|
|
27
|
+
| 'text-embedding-ada-002';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Anthropic model types from the official SDK
|
|
31
|
+
*/
|
|
32
|
+
export type AnthropicModel = AnthropicModelType;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* OpenRouter model types
|
|
36
|
+
* OpenRouter provides access to 300+ models across multiple providers
|
|
37
|
+
* Models are specified in the format 'provider/model-name'
|
|
38
|
+
* Examples: 'openai/gpt-4', 'anthropic/claude-3-opus', 'google/gemini-2.5-flash-lite-preview-09-2025'
|
|
39
|
+
*/
|
|
40
|
+
export type OpenRouterModel = string;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Map of provider to their available models
|
|
44
|
+
*/
|
|
45
|
+
export type ProviderModelMap = {
|
|
46
|
+
openai: OpenAIModel;
|
|
47
|
+
anthropic: AnthropicModel;
|
|
48
|
+
openrouter: OpenRouterModel;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Provider-specific model configuration with automatic model type inference
|
|
53
|
+
* When you set provider: 'openai', the model field will autocomplete with OpenAI models
|
|
54
|
+
* When you set provider: 'anthropic', the model field will autocomplete with Anthropic models
|
|
55
|
+
*/
|
|
56
|
+
export type ModelConfig<P extends keyof ProviderModelMap = keyof ProviderModelMap> = {
|
|
57
|
+
[K in P]: {
|
|
58
|
+
provider: K;
|
|
59
|
+
model: ProviderModelMap[K];
|
|
60
|
+
};
|
|
61
|
+
}[P];
|
package/src/models.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { ModelConfig } from './model-types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default model configurations for LLM operations
|
|
5
|
+
* These are used internally by the LLM package for formatting and structure operations
|
|
6
|
+
*/
|
|
7
|
+
export const DEFAULT_MODELS = {
|
|
8
|
+
/**
|
|
9
|
+
* Model used for converting unstructured content into structured format
|
|
10
|
+
* This is typically used when an Anthropic response needs to be formatted
|
|
11
|
+
*/
|
|
12
|
+
STRUCTURED_FORMATTER: {
|
|
13
|
+
provider: 'openai',
|
|
14
|
+
model: 'gpt-5-mini-2025-08-07',
|
|
15
|
+
} as ModelConfig<'openai'>,
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Model used for language detection and validation
|
|
19
|
+
*/
|
|
20
|
+
LANGUAGE_DETECTOR: {
|
|
21
|
+
provider: 'openai',
|
|
22
|
+
model: 'gpt-5-nano-2025-08-07',
|
|
23
|
+
} as ModelConfig<'openai'>,
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Default Anthropic model for generation tasks
|
|
27
|
+
*/
|
|
28
|
+
ANTHROPIC_DEFAULT: {
|
|
29
|
+
provider: 'anthropic',
|
|
30
|
+
model: 'claude-sonnet-4-6',
|
|
31
|
+
} as ModelConfig<'anthropic'>,
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Default OpenAI model for generation tasks
|
|
35
|
+
*/
|
|
36
|
+
OPENAI_DEFAULT: {
|
|
37
|
+
provider: 'openai',
|
|
38
|
+
model: 'gpt-5.4',
|
|
39
|
+
} as ModelConfig<'openai'>,
|
|
40
|
+
} as const;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Maps reasoning effort levels to provider-specific parameters
|
|
44
|
+
*
|
|
45
|
+
* Note: this map is legacy — it is exported for backwards compatibility but is not
|
|
46
|
+
* consumed by any client. Clients pass the normalized `ReasoningEffortLevel` straight
|
|
47
|
+
* through to the provider (OpenAI and OpenRouter both accept `reasoning.effort`,
|
|
48
|
+
* including 'none'; Anthropic translates it into an extended-thinking budget).
|
|
49
|
+
*/
|
|
50
|
+
export const REASONING_EFFORT_MAP = {
|
|
51
|
+
openai: {
|
|
52
|
+
none: 'none' as const,
|
|
53
|
+
low: undefined, // OpenAI doesn't use reasoning_effort for low
|
|
54
|
+
medium: 'medium' as const,
|
|
55
|
+
high: 'high' as const,
|
|
56
|
+
},
|
|
57
|
+
} as const;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Base max tokens for Anthropic responses
|
|
61
|
+
* When using thinking mode, actual max_tokens will be: max(ANTHROPIC_MAX_TOKENS, budget_tokens + 4096)
|
|
62
|
+
* to ensure max_tokens > thinking.budget_tokens as required by the API
|
|
63
|
+
*/
|
|
64
|
+
export const ANTHROPIC_MAX_TOKENS = 4096;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Default system prompt used across all LLM clients
|
|
68
|
+
* Instructs the model to generate content directly without asking clarifying questions
|
|
69
|
+
*/
|
|
70
|
+
export const DEFAULT_SYSTEM_PROMPT = `You are an expert assistant.
|
|
71
|
+
|
|
72
|
+
When given a task, produce the requested output directly:
|
|
73
|
+
- Do NOT ask clarifying questions
|
|
74
|
+
- Do NOT present multiple options or menus for the user to choose from
|
|
75
|
+
- Do NOT include meta-commentary about the task
|
|
76
|
+
- Make reasonable assumptions when details are unspecified`;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Web search tool configurations for different providers
|
|
80
|
+
*/
|
|
81
|
+
export const WEB_SEARCH_TOOLS = {
|
|
82
|
+
/**
|
|
83
|
+
* Anthropic web search tool configuration
|
|
84
|
+
* See: https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool
|
|
85
|
+
*/
|
|
86
|
+
ANTHROPIC: {
|
|
87
|
+
type: 'web_search_20250305',
|
|
88
|
+
name: 'web_search',
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* OpenAI web search tool configuration for Responses API
|
|
93
|
+
* See: https://cookbook.openai.com/examples/responses_api/responses_example
|
|
94
|
+
*/
|
|
95
|
+
OPENAI: {
|
|
96
|
+
type: 'web_search',
|
|
97
|
+
},
|
|
98
|
+
} as const;
|