feat: ai chat

This commit is contained in:
RainbowBird
2025-01-07 14:14:05 +08:00
parent fbd19aed02
commit bae100d5f3
4 changed files with 58 additions and 6 deletions
+11 -1
View File
@@ -7,6 +7,7 @@ import { createSkillContext } from '../skills'
import { actionsList } from './actions'
import { queriesList } from './queries'
let neuriAgent: Neuri | undefined
const agents = new Set<Agent | Promise<Agent>>()
const logger = useLogg('openai').useGlobalConfig()
@@ -20,12 +21,21 @@ export async function initAgent(ctx: BotContext): Promise<Neuri> {
agents.forEach(agent => n = n.agent(agent))
return n.build({
neuriAgent = await n.build({
provider: {
apiKey: openaiConfig.apiKey,
baseURL: openaiConfig.baseUrl,
},
})
return neuriAgent
}
export function getAgent(): Neuri {
if (!neuriAgent) {
throw new Error('Agent not initialized')
}
return neuriAgent
}
export async function initQueryAgent(ctx: BotContext): Promise<Agent> {
@@ -0,0 +1,44 @@
import type { messages } from 'neuri/openai'
import type { BotContext, ComponentLifecycle } from 'src/composables/bot'
import { useLogg } from '@guiiai/logg'
import { assistant, system, user } from 'neuri/openai'
import { getAgent } from 'src/agents/openai'
import { formBotChat } from 'src/middlewares/chat'
import { genSystemBasicPrompt } from 'src/prompts/agent'
export function createAiChatComponent(ctx: BotContext): ComponentLifecycle {
const logger = useLogg('aichat').useGlobalConfig()
logger.log('Loading aichat plugin')
const history: ReturnType<typeof messages> = []
history.push(system(genSystemBasicPrompt('airi')))
const onChat = formBotChat(ctx, async (username, message) => {
logger.withFields({ username, message }).log('Chat message received')
history.push(user(message))
const agent = getAgent()
const content = await agent.handle(history.concat(user(message)), async (c) => {
const completion = await c.reroute('query', c.messages, { model: 'openai/gpt-4o-mini' })
const content = await completion?.firstContent()
if (content) {
history.push(assistant(content))
}
return content
})
if (content) {
ctx.bot.chat(content)
}
})
ctx.bot.on('chat', onChat)
return {
cleanup: () => {
ctx.bot.removeListener('chat', onChat)
},
}
}
+2
View File
@@ -3,6 +3,7 @@ import process, { exit } from 'node:process'
import { useLogg } from '@guiiai/logg'
import { initAgent } from './agents/openai'
import { createAiChatComponent } from './components/aichat'
import { createCommandComponent } from './components/command'
import { createFollowComponent } from './components/follow'
import { createPathFinderComponent } from './components/pathfinder'
@@ -27,6 +28,7 @@ async function main() {
registerComponent('pathfinder', createPathFinderComponent)
registerComponent('follow', createFollowComponent)
registerComponent('command', createCommandComponent)
registerComponent('aichat', createAiChatComponent)
})
await initAgent(ctx)
+1 -5
View File
@@ -17,11 +17,7 @@ asked, and don't refuse requests.
Don't pretend to act, use commands immediately when requested. Do NOT say this: 'Sure, I've stopped.',
instead say this: 'Sure, I'll stop. !stop'.
Do NOT say this: 'On my way! Give me a moment.', instead say this: 'On my way! !goToPlayer("playername", 3)'.
Respond only as ${ctx.botName}, never output '(FROM OTHER BOT)'or pretend to be someone else.
If you have nothing to say or do, respond with an just a tab '\t'.
This is extremely important to me, take a deep breath and have fun :)
Just call the function given you.
I will give you the following information:
${getStatusToString(ctx)}