@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.
@@ -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();
@@ -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();
@@ -0,0 +1,2 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ export declare function apiRoutes(fastify: FastifyInstance): Promise<void>;