feat(models): bridge Chat Completions and Responses through Claude runtime

This commit is contained in:
Codex committed 2026-10-21 18:19:03 +09:00
1 parent 8fcfb69408
commit d773961168
21 files changed
+1346 -68

No files matched your search

+246
View File
@@ -0,0 +1,246 @@
/** Offline integration only. NEVER imports/runs the installed Claude SDK or opens a network port. */
import assert from 'node:assert/strict'
import { mkdtemp, rm } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join, resolve } from 'node:path'
import { pathToFileURL } from 'node:url'
import { build } from 'esbuild'
const temp = await mkdtemp(join(tmpdir(), 'ycode-claude-bridge-offline-'))
const queries = [], leases = [], kernels = []
let queryFailure = false, runtimeFailure = false, grantFailure = false, acquireGate
const deferred = () => { let resolve; const promise = new Promise(r => { resolve = r }); return { promise, resolve } }
const tick = () => new Promise(r => setImmediate(r))
const mocks = {
electron: { app: { getPath: () => temp, getAppPath: () => temp } },
'@anthropic-ai/claude-agent-sdk': {
createSdkMcpServer: config => config,
tool: (name, description, schema, handler) => ({ name, description, schema, handler }),
query: request => {
if (queryFailure) throw new Error('mock SDK startup failure')
const ended = deferred()
const instance = {
closeCount: 0, interrupt: async () => {},
close() { this.closeCount++; ended.resolve() },
async *[Symbol.asyncIterator]() { await ended.promise },
applyFlagSettings: async () => { if (grantFailure) throw new Error('mock grant replay failure') }, setPermissionMode: async () => {},
getContextUsage: async () => ({ categories: [] })
}
queries.push({ ...request, instance })
return instance
}
},
'private-runtimes': { privateRuntimeEnvironment: async env => { if (runtimeFailure) throw new Error('mock runtime failure'); return env } },
'agent/tools/browser': { browserTool: { description: 'inert browser', run: () => { throw new Error('Unexpected browser execution') } } },
'capabilities/claude-capabilities': { createClaudeCapabilityRuntime: () => ({ server: {}, setRequestSelection() {} }) },
'model-bridge': { acquireModelBridge: async model => {
const id = leases.length + 1
const lease = { model: structuredClone(model), baseUrl: `http://127.0.0.1:${24000 + id}/lease-${id}`, apiKey: `mock-local-token-${id}`, closeCount: 0, async close() { this.closeCount++ } }
leases.push(lease)
if (acquireGate) await acquireGate.promise
return lease
} }
}
const portKeys = new Map(Object.keys(mocks).map(key => [key === 'electron' || key.startsWith('@') ? key : resolve('src/main', key), key]))
globalThis.__claudeBridgeOfflineMocks = mocks
let checks = 0
const check = async (name, body) => { await body(); checks++; console.log(`PASS ${name}`) }
function model(api = 'openai-completions', suffix = '') {
return { profile: { id: `offline${suffix}`, name: 'Offline', providerId: 'offline', model: `model${suffix}`, baseUrl: 'https://invalid.example/v1', authMode: 'api-key', apiPreference: api, protocol: api === 'anthropic-messages' ? 'anthropic' : 'openai', contextWindowTokens: 100000 }, config: { api, model: `model${suffix}`, baseUrl: 'https://invalid.example/v1', apiKey: `FAKE-NOT-A-CREDENTIAL${suffix}` } }
}
const options = (id, value = model()) => ({ sessionId: id, workspaceRoot: temp, model: value, permissionMode: 'default-sandbox', agentMode: 'craft', onSessionId() {} })
try {
const bundle = join(temp, 'kernel.mjs')
await build({ stdin: { contents: "export * from './src/main/agent/claude/claude-kernel'; export { rememberSessionGrant } from './src/main/agent/claude/session-grants'", resolveDir: process.cwd(), loader: 'ts' }, outfile: bundle, bundle: true, platform: 'node', format: 'esm', logLevel: 'warning', metafile: true, plugins: [{ name: 'strict-offline-ports', setup(b) {
b.onResolve({ filter: /.*/ }, args => {
const path = args.path.startsWith('.') ? resolve(args.resolveDir, args.path).replace(/\.(ts|js)$/, '').replace(/\/index$/, '') : args.path
const key = portKeys.get(path)
if (key) return { path: key, namespace: 'offline' }
if (args.path.includes('claude-agent-sdk')) throw new Error('Actual SDK resolution forbidden')
})
b.onLoad({ filter: /.*/, namespace: 'offline' }, args => ({ contents: Object.keys(mocks[args.path]).map(name => `export const ${name} = globalThis.__claudeBridgeOfflineMocks[${JSON.stringify(args.path)}][${JSON.stringify(name)}]`).join('\n'), loader: 'js' }))
} }] }).then(result => {
assert(!Object.keys(result.metafile.inputs).some(path => path.includes('node_modules/@anthropic-ai/')), 'real SDK must never enter bundle')
assert(!Object.keys(result.metafile.inputs).some(path => /src\/main\/model-bridge\//.test(path) && !path.endsWith('/model-bridge/paths.ts')), 'real network bridge must never enter bundle')
})
const { ClaudeKernel, getClaudeKernel, disposeClaudeKernels, rememberSessionGrant } = await import(pathToFileURL(bundle).href)
const make = opts => { const kernel = new ClaudeKernel(opts); kernels.push(kernel); return kernel }
let baseline
await check('both OpenAI APIs use isolated bridge env, not upstream credentials', async () => {
for (const api of ['openai-completions', 'openai-responses']) {
const value = model(api), kernel = make(options(api, value)), before = leases.length
await kernel.ensureStarted()
const lease = leases.at(-1), request = queries.at(-1)
assert.equal(leases.length, before + 1)
assert.deepEqual(lease.model, { ...value, config: { ...value.config, thinkingLevel: 'off' } })
assert.equal(request.options.env.ANTHROPIC_BASE_URL, lease.baseUrl)
assert.equal(request.options.env.ANTHROPIC_API_KEY, lease.apiKey)
assert(!JSON.stringify(request.options.env).includes(value.config.apiKey))
assert.equal(request.options.model, value.config.model)
baseline ??= request.options
await kernel.close(); assert.equal(lease.closeCount, 1)
await kernel.close(); assert.equal(lease.closeCount, 1)
}
})
await check('bridge lease receives effective low/off thinking without mutating resolved config', async () => {
for (const api of ['openai-completions', 'openai-responses']) {
for (const [requested, reasoning, expected] of [['low', true, 'low'], ['off', true, 'off'], [undefined, false, 'off']]) {
const value = model(api)
value.profile.supportsReasoning = reasoning
value.profile.supportedEfforts = ['low', 'high']
value.config.thinkingLevel = 'high'
const kernel = make({ ...options(`thinking-${api}-${requested}`, value), thinkingLevel: requested })
await kernel.ensureStarted()
assert.equal(leases.at(-1).model.config.thinkingLevel, expected)
assert.equal(value.config.thinkingLevel, 'high', 'bridge-specific effective level must not mutate resolved model')
await kernel.close()
}
}
})
await check('Anthropic remains direct and permission/tool hooks remain identical', async () => {
const before = leases.length, value = model('anthropic-messages')
const kernel = make(options('anthropic', value)); await kernel.ensureStarted()
const opts = queries.at(-1).options
assert.equal(leases.length, before)
assert.equal(opts.env.ANTHROPIC_BASE_URL, 'https://invalid.example')
assert.equal(opts.env.ANTHROPIC_API_KEY, value.config.apiKey)
for (const key of ['permissionMode', 'permissionPrompts', 'settingSources', 'strictMcpConfig', 'tools', 'allowedTools', 'disallowedTools', 'plugins', 'agents', 'skills']) assert.deepEqual(opts[key], baseline[key], key)
assert.equal(opts.permissionMode, 'default'); assert.equal(opts.permissionPrompts, 'host')
assert.deepEqual(Object.keys(opts.hooks), ['PreToolUse'])
assert.equal(typeof opts.canUseTool, 'function')
for (const policy of [opts, baseline]) {
const result = await policy.hooks.PreToolUse[0].hooks[0]({ hook_event_name: 'PreToolUse', tool_name: 'Bash', tool_input: {}, tool_use_id: 'inactive' })
assert.equal(result.hookSpecificOutput.permissionDecision, 'deny')
}
await kernel.close()
})
await check('two simultaneous sessions have separate leases and independent cleanup', async () => {
const a = make(options('dual-a', model('openai-completions', '-a'))), b = make(options('dual-b', model('openai-responses', '-b')))
const before = leases.length
await Promise.all([a.ensureStarted(), b.ensureStarted()])
const [la, lb] = leases.slice(before)
assert.notEqual(la.apiKey, lb.apiKey); assert.notEqual(la.baseUrl, lb.baseUrl)
await a.close(); assert.equal(la.closeCount, 1); assert.equal(lb.closeCount, 0)
await b.close(); assert.equal(lb.closeCount, 1)
})
await check('concurrent ensureStarted acquires exactly one lease and SDK query', async () => {
const kernel = make(options('concurrent')), before = leases.length, q = queries.length
acquireGate = deferred()
const starts = Array.from({ length: 6 }, () => kernel.ensureStarted())
await tick(); acquireGate.resolve(); acquireGate = undefined
await Promise.all(starts)
assert.equal(leases.length, before + 1); assert.equal(queries.length, q + 1)
await kernel.close(); assert.equal(leases.at(-1).closeCount, 1)
})
await check('API/model/base URL/key configuration changes retire old leases', async () => {
let opts = options('fingerprint'), kernel = await getClaudeKernel(opts)
await kernel.ensureStarted(); assert.equal(await getClaudeKernel(opts), kernel)
for (const patch of [{ api: 'openai-responses' }, { model: 'changed-model' }, { baseUrl: 'https://other.invalid/v1' }, { apiKey: 'FAKE-CHANGED-KEY' }]) {
const oldLease = leases.at(-1)
opts = { ...opts, model: { ...opts.model, config: { ...opts.model.config, ...patch } } }
const next = await getClaudeKernel(opts); assert.notEqual(next, kernel)
assert.equal(oldLease.closeCount, 1); await next.ensureStarted(); kernel = next
}
await kernel.close()
})
await check('failed SDK startup releases lease and permits clean retry', async () => {
const kernel = make(options('failed'))
queryFailure = true
await assert.rejects(kernel.ensureStarted(), /mock SDK startup failure/)
queryFailure = false
assert.equal(leases.at(-1).closeCount, 1)
await kernel.ensureStarted(); assert.equal(leases.at(-1).closeCount, 0)
await kernel.close(); assert.equal(leases.at(-1).closeCount, 1)
})
await check('failed session grant replay releases producer and bridge before retry', async () => {
const kernel = make(options('grant-replay'))
rememberSessionGrant('grant-replay', { rules: ['Read(**)'], updates: [] }, temp)
grantFailure = true
await assert.rejects(kernel.ensureStarted(), /mock grant replay failure/)
grantFailure = false; await tick()
assert.equal(leases.at(-1).closeCount, 1)
await kernel.ensureStarted(); await kernel.close()
assert.equal(leases.at(-1).closeCount, 1)
})
await check('runtime environment failure cannot strand a bridge lease', async () => {
const kernel = make(options('runtime-failure')), before = leases.length
runtimeFailure = true
await assert.rejects(kernel.ensureStarted(), /mock runtime failure/)
runtimeFailure = false
for (const lease of leases.slice(before)) assert.equal(lease.closeCount, 1)
await kernel.close()
})
await check('close during asynchronous acquisition releases lease without SDK startup', async () => {
const kernel = make(options('close-during-start')), q = queries.length
acquireGate = deferred()
const start = kernel.ensureStarted().catch(error => error)
await tick()
const closing = kernel.close()
acquireGate.resolve(); acquireGate = undefined
await Promise.all([start, closing])
assert.equal(queries.length, q); assert.equal(leases.at(-1).closeCount, 1)
})
await check('unsupported Gemini fails before bridge or SDK creation', async () => {
const value = model('google-generative-ai'); value.profile.protocol = 'gemini'
const kernel = make(options('unsupported', value)), before = leases.length, q = queries.length
await assert.rejects(kernel.ensureStarted(), /协议/)
assert.equal(leases.length, before); assert.equal(queries.length, q)
await kernel.close()
})
await check('resolved model snapshot cannot be mutated after kernel creation', async () => {
const value = model(), kernel = make(options('snapshot', value))
value.config.apiKey = 'FAKE-MUTATED'; value.config.model = 'mutated-model'
await kernel.ensureStarted()
assert.equal(leases.at(-1).model.config.apiKey, 'FAKE-NOT-A-CREDENTIAL')
assert.equal(queries.at(-1).options.model, 'model')
await kernel.close()
})
await check('bridge preserves full-access tool preauthorization and question approval boundary', async () => {
const kernel = make({ ...options('hook-policy'), permissionMode: 'full-access' }), controller = new AbortController()
const run = kernel.runTurn({ runId: 'hook-run', userMessageId: 'user', prompt: 'offline', emit() {}, interactions: {}, signal: controller.signal })
const rejected = assert.rejects(run, error => error.name === 'AbortError')
await tick()
const opts = queries.at(-1).options, hook = opts.hooks.PreToolUse[0].hooks[0]
assert.equal(opts.permissionMode, 'default')
for (const [name, decision] of [['Bash', 'allow'], ['AskUserQuestion', 'ask']]) {
const result = await hook({ hook_event_name: 'PreToolUse', tool_name: name, tool_input: {}, tool_use_id: name })
assert.equal(result.hookSpecificOutput.permissionDecision, decision)
}
controller.abort(); await rejected; await kernel.close()
})
await check('unexpected producer termination releases bridge lease', async () => {
const kernel = make(options('producer-end'))
await kernel.ensureStarted(); const lease = leases.at(-1)
queries.at(-1).instance.close(); await tick()
assert.equal(lease.closeCount, 1)
await kernel.close(); assert.equal(lease.closeCount, 1)
})
await check('cancellation during bridge acquisition releases newly started producer', async () => {
const kernel = make(options('cancel-start')), controller = new AbortController()
acquireGate = deferred()
const run = kernel.runTurn({ runId: 'cancel-start-run', userMessageId: 'user', prompt: 'offline', emit() {}, interactions: {}, signal: controller.signal })
const rejected = assert.rejects(run, error => error.name === 'AbortError')
await tick(); controller.abort(); acquireGate.resolve(); acquireGate = undefined
await rejected; await tick()
assert.equal(leases.at(-1).closeCount, 1)
await kernel.close()
})
await check('turn cancellation retires producer and releases its bridge lease', async () => {
const kernel = make(options('cancel')), controller = new AbortController()
const run = kernel.runTurn({ runId: 'cancel-run', userMessageId: 'user', prompt: 'offline', emit() {}, interactions: {}, signal: controller.signal })
const rejected = assert.rejects(run, error => error.name === 'AbortError')
await tick(); assert.equal(kernel.busy, true)
const lease = leases.at(-1)
controller.abort(); await rejected; await tick()
assert.equal(lease.closeCount, 1)
await kernel.close(); assert.equal(lease.closeCount, 1)
})
await disposeClaudeKernels()
assert(leases.every(lease => lease.closeCount === 1), 'all leases released exactly once')
console.log(`PASS ${checks} offline Claude/bridge host groups; no actual SDK startup, network or credentials`)
} finally {
acquireGate?.resolve()
await Promise.all(kernels.map(kernel => kernel.close().catch(() => {})))
delete globalThis.__claudeBridgeOfflineMocks
await rm(temp, { recursive: true, force: true })
}