@starlink-awaken/agentmesh 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/base.d.ts +22 -0
- package/dist/adapters/base.js +10 -0
- package/dist/adapters/claude-code.d.ts +22 -0
- package/dist/adapters/claude-code.js +112 -0
- package/dist/adapters/openclaw.d.ts +22 -0
- package/dist/adapters/openclaw.js +110 -0
- package/dist/adapters/process.d.ts +28 -0
- package/dist/adapters/process.js +121 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +246 -0
- package/dist/core/agent-registry.d.ts +48 -0
- package/dist/core/agent-registry.js +295 -0
- package/dist/core/config.d.ts +59 -0
- package/dist/core/config.js +101 -0
- package/dist/core/context-manager.d.ts +52 -0
- package/dist/core/context-manager.js +165 -0
- package/dist/core/event-bus.d.ts +35 -0
- package/dist/core/event-bus.js +62 -0
- package/dist/core/metrics.d.ts +87 -0
- package/dist/core/metrics.js +167 -0
- package/dist/core/router.d.ts +46 -0
- package/dist/core/router.js +90 -0
- package/dist/core/task-manager.d.ts +41 -0
- package/dist/core/task-manager.js +197 -0
- package/dist/core/vector-store.d.ts +37 -0
- package/dist/core/vector-store.js +175 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +73 -0
- package/dist/routes/api.d.ts +2 -0
- package/dist/routes/api.js +128 -0
- package/dist/routes/websocket.d.ts +2 -0
- package/dist/routes/websocket.js +64 -0
- package/dist/types/index.d.ts +71 -0
- package/dist/types/index.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Agent, RoutingRule, AgentMessage } from '../types/index.js';
|
|
2
|
+
export declare class Router {
|
|
3
|
+
private rules;
|
|
4
|
+
private agents;
|
|
5
|
+
private defaultAgent?;
|
|
6
|
+
/**
|
|
7
|
+
* 配置路由规则
|
|
8
|
+
*/
|
|
9
|
+
configure(rules: RoutingRule[], defaultAgent?: string): void;
|
|
10
|
+
/**
|
|
11
|
+
* 注册 Agent
|
|
12
|
+
*/
|
|
13
|
+
registerAgent(agent: Agent): void;
|
|
14
|
+
/**
|
|
15
|
+
* 注销 Agent
|
|
16
|
+
*/
|
|
17
|
+
unregisterAgent(agentId: string): void;
|
|
18
|
+
/**
|
|
19
|
+
* 获取所有在线 Agent
|
|
20
|
+
*/
|
|
21
|
+
getOnlineAgents(): Agent[];
|
|
22
|
+
/**
|
|
23
|
+
* 路由任务到合适的 Agent
|
|
24
|
+
*/
|
|
25
|
+
route(message: AgentMessage): {
|
|
26
|
+
agentIds: string[];
|
|
27
|
+
strategy: 'direct' | 'broadcast';
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* 检查任务是否匹配路由关键词
|
|
31
|
+
*/
|
|
32
|
+
private matchesRule;
|
|
33
|
+
/**
|
|
34
|
+
* 检查 Agent 是否在线
|
|
35
|
+
*/
|
|
36
|
+
private isAgentOnline;
|
|
37
|
+
/**
|
|
38
|
+
* 获取 Agent 信息
|
|
39
|
+
*/
|
|
40
|
+
getAgent(agentId: string): Agent | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* 获取所有 Agent
|
|
43
|
+
*/
|
|
44
|
+
getAllAgents(): Agent[];
|
|
45
|
+
}
|
|
46
|
+
export declare const router: Router;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export class Router {
|
|
2
|
+
rules = [];
|
|
3
|
+
agents = new Map();
|
|
4
|
+
defaultAgent;
|
|
5
|
+
/**
|
|
6
|
+
* 配置路由规则
|
|
7
|
+
*/
|
|
8
|
+
configure(rules, defaultAgent) {
|
|
9
|
+
// 按优先级排序
|
|
10
|
+
this.rules = [...rules].sort((a, b) => b.priority - a.priority);
|
|
11
|
+
this.defaultAgent = defaultAgent;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 注册 Agent
|
|
15
|
+
*/
|
|
16
|
+
registerAgent(agent) {
|
|
17
|
+
this.agents.set(agent.id, agent);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 注销 Agent
|
|
21
|
+
*/
|
|
22
|
+
unregisterAgent(agentId) {
|
|
23
|
+
this.agents.delete(agentId);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 获取所有在线 Agent
|
|
27
|
+
*/
|
|
28
|
+
getOnlineAgents() {
|
|
29
|
+
return Array.from(this.agents.values()).filter(a => a.status === 'online');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 路由任务到合适的 Agent
|
|
33
|
+
*/
|
|
34
|
+
route(message) {
|
|
35
|
+
const task = message.payload?.task || '';
|
|
36
|
+
// 匹配路由规则
|
|
37
|
+
for (const rule of this.rules) {
|
|
38
|
+
if (this.matchesRule(task, rule.keywords)) {
|
|
39
|
+
// 检查 Agent 是否在线
|
|
40
|
+
if (rule.strategy === 'broadcast' && rule.agents) {
|
|
41
|
+
const availableAgents = rule.agents.filter(id => this.isAgentOnline(id));
|
|
42
|
+
if (availableAgents.length > 0) {
|
|
43
|
+
return { agentIds: availableAgents, strategy: 'broadcast' };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else if (rule.agent && this.isAgentOnline(rule.agent)) {
|
|
47
|
+
return { agentIds: [rule.agent], strategy: 'direct' };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// 使用默认 Agent
|
|
52
|
+
if (this.defaultAgent && this.isAgentOnline(this.defaultAgent)) {
|
|
53
|
+
return { agentIds: [this.defaultAgent], strategy: 'direct' };
|
|
54
|
+
}
|
|
55
|
+
// 返回所有在线 Agent 作为兜底
|
|
56
|
+
const onlineAgents = this.getOnlineAgents();
|
|
57
|
+
if (onlineAgents.length > 0) {
|
|
58
|
+
return { agentIds: onlineAgents.map(a => a.id), strategy: 'broadcast' };
|
|
59
|
+
}
|
|
60
|
+
// 没有可用的 Agent
|
|
61
|
+
return { agentIds: [], strategy: 'direct' };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 检查任务是否匹配路由关键词
|
|
65
|
+
*/
|
|
66
|
+
matchesRule(task, keywords) {
|
|
67
|
+
const lowerTask = task.toLowerCase();
|
|
68
|
+
return keywords.some(keyword => lowerTask.includes(keyword.toLowerCase()));
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 检查 Agent 是否在线
|
|
72
|
+
*/
|
|
73
|
+
isAgentOnline(agentId) {
|
|
74
|
+
const agent = this.agents.get(agentId);
|
|
75
|
+
return agent?.status === 'online';
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 获取 Agent 信息
|
|
79
|
+
*/
|
|
80
|
+
getAgent(agentId) {
|
|
81
|
+
return this.agents.get(agentId);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 获取所有 Agent
|
|
85
|
+
*/
|
|
86
|
+
getAllAgents() {
|
|
87
|
+
return Array.from(this.agents.values());
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export const router = new Router();
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Task, AgentMessage, Error } from '../types/index.js';
|
|
2
|
+
export declare class TaskManager {
|
|
3
|
+
private tasks;
|
|
4
|
+
/**
|
|
5
|
+
* 创建新任务
|
|
6
|
+
*/
|
|
7
|
+
createTask(request: AgentMessage): Promise<Task>;
|
|
8
|
+
/**
|
|
9
|
+
* 分配任务到 Agent
|
|
10
|
+
*/
|
|
11
|
+
assignTask(taskId: string, agentIds: string[]): Task | null;
|
|
12
|
+
/**
|
|
13
|
+
* 开始执行任务
|
|
14
|
+
*/
|
|
15
|
+
startTask(taskId: string): Task | null;
|
|
16
|
+
/**
|
|
17
|
+
* 完成任务
|
|
18
|
+
*/
|
|
19
|
+
completeTask(taskId: string, result: unknown): Task | null;
|
|
20
|
+
/**
|
|
21
|
+
* 任务失败
|
|
22
|
+
*/
|
|
23
|
+
failTask(taskId: string, error: Error): Task | null;
|
|
24
|
+
/**
|
|
25
|
+
* 获取任务
|
|
26
|
+
*/
|
|
27
|
+
getTask(taskId: string): Task | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* 获取所有任务
|
|
30
|
+
*/
|
|
31
|
+
getAllTasks(): Task[];
|
|
32
|
+
/**
|
|
33
|
+
* 处理任务
|
|
34
|
+
*/
|
|
35
|
+
processTask(message: AgentMessage): Promise<Task>;
|
|
36
|
+
/**
|
|
37
|
+
* 执行任务
|
|
38
|
+
*/
|
|
39
|
+
private executeTask;
|
|
40
|
+
}
|
|
41
|
+
export declare const taskManager: TaskManager;
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
import { eventBus } from './event-bus.js';
|
|
3
|
+
import { router } from './router.js';
|
|
4
|
+
import { contextManager } from './context-manager.js';
|
|
5
|
+
import { agentRegistry } from './agent-registry.js';
|
|
6
|
+
export class TaskManager {
|
|
7
|
+
tasks = new Map();
|
|
8
|
+
/**
|
|
9
|
+
* 创建新任务
|
|
10
|
+
*/
|
|
11
|
+
async createTask(request) {
|
|
12
|
+
const taskId = uuidv4();
|
|
13
|
+
const task = {
|
|
14
|
+
id: taskId,
|
|
15
|
+
status: 'pending',
|
|
16
|
+
request,
|
|
17
|
+
assignedAgents: [],
|
|
18
|
+
createdAt: Date.now(),
|
|
19
|
+
updatedAt: Date.now()
|
|
20
|
+
};
|
|
21
|
+
this.tasks.set(taskId, task);
|
|
22
|
+
// 发布任务提交事件
|
|
23
|
+
eventBus.publishTaskEvent('task.submitted', {
|
|
24
|
+
...request,
|
|
25
|
+
id: taskId
|
|
26
|
+
});
|
|
27
|
+
return task;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 分配任务到 Agent
|
|
31
|
+
*/
|
|
32
|
+
assignTask(taskId, agentIds) {
|
|
33
|
+
const task = this.tasks.get(taskId);
|
|
34
|
+
if (!task) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
task.assignedAgents = agentIds;
|
|
38
|
+
task.status = 'assigned';
|
|
39
|
+
task.updatedAt = Date.now();
|
|
40
|
+
// 发布任务分配事件
|
|
41
|
+
eventBus.publishTaskEvent('task.assigned', {
|
|
42
|
+
...task.request,
|
|
43
|
+
id: taskId
|
|
44
|
+
});
|
|
45
|
+
return task;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 开始执行任务
|
|
49
|
+
*/
|
|
50
|
+
startTask(taskId) {
|
|
51
|
+
const task = this.tasks.get(taskId);
|
|
52
|
+
if (!task) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
task.status = 'running';
|
|
56
|
+
task.updatedAt = Date.now();
|
|
57
|
+
eventBus.publishTaskEvent('task.started', {
|
|
58
|
+
...task.request,
|
|
59
|
+
id: taskId
|
|
60
|
+
});
|
|
61
|
+
return task;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 完成任务
|
|
65
|
+
*/
|
|
66
|
+
completeTask(taskId, result) {
|
|
67
|
+
const task = this.tasks.get(taskId);
|
|
68
|
+
if (!task) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
task.status = 'completed';
|
|
72
|
+
task.result = result;
|
|
73
|
+
task.updatedAt = Date.now();
|
|
74
|
+
eventBus.publishTaskEvent('task.completed', {
|
|
75
|
+
...task.request,
|
|
76
|
+
id: taskId,
|
|
77
|
+
result
|
|
78
|
+
});
|
|
79
|
+
return task;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 任务失败
|
|
83
|
+
*/
|
|
84
|
+
failTask(taskId, error) {
|
|
85
|
+
const task = this.tasks.get(taskId);
|
|
86
|
+
if (!task) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
task.status = 'failed';
|
|
90
|
+
task.error = error;
|
|
91
|
+
task.updatedAt = Date.now();
|
|
92
|
+
eventBus.publishTaskEvent('task.failed', {
|
|
93
|
+
...task.request,
|
|
94
|
+
id: taskId,
|
|
95
|
+
error
|
|
96
|
+
});
|
|
97
|
+
return task;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 获取任务
|
|
101
|
+
*/
|
|
102
|
+
getTask(taskId) {
|
|
103
|
+
return this.tasks.get(taskId);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 获取所有任务
|
|
107
|
+
*/
|
|
108
|
+
getAllTasks() {
|
|
109
|
+
return Array.from(this.tasks.values());
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 处理任务
|
|
113
|
+
*/
|
|
114
|
+
async processTask(message) {
|
|
115
|
+
// 1. 创建任务
|
|
116
|
+
const task = await this.createTask(message);
|
|
117
|
+
// 2. 如果有共享空间,添加消息到上下文
|
|
118
|
+
if (message.payload?.context?.shared_space_id) {
|
|
119
|
+
await contextManager.addMessage(message.payload.context.shared_space_id, message);
|
|
120
|
+
}
|
|
121
|
+
// 3. 路由任务到 Agent
|
|
122
|
+
const { agentIds, strategy } = router.route(message);
|
|
123
|
+
if (agentIds.length === 0) {
|
|
124
|
+
this.failTask(task.id, {
|
|
125
|
+
code: 'NO_AGENT_AVAILABLE',
|
|
126
|
+
message: 'No available agents to handle this task'
|
|
127
|
+
});
|
|
128
|
+
throw new Error('No available agents');
|
|
129
|
+
}
|
|
130
|
+
// 4. 分配任务
|
|
131
|
+
this.assignTask(task.id, agentIds);
|
|
132
|
+
this.startTask(task.id);
|
|
133
|
+
// 5. 执行任务
|
|
134
|
+
await this.executeTask(task, agentIds, strategy);
|
|
135
|
+
return task;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* 执行任务
|
|
139
|
+
*/
|
|
140
|
+
async executeTask(task, agentIds, strategy) {
|
|
141
|
+
const results = {};
|
|
142
|
+
if (strategy === 'direct' && agentIds[0]) {
|
|
143
|
+
// 单 Agent 执行
|
|
144
|
+
const agentId = agentIds[0];
|
|
145
|
+
const adapter = agentRegistry.get(agentId);
|
|
146
|
+
if (!adapter) {
|
|
147
|
+
this.failTask(task.id, {
|
|
148
|
+
code: 'AGENT_NOT_FOUND',
|
|
149
|
+
message: `Agent ${agentId} not found`
|
|
150
|
+
});
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
console.log(`[TaskManager] Executing task ${task.id} with agent ${agentId}`);
|
|
155
|
+
const response = await adapter.invoke(task.request);
|
|
156
|
+
results[agentId] = response.result;
|
|
157
|
+
// 如果有共享空间,添加响应到上下文
|
|
158
|
+
if (task.request.payload?.context?.shared_space_id) {
|
|
159
|
+
await contextManager.addMessage(task.request.payload.context.shared_space_id, response);
|
|
160
|
+
}
|
|
161
|
+
this.completeTask(task.id, response.result);
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
165
|
+
this.failTask(task.id, {
|
|
166
|
+
code: 'EXECUTION_ERROR',
|
|
167
|
+
message: errorMessage
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
// 广播模式:多个 Agent 同时执行
|
|
173
|
+
const promises = agentIds.map(async (agentId) => {
|
|
174
|
+
const adapter = agentRegistry.get(agentId);
|
|
175
|
+
if (!adapter) {
|
|
176
|
+
results[agentId] = { error: `Agent ${agentId} not found` };
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
const response = await adapter.invoke(task.request);
|
|
181
|
+
results[agentId] = response.result;
|
|
182
|
+
// 添加响应到上下文
|
|
183
|
+
if (task.request.payload?.context?.shared_space_id) {
|
|
184
|
+
await contextManager.addMessage(task.request.payload.context.shared_space_id, response);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
189
|
+
results[agentId] = { error: errorMessage };
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
await Promise.all(promises);
|
|
193
|
+
this.completeTask(task.id, results);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
export const taskManager = new TaskManager();
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { AgentMessage } from '../types/index.js';
|
|
2
|
+
export declare class VectorStore {
|
|
3
|
+
private client;
|
|
4
|
+
private collection;
|
|
5
|
+
private isInitialized;
|
|
6
|
+
private baseDir;
|
|
7
|
+
constructor(baseDir?: string);
|
|
8
|
+
/**
|
|
9
|
+
* 初始化向量数据库
|
|
10
|
+
*/
|
|
11
|
+
initialize(): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* 添加消息到向量存储
|
|
14
|
+
*/
|
|
15
|
+
addMessage(spaceId: string, message: AgentMessage): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* 搜索相似上下文
|
|
18
|
+
*/
|
|
19
|
+
searchSimilar(spaceId: string, query: string, limit?: number): Promise<AgentMessage[]>;
|
|
20
|
+
/**
|
|
21
|
+
* 获取空间的向量数量
|
|
22
|
+
*/
|
|
23
|
+
getCount(spaceId: string): Promise<number>;
|
|
24
|
+
/**
|
|
25
|
+
* 删除空间的向量
|
|
26
|
+
*/
|
|
27
|
+
deleteSpace(spaceId: string): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* 将消息转换为可向量化的文本
|
|
30
|
+
*/
|
|
31
|
+
private messageToText;
|
|
32
|
+
/**
|
|
33
|
+
* 检查是否可用
|
|
34
|
+
*/
|
|
35
|
+
isAvailable(): boolean;
|
|
36
|
+
}
|
|
37
|
+
export declare const vectorStore: VectorStore;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { ChromaClient } from 'chromadb';
|
|
2
|
+
export class VectorStore {
|
|
3
|
+
client = null;
|
|
4
|
+
collection = null;
|
|
5
|
+
isInitialized = false;
|
|
6
|
+
baseDir;
|
|
7
|
+
constructor(baseDir = './data/vector-db') {
|
|
8
|
+
this.baseDir = baseDir;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 初始化向量数据库
|
|
12
|
+
*/
|
|
13
|
+
async initialize() {
|
|
14
|
+
if (this.isInitialized)
|
|
15
|
+
return;
|
|
16
|
+
try {
|
|
17
|
+
this.client = new ChromaClient({
|
|
18
|
+
path: 'http://localhost:8000'
|
|
19
|
+
});
|
|
20
|
+
// 尝试获取或创建 collection
|
|
21
|
+
try {
|
|
22
|
+
this.collection = await this.client.getOrCreateCollection({
|
|
23
|
+
name: 'agent-context'
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Collection 可能不存在,创建新的
|
|
28
|
+
this.collection = await this.client.createCollection({
|
|
29
|
+
name: 'agent-context'
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
this.isInitialized = true;
|
|
33
|
+
console.log('[VectorStore] Initialized successfully');
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.warn('[VectorStore] Failed to initialize (ChromaDB not running?):', error);
|
|
37
|
+
this.isInitialized = false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 添加消息到向量存储
|
|
42
|
+
*/
|
|
43
|
+
async addMessage(spaceId, message) {
|
|
44
|
+
if (!this.isInitialized || !this.collection) {
|
|
45
|
+
console.warn('[VectorStore] Not initialized, skipping add');
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const entry = {
|
|
49
|
+
id: `${spaceId}_${message.id}`,
|
|
50
|
+
message
|
|
51
|
+
};
|
|
52
|
+
try {
|
|
53
|
+
// 简单文本向量化(使用消息内容)
|
|
54
|
+
const text = this.messageToText(message);
|
|
55
|
+
await this.collection.add({
|
|
56
|
+
ids: [entry.id],
|
|
57
|
+
documents: [text],
|
|
58
|
+
metadatas: [{
|
|
59
|
+
space_id: spaceId,
|
|
60
|
+
message_id: message.id,
|
|
61
|
+
timestamp: message.timestamp,
|
|
62
|
+
source: message.source,
|
|
63
|
+
type: message.type
|
|
64
|
+
}]
|
|
65
|
+
});
|
|
66
|
+
console.log('[VectorStore] Added message:', entry.id);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.error('[VectorStore] Failed to add message:', error);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 搜索相似上下文
|
|
74
|
+
*/
|
|
75
|
+
async searchSimilar(spaceId, query, limit = 5) {
|
|
76
|
+
if (!this.isInitialized || !this.collection) {
|
|
77
|
+
console.warn('[VectorStore] Not initialized, returning empty');
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const results = await this.collection.query({
|
|
82
|
+
queryTexts: [query],
|
|
83
|
+
nResults: limit,
|
|
84
|
+
where: { space_id: spaceId }
|
|
85
|
+
});
|
|
86
|
+
const messages = [];
|
|
87
|
+
if (results.documents && results.documents[0]) {
|
|
88
|
+
for (let i = 0; i < results.documents[0].length; i++) {
|
|
89
|
+
const metadata = results.metadatas?.[0]?.[i];
|
|
90
|
+
if (metadata?.message_id) {
|
|
91
|
+
// 这里返回元数据,实际使用时可以从文件/内存中获取完整消息
|
|
92
|
+
messages.push({
|
|
93
|
+
id: metadata.message_id,
|
|
94
|
+
type: 'event',
|
|
95
|
+
source: metadata.source,
|
|
96
|
+
target: 'search',
|
|
97
|
+
correlation_id: '',
|
|
98
|
+
timestamp: metadata.timestamp,
|
|
99
|
+
payload: {
|
|
100
|
+
task: results.documents[0][i] || ''
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return messages;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
console.error('[VectorStore] Search failed:', error);
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 获取空间的向量数量
|
|
115
|
+
*/
|
|
116
|
+
async getCount(spaceId) {
|
|
117
|
+
if (!this.isInitialized || !this.collection) {
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
const results = await this.collection.get({
|
|
122
|
+
where: { space_id: spaceId }
|
|
123
|
+
});
|
|
124
|
+
return results.ids?.length || 0;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return 0;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* 删除空间的向量
|
|
132
|
+
*/
|
|
133
|
+
async deleteSpace(spaceId) {
|
|
134
|
+
if (!this.isInitialized || !this.collection) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
// 获取该 space 的所有 ID
|
|
139
|
+
const results = await this.collection.get({
|
|
140
|
+
where: { space_id: spaceId }
|
|
141
|
+
});
|
|
142
|
+
if (results.ids && results.ids.length > 0) {
|
|
143
|
+
await this.collection.delete({
|
|
144
|
+
ids: results.ids
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
console.error('[VectorStore] Delete space failed:', error);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* 将消息转换为可向量化的文本
|
|
154
|
+
*/
|
|
155
|
+
messageToText(message) {
|
|
156
|
+
const parts = [];
|
|
157
|
+
if (message.payload?.task) {
|
|
158
|
+
parts.push(`Task: ${message.payload.task}`);
|
|
159
|
+
}
|
|
160
|
+
if (message.result) {
|
|
161
|
+
parts.push(`Result: ${JSON.stringify(message.result)}`);
|
|
162
|
+
}
|
|
163
|
+
if (message.error) {
|
|
164
|
+
parts.push(`Error: ${message.error.message}`);
|
|
165
|
+
}
|
|
166
|
+
return parts.join('\n') || JSON.stringify(message);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* 检查是否可用
|
|
170
|
+
*/
|
|
171
|
+
isAvailable() {
|
|
172
|
+
return this.isInitialized;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
export const vectorStore = new VectorStore();
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import Fastify from 'fastify';
|
|
2
|
+
import cors from '@fastify/cors';
|
|
3
|
+
import { apiRoutes } from './routes/api.js';
|
|
4
|
+
import { websocketRoutes } from './routes/websocket.js';
|
|
5
|
+
import { eventBus } from './core/event-bus.js';
|
|
6
|
+
import { router } from './core/router.js';
|
|
7
|
+
import { agentRegistry } from './core/agent-registry.js';
|
|
8
|
+
import { vectorStore } from './core/vector-store.js';
|
|
9
|
+
import { loadConfig, getRoutingRules, getDefaultAgent } from './core/config.js';
|
|
10
|
+
async function main() {
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
// 初始化 Fastify
|
|
13
|
+
const fastify = Fastify({
|
|
14
|
+
logger: {
|
|
15
|
+
level: config.logLevel
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
// 注册 CORS
|
|
19
|
+
await fastify.register(cors, {
|
|
20
|
+
origin: true
|
|
21
|
+
});
|
|
22
|
+
// 注册路由
|
|
23
|
+
await fastify.register(apiRoutes);
|
|
24
|
+
await fastify.register(websocketRoutes);
|
|
25
|
+
// 初始化组件
|
|
26
|
+
const rules = getRoutingRules();
|
|
27
|
+
const defaultAgent = getDefaultAgent();
|
|
28
|
+
router.configure(rules, defaultAgent);
|
|
29
|
+
// 初始化 Agent Registry
|
|
30
|
+
agentRegistry.initialize();
|
|
31
|
+
// 注册所有 Agent 到 Router
|
|
32
|
+
agentRegistry.getAgents().forEach(agent => {
|
|
33
|
+
router.registerAgent(agent);
|
|
34
|
+
});
|
|
35
|
+
// 初始化向量存储(异步)
|
|
36
|
+
vectorStore.initialize().catch(err => {
|
|
37
|
+
console.warn('[VectorStore] Init failed:', err);
|
|
38
|
+
});
|
|
39
|
+
// 启动服务器
|
|
40
|
+
try {
|
|
41
|
+
await fastify.listen({
|
|
42
|
+
port: config.port,
|
|
43
|
+
host: config.host
|
|
44
|
+
});
|
|
45
|
+
console.log(`
|
|
46
|
+
╔═══════════════════════════════════════════════════╗
|
|
47
|
+
║ Agent Gateway Server ║
|
|
48
|
+
╠═══════════════════════════════════════════════════╣
|
|
49
|
+
║ HTTP Server: http://${config.host}:${config.port} ║
|
|
50
|
+
║ WebSocket: ws://${config.host}:${config.port}/ws ║
|
|
51
|
+
║ SSE: http://${config.host}:${config.port}/events ║
|
|
52
|
+
║ Health: http://${config.host}:${config.port}/health ║
|
|
53
|
+
║ Tasks: http://${config.host}:${config.port}/tasks ║
|
|
54
|
+
║ Spaces: http://${config.host}:${config.port}/spaces ║
|
|
55
|
+
║ Agents: http://${config.host}:${config.port}/agents ║
|
|
56
|
+
╚═══════════════════════════════════════════════════╝
|
|
57
|
+
`);
|
|
58
|
+
// 订阅事件日志
|
|
59
|
+
eventBus.getEventTypes().forEach(eventType => {
|
|
60
|
+
eventBus.subscribe(eventType, (event) => {
|
|
61
|
+
console.log(`[Event] ${event.type}:`, {
|
|
62
|
+
id: event.data.id,
|
|
63
|
+
correlation_id: event.data.correlation_id
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
fastify.log.error(error);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
main();
|