diff --git a/packages/llms/src/utils.test.ts b/packages/llms/src/utils.test.ts index 7e0269713..0a1644727 100644 --- a/packages/llms/src/utils.test.ts +++ b/packages/llms/src/utils.test.ts @@ -1,7 +1,66 @@ +import { fileURLToPath } from 'node:url' +import { build, minify } from 'vite' import { describe, expect, it } from 'vitest' import { modelPatch, normalizeModelName } from './utils' +describe('modelPatch', () => { + it('remains executable when a consumer bundle drops console calls', async () => { + const entryId = 'virtual:drop-console-entry' + const resolvedEntryId = `\0${entryId}` + const resultKey = '__PAGE_AGENT_DROP_CONSOLE_TEST_RESULT__' + const utilsPath = fileURLToPath(new URL('./utils.ts', import.meta.url)) + + const buildResult = await build({ + configFile: false, + logLevel: 'silent', + plugins: [ + { + name: 'drop-console-test-entry', + resolveId(id) { + if (id === entryId) return resolvedEntryId + }, + load(id) { + if (id !== resolvedEntryId) return + return ` + import { modelPatch } from ${JSON.stringify(utilsPath)} + globalThis[${JSON.stringify(resultKey)}] = modelPatch({ model: 'qwen-plus' }) + ` + }, + }, + ], + build: { + minify: false, + rollupOptions: { input: entryId }, + write: false, + }, + }) + + const buildOutputs = Array.isArray(buildResult) ? buildResult : [buildResult] + const chunk = buildOutputs + .flatMap((output) => ('output' in output ? output.output : [])) + .find((output) => output.type === 'chunk') + expect(chunk).toBeDefined() + if (!chunk || chunk.type !== 'chunk') throw new Error('Vite did not produce an output chunk') + + const optimizedBundle = await minify('drop-console-bundle.js', chunk.code, { + compress: { dropConsole: true }, + mangle: false, + }) + expect(optimizedBundle.code).not.toMatch(/\bconsole\b/) + + const moduleUrl = `data:text/javascript;base64,${Buffer.from(optimizedBundle.code).toString('base64')}` + await import(/* @vite-ignore */ moduleUrl) + + const testGlobals = globalThis as typeof globalThis & Record + expect(testGlobals[resultKey]).toEqual({ + model: 'qwen-plus', + enable_thinking: false, + }) + delete testGlobals[resultKey] + }) +}) + describe('normalizeModelName', () => { it.each([ ['gpt-5.2', 'gpt-52'], diff --git a/packages/llms/src/utils.ts b/packages/llms/src/utils.ts index cfebb814d..ebac49fd0 100644 --- a/packages/llms/src/utils.ts +++ b/packages/llms/src/utils.ts @@ -6,7 +6,11 @@ import * as z from 'zod/v4' import type { Tool } from './types' -const debug = console.debug.bind(console, chalk.gray('[LLM]')) +// Keep console access inside the wrapper so bundlers can drop it without +// replacing the callable logger itself with `undefined`. +function debug(...args: unknown[]) { + console.debug(chalk.gray('[LLM]'), ...args) +} /** * Convert Zod schema to OpenAI tool format