(params: {
messages: TokenCountRequest['messages']
system: string | undefined
model: string
fetch: typeof globalThis.fetch
logger: Logger
})
| 126 | const NON_ANTHROPIC_TOKEN_BUFFER = 0.3 |
| 127 | |
| 128 | export async function countTokensViaOpenAI(params: { |
| 129 | messages: TokenCountRequest['messages'] |
| 130 | system: string | undefined |
| 131 | model: string |
| 132 | fetch: typeof globalThis.fetch |
| 133 | logger: Logger |
| 134 | }): Promise<number> { |
| 135 | const { messages, system, model, fetch, logger } = params |
| 136 | |
| 137 | const openaiModelId = model.startsWith('openai/') |
| 138 | ? model.slice('openai/'.length) |
| 139 | : model |
| 140 | |
| 141 | const input = convertToResponsesApiInput(messages) |
| 142 | |
| 143 | const response = await fetch( |
| 144 | 'https://api.openai.com/v1/responses/input_tokens', |
| 145 | { |
| 146 | method: 'POST', |
| 147 | headers: { |
| 148 | Authorization: `Bearer ${env.OPENAI_API_KEY}`, |
| 149 | 'Content-Type': 'application/json', |
| 150 | }, |
| 151 | body: JSON.stringify({ |
| 152 | model: openaiModelId, |
| 153 | input, |
| 154 | ...(system && { instructions: system }), |
| 155 | }), |
| 156 | }, |
| 157 | ) |
| 158 | |
| 159 | if (!response.ok) { |
| 160 | const errorText = await response.text() |
| 161 | logger.error( |
| 162 | { status: response.status, errorText, model }, |
| 163 | 'OpenAI token count API error', |
| 164 | ) |
| 165 | throw new Error(`OpenAI API error: ${response.status} - ${errorText}`) |
| 166 | } |
| 167 | |
| 168 | const data = await response.json() |
| 169 | return data.input_tokens |
| 170 | } |
| 171 | |
| 172 | export type ResponsesApiContentPart = |
| 173 | | { type: 'input_text'; text: string } |
no test coverage detected