mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-27 07:16:19 +09:00
125 lines
3.3 KiB
TypeScript
125 lines
3.3 KiB
TypeScript
import { streamText, generateText, ModelMessage, stepCountIs, UserModelMessage } from 'ai'
|
|
import { AgentParams } from './types'
|
|
import { system, schedule as schedulePrompt } from './prompts'
|
|
import { getMemoryTools, getScheduleTools, getMessageTools } from './tools'
|
|
import { createChatGateway } from '@memohome/ai-gateway'
|
|
import { Schedule } from '@memohome/shared'
|
|
|
|
export const createAgent = (params: AgentParams) => {
|
|
const messages: ModelMessage[] = []
|
|
|
|
const gateway = createChatGateway(params.model)
|
|
|
|
const maxContextLoadTime = params.maxContextLoadTime ?? 24 * 60 // 24 hours
|
|
const language = params.language ?? 'Same as user input'
|
|
const platforms = params.platforms ?? []
|
|
const currentPlatform = params.platforms
|
|
? platforms.find(p => p.name === params.currentPlatform)?.name ?? 'Unknown Platform'
|
|
: 'client'
|
|
|
|
const getTools = async () => {
|
|
return {
|
|
...getMemoryTools({
|
|
searchMemory: params.onSearchMemory ?? (() => Promise.resolve([]))
|
|
}),
|
|
...getScheduleTools({
|
|
onGetSchedules: params.onGetSchedules ?? (() => Promise.resolve([])),
|
|
onRemoveSchedule: params.onRemoveSchedule ?? (() => Promise.resolve()),
|
|
onSchedule: params.onSchedule ?? (() => Promise.resolve()),
|
|
}),
|
|
...getMessageTools(
|
|
platforms,
|
|
params.onSendMessage ?? (() => Promise.resolve())
|
|
),
|
|
}
|
|
}
|
|
|
|
const loadContext = async () => {
|
|
const from = new Date(Date.now() - maxContextLoadTime * 60 * 1000)
|
|
const to = new Date()
|
|
const memory = await params.onReadMemory?.(from, to) ?? []
|
|
const context = memory.flatMap(m => m.messages)
|
|
messages.unshift(...context)
|
|
}
|
|
|
|
const getSystemPrompt = () => {
|
|
return system({
|
|
date: new Date(),
|
|
language,
|
|
locale: params.locale,
|
|
maxContextLoadTime,
|
|
platforms,
|
|
currentPlatform,
|
|
})
|
|
}
|
|
|
|
const getSchedulePrompt = (schedule: Schedule) => {
|
|
return schedulePrompt({
|
|
schedule,
|
|
locale: params.locale,
|
|
date: new Date(),
|
|
})
|
|
}
|
|
|
|
async function askDirectly(input: string) {
|
|
await loadContext()
|
|
const user = {
|
|
role: 'user',
|
|
content: input,
|
|
} as UserModelMessage
|
|
messages.push(user)
|
|
const { response } = await generateText({
|
|
model: gateway,
|
|
system: getSystemPrompt(),
|
|
messages,
|
|
tools: await getTools(),
|
|
})
|
|
await params.onFinish?.([
|
|
user as ModelMessage,
|
|
...response.messages,
|
|
])
|
|
}
|
|
|
|
async function* ask(input: string) {
|
|
await loadContext()
|
|
const user = {
|
|
role: 'user',
|
|
content: input,
|
|
} as UserModelMessage
|
|
messages.push(user)
|
|
const { fullStream, response } = streamText({
|
|
model: gateway,
|
|
system: getSystemPrompt(),
|
|
prepareStep: async () => {
|
|
return {
|
|
system: getSystemPrompt(),
|
|
}
|
|
},
|
|
stopWhen: stepCountIs(10),
|
|
messages,
|
|
tools: await getTools(),
|
|
})
|
|
for await (const event of fullStream) {
|
|
yield event
|
|
}
|
|
const newMessages = (await response).messages
|
|
await params.onFinish?.([
|
|
user as ModelMessage,
|
|
...newMessages,
|
|
])
|
|
}
|
|
|
|
const triggerSchedule = async (schedule: Schedule) => {
|
|
const prompt = getSchedulePrompt(schedule)
|
|
await askDirectly(prompt)
|
|
}
|
|
|
|
return {
|
|
ask,
|
|
askDirectly,
|
|
loadContext,
|
|
getSystemPrompt,
|
|
getSchedulePrompt,
|
|
triggerSchedule,
|
|
}
|
|
} |