feat: wire LogService into LLM layer for error/warning logging
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -65,7 +65,7 @@ export class GameLoop {
|
||||
this.runtimeConstants = createRuntimeConstants();
|
||||
this.world = new World();
|
||||
this.map = new GameMap();
|
||||
this.llmService = createLlmService();
|
||||
this.llmService = createLlmService(this.logService);
|
||||
this.narrationService = createNarrationService(this.llmService);
|
||||
this.eventMemoryService = createEventMemoryService();
|
||||
this.thoughtSystem = createThoughtSystem(this.llmService, this.narrationService, this.eventMemoryService);
|
||||
@@ -228,7 +228,7 @@ export class GameLoop {
|
||||
}
|
||||
|
||||
generateNpcBackstory(entityId: number): void {
|
||||
generateBackstoryAndDesires(this.world, entityId, this.llmService, this.tick);
|
||||
generateBackstoryAndDesires(this.world, entityId, this.llmService, this.tick, this.logService);
|
||||
}
|
||||
|
||||
private spawnInitialNPCs(count: number): void {
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { LlmService } from './llmService.js';
|
||||
import type { ItemRegistry } from '../industry/itemRegistry.js';
|
||||
import type { RecipeRegistry } from '../industry/recipeRegistry.js';
|
||||
import type { StructureData } from '../systems/buildingSystem.js';
|
||||
import type { LogService } from '../services/logService.js';
|
||||
|
||||
const STAT_KEYS: (keyof Stats)[] = [
|
||||
'strength', 'dexterity', 'constitution', 'intelligence', 'perception',
|
||||
@@ -87,6 +88,7 @@ export async function generateBackstoryAndDesires(
|
||||
entityId: number,
|
||||
llmService: LlmService,
|
||||
tick: number,
|
||||
logService?: LogService,
|
||||
): Promise<void> {
|
||||
const name = world.getComponent<string>(entityId, 'name');
|
||||
const stats = world.getComponent<Stats>(entityId, 'stats');
|
||||
@@ -109,6 +111,7 @@ export async function generateBackstoryAndDesires(
|
||||
parsed = JSON.parse(result);
|
||||
} catch {
|
||||
// JSON parse failed — use raw string as backstory fallback
|
||||
logService?.log('warning', 'LLM', `JSON parse failed for backstory (entity ${entityId}), using raw string`);
|
||||
world.addComponent<string>(entityId, 'backstory', result);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { createUsageCounters } from './usageCounters.js';
|
||||
import { renderTemplate } from './promptTemplate.js';
|
||||
import { templates } from './templates.js';
|
||||
import { createTokenTracker, type TokenTracker } from './tokenTracker.js';
|
||||
import type { LogService } from '../services/logService.js';
|
||||
|
||||
export interface LlmService {
|
||||
generate(templateName: string, variables: Record<string, string>): Promise<string | null>;
|
||||
@@ -17,7 +18,7 @@ export interface LlmService {
|
||||
tokenUsage(): TokenTracker;
|
||||
}
|
||||
|
||||
export function createLlmService(): LlmService {
|
||||
export function createLlmService(logService?: LogService): LlmService {
|
||||
const config = getLlmConfig();
|
||||
|
||||
if (!config.enabled || !config.model) {
|
||||
@@ -33,7 +34,7 @@ export function createLlmService(): LlmService {
|
||||
};
|
||||
}
|
||||
|
||||
const client = createOpenRouterClient(config);
|
||||
const client = createOpenRouterClient(config, logService);
|
||||
const queue = createGenerationQueue(client, {
|
||||
requestsPerMinute: config.requestsPerMinute,
|
||||
});
|
||||
@@ -56,6 +57,7 @@ export function createLlmService(): LlmService {
|
||||
|
||||
currentModel = config.fallbackModel;
|
||||
console.log(`[LLM] Switched to fallback model: ${currentModel}`);
|
||||
logService?.log('warning', 'LLM', `Switched to fallback model: ${currentModel}`);
|
||||
|
||||
const resetTime = resetAt ?? getNextMidnightUTC();
|
||||
const delay = Math.max(0, resetTime - Date.now());
|
||||
@@ -65,6 +67,7 @@ export function createLlmService(): LlmService {
|
||||
currentModel = config.model;
|
||||
switchBackTimer = null;
|
||||
console.log(`[LLM] Switched back to primary model: ${currentModel}`);
|
||||
logService?.log('info', 'LLM', `Switched back to primary model: ${currentModel}`);
|
||||
}, delay);
|
||||
}
|
||||
|
||||
@@ -82,6 +85,7 @@ export function createLlmService(): LlmService {
|
||||
const result = await queue.enqueue({ ...rendered, model: currentModel });
|
||||
|
||||
if (isRateLimited(result)) {
|
||||
logService?.log('warning', 'LLM', 'Rate limited, switching to fallback');
|
||||
switchToFallback(result.resetAt);
|
||||
return null;
|
||||
}
|
||||
@@ -95,6 +99,7 @@ export function createLlmService(): LlmService {
|
||||
const totalRequests = Object.values(counters.getStats()).reduce((sum, s) => sum + s.total, 0);
|
||||
if (totalRequests % 100 === 0) {
|
||||
console.log(`[LLM] ${counters.getSummary()}`);
|
||||
logService?.log('info', 'LLM', counters.getSummary());
|
||||
}
|
||||
return result.content;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { LlmConfig } from '../config/llmConfig.js';
|
||||
import type { RenderedPrompt } from './promptTemplate.js';
|
||||
import type { LogService } from '../services/logService.js';
|
||||
|
||||
const OPENROUTER_URL = 'https://openrouter.ai/api/v1/chat/completions';
|
||||
|
||||
@@ -38,7 +39,7 @@ export interface OpenRouterClient {
|
||||
complete(request: CompletionRequest): Promise<CompletionResult>;
|
||||
}
|
||||
|
||||
export function createOpenRouterClient(config: LlmConfig): OpenRouterClient {
|
||||
export function createOpenRouterClient(config: LlmConfig, logService?: LogService): OpenRouterClient {
|
||||
return {
|
||||
async complete(request: CompletionRequest): Promise<CompletionResult> {
|
||||
try {
|
||||
@@ -72,6 +73,7 @@ export function createOpenRouterClient(config: LlmConfig): OpenRouterClient {
|
||||
}
|
||||
}
|
||||
console.warn(`OpenRouter API error: ${response.status} ${response.statusText}`);
|
||||
logService?.log('error', 'LLM', `OpenRouter API error: ${response.status} ${response.statusText}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -88,6 +90,7 @@ export function createOpenRouterClient(config: LlmConfig): OpenRouterClient {
|
||||
};
|
||||
} catch (error) {
|
||||
console.warn('OpenRouter request failed:', (error as Error).message);
|
||||
logService?.log('error', 'LLM', `OpenRouter request failed: ${(error as Error).message}`);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user