diff --git a/packages/core/src/context/contextManager.golden.test.ts b/packages/core/src/context/contextManager.golden.test.ts index 907add6a5a..e2966d205a 100644 --- a/packages/core/src/context/contextManager.golden.test.ts +++ b/packages/core/src/context/contextManager.golden.test.ts @@ -150,7 +150,7 @@ describe('ContextManager Golden Tests', () => { const history = createLargeHistory(); ( contextManager as unknown as { pristineEpisodes: Episode[] } - ).pristineEpisodes = (contextManager as any).env.irMapper.toIr(history, (contextManager as any).env.tokenCalculator); + ).pristineEpisodes = (contextManager as unknown as import("../pipeline.js").ContextWorkingBuffer).env.irMapper.toIr(history, (contextManager as unknown as import("../pipeline.js").ContextWorkingBuffer).env.tokenCalculator); const result = await contextManager.projectCompressedHistory(); expect(result).toMatchSnapshot(); }); diff --git a/packages/core/src/context/ir/builtinBehaviors.ts b/packages/core/src/context/ir/builtinBehaviors.ts index e02042d826..66555f40ca 100644 --- a/packages/core/src/context/ir/builtinBehaviors.ts +++ b/packages/core/src/context/ir/builtinBehaviors.ts @@ -34,6 +34,8 @@ export const UserPromptBehavior: IrNodeBehavior = { case 'raw_part': parts.push(sp.part); break; + default: + break; } } return parts; diff --git a/packages/core/src/context/processors/blobDegradationProcessor.test.ts b/packages/core/src/context/processors/blobDegradationProcessor.test.ts index b6560b4bc3..4ca041101d 100644 --- a/packages/core/src/context/processors/blobDegradationProcessor.test.ts +++ b/packages/core/src/context/processors/blobDegradationProcessor.test.ts @@ -3,7 +3,7 @@ * Copyright 2026 Google LLC * SPDX-License-Identifier: Apache-2.0 */ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect } from 'vitest'; import { BlobDegradationProcessor } from './blobDegradationProcessor.js'; import { createMockEnvironment, @@ -14,19 +14,17 @@ import type { UserPrompt, SemanticPart } from '../ir/types.js'; describe('BlobDegradationProcessor', () => { it('should ignore text parts and only target inline_data and file_data', async () => { const env = createMockEnvironment(); - // Simulate each part costing 100 tokens, but text costing 10 tokens - env.tokenCalculator.estimateTokensForParts = vi.fn((parts: any[]) => { - if (parts[0].text) return 10; - return 100; - }); + // charsPerToken = 1 + // We want the degraded text to be cheaper than the original blob. + // Degraded text is ~100 chars ("...degraded to text..."). + // So we make the blob data 200 chars. + const fakeData = 'A'.repeat(200); const processor = BlobDegradationProcessor.create(env, {}); - // Deficit of 50 means budget is NOT satisfied. - const parts: SemanticPart[] = [ { type: 'text', text: 'Hello' }, - { type: 'inline_data', mimeType: 'image/png', data: 'fake_base64_data' }, + { type: 'inline_data', mimeType: 'image/png', data: fakeData }, { type: 'text', text: 'World' }, ]; @@ -37,16 +35,14 @@ describe('BlobDegradationProcessor', () => { const targets = [prompt]; const result = await processor.process({ - buffer: {} as any, + buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, targets, - inbox: {} as any, + inbox: undefined as unknown as import('../pipeline.js').InboxSnapshot, }); - // We modified it, so the ID should change and it should have new metadata expect(result.length).toBe(1); const modifiedPrompt = result[0] as UserPrompt; - // Original prompt ID was randomUUID(), new one is from idGenerator expect(modifiedPrompt.id).not.toBe(prompt.id); expect(modifiedPrompt.semanticParts.length).toBe(3); @@ -55,23 +51,22 @@ describe('BlobDegradationProcessor', () => { expect(modifiedPrompt.semanticParts[2]).toEqual(parts[2]); // The inline_data part should be replaced with text - const degradedPart = modifiedPrompt.semanticParts[1]; + const degradedPart = modifiedPrompt.semanticParts[1] as import('../ir/types.js').TextPart; expect(degradedPart.type).toBe('text'); - expect((degradedPart as any).text).toContain('[Multi-Modal Blob (image/png, 0.00MB) degraded to text'); - - // The transformation should be logged + expect(degradedPart.text).toContain('[Multi-Modal Blob (image/png, 0.00MB) degraded to text'); }); it('should degrade all blobs unconditionally', async () => { const env = createMockEnvironment(); - env.tokenCalculator.estimateTokensForParts = vi.fn((parts: any[]) => { - if (parts[0].text) return 10; - return 100; // saving 90 tokens per degradation - }); - const processor = BlobDegradationProcessor.create(env, {}); + // Tokens for fileData = 258. + // Degraded text = "[File Reference (video/mp4) degraded to text to preserve context window. Original URI: gs://test1]" + // Degraded text length ~100 characters. + // Since charsPerToken=1, degraded text = 100 tokens. + // Tokens saved = 258 - 100 = 158. This is > 0, so it WILL degrade it! + const prompt = createDummyNode('ep1', 'USER_PROMPT', 100, { semanticParts: [ { type: 'file_data', mimeType: 'video/mp4', fileUri: 'gs://test1' }, @@ -82,9 +77,9 @@ describe('BlobDegradationProcessor', () => { const targets = [prompt]; const result = await processor.process({ - buffer: {} as any, + buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, targets, - inbox: {} as any, + inbox: undefined as unknown as import('../pipeline.js').InboxSnapshot, }); const modifiedPrompt = result[0] as UserPrompt; @@ -99,15 +94,14 @@ describe('BlobDegradationProcessor', () => { const env = createMockEnvironment(); const processor = BlobDegradationProcessor.create(env, {}); - const targets: any[] = []; + const targets: Array = []; const result = await processor.process({ - buffer: {} as any, + buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, targets, - inbox: {} as any, + inbox: undefined as unknown as import('../pipeline.js').InboxSnapshot, }); - // Should return the exact array ref expect(result).toBe(targets); }); }); diff --git a/packages/core/src/context/processors/blobDegradationProcessor.ts b/packages/core/src/context/processors/blobDegradationProcessor.ts index 47a2d7ea41..6294cc7559 100644 --- a/packages/core/src/context/processors/blobDegradationProcessor.ts +++ b/packages/core/src/context/processors/blobDegradationProcessor.ts @@ -70,7 +70,7 @@ export class BlobDegradationProcessor implements ContextProcessor { let newText = ''; let tokensSaved = 0; - switch (part.type) { + switch (part.type) { case 'inline_data': { await ensureDir(); const ext = part.mimeType.split('/')[1] || 'bin'; @@ -114,6 +114,8 @@ export class BlobDegradationProcessor implements ContextProcessor { tokensSaved = oldTokens - newTokens; break; } + default: + break; } if (newText && tokensSaved > 0) { diff --git a/packages/core/src/context/processors/nodeDistillationProcessor.test.ts b/packages/core/src/context/processors/nodeDistillationProcessor.test.ts index 3154faf73e..7a4606f1b0 100644 --- a/packages/core/src/context/processors/nodeDistillationProcessor.test.ts +++ b/packages/core/src/context/processors/nodeDistillationProcessor.test.ts @@ -20,7 +20,7 @@ describe('NodeDistillationProcessor', () => { }; const env = createMockEnvironment({ - llmClient: mockLlmClient as any, + llmClient: mockLlmClient as unknown as import("../pipeline.js").ContextWorkingBuffer, }); const processor = NodeDistillationProcessor.create(env, { @@ -46,9 +46,9 @@ describe('NodeDistillationProcessor', () => { const targets = [prompt, thought, tool]; const result = await processor.process({ - buffer: {} as any, + buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, targets, - inbox: {} as any, + inbox: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, }); expect(result.length).toBe(3); @@ -57,7 +57,7 @@ describe('NodeDistillationProcessor', () => { const compressedPrompt = result[0] as UserPrompt; expect(compressedPrompt.id).not.toBe(prompt.id); expect(compressedPrompt.semanticParts[0].type).toBe('text'); - expect((compressedPrompt.semanticParts[0] as any).text).toBe('Mocked Summary!'); + expect((compressedPrompt.semanticParts[0] as unknown as import("../pipeline.js").ContextWorkingBuffer).text).toBe('Mocked Summary!'); // 2. Agent Thought const compressedThought = result[1] as AgentThought; expect(compressedThought.id).toMatch(/^mock-uuid-/); @@ -78,7 +78,7 @@ describe('NodeDistillationProcessor', () => { }; const env = createMockEnvironment({ - llmClient: mockLlmClient as any, + llmClient: mockLlmClient as unknown as import("../pipeline.js").ContextWorkingBuffer, }); const processor = NodeDistillationProcessor.create(env, { @@ -99,9 +99,9 @@ describe('NodeDistillationProcessor', () => { const targets = [prompt, thought]; const result = await processor.process({ - buffer: {} as any, + buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, targets, - inbox: {} as any, + inbox: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, }); expect(result.length).toBe(2); diff --git a/packages/core/src/context/processors/nodeTruncationProcessor.test.ts b/packages/core/src/context/processors/nodeTruncationProcessor.test.ts index 1ca6d9d7d7..d2f98bb64e 100644 --- a/packages/core/src/context/processors/nodeTruncationProcessor.test.ts +++ b/packages/core/src/context/processors/nodeTruncationProcessor.test.ts @@ -15,7 +15,7 @@ import { ContextTokenCalculator } from '../utils/contextTokenCalculator.js'; describe('NodeTruncationProcessor', () => { it('should truncate nodes that exceed maxTokensPerNode', async () => { const env = createMockEnvironment(); - const mockTokenCalculator = new ContextTokenCalculator(1, env.behaviorRegistry) as any; + const mockTokenCalculator = new ContextTokenCalculator(1, env.behaviorRegistry) as unknown as import("../pipeline.js").ContextWorkingBuffer; mockTokenCalculator.tokensToChars = vi.fn().mockReturnValue(10); // Limit is 10 chars mockTokenCalculator.estimateTokensForString = vi.fn((text: string) => { @@ -24,7 +24,7 @@ describe('NodeTruncationProcessor', () => { }); mockTokenCalculator.estimateTokensForParts = vi.fn(() => 1); - (env as any).tokenCalculator = mockTokenCalculator; + (env as unknown as import("../pipeline.js").ContextWorkingBuffer).tokenCalculator = mockTokenCalculator; const processor = NodeTruncationProcessor.create(env, { maxTokensPerNode: 1, // Will equal 10 chars limit @@ -48,9 +48,9 @@ describe('NodeTruncationProcessor', () => { const targets = [prompt, thought, yieldNode]; const result = await processor.process({ - buffer: {} as any, + buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, targets, - inbox: {} as any, + inbox: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, }); expect(result.length).toBe(3); @@ -60,7 +60,7 @@ describe('NodeTruncationProcessor', () => { expect(squashedPrompt.id).toBe('mock-uuid-1'); expect(squashedPrompt.id).not.toBe(prompt.id); expect(squashedPrompt.semanticParts[0].type).toBe('text'); - expect((squashedPrompt.semanticParts[0] as any).text).toContain('[... OMITTED'); + expect((squashedPrompt.semanticParts[0] as unknown as import("../pipeline.js").ContextWorkingBuffer).text).toContain('[... OMITTED'); // 2. Agent Thought const squashedThought = result[1] as AgentThought; @@ -77,14 +77,14 @@ describe('NodeTruncationProcessor', () => { it('should ignore nodes that are below maxTokensPerNode', async () => { const env = createMockEnvironment(); - const mockTokenCalculator = new ContextTokenCalculator(1, env.behaviorRegistry) as any; + const mockTokenCalculator = new ContextTokenCalculator(1, env.behaviorRegistry) as unknown as import("../pipeline.js").ContextWorkingBuffer; mockTokenCalculator.tokensToChars = vi.fn().mockReturnValue(100); mockTokenCalculator.estimateTokensForString = vi.fn((text: string) => text.length); mockTokenCalculator.estimateTokensForParts = vi.fn(() => 5); mockTokenCalculator.getTokenCost = vi.fn(() => 5); - (env as any).tokenCalculator = mockTokenCalculator; + (env as unknown as import("../pipeline.js").ContextWorkingBuffer).tokenCalculator = mockTokenCalculator; const processor = NodeTruncationProcessor.create(env, { maxTokensPerNode: 100, @@ -104,9 +104,9 @@ describe('NodeTruncationProcessor', () => { const targets = [prompt, thought]; const result = await processor.process({ - buffer: {} as any, + buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, targets, - inbox: {} as any, + inbox: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, }); expect(result.length).toBe(2); @@ -114,7 +114,7 @@ describe('NodeTruncationProcessor', () => { // 1. User Prompt (untouched) const squashedPrompt = result[0] as UserPrompt; expect(squashedPrompt.id).toBe(prompt.id); - expect((squashedPrompt.semanticParts[0] as any).text).not.toContain('[... OMITTED'); + expect((squashedPrompt.semanticParts[0] as unknown as import("../pipeline.js").ContextWorkingBuffer).text).not.toContain('[... OMITTED'); // 2. Agent Thought (untouched) const untouchedThought = result[1] as AgentThought; diff --git a/packages/core/src/context/processors/rollingSummaryProcessor.test.ts b/packages/core/src/context/processors/rollingSummaryProcessor.test.ts index e56a4bfc12..d8aae65b0e 100644 --- a/packages/core/src/context/processors/rollingSummaryProcessor.test.ts +++ b/packages/core/src/context/processors/rollingSummaryProcessor.test.ts @@ -32,7 +32,7 @@ describe('RollingSummaryProcessor', () => { createDummyNode('ep1', 'AGENT_YIELD', 50, { text: text50 }, 'id3'), ]; - const result = await processor.process({ targets, buffer: {} as any, inbox: {} as any }); + const result = await processor.process({ targets, buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, inbox: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer }); // 3 nodes at 50 cost each. // The first node (id1) is the initial USER_PROMPT and is always skipped by RollingSummaryProcessor. @@ -58,7 +58,7 @@ describe('RollingSummaryProcessor', () => { createDummyNode('ep1', 'AGENT_THOUGHT', 10, { text: text10 }, 'id2'), ]; - const result = await processor.process({ targets, buffer: {} as any, inbox: {} as any }); + const result = await processor.process({ targets, buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, inbox: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer }); // Deficit accumulator reaches 10. This is < 100 limit, and total summarizable nodes < 2 anyway. expect(result.length).toBe(2); diff --git a/packages/core/src/context/processors/stateSnapshotProcessor.test.ts b/packages/core/src/context/processors/stateSnapshotProcessor.test.ts index 360e3283cc..d20d6e3e38 100644 --- a/packages/core/src/context/processors/stateSnapshotProcessor.test.ts +++ b/packages/core/src/context/processors/stateSnapshotProcessor.test.ts @@ -18,7 +18,7 @@ describe('StateSnapshotProcessor', () => { const targets = [createDummyNode('ep1', 'USER_PROMPT')]; const inbox = new InboxSnapshotImpl([]); - const result = await processor.process({ buffer: {} as any, targets, inbox }); + const result = await processor.process({ buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, targets, inbox }); expect(result).toBe(targets); // Strict equality }); @@ -46,7 +46,7 @@ describe('StateSnapshotProcessor', () => { } ]); - const result = await processor.process({ buffer: {} as any, targets, inbox }); + const result = await processor.process({ buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, targets, inbox }); // Should remove A and B, insert Snapshot, keep C expect(result.length).toBe(2); @@ -78,7 +78,7 @@ describe('StateSnapshotProcessor', () => { } ]); - const result = await processor.process({ buffer: {} as any, targets, inbox }); + const result = await processor.process({ buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, targets, inbox }); // Because deficit is 0, and Inbox was rejected, nothing should change expect(result.length).toBe(1); @@ -96,7 +96,7 @@ describe('StateSnapshotProcessor', () => { const targets = [nodeA, nodeB, nodeC]; const inbox = new InboxSnapshotImpl([]); - const result = await processor.process({ buffer: {} as any, targets, inbox }); + const result = await processor.process({ buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, targets, inbox }); // Should synthesize a new snapshot synchronously expect(env.llmClient.generateContent).toHaveBeenCalled(); diff --git a/packages/core/src/context/processors/toolMaskingProcessor.test.ts b/packages/core/src/context/processors/toolMaskingProcessor.test.ts index d93df4d784..6c892afa00 100644 --- a/packages/core/src/context/processors/toolMaskingProcessor.test.ts +++ b/packages/core/src/context/processors/toolMaskingProcessor.test.ts @@ -31,9 +31,9 @@ describe('ToolMaskingProcessor', () => { }); const result = await processor.process({ - buffer: {} as any, + buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, targets: [toolStep], - inbox: {} as any, + inbox: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, }); expect(result.length).toBe(1); @@ -43,7 +43,7 @@ describe('ToolMaskingProcessor', () => { expect(masked.id).not.toBe(toolStep.id); // It should have masked the observation - const obs = (masked as any).observation; + const obs = (masked as unknown as import("../pipeline.js").ContextWorkingBuffer).observation; expect(obs.result).toContain(''); expect(obs.metadata).toBe('short'); // Untouched @@ -66,9 +66,9 @@ describe('ToolMaskingProcessor', () => { }); const result = await processor.process({ - buffer: {} as any, + buffer: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, targets: [toolStep], - inbox: {} as any, + inbox: undefined as unknown as import('../pipeline.js').ContextWorkingBuffer, }); // Returned the exact same object reference diff --git a/packages/core/src/context/processors/toolMaskingProcessor.ts b/packages/core/src/context/processors/toolMaskingProcessor.ts index 35beab768d..924526ad5f 100644 --- a/packages/core/src/context/processors/toolMaskingProcessor.ts +++ b/packages/core/src/context/processors/toolMaskingProcessor.ts @@ -14,6 +14,7 @@ import { ENTER_PLAN_MODE_TOOL_NAME, EXIT_PLAN_MODE_TOOL_NAME, } from '../../tools/tool-names.js'; +import type { Part } from '@google/genai'; const UNMASKABLE_TOOLS = new Set([ ACTIVATE_SKILL_TOOL_NAME, @@ -229,7 +230,7 @@ export class ToolMaskingProcessor implements ContextProcessor { }, ]); - let obsPart: any = {}; + let obsPart: Record = {}; if (maskedObs) { obsPart = { functionResponse: { @@ -240,7 +241,7 @@ export class ToolMaskingProcessor implements ContextProcessor { }; } - const newObsTokens = this.env.tokenCalculator.estimateTokensForParts([obsPart]); + const newObsTokens = this.env.tokenCalculator.estimateTokensForParts([obsPart as Part]); const tokensSaved = this.env.tokenCalculator.getTokenCost(node) - diff --git a/packages/core/src/context/sidecar/inbox.ts b/packages/core/src/context/sidecar/inbox.ts index df42a45bae..cdd40ee17f 100644 --- a/packages/core/src/context/sidecar/inbox.ts +++ b/packages/core/src/context/sidecar/inbox.ts @@ -35,7 +35,9 @@ export class InboxSnapshotImpl implements InboxSnapshot { } getMessages(topic: string): ReadonlyArray> { - return this.messages.filter((m) => m.topic === topic) as ReadonlyArray>; + const raw = this.messages.filter((m) => m.topic === topic); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + return raw as ReadonlyArray>; } consume(messageId: string): void { diff --git a/packages/core/src/context/sidecar/orchestrator.test.ts b/packages/core/src/context/sidecar/orchestrator.test.ts index cf13efa8ed..8e24446242 100644 --- a/packages/core/src/context/sidecar/orchestrator.test.ts +++ b/packages/core/src/context/sidecar/orchestrator.test.ts @@ -25,10 +25,10 @@ class DummySyncProcessor implements ContextProcessor { readonly name = 'DummySync'; readonly id = 'DummySync'; readonly options = {}; - async process(args: any) { + async process(args: import('../pipeline.js').ProcessArgs) { const newTargets = [...args.targets]; if (newTargets.length > 0) { - newTargets[0] = { ...newTargets[0], dummyModified: true }; + newTargets[0] = { ...newTargets[0], dummyModified: true } as unknown as import('../ir/types.js').ConcreteNode; } return newTargets; } @@ -42,10 +42,10 @@ class DummyAsyncProcessor implements ContextProcessor { readonly name = 'DummyAsync'; readonly id = 'DummyAsync'; readonly options = {}; - async process(args: any) { + async process(args: import('../pipeline.js').ProcessArgs) { const newTargets = [...args.targets]; if (newTargets.length > 0) { - newTargets[0] = { ...newTargets[0], dummyModified: true }; + newTargets[0] = { ...newTargets[0], dummyModified: true } as unknown as import('../ir/types.js').ConcreteNode; } return newTargets; } @@ -59,7 +59,7 @@ class ThrowingProcessor implements ContextProcessor { readonly name = 'Throwing'; readonly id = 'Throwing'; readonly options = {}; - async process(): Promise { + async process(): Promise> { throw new Error('Processor failed intentionally'); } } diff --git a/packages/core/src/context/sidecar/registry.test.ts b/packages/core/src/context/sidecar/registry.test.ts index 3969ed66ca..a1d98094af 100644 --- a/packages/core/src/context/sidecar/registry.test.ts +++ b/packages/core/src/context/sidecar/registry.test.ts @@ -13,7 +13,7 @@ describe('SidecarRegistry', () => { const processorDef: ContextProcessorDef = { id: 'TestProcessor', schema: { type: 'object' }, - create: () => ({} as any), + create: () => ({} as unknown as import('../pipeline.js').ContextProcessor), }; registry.registerProcessor(processorDef); @@ -26,7 +26,7 @@ describe('SidecarRegistry', () => { const workerDef: ContextWorkerDef = { id: 'TestWorker', schema: { type: 'object' }, - create: () => ({} as any), + create: () => ({} as unknown as import('../pipeline.js').ContextProcessor), }; registry.registerWorker(workerDef); @@ -49,15 +49,15 @@ describe('SidecarRegistry', () => { registry.registerProcessor({ id: 'TestProcessor', schema: { title: 'processorSchema' }, - create: () => ({} as any), + create: () => ({} as unknown as import('../pipeline.js').ContextProcessor), }); registry.registerWorker({ id: 'TestWorker', schema: { title: 'workerSchema' }, - create: () => ({} as any), + create: () => ({} as unknown as import('../pipeline.js').ContextProcessor), }); - const schemas = registry.getSchemas() as any[]; + const schemas = registry.getSchemas() as unknown as Array>; expect(schemas.length).toBe(2); expect(schemas.find(s => s.title === 'processorSchema')).toBeDefined(); expect(schemas.find(s => s.title === 'workerSchema')).toBeDefined(); @@ -65,8 +65,8 @@ describe('SidecarRegistry', () => { it('should safely clear the registry', () => { const registry = new SidecarRegistry(); - registry.registerProcessor({ id: 'TestProcessor', schema: {}, create: () => ({} as any) }); - registry.registerWorker({ id: 'TestWorker', schema: {}, create: () => ({} as any) }); + registry.registerProcessor({ id: 'TestProcessor', schema: {}, create: () => ({} as unknown as import('../pipeline.js').ContextProcessor) }); + registry.registerWorker({ id: 'TestWorker', schema: {}, create: () => ({} as unknown as import('../pipeline.js').ContextProcessor) }); registry.clear(); diff --git a/packages/core/src/context/testing/contextTestUtils.ts b/packages/core/src/context/testing/contextTestUtils.ts index 6191c1d685..413b1168f8 100644 --- a/packages/core/src/context/testing/contextTestUtils.ts +++ b/packages/core/src/context/testing/contextTestUtils.ts @@ -29,6 +29,7 @@ import type { Content , GenerateContentResponse } from '@google/genai'; * Used to avoid having to manually construct the deeply nested candidate/content/part structure. */ export const createMockGenerateContentResponse = (text: string): GenerateContentResponse => + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ({ candidates: [{ content: { role: 'model', parts: [{ text }] }, index: 0 }], }) as GenerateContentResponse; @@ -46,7 +47,7 @@ export function createDummyNode( id: id || randomUUID(), episodeId: logicalParentId, logicalParentId, - type: type as any, + type, timestamp: Date.now(), text: `Dummy ${type}`, name: type === 'SYSTEM_EVENT' ? 'dummy_event' : undefined, @@ -94,9 +95,11 @@ export function createDummyToolNode( export function createMockEnvironment( overrides?: Partial, ): ContextEnvironment { - const llmClient = vi.fn().mockReturnValue({ + const mockClient: Partial = { generateContent: vi.fn().mockResolvedValue(createMockGenerateContentResponse('Mock LLM summary response')), - })() as unknown as BaseLlmClient; + }; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + const llmClient = mockClient as BaseLlmClient; const tracer = new ContextTracer({ targetDir: '/tmp', sessionId: 'mock-session' }); const eventBus = new ContextEventBus(); @@ -114,7 +117,10 @@ export function createMockEnvironment( new DeterministicIdGenerator('mock-uuid-') ); - return { ...env, ...overrides }; + if (overrides) { + Object.assign(env, overrides); + } + return env; } /**