chore: useLogger

This commit is contained in:
RainbowBird
2025-02-07 01:55:41 +08:00
parent 63643b9832
commit fdb1bd1b00
28 changed files with 86 additions and 76 deletions
@@ -3,15 +3,15 @@ import type { Message } from 'neuri/openai'
import type { Mineflayer } from '../../libs/mineflayer'
import type { PlanStep } from '../planning/adapter'
import { useLogg } from '@guiiai/logg'
import { agent } from 'neuri'
import { system, user } from 'neuri/openai'
import { BaseLLMHandler } from '../../libs/llm-agent/handler'
import { useLogger } from '../../utils/logger'
import { actionsList } from './tools'
export async function createActionNeuriAgent(mineflayer: Mineflayer): Promise<Agent> {
const logger = useLogg('action-neuri').useGlobalConfig()
const logger = useLogger()
logger.log('Initializing action agent')
let actionAgent = agent('action')
@@ -1,6 +1,5 @@
import type { Action } from '../../libs/mineflayer'
import { useLogg } from '@guiiai/logg'
import { z } from 'zod'
import * as skills from '../../skills'
@@ -8,10 +7,10 @@ import { collectBlock } from '../../skills/actions/collect-block'
import { discard, equip, putInChest, takeFromChest, viewChest } from '../../skills/actions/inventory'
import { activateNearestBlock, placeBlock } from '../../skills/actions/world-interactions'
import * as world from '../../skills/world'
import { useLogger } from '../../utils/logger'
// Utils
const pad = (str: string): string => `\n${str}\n`
const logger = useLogg('actions').useGlobalConfig()
function formatInventoryItem(item: string, count: number): string {
return count > 0 ? `\n- ${item}: ${count}` : ''
@@ -59,7 +58,7 @@ export const actionsList: Action[] = [
schema: z.object({}),
perform: mineflayer => (): string => {
const blocks = world.getNearbyBlockTypes(mineflayer)
logger.withFields({ blocks }).log('nearbyBlocks')
useLogger().withFields({ blocks }).log('nearbyBlocks')
return pad(`NEARBY_BLOCKS${blocks.map((b: string) => `\n- ${b}`).join('') || ': none'}`)
},
},
+2 -3
View File
@@ -1,16 +1,14 @@
import type { Agent, Neuri } from 'neuri'
import type { ChatHistory } from './types'
import { useLogg } from '@guiiai/logg'
import { agent } from 'neuri'
import { system, user } from 'neuri/openai'
import { config as appConfig } from '../../composables/config'
import { toRetriable } from '../../utils/helper'
import { useLogger } from '../../utils/logger'
import { generateChatAgentPrompt } from './adapter'
const logger = useLogg('chat-llm').useGlobalConfig()
interface LLMChatConfig {
agent: Neuri
model?: string
@@ -31,6 +29,7 @@ export async function generateChatResponse(
const systemPrompt = generateChatAgentPrompt()
const chatHistory = formatChatHistory(history, config.maxContextLength ?? 10)
const userPrompt = message
const logger = useLogger()
const messages = [
system(systemPrompt),
+9 -10
View File
@@ -2,11 +2,8 @@ import type { Message } from 'neuri/openai'
import type { Action } from '../../libs/mineflayer'
import type { AgentConfig, MemoryAgent } from '../../libs/mineflayer/base-agent'
import { useLogg } from '@guiiai/logg'
import { Memory } from '../../libs/mineflayer/memory'
const logger = useLogg('memory-agent').useGlobalConfig()
import { type Logger, useLogger } from '../../utils/logger'
export class MemoryAgentImpl implements MemoryAgent {
public readonly type = 'memory' as const
@@ -14,12 +11,14 @@ export class MemoryAgentImpl implements MemoryAgent {
private memory: Map<string, unknown>
private initialized: boolean
private memoryInstance: Memory
private logger: Logger
constructor(config: AgentConfig) {
this.id = config.id
this.memory = new Map()
this.initialized = false
this.memoryInstance = new Memory()
this.logger = useLogger()
}
async init(): Promise<void> {
@@ -27,7 +26,7 @@ export class MemoryAgentImpl implements MemoryAgent {
return
}
logger.log('Initializing memory agent')
this.logger.log('Initializing memory agent')
this.initialized = true
}
@@ -41,7 +40,7 @@ export class MemoryAgentImpl implements MemoryAgent {
throw new Error('Memory agent not initialized')
}
logger.withFields({ key, value }).log('Storing memory')
this.logger.withFields({ key, value }).log('Storing memory')
this.memory.set(key, value)
}
@@ -51,7 +50,7 @@ export class MemoryAgentImpl implements MemoryAgent {
}
const value = this.memory.get(key) as T | undefined
logger.withFields({ key, value }).log('Recalling memory')
this.logger.withFields({ key, value }).log('Recalling memory')
return value
}
@@ -60,7 +59,7 @@ export class MemoryAgentImpl implements MemoryAgent {
throw new Error('Memory agent not initialized')
}
logger.withFields({ key }).log('Forgetting memory')
this.logger.withFields({ key }).log('Forgetting memory')
this.memory.delete(key)
}
@@ -78,7 +77,7 @@ export class MemoryAgentImpl implements MemoryAgent {
}
this.memoryInstance.chatHistory.push(message)
logger.withFields({ message }).log('Adding chat message to memory')
this.logger.withFields({ message }).log('Adding chat message to memory')
}
addAction(action: Action): void {
@@ -87,7 +86,7 @@ export class MemoryAgentImpl implements MemoryAgent {
}
this.memoryInstance.actions.push(action)
logger.withFields({ action }).log('Adding action to memory')
this.logger.withFields({ action }).log('Adding action to memory')
}
getChatHistory(): Message[] {
+3 -2
View File
@@ -1,9 +1,10 @@
import type { BotOptions } from 'mineflayer'
import { env } from 'node:process'
import { useLogg } from '@guiiai/logg'
const logger = useLogg('config').useGlobalConfig()
import { useLogger } from '../utils/logger'
const logger = useLogger()
// Configuration interfaces
interface OpenAIConfig {
+2 -4
View File
@@ -1,21 +1,19 @@
import type { Agent, Neuri } from 'neuri'
import type { Mineflayer } from '../libs/mineflayer'
import { useLogg } from '@guiiai/logg'
import { neuri } from 'neuri'
import { createActionNeuriAgent } from '../agents/action/adapter'
import { createChatNeuriAgent } from '../agents/chat/llm'
import { createPlanningNeuriAgent } from '../agents/planning/adapter'
import { useLogger } from '../utils/logger'
import { config } from './config'
let neuriAgent: Neuri | undefined
const agents = new Set<Agent | Promise<Agent>>()
const logger = useLogg('neuri').useGlobalConfig()
export async function createNeuriAgent(mineflayer: Mineflayer): Promise<Neuri> {
logger.log('Initializing neuri agent')
useLogger().log('Initializing neuri agent')
let n = neuri()
agents.add(createPlanningNeuriAgent())
@@ -1,5 +1,5 @@
import type { useLogg } from '@guiiai/logg'
import type { Neuri, NeuriContext } from 'neuri'
import type { Logger } from '../../utils/logger'
import type { MineflayerWithAgents } from './types'
import { system, user } from 'neuri/openai'
@@ -8,7 +8,7 @@ import { toRetriable } from '../../utils/helper'
import { handleLLMCompletion } from './completion'
import { generateStatusPrompt } from './prompt'
export async function handleChatMessage(username: string, message: string, bot: MineflayerWithAgents, agent: Neuri, logger: ReturnType<typeof useLogg>): Promise<void> {
export async function handleChatMessage(username: string, message: string, bot: MineflayerWithAgents, agent: Neuri, logger: Logger): Promise<void> {
logger.withFields({ username, message }).log('Chat message received')
bot.memory.chatHistory.push(user(`${username}: ${message}`))
@@ -1,13 +1,13 @@
import type { useLogg } from '@guiiai/logg'
import type { NeuriContext } from 'neuri'
import type { ChatCompletion } from 'neuri/openai'
import type { Logger } from '../../utils/logger'
import type { MineflayerWithAgents } from './types'
import { assistant } from 'neuri/openai'
import { config } from '../../composables/config'
export async function handleLLMCompletion(context: NeuriContext, bot: MineflayerWithAgents, logger: ReturnType<typeof useLogg>): Promise<string> {
export async function handleLLMCompletion(context: NeuriContext, bot: MineflayerWithAgents, logger: Logger): Promise<string> {
logger.log('rerouting...')
const completion = await context.reroute('action', context.messages, {
@@ -1,4 +1,5 @@
import type { Neuri } from 'neuri'
import type { Logger } from '../../utils/logger'
import { useLogg } from '@guiiai/logg'
import { asClass, asFunction, createContainer, InjectionMode } from 'awilix'
@@ -8,7 +9,7 @@ import { ChatAgentImpl } from '../../agents/chat'
import { PlanningAgentImpl } from '../../agents/planning'
export interface ContainerServices {
logger: ReturnType<typeof useLogg>
logger: Logger
actionAgent: ActionAgentImpl
planningAgent: PlanningAgentImpl
chatAgent: ChatAgentImpl
@@ -27,7 +28,7 @@ export function createAgentContainer(options: {
// Register services
container.register({
// Create independent logger for each agent
logger: asFunction(() => useLogg('app').useGlobalConfig()).singleton(),
logger: asFunction(() => useLogg('agent').useGlobalConfig()).singleton(),
// Register neuri client
neuri: asFunction(() => options.neuri).singleton(),
@@ -2,15 +2,16 @@ import type { NeuriContext } from 'neuri'
import type { ChatCompletion, Message } from 'neuri/openai'
import type { LLMConfig, LLMResponse } from './types'
import { useLogg } from '@guiiai/logg'
import { config } from '../../composables/config'
import { toRetriable } from '../../utils/helper'
import { type Logger, useLogger } from '../../utils/logger'
export abstract class BaseLLMHandler {
protected logger = useLogg('llm-handler').useGlobalConfig()
protected logger: Logger
constructor(protected config: LLMConfig) {}
constructor(protected config: LLMConfig) {
this.logger = useLogger()
}
protected async handleCompletion(
context: NeuriContext,
@@ -1,10 +1,10 @@
import type { MineflayerPlugin } from '../mineflayer'
import type { LLMAgentOptions, MineflayerWithAgents } from './types'
import { useLogg } from '@guiiai/logg'
import { system } from 'neuri/openai'
import { config } from '../../composables/config'
import { useLogger } from '../../utils/logger'
import { ChatMessageHandler } from '../mineflayer'
import { handleChatMessage } from './chat'
import { createAgentContainer } from './container'
@@ -14,7 +14,7 @@ import { handleVoiceInput } from './voice'
export function LLMAgent(options: LLMAgentOptions): MineflayerPlugin {
return {
async created(bot) {
const logger = useLogg('LLMAgent').useGlobalConfig()
const logger = useLogger()
// Create container and get required services
const container = createAgentContainer({
@@ -1,5 +1,5 @@
import type { useLogg } from '@guiiai/logg'
import type { Neuri, NeuriContext } from 'neuri'
import type { Logger } from '../../utils/logger'
import type { MineflayerWithAgents } from './types'
import { system, user } from 'neuri/openai'
@@ -8,7 +8,7 @@ import { toRetriable } from '../../utils/helper'
import { handleLLMCompletion } from './completion'
import { generateStatusPrompt } from './prompt'
export async function handleVoiceInput(event: any, bot: MineflayerWithAgents, agent: Neuri, logger: ReturnType<typeof useLogg>): Promise<void> {
export async function handleVoiceInput(event: any, bot: MineflayerWithAgents, agent: Neuri, logger: Logger): Promise<void> {
logger
.withFields({
user: event.data.discord?.guildMember,
@@ -1,4 +1,5 @@
import type { PlanStep } from '../../agents/planning/adapter'
import type { Logger } from '../../utils/logger'
import type { Action } from './action'
import { useLogg } from '@guiiai/logg'
@@ -59,7 +60,7 @@ export abstract class AbstractAgent extends EventEmitter3 implements BaseAgent {
public readonly name: string
protected initialized: boolean
protected logger: ReturnType<typeof useLogg>
protected logger: Logger
// protected actionManager: ReturnType<typeof useActionManager>
// protected conversationStore: ReturnType<typeof useConversationStore>
@@ -1,14 +1,14 @@
import type { Logg } from '@guiiai/logg'
import type { Handler } from './types'
import { useLogg } from '@guiiai/logg'
import { useLogger } from '../../utils/logger'
export class Components {
private components: Map<string, Handler> = new Map()
private logger: Logg
constructor() {
this.logger = useLogg('Components').useGlobalConfig()
this.logger = useLogger()
}
register(componentName: string, component: Handler) {
+2 -5
View File
@@ -1,5 +1,4 @@
import process, { exit } from 'node:process'
import { useLogg } from '@guiiai/logg'
import { Client } from '@proj-airi/server-sdk'
import MineflayerArmorManager from 'mineflayer-armor-manager'
import { loader as MineflayerAutoEat } from 'mineflayer-auto-eat'
@@ -13,9 +12,7 @@ import { config, initEnv } from './composables/config'
import { createNeuriAgent } from './composables/neuri'
import { LLMAgent } from './libs/llm-agent'
import { wrapPlugin } from './libs/mineflayer'
import { initLogger } from './utils/logger'
const logger = useLogg('main').useGlobalConfig()
import { initLogger, useLogger } from './utils/logger'
async function main() {
initLogger() // todo: save logs to file
@@ -50,6 +47,6 @@ async function main() {
}
main().catch((err: Error) => {
logger.errorWithError('Fatal error', err)
useLogger().errorWithError('Fatal error', err)
exit(1)
})
+2 -3
View File
@@ -1,11 +1,10 @@
import type { MineflayerPlugin } from '../libs/mineflayer/plugin'
import { useLogg } from '@guiiai/logg'
import { ChatMessageHandler } from '../libs/mineflayer/message'
import { useLogger } from '../utils/logger'
export function Echo(): MineflayerPlugin {
const logger = useLogg('Echo').useGlobalConfig()
const logger = useLogger()
return {
spawned(mineflayer) {
+3 -2
View File
@@ -1,10 +1,11 @@
import type { MineflayerPlugin } from '../libs/mineflayer/plugin'
import { useLogg } from '@guiiai/logg'
import pathfinderModel from 'mineflayer-pathfinder'
import { useLogger } from '../utils/logger'
export function FollowCommand(options?: { rangeGoal: number }): MineflayerPlugin {
const logger = useLogg('follow').useGlobalConfig()
const logger = useLogger()
const { goals, Movements } = pathfinderModel
return {
+3 -2
View File
@@ -1,15 +1,16 @@
import type { Context } from '../libs/mineflayer'
import type { MineflayerPlugin } from '../libs/mineflayer/plugin'
import { useLogg } from '@guiiai/logg'
import pathfinderModel from 'mineflayer-pathfinder'
import { useLogger } from '../utils/logger'
const { goals, Movements } = pathfinderModel
export function PathFinder(options?: { rangeGoal: number }): MineflayerPlugin {
return {
created(bot) {
const logger = useLogg('pathfinder').useGlobalConfig()
const logger = useLogger()
let defaultMove: any
+2 -2
View File
@@ -1,11 +1,11 @@
import type { MineflayerPlugin } from '../libs/mineflayer/plugin'
import { useLogg } from '@guiiai/logg'
import { useLogger } from '../utils/logger'
export function Status(): MineflayerPlugin {
return {
created(bot) {
const logger = useLogg('status').useGlobalConfig()
const logger = useLogger()
logger.log('Loading status component')
bot.onCommand('status', () => {
@@ -1,15 +1,15 @@
import type { Block } from 'prismarine-block'
import type { Mineflayer } from '../../libs/mineflayer'
import { useLogg } from '@guiiai/logg'
import pathfinder from 'mineflayer-pathfinder'
import { useLogger } from '../../utils/logger'
import { breakBlockAt } from '../blocks'
import { getNearestBlocks } from '../world'
import { ensurePickaxe } from './ensure'
import { pickupNearbyItems } from './world-interactions'
const logger = useLogg('Action:CollectBlock').useGlobalConfig()
const logger = useLogger()
function isMessagable(err: unknown): err is { message: string } {
return (err instanceof Error || (typeof err === 'object' && !!err && 'message' in err && typeof err.message === 'string'))
@@ -1,7 +1,6 @@
import type { Mineflayer } from '../../libs/mineflayer'
import { useLogg } from '@guiiai/logg'
import { useLogger } from '../../utils/logger'
import { getItemId } from '../../utils/mcdata'
import { craftRecipe } from '../crafting'
import { moveAway } from '../movement'
@@ -12,8 +11,7 @@ import { getItemCount } from './inventory'
// Constants for crafting and gathering
const PLANKS_PER_LOG = 4
const STICKS_PER_PLANK = 2
const logger = useLogg('Action:Ensure').useGlobalConfig()
const logger = useLogger()
// Helper function to ensure a crafting table
export async function ensureCraftingTable(mineflayer: Mineflayer): Promise<boolean> {
@@ -1,14 +1,13 @@
import type { Mineflayer } from '../../libs/mineflayer'
import { useLogg } from '@guiiai/logg'
import { sleep } from '../../utils/helper'
import { useLogger } from '../../utils/logger'
import { breakBlockAt } from '../blocks'
import { goToPosition, moveAway } from '../movement'
import { getNearestBlocks } from '../world'
import { pickupNearbyItems } from './world-interactions'
const logger = useLogg('Action:GatherWood').useGlobalConfig()
const logger = useLogger()
/**
* Gather wood blocks nearby to collect logs.
@@ -1,12 +1,11 @@
import type { Item } from 'prismarine-item'
import type { Mineflayer } from '../../libs/mineflayer'
import { useLogg } from '@guiiai/logg'
import { useLogger } from '../../utils/logger'
import { goToPlayer, goToPosition } from '../movement'
import { getNearestBlock } from '../world'
const logger = useLogg('Action:Inventory').useGlobalConfig()
const logger = useLogger()
/**
* Equip an item from the bot's inventory.
@@ -2,15 +2,15 @@ import type { Bot } from 'mineflayer'
import type { Block } from 'prismarine-block'
import type { Mineflayer } from '../../libs/mineflayer'
import { useLogg } from '@guiiai/logg'
import pathfinder from 'mineflayer-pathfinder'
import { Vec3 } from 'vec3'
import { sleep } from '../../utils/helper'
import { useLogger } from '../../utils/logger'
import { getNearestBlock, makeItem } from '../../utils/mcdata'
import { goToPosition } from '../movement'
const logger = useLogg('Action:WorldInteractions').useGlobalConfig()
const logger = useLogger()
export async function placeBlock(
mineflayer: Mineflayer,
+2 -2
View File
@@ -1,8 +1,8 @@
import type { Mineflayer } from '../libs/mineflayer'
import { useLogg } from '@guiiai/logg'
import { useLogger } from '../utils/logger'
const logger = useLogg('skills').useGlobalConfig()
const logger = useLogger()
/**
* Log a message to the context's output buffer
+2 -3
View File
@@ -3,15 +3,14 @@ import type { Item } from 'prismarine-item'
import type { Recipe } from 'prismarine-recipe'
import type { Mineflayer } from '../libs/mineflayer'
import { useLogg } from '@guiiai/logg'
import { useLogger } from '../utils/logger'
import { getItemId, getItemName } from '../utils/mcdata'
import { ensureCraftingTable } from './actions/ensure'
import { collectBlock, placeBlock } from './blocks'
import { goToNearestBlock, goToPosition, moveAway } from './movement'
import { getInventoryCounts, getNearestBlock, getNearestFreeSpace } from './world'
const logger = useLogg('Skill:Crafting').useGlobalConfig()
const logger = useLogger()
/*
Possible Scenarios:
+2 -2
View File
@@ -1,16 +1,16 @@
import type { Entity } from 'prismarine-entity'
import type { Mineflayer } from '../libs/mineflayer'
import { useLogg } from '@guiiai/logg'
import { randomInt } from 'es-toolkit'
import pathfinder from 'mineflayer-pathfinder'
import { Vec3 } from 'vec3'
import { sleep } from '../utils/helper'
import { useLogger } from '../utils/logger'
import { log } from './base'
import { getNearestBlock, getNearestEntityWhere } from './world'
const logger = useLogg('Skill:Movement').useGlobalConfig()
const logger = useLogger()
const { goals, Movements } = pathfinder
export async function goToPosition(
+18
View File
@@ -1,5 +1,7 @@
import { Format, LogLevel, setGlobalFormat, setGlobalLogLevel, useLogg } from '@guiiai/logg'
export type Logger = ReturnType<typeof useLogg>
export function initLogger() {
setGlobalLogLevel(LogLevel.Debug)
setGlobalFormat(Format.Pretty)
@@ -7,3 +9,19 @@ export function initLogger() {
const logger = useLogg('logger').useGlobalConfig()
logger.log('Logger initialized')
}
/**
* Get logger instance with directory name and filename
* @returns logger instance configured with "directoryName/filename"
*/
export function useLogger() {
const stack = new Error('logger').stack
const caller = stack?.split('\n')[2]
// Match the parent directory and filename without extension
const match = caller?.match(/\/([^/]+)\/([^/]+?)\.[jt]s/)
const dirName = match?.[1] || 'unknown'
const fileName = match?.[2] || 'unknown'
return useLogg(`${dirName}/${fileName}`).useGlobalConfig()
}