From 1acfc78e13abae5bbe77643ec7c043733ed4eefc Mon Sep 17 00:00:00 2001 From: root Date: Mon, 9 Mar 2026 16:03:09 +0000 Subject: [PATCH] refactor(llm): remove isDailyLimitReached from downstream consumers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LlmService interface no longer exposes isDailyLimitReached — model switching is handled internally. Remove all checks in thoughtSystem, inventionSystem, narrationService, and thoughtGenerator. Update mocks in test files to match the new interface and remove obsolete daily-limit test cases. Co-Authored-By: Claude Opus 4.6 --- .../src/llm/__tests__/narrationService.test.ts | 12 +++--------- .../src/llm/__tests__/thoughtGenerator.test.ts | 17 +++-------------- server/src/llm/narrationService.ts | 3 +-- server/src/llm/thoughtGenerator.ts | 1 - .../__tests__/inventionIntegration.test.ts | 4 +++- .../systems/__tests__/inventionSystem.test.ts | 16 +++------------- .../src/systems/__tests__/thoughtSystem.test.ts | 16 +++------------- server/src/systems/inventionSystem.ts | 3 --- server/src/systems/thoughtSystem.ts | 1 - 9 files changed, 16 insertions(+), 57 deletions(-) diff --git a/server/src/llm/__tests__/narrationService.test.ts b/server/src/llm/__tests__/narrationService.test.ts index 7dbd415..478798a 100644 --- a/server/src/llm/__tests__/narrationService.test.ts +++ b/server/src/llm/__tests__/narrationService.test.ts @@ -9,7 +9,9 @@ function mockLlmService(overrides: Partial = {}): LlmService { generate: vi.fn().mockResolvedValue('LLM narration text'), queueDepth: vi.fn().mockReturnValue(0), clear: vi.fn(), - isDailyLimitReached: vi.fn().mockReturnValue(false), + activeModel: vi.fn().mockReturnValue('test-model'), + usageStats: vi.fn().mockReturnValue({}), + usageSummary: vi.fn().mockReturnValue(''), ...overrides, }; } @@ -90,14 +92,6 @@ describe('NarrationService', () => { expect(llm.generate).not.toHaveBeenCalled(); }); - it('does not queue LLM when daily limit is reached', () => { - llm = mockLlmService({ isDailyLimitReached: vi.fn().mockReturnValue(true) }); - const service = createNarrationService(llm); - service.recordInteraction(makeRecord({ isPriority: true })); - - expect(llm.generate).not.toHaveBeenCalled(); - }); - it('rolling buffer caps at 50', () => { const service = createNarrationService(llm); for (let i = 0; i < 55; i++) { diff --git a/server/src/llm/__tests__/thoughtGenerator.test.ts b/server/src/llm/__tests__/thoughtGenerator.test.ts index 6dc1522..d66f1b4 100644 --- a/server/src/llm/__tests__/thoughtGenerator.test.ts +++ b/server/src/llm/__tests__/thoughtGenerator.test.ts @@ -7,7 +7,9 @@ function mockLlmService(overrides: Partial = {}): LlmService { generate: vi.fn().mockResolvedValue(null), queueDepth: vi.fn().mockReturnValue(0), clear: vi.fn(), - isDailyLimitReached: vi.fn().mockReturnValue(false), + activeModel: vi.fn().mockReturnValue('test-model'), + usageStats: vi.fn().mockReturnValue({}), + usageSummary: vi.fn().mockReturnValue(''), ...overrides, }; } @@ -98,17 +100,4 @@ describe('generateBatchedThoughts', () => { expect(result).toEqual([]); }); - it('returns empty array when daily limit reached', async () => { - const llm = mockLlmService({ - isDailyLimitReached: vi.fn().mockReturnValue(true), - }); - - const requests: ThoughtRequest[] = [ - { entityId: 1, name: 'A', personality: '', currentState: '', recentEvents: '' }, - ]; - - const result = await generateBatchedThoughts(requests, llm); - expect(result).toEqual([]); - expect(llm.generate).not.toHaveBeenCalled(); - }); }); diff --git a/server/src/llm/narrationService.ts b/server/src/llm/narrationService.ts index 424a60a..700ba18 100644 --- a/server/src/llm/narrationService.ts +++ b/server/src/llm/narrationService.ts @@ -62,8 +62,7 @@ export function createNarrationService(llmService: LlmService): NarrationService if (persistFn) persistFn(event); service.onEventCreated?.(event); - const shouldQueueLlm = - (record.isProposal || record.isPriority) && !llmService.isDailyLimitReached(); + const shouldQueueLlm = record.isProposal || record.isPriority; if (shouldQueueLlm) { const variables: Record = { diff --git a/server/src/llm/thoughtGenerator.ts b/server/src/llm/thoughtGenerator.ts index 5a5a64a..5eed575 100644 --- a/server/src/llm/thoughtGenerator.ts +++ b/server/src/llm/thoughtGenerator.ts @@ -19,7 +19,6 @@ export async function generateBatchedThoughts( llmService: LlmService, ): Promise { if (requests.length === 0) return []; - if (llmService.isDailyLimitReached()) return []; const npcList = requests .map((r, i) => diff --git a/server/src/systems/__tests__/inventionIntegration.test.ts b/server/src/systems/__tests__/inventionIntegration.test.ts index db83d9d..03d8240 100644 --- a/server/src/systems/__tests__/inventionIntegration.test.ts +++ b/server/src/systems/__tests__/inventionIntegration.test.ts @@ -41,7 +41,9 @@ describe('invention integration', () => { generate: generateMock, queueDepth: () => 0, clear: () => {}, - isDailyLimitReached: () => false, + activeModel: () => 'test-model', + usageStats: () => ({}), + usageSummary: () => '', }; const narrationEvents: any[] = []; diff --git a/server/src/systems/__tests__/inventionSystem.test.ts b/server/src/systems/__tests__/inventionSystem.test.ts index 14434da..250ca88 100644 --- a/server/src/systems/__tests__/inventionSystem.test.ts +++ b/server/src/systems/__tests__/inventionSystem.test.ts @@ -14,7 +14,9 @@ function createMockLlm(): LlmService { generate: vi.fn().mockResolvedValue(null), queueDepth: () => 0, clear: () => {}, - isDailyLimitReached: () => false, + activeModel: () => 'test-model', + usageStats: () => ({}), + usageSummary: () => '', }; } @@ -154,16 +156,4 @@ describe('inventionSystem', () => { expect(itemRegistry.getAll().length).toBe(5); }); - it('skips when daily LLM limit reached', () => { - const { world } = setupWorld(); - addNPC(world, { inv: new Map([['log', 5]]) }); - const llm = createMockLlm(); - (llm as any).isDailyLimitReached = () => true; - const system = createInventionSystem(llm, createMockNarration(), createEventMemoryService()); - - vi.spyOn(Math, 'random').mockReturnValue(0); - system.update(world, 100); - expect(llm.generate).not.toHaveBeenCalled(); - vi.restoreAllMocks(); - }); }); diff --git a/server/src/systems/__tests__/thoughtSystem.test.ts b/server/src/systems/__tests__/thoughtSystem.test.ts index ef999e8..afb1488 100644 --- a/server/src/systems/__tests__/thoughtSystem.test.ts +++ b/server/src/systems/__tests__/thoughtSystem.test.ts @@ -9,7 +9,9 @@ function mockLlmService(overrides: Partial = {}): LlmService { generate: vi.fn().mockResolvedValue(null), queueDepth: vi.fn().mockReturnValue(0), clear: vi.fn(), - isDailyLimitReached: vi.fn().mockReturnValue(false), + activeModel: vi.fn().mockReturnValue('test-model'), + usageStats: vi.fn().mockReturnValue({}), + usageSummary: vi.fn().mockReturnValue(''), ...overrides, }; } @@ -118,16 +120,4 @@ describe('ThoughtSystem', () => { expect(llm.generate).toHaveBeenCalledOnce(); // still just once — cooldown not expired yet }); - it('does not generate when daily limit reached', () => { - llm = mockLlmService({ - isDailyLimitReached: vi.fn().mockReturnValue(true), - }); - - const system = createThoughtSystem(llm); - const e = makeNpc(world, 'Bjorn'); - followedIds.add(e); - - system.update(world, followedIds, 900); - expect(llm.generate).not.toHaveBeenCalled(); - }); }); diff --git a/server/src/systems/inventionSystem.ts b/server/src/systems/inventionSystem.ts index b1e24e8..06165ec 100644 --- a/server/src/systems/inventionSystem.ts +++ b/server/src/systems/inventionSystem.ts @@ -31,9 +31,6 @@ export function createInventionSystem( // Only check on interval ticks if (tick % industryConfig.inventionCheckInterval !== 0) return; - // Skip if daily limit reached - if (llmService.isDailyLimitReached()) return; - const itemRegistry = world.getSingleton('itemRegistry'); const recipeRegistry = world.getSingleton('recipeRegistry'); const timeline = world.getSingleton('inventionTimeline'); diff --git a/server/src/systems/thoughtSystem.ts b/server/src/systems/thoughtSystem.ts index 5a01791..918ae7a 100644 --- a/server/src/systems/thoughtSystem.ts +++ b/server/src/systems/thoughtSystem.ts @@ -36,7 +36,6 @@ export function createThoughtSystem( lastPeriodicTick = tick; if (pendingGeneration) return; - if (llmService.isDailyLimitReached()) return; const eligible: { entityId: EntityId; context: ThoughtContext }[] = []; const npcs = world.query('npcBrain', 'name', 'stats', 'needs');