mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 12:55:51 +00:00
refactor: 将 codex provider 转换工具迁移至 @ant/model-provider 包
将纯转换工具(callIds、modelMapping、convertMessages、convertTools) 从 src/services/api/codex/ 迁移到 packages/@ant/model-provider/src/providers/codex/, 与 OpenAI/Gemini/Grok provider 保持一致的代码组织模式。同时修复了 streaming.test.ts 中缺失的 mock 导出(logAntError、context 常量、langfuse 导出)。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -61,3 +61,10 @@ export { anthropicMessagesToOpenAI } from './shared/openaiConvertMessages.js'
|
||||
export type { ConvertMessagesOptions } from './shared/openaiConvertMessages.js'
|
||||
export { anthropicToolsToOpenAI, anthropicToolChoiceToOpenAI } from './shared/openaiConvertTools.js'
|
||||
export { adaptOpenAIStreamToAnthropic } from './shared/openaiStreamAdapter.js'
|
||||
|
||||
// Codex provider utilities
|
||||
export { normalizeCodexCallId, resolveCodexCallId, createCodexFallbackCallId } from './providers/codex/callIds.js'
|
||||
export { resolveCodexModel, resolveCodexMaxTokens } from './providers/codex/modelMapping.js'
|
||||
export { anthropicMessagesToCodexInput } from './providers/codex/convertMessages.js'
|
||||
export type { CodexImageConversionOptions } from './providers/codex/convertMessages.js'
|
||||
export { anthropicToolsToCodex } from './providers/codex/convertTools.js'
|
||||
|
||||
@@ -4,7 +4,7 @@ import type {
|
||||
ResponseInputItem,
|
||||
ResponseInputText,
|
||||
} from 'openai/resources/responses/responses.mjs'
|
||||
import type { Message } from '../../../types/message.js'
|
||||
import type { Message } from '../../types/index.js'
|
||||
import {
|
||||
normalizeCodexCallId,
|
||||
resolveCodexCallId,
|
||||
@@ -1,7 +1,6 @@
|
||||
import { describe, expect, test } from 'bun:test'
|
||||
import { createAssistantMessage, createUserMessage } from '../../../../utils/messages.js'
|
||||
import { anthropicMessagesToCodexInput } from '../convertMessages.js'
|
||||
import { anthropicToolsToCodex } from '../convertTools.js'
|
||||
import { anthropicMessagesToCodexInput, anthropicToolsToCodex } from '@ant/model-provider'
|
||||
|
||||
describe('anthropicMessagesToCodexInput', () => {
|
||||
test('replays assistant tool calls and user tool results in order', async () => {
|
||||
|
||||
@@ -97,33 +97,68 @@ mock.module('../client.js', () => ({
|
||||
}),
|
||||
}))
|
||||
|
||||
mock.module('../convertMessages.js', () => ({
|
||||
anthropicMessagesToCodexInput: () => [],
|
||||
}))
|
||||
|
||||
mock.module('../convertTools.js', () => ({
|
||||
anthropicToolsToCodex: () => [],
|
||||
}))
|
||||
|
||||
mock.module('../model.js', () => ({
|
||||
resolveCodexModel: () => 'gpt-5.4',
|
||||
resolveCodexMaxTokens: () => 4096,
|
||||
}))
|
||||
// Mock only model resolution — conversion functions can use real implementations
|
||||
// since the client mock controls API responses.
|
||||
mock.module('@ant/model-provider', () => {
|
||||
// Import the real module to preserve conversion functions
|
||||
const real = require('@ant/model-provider')
|
||||
return {
|
||||
...real,
|
||||
resolveCodexModel: () => 'gpt-5.4',
|
||||
resolveCodexMaxTokens: () => 4096,
|
||||
}
|
||||
})
|
||||
|
||||
mock.module('../../../../utils/context.js', () => ({
|
||||
MODEL_CONTEXT_WINDOW_DEFAULT: 200_000,
|
||||
COMPACT_MAX_OUTPUT_TOKENS: 20_000,
|
||||
CAPPED_DEFAULT_MAX_TOKENS: 8_000,
|
||||
ESCALATED_MAX_TOKENS: 64_000,
|
||||
is1mContextDisabled: () => false,
|
||||
has1mContext: () => false,
|
||||
modelSupports1M: () => false,
|
||||
getContextWindowForModel: () => 200_000,
|
||||
getSonnet1mExpTreatmentEnabled: () => false,
|
||||
calculateContextPercentages: () => ({}),
|
||||
getModelMaxOutputTokens: () => ({ upperLimit: 4096 }),
|
||||
getMaxThinkingTokensForModel: () => 0,
|
||||
}))
|
||||
|
||||
mock.module('../../../../utils/api.js', () => ({
|
||||
toolToAPISchema: async () => ({}),
|
||||
appendSystemContext: () => {},
|
||||
prependUserContext: () => {},
|
||||
logAPIPrefix: () => {},
|
||||
splitSysPromptPrefix: () => ({ prefix: '', rest: [] }),
|
||||
logContextMetrics: async () => {},
|
||||
normalizeToolInput: (input: any) => input,
|
||||
normalizeToolInputForAPI: (input: any) => input,
|
||||
}))
|
||||
|
||||
mock.module('../../../../utils/debug.js', () => ({
|
||||
mock.module('src/utils/debug.ts', () => ({
|
||||
getMinDebugLogLevel: () => 'debug' as const,
|
||||
isDebugMode: () => false,
|
||||
enableDebugLogging: () => false,
|
||||
getDebugFilter: () => null,
|
||||
isDebugToStdErr: () => false,
|
||||
getDebugFilePath: () => null as string | null,
|
||||
setHasFormattedOutput: () => {},
|
||||
getHasFormattedOutput: () => false,
|
||||
flushDebugLogs: async () => {},
|
||||
logForDebugging: () => {},
|
||||
getDebugLogPath: () => '/tmp/mock-debug.log',
|
||||
logAntError: () => {},
|
||||
}))
|
||||
|
||||
mock.module('../../../../services/langfuse/tracing.js', () => ({
|
||||
createTrace: () => null,
|
||||
recordLLMObservation: () => {},
|
||||
recordToolObservation: () => {},
|
||||
createToolBatchSpan: () => null,
|
||||
endToolBatchSpan: () => {},
|
||||
createSubagentTrace: () => null,
|
||||
createChildSpan: () => null,
|
||||
endTrace: () => {},
|
||||
}))
|
||||
|
||||
mock.module('../../../../services/langfuse/convert.js', () => ({
|
||||
|
||||
@@ -27,15 +27,18 @@ import {
|
||||
convertOutputToLangfuse,
|
||||
convertToolsToLangfuse,
|
||||
} from '../../../services/langfuse/convert.js'
|
||||
import { anthropicMessagesToCodexInput } from './convertMessages.js'
|
||||
import { anthropicToolsToCodex } from './convertTools.js'
|
||||
import {
|
||||
anthropicMessagesToCodexInput,
|
||||
anthropicToolsToCodex,
|
||||
resolveCodexMaxTokens,
|
||||
resolveCodexModel,
|
||||
} from '@ant/model-provider'
|
||||
import { getCodexClient } from './client.js'
|
||||
import { uploadCodexBase64Image } from './imageUpload.js'
|
||||
import {
|
||||
getCodexConfigurationError,
|
||||
normalizeCodexError,
|
||||
} from './errors.js'
|
||||
import { resolveCodexMaxTokens, resolveCodexModel } from './model.js'
|
||||
import { sanitizeCodexRequest } from './preflight.js'
|
||||
import {
|
||||
addCodexUsage,
|
||||
|
||||
@@ -4,7 +4,7 @@ import type {
|
||||
ResponseInputItem,
|
||||
Tool,
|
||||
} from 'openai/resources/responses/responses.mjs'
|
||||
import { normalizeCodexCallId } from './callIds.js'
|
||||
import { normalizeCodexCallId } from '@ant/model-provider'
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
normalizeContentFromAPI,
|
||||
} from '../../../utils/messages.js'
|
||||
import { getCodexClient } from './client.js'
|
||||
import { resolveCodexCallId } from './callIds.js'
|
||||
import { resolveCodexCallId } from '@ant/model-provider'
|
||||
import { toStreamingCodexRequest } from './preflight.js'
|
||||
|
||||
export type RawAssistantBlock =
|
||||
|
||||
Reference in New Issue
Block a user