From 2631b4041b20091a402f83ee4dc3194edc0f9a32 Mon Sep 17 00:00:00 2001 From: RainbowBird Date: Fri, 7 Feb 2025 01:22:44 +0800 Subject: [PATCH] refactor: move prompt to self folders --- .../{llm-handler.test.ts => adapter.test.ts} | 0 .../action/{llm-handler.ts => adapter.ts} | 2 +- services/minecraft/src/agents/action/index.ts | 2 +- .../chat/{llm-handler.ts => adapter.ts} | 25 ++++++++- services/minecraft/src/agents/chat/llm.ts | 4 +- .../planning/{llm-handler.ts => adapter.ts} | 51 +++++++++++++++++-- .../minecraft/src/agents/planning/index.ts | 4 +- services/minecraft/src/agents/prompt/chat.ts | 21 -------- .../minecraft/src/agents/prompt/planning.ts | 47 ----------------- services/minecraft/src/composables/neuri.ts | 4 +- services/minecraft/src/libs/llm-agent/chat.ts | 4 +- .../src/libs/llm-agent/completion.ts | 2 +- .../minecraft/src/libs/llm-agent/index.ts | 4 +- .../llm-agent.ts => libs/llm-agent/prompt.ts} | 42 +++++++-------- services/minecraft/src/libs/llm-agent/type.ts | 15 ------ .../minecraft/src/libs/llm-agent/types.ts | 14 +++++ .../minecraft/src/libs/llm-agent/voice.ts | 4 +- .../src/libs/mineflayer/base-agent.ts | 2 +- 18 files changed, 122 insertions(+), 125 deletions(-) rename services/minecraft/src/agents/action/{llm-handler.test.ts => adapter.test.ts} (100%) rename services/minecraft/src/agents/action/{llm-handler.ts => adapter.ts} (98%) rename services/minecraft/src/agents/chat/{llm-handler.ts => adapter.ts} (61%) rename services/minecraft/src/agents/planning/{llm-handler.ts => adapter.ts} (67%) delete mode 100644 services/minecraft/src/agents/prompt/chat.ts delete mode 100644 services/minecraft/src/agents/prompt/planning.ts rename services/minecraft/src/{agents/prompt/llm-agent.ts => libs/llm-agent/prompt.ts} (96%) delete mode 100644 services/minecraft/src/libs/llm-agent/type.ts diff --git a/services/minecraft/src/agents/action/llm-handler.test.ts b/services/minecraft/src/agents/action/adapter.test.ts similarity index 100% rename from services/minecraft/src/agents/action/llm-handler.test.ts rename to services/minecraft/src/agents/action/adapter.test.ts diff --git a/services/minecraft/src/agents/action/llm-handler.ts b/services/minecraft/src/agents/action/adapter.ts similarity index 98% rename from services/minecraft/src/agents/action/llm-handler.ts rename to services/minecraft/src/agents/action/adapter.ts index a104eb04d..2d1f19916 100644 --- a/services/minecraft/src/agents/action/llm-handler.ts +++ b/services/minecraft/src/agents/action/adapter.ts @@ -1,7 +1,7 @@ import type { Agent } from 'neuri' import type { Message } from 'neuri/openai' import type { Mineflayer } from '../../libs/mineflayer' -import type { PlanStep } from '../planning/llm-handler' +import type { PlanStep } from '../planning/adapter' import { useLogg } from '@guiiai/logg' import { agent } from 'neuri' diff --git a/services/minecraft/src/agents/action/index.ts b/services/minecraft/src/agents/action/index.ts index 19109b000..6565a466d 100644 --- a/services/minecraft/src/agents/action/index.ts +++ b/services/minecraft/src/agents/action/index.ts @@ -1,7 +1,7 @@ import type { Mineflayer } from '../../libs/mineflayer' import type { Action } from '../../libs/mineflayer/action' import type { ActionAgent, AgentConfig } from '../../libs/mineflayer/base-agent' -import type { PlanStep } from '../planning/llm-handler' +import type { PlanStep } from '../planning/adapter' import { useBot } from '../../composables/bot' import { AbstractAgent } from '../../libs/mineflayer/base-agent' diff --git a/services/minecraft/src/agents/chat/llm-handler.ts b/services/minecraft/src/agents/chat/adapter.ts similarity index 61% rename from services/minecraft/src/agents/chat/llm-handler.ts rename to services/minecraft/src/agents/chat/adapter.ts index 2803c2938..bc03b45a9 100644 --- a/services/minecraft/src/agents/chat/llm-handler.ts +++ b/services/minecraft/src/agents/chat/adapter.ts @@ -3,14 +3,35 @@ import type { ChatHistory } from './types' import { system, user } from 'neuri/openai' import { BaseLLMHandler } from '../../libs/llm-agent/handler' -import { genChatAgentPrompt } from '../prompt/chat' + +export function generateChatAgentPrompt(): string { + return `You are a Minecraft bot assistant. Your task is to engage in natural conversation with players while helping them achieve their goals. + +Guidelines: +1. Be friendly and helpful +2. Keep responses concise but informative +3. Use game-appropriate language +4. Acknowledge player's emotions and intentions +5. Ask for clarification when needed +6. Remember context from previous messages +7. Be proactive in suggesting helpful actions + +You can: +- Answer questions about the game +- Help with tasks and crafting +- Give directions and suggestions +- Engage in casual conversation +- Coordinate with other bots + +Remember that you're operating in a Minecraft world and should maintain that context in your responses.` +} export class ChatLLMHandler extends BaseLLMHandler { public async generateResponse( message: string, history: ChatHistory[], ): Promise { - const systemPrompt = genChatAgentPrompt() + const systemPrompt = generateChatAgentPrompt() const chatHistory = this.formatChatHistory(history, this.config.maxContextLength ?? 10) const messages = [ system(systemPrompt), diff --git a/services/minecraft/src/agents/chat/llm.ts b/services/minecraft/src/agents/chat/llm.ts index 0d775790c..6b97f3b54 100644 --- a/services/minecraft/src/agents/chat/llm.ts +++ b/services/minecraft/src/agents/chat/llm.ts @@ -7,7 +7,7 @@ import { system, user } from 'neuri/openai' import { openaiConfig } from '../../composables/config' import { toRetriable } from '../../utils/helper' -import { genChatAgentPrompt } from '../prompt/chat' +import { generateChatAgentPrompt } from './adapter' const logger = useLogg('chat-llm').useGlobalConfig() @@ -28,7 +28,7 @@ export async function generateChatResponse( history: ChatHistory[], config: LLMChatConfig, ): Promise { - const systemPrompt = genChatAgentPrompt() + const systemPrompt = generateChatAgentPrompt() const chatHistory = formatChatHistory(history, config.maxContextLength ?? 10) const userPrompt = message diff --git a/services/minecraft/src/agents/planning/llm-handler.ts b/services/minecraft/src/agents/planning/adapter.ts similarity index 67% rename from services/minecraft/src/agents/planning/llm-handler.ts rename to services/minecraft/src/agents/planning/adapter.ts index 01be58d54..fd964a649 100644 --- a/services/minecraft/src/agents/planning/llm-handler.ts +++ b/services/minecraft/src/agents/planning/adapter.ts @@ -5,7 +5,6 @@ import { agent } from 'neuri' import { system, user } from 'neuri/openai' import { BaseLLMHandler } from '../../libs/llm-agent/handler' -import { generatePlanningAgentSystemPrompt, generatePlanningAgentUserPrompt } from '../prompt/planning' export async function createPlanningNeuriAgent(): Promise { return agent('planning').build() @@ -24,8 +23,8 @@ export class PlanningLLMHandler extends BaseLLMHandler { sender: string, feedback?: string, ): Promise { - const systemPrompt = generatePlanningAgentSystemPrompt(availableActions) - const userPrompt = generatePlanningAgentUserPrompt(goal, sender, feedback) + const systemPrompt = this.generatePlanningAgentSystemPrompt(availableActions) + const userPrompt = this.generatePlanningAgentUserPrompt(goal, sender, feedback) const messages = [system(systemPrompt), user(userPrompt)] const result = await this.config.agent.handleStateless(messages, async (context) => { @@ -98,4 +97,50 @@ export class PlanningLLMHandler extends BaseLLMHandler { } }) } + + private generatePlanningAgentSystemPrompt(availableActions: Action[]): string { + const actionsList = availableActions + .map((action) => { + const params = Object.keys(action.schema.shape) + .map(name => ` - ${name}`) + .join('\n') + return `- ${action.name}: ${action.description}\n Parameters:\n${params}` + }) + .join('\n\n') + + return `You are a Minecraft bot planner. Break down goals into simple action steps. + +Available tools: +${actionsList} + +Format each step as: +1. Action description (short, direct command) +2. Tool name +3. Required parameters + +Example: +1. Follow player + Tool: followPlayer + Params: + player: luoling8192 + follow_dist: 3 + +Keep steps: +- Short and direct +- Action-focused +- Parameters precise +- Generate all steps at once` + } + + private generatePlanningAgentUserPrompt(goal: string, sender: string, feedback?: string): string { + let prompt = `${sender}: ${goal} + +Generate minimal steps with exact parameters. +Use the sender's name (${sender}) for player-related parameters.` + + if (feedback) { + prompt += `\n\nPrevious attempt failed: ${feedback}` + } + return prompt + } } diff --git a/services/minecraft/src/agents/planning/index.ts b/services/minecraft/src/agents/planning/index.ts index 110e1ea19..274fd2f45 100644 --- a/services/minecraft/src/agents/planning/index.ts +++ b/services/minecraft/src/agents/planning/index.ts @@ -1,11 +1,11 @@ import type { Neuri } from 'neuri' import type { Action } from '../../libs/mineflayer/action' import type { ActionAgent, AgentConfig, MemoryAgent, Plan, PlanningAgent } from '../../libs/mineflayer/base-agent' -import type { PlanStep } from './llm-handler' +import type { PlanStep } from './adapter' import { AbstractAgent } from '../../libs/mineflayer/base-agent' import { ActionAgentImpl } from '../action' -import { PlanningLLMHandler } from './llm-handler' +import { PlanningLLMHandler } from './adapter' interface PlanContext { goal: string diff --git a/services/minecraft/src/agents/prompt/chat.ts b/services/minecraft/src/agents/prompt/chat.ts deleted file mode 100644 index a07f41c8b..000000000 --- a/services/minecraft/src/agents/prompt/chat.ts +++ /dev/null @@ -1,21 +0,0 @@ -export function genChatAgentPrompt(): string { - return `You are a Minecraft bot assistant. Your task is to engage in natural conversation with players while helping them achieve their goals. - -Guidelines: -1. Be friendly and helpful -2. Keep responses concise but informative -3. Use game-appropriate language -4. Acknowledge player's emotions and intentions -5. Ask for clarification when needed -6. Remember context from previous messages -7. Be proactive in suggesting helpful actions - -You can: -- Answer questions about the game -- Help with tasks and crafting -- Give directions and suggestions -- Engage in casual conversation -- Coordinate with other bots - -Remember that you're operating in a Minecraft world and should maintain that context in your responses.` -} diff --git a/services/minecraft/src/agents/prompt/planning.ts b/services/minecraft/src/agents/prompt/planning.ts deleted file mode 100644 index 87928c76e..000000000 --- a/services/minecraft/src/agents/prompt/planning.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { Action } from '../../libs/mineflayer/action' - -export function generatePlanningAgentSystemPrompt(availableActions: Action[]): string { - const actionsList = availableActions - .map((action) => { - const params = Object.keys(action.schema.shape) - .map(name => ` - ${name}`) - .join('\n') - return `- ${action.name}: ${action.description}\n Parameters:\n${params}` - }) - .join('\n\n') - - return `You are a Minecraft bot planner. Break down goals into simple action steps. - -Available tools: -${actionsList} - -Format each step as: -1. Action description (short, direct command) -2. Tool name -3. Required parameters - -Example: -1. Follow player - Tool: followPlayer - Params: - player: luoling8192 - follow_dist: 3 - -Keep steps: -- Short and direct -- Action-focused -- Parameters precise -- Generate all steps at once` -} - -export function generatePlanningAgentUserPrompt(goal: string, sender: string, feedback?: string): string { - let prompt = `${sender}: ${goal} - -Generate minimal steps with exact parameters. -Use the sender's name (${sender}) for player-related parameters.` - - if (feedback) { - prompt += `\n\nPrevious attempt failed: ${feedback}` - } - return prompt -} diff --git a/services/minecraft/src/composables/neuri.ts b/services/minecraft/src/composables/neuri.ts index 1c6216013..08ee32b6d 100644 --- a/services/minecraft/src/composables/neuri.ts +++ b/services/minecraft/src/composables/neuri.ts @@ -4,9 +4,9 @@ import type { Mineflayer } from '../libs/mineflayer' import { useLogg } from '@guiiai/logg' import { neuri } from 'neuri' -import { createActionNeuriAgent } from '../agents/action/llm-handler' +import { createActionNeuriAgent } from '../agents/action/adapter' import { createChatNeuriAgent } from '../agents/chat/llm' -import { createPlanningNeuriAgent } from '../agents/planning/llm-handler' +import { createPlanningNeuriAgent } from '../agents/planning/adapter' import { openaiConfig } from './config' let neuriAgent: Neuri | undefined diff --git a/services/minecraft/src/libs/llm-agent/chat.ts b/services/minecraft/src/libs/llm-agent/chat.ts index 08fc7a74a..48c638529 100644 --- a/services/minecraft/src/libs/llm-agent/chat.ts +++ b/services/minecraft/src/libs/llm-agent/chat.ts @@ -1,12 +1,12 @@ import type { useLogg } from '@guiiai/logg' import type { Neuri, NeuriContext } from 'neuri' -import type { MineflayerWithAgents } from './type' +import type { MineflayerWithAgents } from './types' import { system, user } from 'neuri/openai' -import { generateStatusPrompt } from '../../agents/prompt/llm-agent' 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): Promise { logger.withFields({ username, message }).log('Chat message received') diff --git a/services/minecraft/src/libs/llm-agent/completion.ts b/services/minecraft/src/libs/llm-agent/completion.ts index 12a621dca..084055b39 100644 --- a/services/minecraft/src/libs/llm-agent/completion.ts +++ b/services/minecraft/src/libs/llm-agent/completion.ts @@ -1,7 +1,7 @@ import type { useLogg } from '@guiiai/logg' import type { NeuriContext } from 'neuri' import type { ChatCompletion } from 'neuri/openai' -import type { MineflayerWithAgents } from './type' +import type { MineflayerWithAgents } from './types' import { assistant } from 'neuri/openai' diff --git a/services/minecraft/src/libs/llm-agent/index.ts b/services/minecraft/src/libs/llm-agent/index.ts index c2cabaa8b..150d7e7d6 100644 --- a/services/minecraft/src/libs/llm-agent/index.ts +++ b/services/minecraft/src/libs/llm-agent/index.ts @@ -1,14 +1,14 @@ import type { MineflayerPlugin } from '../mineflayer' -import type { LLMAgentOptions, MineflayerWithAgents } from './type' +import type { LLMAgentOptions, MineflayerWithAgents } from './types' import { useLogg } from '@guiiai/logg' import { system } from 'neuri/openai' -import { generateActionAgentPrompt } from '../../agents/prompt/llm-agent' import { openaiConfig } from '../../composables/config' import { createAppContainer } from '../../container' import { ChatMessageHandler } from '../mineflayer' import { handleChatMessage } from './chat' +import { generateActionAgentPrompt } from './prompt' import { handleVoiceInput } from './voice' export function LLMAgent(options: LLMAgentOptions): MineflayerPlugin { diff --git a/services/minecraft/src/agents/prompt/llm-agent.ts b/services/minecraft/src/libs/llm-agent/prompt.ts similarity index 96% rename from services/minecraft/src/agents/prompt/llm-agent.ts rename to services/minecraft/src/libs/llm-agent/prompt.ts index 273e74d6e..61591b7a4 100644 --- a/services/minecraft/src/agents/prompt/llm-agent.ts +++ b/services/minecraft/src/libs/llm-agent/prompt.ts @@ -1,27 +1,7 @@ -import type { Mineflayer } from '../../libs/mineflayer' +import type { Mineflayer } from '../mineflayer' import { listInventory } from '../../skills/actions/inventory' -export function generateSystemBasicPrompt(botName: string): string { - // ${ctx.prompt.selfPrompt} - return `You are a playful Minecraft bot named ${botName} that can converse with players, see, move, -mine, build, and interact with the world by using commands.` -} - -export function generateActionAgentPrompt(mineflayer: Mineflayer): string { - return `${generateSystemBasicPrompt(mineflayer.username)} - -Act human-like as if you were a typical Minecraft player, rather than an AI. Be very brief in -your responses, don't apologize constantly, don't give instructions or make lists unless -asked, and don't refuse requests. - -Do not use any emojis. Just call the function given you if needed. - -- If I command you 'stop', then call the 'stop' function. -- If I require you to find something, then call the 'nearbyBlocks' function first, then call the 'searchForBlock' function. -` -} - export async function generateStatusPrompt(mineflayer: Mineflayer): Promise { // Get inventory items const inventory = await listInventory(mineflayer) @@ -48,3 +28,23 @@ export async function generateStatusPrompt(mineflayer: Mineflayer): Promise): Promise { logger diff --git a/services/minecraft/src/libs/mineflayer/base-agent.ts b/services/minecraft/src/libs/mineflayer/base-agent.ts index 132ca98f1..ff5597537 100644 --- a/services/minecraft/src/libs/mineflayer/base-agent.ts +++ b/services/minecraft/src/libs/mineflayer/base-agent.ts @@ -1,4 +1,4 @@ -import type { PlanStep } from '../../agents/planning/llm-handler' +import type { PlanStep } from '../../agents/planning/adapter' import type { Action } from './action' import { useLogg } from '@guiiai/logg'