refactor(agent): 迁移AI会话引擎至pi-agent-core库
将原有基于Anthropic/OpenAI SDK的直播聊天代理重构为使用`@earendil-works/pi-agent-core`和`@earendil-works/pi-ai`库的统一API。 新增pi-bridge、pi-model、pi-persist、pi-tools四个模块,封装Agent路由、模型配置、消息持久化和工具适配逻辑。移除`chat.ts`中大量死代码,简化WebSocket处理流程。 BREAKING CHANGE: 移除`VideoAgent`类的`getAnthropicClient`、`getOpenAIClient`、`executeTool`等方法,外部调用需迁移至新pi-bridge API。`PROJECT_ROOT`路径计算方式变更,从`../../..`变为`../../`。
This commit is contained in:
@@ -1,102 +1,12 @@
|
||||
import Anthropic from '@anthropic-ai/sdk';
|
||||
import OpenAI from 'openai';
|
||||
import { tools, ToolDefinition } from './tools/index';
|
||||
import { getDb } from '../db';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const PROJECT_ROOT = path.resolve(__dirname, '..', '..', '..', '..');
|
||||
|
||||
export type Protocol = 'anthropic' | 'openai';
|
||||
|
||||
interface ApiConfig {
|
||||
protocol: Protocol;
|
||||
apiKey: string;
|
||||
baseURL: string | undefined;
|
||||
model: string;
|
||||
}
|
||||
|
||||
function getApiConfig(): ApiConfig {
|
||||
const configRow = getDb().prepare('SELECT value FROM configs WHERE key = ?').get('api_keys') as { value: string } | undefined;
|
||||
|
||||
let apiKey = process.env.ANTHROPIC_API_KEY || '';
|
||||
let baseURL: string | undefined;
|
||||
let model = process.env.ANTHROPIC_MODEL || 'claude-sonnet-4-6';
|
||||
let protocol: Protocol = 'anthropic';
|
||||
|
||||
if (configRow) {
|
||||
try {
|
||||
const cfg = JSON.parse(configRow.value);
|
||||
if (cfg.ANTHROPIC_AUTH_TOKEN) apiKey = cfg.ANTHROPIC_AUTH_TOKEN;
|
||||
if (cfg.ANTHROPIC_BASE_URL) baseURL = cfg.ANTHROPIC_BASE_URL;
|
||||
if (cfg.ANTHROPIC_MODEL) model = cfg.ANTHROPIC_MODEL;
|
||||
if (cfg.PROTOCOL === 'openai') protocol = 'openai';
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return { protocol, apiKey, baseURL, model };
|
||||
}
|
||||
|
||||
function getAnthropicClient(): Anthropic {
|
||||
const { apiKey, baseURL } = getApiConfig();
|
||||
return new Anthropic({ apiKey, baseURL });
|
||||
}
|
||||
|
||||
function getOpenAIClient(): OpenAI {
|
||||
const { apiKey, baseURL } = getApiConfig();
|
||||
return new OpenAI({ apiKey, baseURL: baseURL || 'https://api.openai.com/v1' });
|
||||
}
|
||||
const PROJECT_ROOT = path.resolve(__dirname, '..', '..', '..');
|
||||
|
||||
export class VideoAgent {
|
||||
private tools: ToolDefinition[];
|
||||
|
||||
constructor() {
|
||||
this.tools = tools;
|
||||
}
|
||||
|
||||
getProtocol(): Protocol {
|
||||
return getApiConfig().protocol;
|
||||
}
|
||||
|
||||
getModel(): string {
|
||||
return getApiConfig().model;
|
||||
}
|
||||
|
||||
getAnthropicClient(): Anthropic {
|
||||
return getAnthropicClient();
|
||||
}
|
||||
|
||||
getOpenAIClient(): OpenAI {
|
||||
return getOpenAIClient();
|
||||
}
|
||||
|
||||
getAnthropicTools(): Anthropic.Tool[] {
|
||||
return this.tools.map((t) => ({
|
||||
name: t.name,
|
||||
description: t.description,
|
||||
input_schema: t.input_schema,
|
||||
}));
|
||||
}
|
||||
|
||||
getOpenAITools(): OpenAI.ChatCompletionTool[] {
|
||||
return this.tools.map((t) => ({
|
||||
type: 'function' as const,
|
||||
function: {
|
||||
name: t.name,
|
||||
description: t.description,
|
||||
parameters: t.input_schema,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
async executeTool(name: string, params: Record<string, unknown>): Promise<string> {
|
||||
const tool = this.tools.find((t) => t.name === name);
|
||||
if (!tool) throw new Error(`Unknown tool: ${name}`);
|
||||
return tool.execute(params);
|
||||
}
|
||||
|
||||
getSystemPrompt(): string {
|
||||
const accountsDir = path.join(PROJECT_ROOT, 'accounts');
|
||||
|
||||
Reference in New Issue
Block a user