From cdbbb98ce54b7480fde31040990ab23e15d80aa9 Mon Sep 17 00:00:00 2001 From: unadlib Date: Sun, 7 Jun 2026 02:10:36 +0800 Subject: [PATCH 1/2] fix(llm): send Google config through SDK config --- src/llm/google/chat.ts | 66 +++++++++++-------- test/llm-google-alignment.test.ts | 62 +++++++++++------- test/llm-google-wire-request.test.ts | 97 ++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+), 51 deletions(-) create mode 100644 test/llm-google-wire-request.test.ts diff --git a/src/llm/google/chat.ts b/src/llm/google/chat.ts index 6e8bbed0..4d636c1f 100644 --- a/src/llm/google/chat.ts +++ b/src/llm/google/chat.ts @@ -1,4 +1,8 @@ -import { GoogleGenAI } from '@google/genai'; +import { GoogleGenAI, ThinkingLevel } from '@google/genai'; +import type { + GenerateContentConfig, + GenerateContentParameters, +} from '@google/genai'; import type { BaseChatModel, ChatInvokeOptions } from '../base.js'; import { ModelProviderError } from '../exceptions.js'; import { ChatInvokeCompletion, type ChatInvokeUsage } from '../views.js'; @@ -58,6 +62,13 @@ const buildGoogleHttpOptions = ( return resolvedHttpOptions; }; +const googleThinkingLevelByName = { + minimal: ThinkingLevel.MINIMAL, + low: ThinkingLevel.LOW, + medium: ThinkingLevel.MEDIUM, + high: ThinkingLevel.HIGH, +} as const; + export class ChatGoogle implements BaseChatModel { public model: string; public provider = 'google'; @@ -349,15 +360,17 @@ export class ChatGoogle implements BaseChatModel { this.includeSystemInUser ); - const generationConfig: any = this.config ? { ...this.config } : {}; + const requestConfig: GenerateContentConfig = this.config + ? { ...(this.config as GenerateContentConfig) } + : {}; if (this.temperature !== null) { - generationConfig.temperature = this.temperature; + requestConfig.temperature = this.temperature; } if (this.topP !== null) { - generationConfig.topP = this.topP; + requestConfig.topP = this.topP; } if (this.seed !== null) { - generationConfig.seed = this.seed; + requestConfig.seed = this.seed; } const isGemini3Pro = this.model.includes('gemini-3-pro'); @@ -368,16 +381,16 @@ export class ChatGoogle implements BaseChatModel { if (level === 'minimal' || level === 'medium') { level = 'low'; } - generationConfig.thinkingConfig = { - thinkingLevel: level.toUpperCase(), + requestConfig.thinkingConfig = { + thinkingLevel: googleThinkingLevelByName[level], }; } else if (isGemini3Flash) { if (this.thinkingLevel !== null) { - generationConfig.thinkingConfig = { - thinkingLevel: this.thinkingLevel.toUpperCase(), + requestConfig.thinkingConfig = { + thinkingLevel: googleThinkingLevelByName[this.thinkingLevel], }; } else { - generationConfig.thinkingConfig = { + requestConfig.thinkingConfig = { thinkingBudget: this.thinkingBudget === null ? -1 : this.thinkingBudget, }; @@ -392,12 +405,12 @@ export class ChatGoogle implements BaseChatModel { budget = -1; } if (budget !== null) { - generationConfig.thinkingConfig = { thinkingBudget: budget }; + requestConfig.thinkingConfig = { thinkingBudget: budget }; } } if (this.maxOutputTokens !== null) { - generationConfig.maxOutputTokens = this.maxOutputTokens; + requestConfig.maxOutputTokens = this.maxOutputTokens; } // Try to get schema from output_format @@ -437,8 +450,8 @@ export class ChatGoogle implements BaseChatModel { } if (cleanSchemaForJson && this.supportsStructuredOutput) { - generationConfig.responseMimeType = 'application/json'; - generationConfig.responseSchema = cleanSchemaForJson; + requestConfig.responseMimeType = 'application/json'; + requestConfig.responseSchema = cleanSchemaForJson; } const requestContents = (contents as any[]).map((entry) => ({ @@ -462,28 +475,29 @@ export class ChatGoogle implements BaseChatModel { } } - const request: any = { - model: this.model, - contents: requestContents, - }; - if (systemInstruction && !this.includeSystemInUser) { - request.systemInstruction = { + requestConfig.systemInstruction = { role: 'system', parts: [{ text: systemInstruction }], }; } - if (Object.keys(generationConfig).length > 0) { - request.generationConfig = generationConfig; + if (options.signal) { + requestConfig.abortSignal = options.signal; + } + + const request: GenerateContentParameters = { + model: this.model, + contents: requestContents as any, + }; + + if (Object.keys(requestConfig).length > 0) { + request.config = requestConfig; } for (let attempt = 0; attempt < this.maxRetries; attempt += 1) { try { - const result = await (this.client.models as any).generateContent( - request, - options.signal ? { signal: options.signal } : undefined - ); + const result = await this.client.models.generateContent(request); const candidate = result.candidates?.[0]; const textParts = diff --git a/test/llm-google-alignment.test.ts b/test/llm-google-alignment.test.ts index 24e29b23..c3a36148 100644 --- a/test/llm-google-alignment.test.ts +++ b/test/llm-google-alignment.test.ts @@ -15,7 +15,15 @@ vi.mock('@google/genai', () => { } } - return { GoogleGenAI }; + return { + GoogleGenAI, + ThinkingLevel: { + MINIMAL: 'MINIMAL', + LOW: 'LOW', + MEDIUM: 'MEDIUM', + HIGH: 'HIGH', + }, + }; }); import { @@ -213,19 +221,25 @@ describe('Google LLM alignment', () => { }, }); - const response = await llm.ainvoke([ - new SystemMessage('sys'), - new UserMessage('hello'), - ]); + const controller = new AbortController(); + const response = await llm.ainvoke( + [new SystemMessage('sys'), new UserMessage('hello')], + undefined, + { signal: controller.signal } + ); const request = generateContentMock.mock.calls[0]?.[0] ?? {}; - expect(request.generationConfig.temperature).toBe(0.3); - expect(request.generationConfig.topP).toBe(0.8); - expect(request.generationConfig.seed).toBe(7); - expect(request.generationConfig.stopSequences).toEqual(['DONE']); - expect(request.generationConfig.thinkingConfig.thinkingBudget).toBe(-1); - expect(request.generationConfig.maxOutputTokens).toBe(512); - expect(request.systemInstruction.parts[0].text).toBe('sys'); + expect(generateContentMock.mock.calls[0]).toHaveLength(1); + expect(request.generationConfig).toBeUndefined(); + expect(request.systemInstruction).toBeUndefined(); + expect(request.config.temperature).toBe(0.3); + expect(request.config.topP).toBe(0.8); + expect(request.config.seed).toBe(7); + expect(request.config.stopSequences).toEqual(['DONE']); + expect(request.config.thinkingConfig.thinkingBudget).toBe(-1); + expect(request.config.maxOutputTokens).toBe(512); + expect(request.config.systemInstruction.parts[0].text).toBe('sys'); + expect(request.config.abortSignal).toBe(controller.signal); expect(response.completion).toBe('plain response'); expect(response.usage?.completion_tokens).toBe(6); expect(response.usage?.prompt_cached_tokens).toBe(3); @@ -238,9 +252,7 @@ describe('Google LLM alignment', () => { }); await llmDefault.ainvoke([new UserMessage('hello')]); const defaultRequest = generateContentMock.mock.calls[0]?.[0] ?? {}; - expect(defaultRequest.generationConfig.thinkingConfig.thinkingLevel).toBe( - 'LOW' - ); + expect(defaultRequest.config.thinkingConfig.thinkingLevel).toBe('LOW'); generateContentMock.mockClear(); @@ -250,9 +262,7 @@ describe('Google LLM alignment', () => { }); await llmMinimal.ainvoke([new UserMessage('hello')]); const minimalRequest = generateContentMock.mock.calls[0]?.[0] ?? {}; - expect(minimalRequest.generationConfig.thinkingConfig.thinkingLevel).toBe( - 'LOW' - ); + expect(minimalRequest.config.thinkingConfig.thinkingLevel).toBe('LOW'); }); it('supports Gemini 3 flash thinking level and budget behavior', async () => { @@ -262,7 +272,7 @@ describe('Google LLM alignment', () => { }); await llmWithLevel.ainvoke([new UserMessage('hello')]); const levelRequest = generateContentMock.mock.calls[0]?.[0] ?? {}; - expect(levelRequest.generationConfig.thinkingConfig).toEqual({ + expect(levelRequest.config.thinkingConfig).toEqual({ thinkingLevel: 'HIGH', }); @@ -273,7 +283,7 @@ describe('Google LLM alignment', () => { }); await llmWithDefaultBudget.ainvoke([new UserMessage('hello')]); const budgetRequest = generateContentMock.mock.calls[0]?.[0] ?? {}; - expect(budgetRequest.generationConfig.thinkingConfig).toEqual({ + expect(budgetRequest.config.thinkingConfig).toEqual({ thinkingBudget: -1, }); }); @@ -296,9 +306,11 @@ describe('Google LLM alignment', () => { const request = generateContentMock.mock.calls[0]?.[0] ?? {}; expect(request.systemInstruction).toBeUndefined(); + expect(request.generationConfig).toBeUndefined(); + expect(request.config.systemInstruction).toBeUndefined(); expect(request.contents[0].parts[0].text as string).toContain('sys prompt'); - expect(request.generationConfig.responseMimeType).toBe('application/json'); - expect(request.generationConfig.responseSchema).toBeDefined(); + expect(request.config.responseMimeType).toBe('application/json'); + expect(request.config.responseSchema).toBeDefined(); expect((response.completion as any).value).toBe('ok'); }); @@ -318,8 +330,8 @@ describe('Google LLM alignment', () => { ); const request = generateContentMock.mock.calls[0]?.[0] ?? {}; - expect(request.generationConfig.responseMimeType).toBeUndefined(); - expect(request.generationConfig.responseSchema).toBeUndefined(); + expect(request.config.responseMimeType).toBeUndefined(); + expect(request.config.responseSchema).toBeUndefined(); expect((request.contents?.[0]?.parts?.[1]?.text as string) ?? '').toContain( 'Please respond with a valid JSON object that matches this schema' ); @@ -361,7 +373,7 @@ describe('Google LLM alignment', () => { await llm.ainvoke([new UserMessage('extract')], schema as any); const request = generateContentMock.mock.calls[0]?.[0] ?? {}; - const responseSchema = request.generationConfig.responseSchema ?? {}; + const responseSchema = request.config.responseSchema ?? {}; const serializedSchema = JSON.stringify(responseSchema); expect(serializedSchema).not.toContain('output_schema'); diff --git a/test/llm-google-wire-request.test.ts b/test/llm-google-wire-request.test.ts new file mode 100644 index 00000000..49c4c172 --- /dev/null +++ b/test/llm-google-wire-request.test.ts @@ -0,0 +1,97 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { z } from 'zod'; + +import { ChatGoogle } from '../src/llm/google/chat.js'; +import { SystemMessage, UserMessage } from '../src/llm/messages.js'; + +describe('Google LLM wire request', () => { + afterEach(() => { + vi.unstubAllGlobals(); + }); + + it('sends system instruction, generation config, schema, and abort signal through SDK config', async () => { + let capturedBody: Record | null = null; + let capturedSignal: AbortSignal | null = null; + + const fetchMock = vi.fn( + async ( + _url: Parameters[0], + init?: Parameters[1] + ) => { + capturedSignal = init?.signal ?? null; + capturedBody = init?.body ? JSON.parse(String(init.body)) : null; + + return new Response( + JSON.stringify({ + candidates: [ + { + content: { + parts: [{ text: '{"value":"ok"}' }], + }, + finishReason: 'STOP', + }, + ], + }), + { + status: 200, + headers: { 'content-type': 'application/json' }, + } + ); + } + ); + vi.stubGlobal('fetch', fetchMock); + + const controller = new AbortController(); + const schema = z.object({ value: z.string() }); + const llm = new ChatGoogle({ + model: 'gemini-2.5-flash', + apiKey: 'test-key', + temperature: 0.3, + topP: 0.8, + seed: 7, + thinkingBudget: 0, + maxOutputTokens: 512, + config: { + stopSequences: ['DONE'], + }, + supportsStructuredOutput: true, + }); + + const response = await llm.ainvoke( + [new SystemMessage('SYSTEM-PROMPT'), new UserMessage('extract')], + schema as any, + { signal: controller.signal } + ); + + expect(fetchMock).toHaveBeenCalledTimes(1); + expect(capturedSignal).toBeTruthy(); + expect(capturedBody).not.toBeNull(); + const body = capturedBody as unknown as Record; + + expect(body).toMatchObject({ + contents: [ + { + role: 'user', + parts: [{ text: 'extract' }], + }, + ], + systemInstruction: { + role: 'system', + parts: [{ text: 'SYSTEM-PROMPT' }], + }, + generationConfig: { + temperature: 0.3, + topP: 0.8, + seed: 7, + stopSequences: ['DONE'], + thinkingConfig: { thinkingBudget: 0 }, + maxOutputTokens: 512, + responseMimeType: 'application/json', + }, + }); + expect(body.generationConfig?.responseSchema).toBeDefined(); + expect(body).not.toHaveProperty('config'); + expect(body).not.toHaveProperty('generation_config'); + expect((response.completion as any).value).toBe('ok'); + }); +}); From 4194b3b1b0157cb75f2625f0c56f32ef1af975f6 Mon Sep 17 00:00:00 2001 From: unadlib Date: Sun, 7 Jun 2026 02:27:13 +0800 Subject: [PATCH 2/2] fix(ci): clear dependency audit failures --- package.json | 6 +- pnpm-lock.yaml | 191 +++++++++++++++++++++++++------------------------ 2 files changed, 101 insertions(+), 96 deletions(-) diff --git a/package.json b/package.json index c8335a75..abb10126 100644 --- a/package.json +++ b/package.json @@ -354,7 +354,7 @@ "@types/turndown": "^5.0.6", "@typescript-eslint/eslint-plugin": "^8.54.0", "@typescript-eslint/parser": "^8.54.0", - "@vitest/coverage-v8": "^4.0.18", + "@vitest/coverage-v8": "^4.1.8", "commitizen": "^4.3.1", "cz-conventional-changelog": "^3.3.0", "eslint": "^9.39.2", @@ -366,7 +366,7 @@ "tsx": "^4.21.0", "typescript": "^5.9.3", "vite": "^7.3.2", - "vitest": "^4.0.18" + "vitest": "^4.1.8" }, "pnpm": { "onlyBuiltDependencies": [ @@ -384,7 +384,7 @@ "fast-xml-builder": "1.2.0", "fast-xml-parser": "5.7.3", "flatted": "3.4.2", - "hono": "4.12.18", + "hono": "4.12.23", "ip-address": "10.2.0", "lodash": "4.18.1", "minimatch": "10.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 20d5a2bb..50705c14 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,7 +14,7 @@ overrides: fast-xml-builder: 1.2.0 fast-xml-parser: 5.7.3 flatted: 3.4.2 - hono: 4.12.18 + hono: 4.12.23 ip-address: 10.2.0 lodash: 4.18.1 minimatch: 10.2.4 @@ -140,8 +140,8 @@ importers: specifier: ^8.54.0 version: 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@vitest/coverage-v8': - specifier: ^4.0.18 - version: 4.0.18(vitest@4.0.18(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0)) + specifier: ^4.1.8 + version: 4.1.8(vitest@4.1.8) commitizen: specifier: ^4.3.1 version: 4.3.1(@types/node@25.2.3)(typescript@5.9.3) @@ -176,8 +176,8 @@ importers: specifier: ^7.3.2 version: 7.3.2(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0) vitest: - specifier: ^4.0.18 - version: 4.0.18(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0) + specifier: ^4.1.8 + version: 4.1.8(@types/node@25.2.3)(@vitest/coverage-v8@4.1.8)(vite@7.3.2(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0)) packages: @@ -582,7 +582,7 @@ packages: resolution: {integrity: sha512-TsQLe4i2gvoTtrHje625ngThGBySOgSK3Xo2XRYOdqGN1teR8+I7vchQC46uLJi8OF62YTYA3AhSpumtkhsaKQ==} engines: {node: '>=18.14.1'} peerDependencies: - hono: 4.12.18 + hono: 4.12.23 '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} @@ -1178,43 +1178,43 @@ packages: resolution: {integrity: sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitest/coverage-v8@4.0.18': - resolution: {integrity: sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==} + '@vitest/coverage-v8@4.1.8': + resolution: {integrity: sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==} peerDependencies: - '@vitest/browser': 4.0.18 - vitest: 4.0.18 + '@vitest/browser': 4.1.8 + vitest: 4.1.8 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.0.18': - resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} + '@vitest/expect@4.1.8': + resolution: {integrity: sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==} - '@vitest/mocker@4.0.18': - resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} + '@vitest/mocker@4.1.8': + resolution: {integrity: sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==} peerDependencies: msw: ^2.4.9 - vite: ^6.0.0 || ^7.0.0-0 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: msw: optional: true vite: optional: true - '@vitest/pretty-format@4.0.18': - resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} + '@vitest/pretty-format@4.1.8': + resolution: {integrity: sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==} - '@vitest/runner@4.0.18': - resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==} + '@vitest/runner@4.1.8': + resolution: {integrity: sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==} - '@vitest/snapshot@4.0.18': - resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} + '@vitest/snapshot@4.1.8': + resolution: {integrity: sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==} - '@vitest/spy@4.0.18': - resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} + '@vitest/spy@4.1.8': + resolution: {integrity: sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==} - '@vitest/utils@4.0.18': - resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} + '@vitest/utils@4.1.8': + resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==} abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} @@ -1324,8 +1324,8 @@ packages: ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - ast-v8-to-istanbul@0.3.11: - resolution: {integrity: sha512-Qya9fkoofMjCBNVdWINMjB5KZvkYfaO9/anwkWnjxibpWUxo5iHl2sOdP7/uAqaRuUYuoo8rDwnbaaKVFxoUvw==} + ast-v8-to-istanbul@1.0.3: + resolution: {integrity: sha512-jCMQ6ZylLPudp0CDfBmQBZUsrh1/8psbmu9ibeVWKuHWD0YrH9YABwlKu5kVEFoT0GCQQW9Z/SxfuEbbkGQCRg==} async-function@1.0.0: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} @@ -1504,6 +1504,9 @@ packages: engines: {node: '>=18'} hasBin: true + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} @@ -1691,8 +1694,8 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} @@ -2183,8 +2186,8 @@ packages: resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} engines: {node: '>=0.10.0'} - hono@4.12.18: - resolution: {integrity: sha512-RWzP96k/yv0PQfyXnWjs6zot20TqfpfsNXhOnev8d1InAxubW93L11/oNUc3tQqn2G0bSdAOBpX+2uDFHV7kdQ==} + hono@4.12.23: + resolution: {integrity: sha512-eIaZ9qDgu7XV0pxOCrg7/WhnQ6Ivm22UcxhXx/A3dcbqbbYgBEkc6e/J/s7j2tS96zoB0S9VBdLwQNCWwUo4LA==} engines: {node: '>=16.9.0'} html-escaper@2.0.2: @@ -3110,8 +3113,8 @@ packages: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} - std-env@3.10.0: - resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + std-env@4.1.0: + resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} @@ -3211,8 +3214,8 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} - tinyrainbow@3.0.3: - resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} tmp@0.2.6: @@ -3377,20 +3380,23 @@ packages: yaml: optional: true - vitest@4.0.18: - resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} + vitest@4.1.8: + resolution: {integrity: sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.18 - '@vitest/browser-preview': 4.0.18 - '@vitest/browser-webdriverio': 4.0.18 - '@vitest/ui': 4.0.18 + '@vitest/browser-playwright': 4.1.8 + '@vitest/browser-preview': 4.1.8 + '@vitest/browser-webdriverio': 4.1.8 + '@vitest/coverage-istanbul': 4.1.8 + '@vitest/coverage-v8': 4.1.8 + '@vitest/ui': 4.1.8 happy-dom: '*' jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: '@edge-runtime/vm': optional: true @@ -3404,6 +3410,10 @@ packages: optional: true '@vitest/browser-webdriverio': optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true '@vitest/ui': optional: true happy-dom: @@ -4094,9 +4104,9 @@ snapshots: - supports-color - utf-8-validate - '@hono/node-server@1.19.13(hono@4.12.18)': + '@hono/node-server@1.19.13(hono@4.12.23)': dependencies: - hono: 4.12.18 + hono: 4.12.23 '@humanfs/core@0.19.1': {} @@ -4131,7 +4141,7 @@ snapshots: '@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6)': dependencies: - '@hono/node-server': 1.19.13(hono@4.12.18) + '@hono/node-server': 1.19.13(hono@4.12.23) ajv: 8.20.0 ajv-formats: 3.0.1 content-type: 1.0.5 @@ -4141,7 +4151,7 @@ snapshots: eventsource-parser: 3.0.6 express: 5.2.1 express-rate-limit: 8.2.2(express@5.2.1) - hono: 4.12.18 + hono: 4.12.23 jose: 6.1.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -4772,58 +4782,60 @@ snapshots: '@typescript-eslint/types': 8.55.0 eslint-visitor-keys: 4.2.1 - '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0))': + '@vitest/coverage-v8@4.1.8(vitest@4.1.8)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.0.18 - ast-v8-to-istanbul: 0.3.11 + '@vitest/utils': 4.1.8 + ast-v8-to-istanbul: 1.0.3 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 magicast: 0.5.2 obug: 2.1.1 - std-env: 3.10.0 - tinyrainbow: 3.0.3 - vitest: 4.0.18(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0) + std-env: 4.1.0 + tinyrainbow: 3.1.0 + vitest: 4.1.8(@types/node@25.2.3)(@vitest/coverage-v8@4.1.8)(vite@7.3.2(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0)) - '@vitest/expect@4.0.18': + '@vitest/expect@4.1.8': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.0.18 - '@vitest/utils': 4.0.18 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 chai: 6.2.2 - tinyrainbow: 3.0.3 + tinyrainbow: 3.1.0 - '@vitest/mocker@4.0.18(vite@7.3.2(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0))': + '@vitest/mocker@4.1.8(vite@7.3.2(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0))': dependencies: - '@vitest/spy': 4.0.18 + '@vitest/spy': 4.1.8 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: vite: 7.3.2(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0) - '@vitest/pretty-format@4.0.18': + '@vitest/pretty-format@4.1.8': dependencies: - tinyrainbow: 3.0.3 + tinyrainbow: 3.1.0 - '@vitest/runner@4.0.18': + '@vitest/runner@4.1.8': dependencies: - '@vitest/utils': 4.0.18 + '@vitest/utils': 4.1.8 pathe: 2.0.3 - '@vitest/snapshot@4.0.18': + '@vitest/snapshot@4.1.8': dependencies: - '@vitest/pretty-format': 4.0.18 + '@vitest/pretty-format': 4.1.8 + '@vitest/utils': 4.1.8 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.0.18': {} + '@vitest/spy@4.1.8': {} - '@vitest/utils@4.0.18': + '@vitest/utils@4.1.8': dependencies: - '@vitest/pretty-format': 4.0.18 - tinyrainbow: 3.0.3 + '@vitest/pretty-format': 4.1.8 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 abort-controller@3.0.0: dependencies: @@ -4948,7 +4960,7 @@ snapshots: ast-types-flow@0.0.8: {} - ast-v8-to-istanbul@0.3.11: + ast-v8-to-istanbul@1.0.3: dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 @@ -5136,6 +5148,8 @@ snapshots: meow: 13.2.0 optional: true + convert-source-map@2.0.0: {} + cookie-signature@1.2.2: {} cookie@0.7.2: {} @@ -5363,7 +5377,7 @@ snapshots: es-errors@1.3.0: {} - es-module-lexer@1.7.0: {} + es-module-lexer@2.1.0: {} es-object-atoms@1.1.1: dependencies: @@ -6006,7 +6020,7 @@ snapshots: dependencies: parse-passwd: 1.0.0 - hono@4.12.18: {} + hono@4.12.23: {} html-escaper@2.0.2: {} @@ -7027,7 +7041,7 @@ snapshots: statuses@2.0.2: {} - std-env@3.10.0: {} + std-env@4.1.0: {} stop-iteration-iterator@1.1.0: dependencies: @@ -7139,7 +7153,7 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - tinyrainbow@3.0.3: {} + tinyrainbow@3.1.0: {} tmp@0.2.6: {} @@ -7287,42 +7301,33 @@ snapshots: jiti: 2.6.1 tsx: 4.21.0 - vitest@4.0.18(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0): + vitest@4.1.8(@types/node@25.2.3)(@vitest/coverage-v8@4.1.8)(vite@7.3.2(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0)): dependencies: - '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.2(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0)) - '@vitest/pretty-format': 4.0.18 - '@vitest/runner': 4.0.18 - '@vitest/snapshot': 4.0.18 - '@vitest/spy': 4.0.18 - '@vitest/utils': 4.0.18 - es-module-lexer: 1.7.0 + '@vitest/expect': 4.1.8 + '@vitest/mocker': 4.1.8(vite@7.3.2(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0)) + '@vitest/pretty-format': 4.1.8 + '@vitest/runner': 4.1.8 + '@vitest/snapshot': 4.1.8 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 + es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 obug: 2.1.1 pathe: 2.0.3 picomatch: 4.0.4 - std-env: 3.10.0 + std-env: 4.1.0 tinybench: 2.9.0 tinyexec: 1.0.2 tinyglobby: 0.2.15 - tinyrainbow: 3.0.3 + tinyrainbow: 3.1.0 vite: 7.3.2(@types/node@25.2.3)(jiti@2.6.1)(tsx@4.21.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 25.2.3 + '@vitest/coverage-v8': 4.1.8(vitest@4.1.8) transitivePeerDependencies: - - jiti - - less - - lightningcss - msw - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - - yaml wcwidth@1.0.1: dependencies: