100 lines
2.8 KiB
TypeScript
100 lines
2.8 KiB
TypeScript
import { initDatabase, closeDb } from './db/database'
|
||
import { startWebSocketServer } from './transport/websocket'
|
||
import { syncWorker } from './sync/worker'
|
||
import { WorkflowEngine } from './workflow/engine'
|
||
import { ToolRegistry, readFileTool } from './tools/registry'
|
||
import type { AgentContext, LLMConfig, StreamCallbacks } from './types'
|
||
|
||
export * from './types'
|
||
export { WorkflowEngine } from './workflow/engine'
|
||
export { ToolRegistry, readFileTool } from './tools/registry'
|
||
export { LLMProvider } from './llm/provider'
|
||
export { llmConfigManager } from './llm/config'
|
||
|
||
// ============ 启动配置 ============
|
||
|
||
const WS_PORT = Number(process.env.AGENT_CORE_PORT) || 8787
|
||
const DB_DIR = process.env.AGENT_CORE_DB_DIR || './data'
|
||
|
||
/**
|
||
* agent-core 入口
|
||
* 启动 SQLite + WebSocket 服务器
|
||
*/
|
||
function main() {
|
||
console.log('========================================')
|
||
console.log(' dndClaw agent-core 启动中...')
|
||
console.log('========================================')
|
||
|
||
// 1. 初始化 SQLite
|
||
initDatabase(DB_DIR)
|
||
console.log(`[core] 数据库目录: ${DB_DIR}`)
|
||
|
||
// 2. 启动 WebSocket
|
||
const wss = startWebSocketServer(WS_PORT)
|
||
console.log(`[core] WebSocket 端口: ${WS_PORT}`)
|
||
|
||
// 3. 启动云端同步 Worker(本地变更 → outbox → 云端推送;云端变更 → 拉取合并)
|
||
syncWorker.start()
|
||
|
||
// 优雅退出
|
||
process.on('SIGINT', () => {
|
||
console.log('\n[core] 正在关闭...')
|
||
syncWorker.stop()
|
||
wss.close()
|
||
closeDb()
|
||
process.exit(0)
|
||
})
|
||
|
||
console.log('========================================')
|
||
console.log(' dndClaw agent-core 已就绪')
|
||
console.log('========================================')
|
||
}
|
||
|
||
// ============ 智能体工厂(供编程调用) ============
|
||
|
||
export function createAgent(config: LLMConfig) {
|
||
const toolRegistry = new ToolRegistry()
|
||
toolRegistry.register(readFileTool)
|
||
|
||
const context: AgentContext = {
|
||
messages: [],
|
||
config,
|
||
tools: toolRegistry.list()
|
||
}
|
||
|
||
const engine = new WorkflowEngine(context)
|
||
|
||
return {
|
||
async chat(userInput: string, callbacks?: StreamCallbacks) {
|
||
return engine.run(userInput, callbacks)
|
||
},
|
||
getMessages() {
|
||
return context.messages
|
||
},
|
||
clear() {
|
||
context.messages = []
|
||
},
|
||
registerTool(
|
||
name: string,
|
||
description: string,
|
||
execute: (params: Record<string, unknown>) => Promise<string>
|
||
) {
|
||
toolRegistry.register({ name, description, parameters: {}, execute })
|
||
context.tools = toolRegistry.list()
|
||
},
|
||
listTools() {
|
||
return toolRegistry.list()
|
||
}
|
||
}
|
||
}
|
||
|
||
export type Agent = ReturnType<typeof createAgent>
|
||
|
||
// 直接运行时启动服务(ESM)
|
||
import { fileURLToPath } from 'url'
|
||
import { resolve } from 'path'
|
||
const __filename = fileURLToPath(import.meta.url)
|
||
if (process.argv[1] && resolve(process.argv[1]) === resolve(__filename)) {
|
||
main()
|
||
}
|