js-agent-core 1.0.1

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.
Files changed (168) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +29 -0
  3. package/dist/core/AgentDashboard.d.ts +33 -0
  4. package/dist/core/AgentDashboard.d.ts.map +1 -0
  5. package/dist/core/AgentDashboard.js +477 -0
  6. package/dist/core/AgentDashboard.js.map +1 -0
  7. package/dist/core/AutoVectorStore.d.ts +23 -0
  8. package/dist/core/AutoVectorStore.d.ts.map +1 -0
  9. package/dist/core/AutoVectorStore.js +55 -0
  10. package/dist/core/AutoVectorStore.js.map +1 -0
  11. package/dist/core/BaseAgent.d.ts +70 -0
  12. package/dist/core/BaseAgent.d.ts.map +1 -0
  13. package/dist/core/BaseAgent.js +583 -0
  14. package/dist/core/BaseAgent.js.map +1 -0
  15. package/dist/core/EventEmitter.d.ts +8 -0
  16. package/dist/core/EventEmitter.d.ts.map +1 -0
  17. package/dist/core/EventEmitter.js +32 -0
  18. package/dist/core/EventEmitter.js.map +1 -0
  19. package/dist/core/LocalEmbedder.d.ts +25 -0
  20. package/dist/core/LocalEmbedder.d.ts.map +1 -0
  21. package/dist/core/LocalEmbedder.js +62 -0
  22. package/dist/core/LocalEmbedder.js.map +1 -0
  23. package/dist/core/LongTermMemory.d.ts +30 -0
  24. package/dist/core/LongTermMemory.d.ts.map +1 -0
  25. package/dist/core/LongTermMemory.js +123 -0
  26. package/dist/core/LongTermMemory.js.map +1 -0
  27. package/dist/core/MemoryVectorStore.d.ts +17 -0
  28. package/dist/core/MemoryVectorStore.d.ts.map +1 -0
  29. package/dist/core/MemoryVectorStore.js +44 -0
  30. package/dist/core/MemoryVectorStore.js.map +1 -0
  31. package/dist/core/OpenAIProvider.d.ts +21 -0
  32. package/dist/core/OpenAIProvider.d.ts.map +1 -0
  33. package/dist/core/OpenAIProvider.js +254 -0
  34. package/dist/core/OpenAIProvider.js.map +1 -0
  35. package/dist/core/SimpleMemory.d.ts +12 -0
  36. package/dist/core/SimpleMemory.d.ts.map +1 -0
  37. package/dist/core/SimpleMemory.js +27 -0
  38. package/dist/core/SimpleMemory.js.map +1 -0
  39. package/dist/core/StructuredPlanner.d.ts +13 -0
  40. package/dist/core/StructuredPlanner.d.ts.map +1 -0
  41. package/dist/core/StructuredPlanner.js +156 -0
  42. package/dist/core/StructuredPlanner.js.map +1 -0
  43. package/dist/core/ToolRegistry.d.ts +18 -0
  44. package/dist/core/ToolRegistry.d.ts.map +1 -0
  45. package/dist/core/ToolRegistry.js +74 -0
  46. package/dist/core/ToolRegistry.js.map +1 -0
  47. package/dist/core/index.d.ts +14 -0
  48. package/dist/core/index.d.ts.map +1 -0
  49. package/dist/core/index.js +14 -0
  50. package/dist/core/index.js.map +1 -0
  51. package/dist/core/logging/CompositeLogger.d.ts +8 -0
  52. package/dist/core/logging/CompositeLogger.d.ts.map +1 -0
  53. package/dist/core/logging/CompositeLogger.js +23 -0
  54. package/dist/core/logging/CompositeLogger.js.map +1 -0
  55. package/dist/core/logging/NodeFsLogger.d.ts +12 -0
  56. package/dist/core/logging/NodeFsLogger.d.ts.map +1 -0
  57. package/dist/core/logging/NodeFsLogger.js +46 -0
  58. package/dist/core/logging/NodeFsLogger.js.map +1 -0
  59. package/dist/core/logging/WebIndexedDbLogger.d.ts +15 -0
  60. package/dist/core/logging/WebIndexedDbLogger.d.ts.map +1 -0
  61. package/dist/core/logging/WebIndexedDbLogger.js +65 -0
  62. package/dist/core/logging/WebIndexedDbLogger.js.map +1 -0
  63. package/dist/core/logging/index.d.ts +11 -0
  64. package/dist/core/logging/index.d.ts.map +1 -0
  65. package/dist/core/logging/index.js +33 -0
  66. package/dist/core/logging/index.js.map +1 -0
  67. package/dist/core/persistence/NodeFsSkillStore.d.ts +17 -0
  68. package/dist/core/persistence/NodeFsSkillStore.d.ts.map +1 -0
  69. package/dist/core/persistence/NodeFsSkillStore.js +124 -0
  70. package/dist/core/persistence/NodeFsSkillStore.js.map +1 -0
  71. package/dist/core/persistence/NodeFsVectorStore.d.ts +25 -0
  72. package/dist/core/persistence/NodeFsVectorStore.d.ts.map +1 -0
  73. package/dist/core/persistence/NodeFsVectorStore.js +74 -0
  74. package/dist/core/persistence/NodeFsVectorStore.js.map +1 -0
  75. package/dist/core/persistence/SkillLoader.d.ts +26 -0
  76. package/dist/core/persistence/SkillLoader.d.ts.map +1 -0
  77. package/dist/core/persistence/SkillLoader.js +144 -0
  78. package/dist/core/persistence/SkillLoader.js.map +1 -0
  79. package/dist/core/persistence/WebIndexedDbSkillStore.d.ts +21 -0
  80. package/dist/core/persistence/WebIndexedDbSkillStore.d.ts.map +1 -0
  81. package/dist/core/persistence/WebIndexedDbSkillStore.js +119 -0
  82. package/dist/core/persistence/WebIndexedDbSkillStore.js.map +1 -0
  83. package/dist/core/persistence/WebIndexedDbVectorStore.d.ts +30 -0
  84. package/dist/core/persistence/WebIndexedDbVectorStore.d.ts.map +1 -0
  85. package/dist/core/persistence/WebIndexedDbVectorStore.js +87 -0
  86. package/dist/core/persistence/WebIndexedDbVectorStore.js.map +1 -0
  87. package/dist/core/persistence/index.d.ts +6 -0
  88. package/dist/core/persistence/index.d.ts.map +1 -0
  89. package/dist/core/persistence/index.js +21 -0
  90. package/dist/core/persistence/index.js.map +1 -0
  91. package/dist/index.d.ts +3 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +3 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/interfaces/IAgentEvent.d.ts +27 -0
  96. package/dist/interfaces/IAgentEvent.d.ts.map +1 -0
  97. package/dist/interfaces/IAgentEvent.js +2 -0
  98. package/dist/interfaces/IAgentEvent.js.map +1 -0
  99. package/dist/interfaces/IAgentState.d.ts +22 -0
  100. package/dist/interfaces/IAgentState.d.ts.map +1 -0
  101. package/dist/interfaces/IAgentState.js +2 -0
  102. package/dist/interfaces/IAgentState.js.map +1 -0
  103. package/dist/interfaces/ILLMProvider.d.ts +43 -0
  104. package/dist/interfaces/ILLMProvider.d.ts.map +1 -0
  105. package/dist/interfaces/ILLMProvider.js +2 -0
  106. package/dist/interfaces/ILLMProvider.js.map +1 -0
  107. package/dist/interfaces/ILogger.d.ts +15 -0
  108. package/dist/interfaces/ILogger.d.ts.map +1 -0
  109. package/dist/interfaces/ILogger.js +2 -0
  110. package/dist/interfaces/ILogger.js.map +1 -0
  111. package/dist/interfaces/IMemory.d.ts +32 -0
  112. package/dist/interfaces/IMemory.d.ts.map +1 -0
  113. package/dist/interfaces/IMemory.js +2 -0
  114. package/dist/interfaces/IMemory.js.map +1 -0
  115. package/dist/interfaces/IPlanner.d.ts +20 -0
  116. package/dist/interfaces/IPlanner.d.ts.map +1 -0
  117. package/dist/interfaces/IPlanner.js +2 -0
  118. package/dist/interfaces/IPlanner.js.map +1 -0
  119. package/dist/interfaces/ISkill.d.ts +9 -0
  120. package/dist/interfaces/ISkill.d.ts.map +1 -0
  121. package/dist/interfaces/ISkill.js +2 -0
  122. package/dist/interfaces/ISkill.js.map +1 -0
  123. package/dist/interfaces/ISkillStore.d.ts +53 -0
  124. package/dist/interfaces/ISkillStore.d.ts.map +1 -0
  125. package/dist/interfaces/ISkillStore.js +2 -0
  126. package/dist/interfaces/ISkillStore.js.map +1 -0
  127. package/dist/interfaces/ITool.d.ts +32 -0
  128. package/dist/interfaces/ITool.d.ts.map +1 -0
  129. package/dist/interfaces/ITool.js +2 -0
  130. package/dist/interfaces/ITool.js.map +1 -0
  131. package/dist/interfaces/index.d.ts +10 -0
  132. package/dist/interfaces/index.d.ts.map +1 -0
  133. package/dist/interfaces/index.js +10 -0
  134. package/dist/interfaces/index.js.map +1 -0
  135. package/package.json +47 -0
  136. package/src/core/AgentDashboard.ts +533 -0
  137. package/src/core/AutoVectorStore.ts +60 -0
  138. package/src/core/BaseAgent.ts +676 -0
  139. package/src/core/EventEmitter.ts +35 -0
  140. package/src/core/LocalEmbedder.ts +68 -0
  141. package/src/core/LongTermMemory.ts +146 -0
  142. package/src/core/MemoryVectorStore.ts +54 -0
  143. package/src/core/OpenAIProvider.ts +274 -0
  144. package/src/core/SimpleMemory.ts +31 -0
  145. package/src/core/StructuredPlanner.ts +165 -0
  146. package/src/core/ToolRegistry.ts +89 -0
  147. package/src/core/index.ts +16 -0
  148. package/src/core/logging/CompositeLogger.ts +26 -0
  149. package/src/core/logging/NodeFsLogger.ts +53 -0
  150. package/src/core/logging/WebIndexedDbLogger.ts +76 -0
  151. package/src/core/logging/index.ts +35 -0
  152. package/src/core/persistence/NodeFsSkillStore.ts +138 -0
  153. package/src/core/persistence/NodeFsVectorStore.ts +86 -0
  154. package/src/core/persistence/SkillLoader.ts +153 -0
  155. package/src/core/persistence/WebIndexedDbSkillStore.ts +139 -0
  156. package/src/core/persistence/WebIndexedDbVectorStore.ts +106 -0
  157. package/src/core/persistence/index.ts +22 -0
  158. package/src/index.ts +2 -0
  159. package/src/interfaces/IAgentEvent.ts +46 -0
  160. package/src/interfaces/IAgentState.ts +22 -0
  161. package/src/interfaces/ILLMProvider.ts +47 -0
  162. package/src/interfaces/ILogger.ts +16 -0
  163. package/src/interfaces/IMemory.ts +29 -0
  164. package/src/interfaces/IPlanner.ts +22 -0
  165. package/src/interfaces/ISkill.ts +9 -0
  166. package/src/interfaces/ISkillStore.ts +60 -0
  167. package/src/interfaces/ITool.ts +38 -0
  168. package/src/interfaces/index.ts +10 -0
@@ -0,0 +1,153 @@
1
+ import { ISkill, ITool, SkillFile, SkillMetadata } from '../../interfaces/index.js';
2
+ import { z } from 'zod';
3
+
4
+ /**
5
+ * 环境感知型技能加载器
6
+ */
7
+ export class SkillLoader {
8
+ /**
9
+ * 将技能代码和元数据转化为可执行的 ISkill 或 ITool
10
+ * @param metadata 技能元数据
11
+ * @param files 技能文件列表
12
+ * @param baseDir 可选的基础目录 (用于 Node.js 子进程定位文件)
13
+ */
14
+ static async load(metadata: SkillMetadata, files: SkillFile[], baseDir?: string): Promise<ISkill> {
15
+ const isWeb = typeof window !== 'undefined';
16
+
17
+ switch (metadata.runtime) {
18
+ case 'javascript':
19
+ return await this.loadJavascript(metadata, files, baseDir);
20
+ case 'python':
21
+ case 'bash':
22
+ if (isWeb) {
23
+ throw new Error(`Runtime ${metadata.runtime} is not supported in the browser.`);
24
+ }
25
+ return await this.loadScriptProxy(metadata, files, baseDir!);
26
+ case 'wasm':
27
+ return await this.loadWasm(metadata, files);
28
+ default:
29
+ throw new Error(`Unsupported runtime: ${metadata.runtime}`);
30
+ }
31
+ }
32
+
33
+ /**
34
+ * 加载 JavaScript 技能
35
+ */
36
+ private static async loadJavascript(metadata: SkillMetadata, files: SkillFile[], baseDir?: string): Promise<ISkill> {
37
+ const entryFile = files.find(f => f.path === metadata.entry);
38
+ if (!entryFile) throw new Error(`Entry file ${metadata.entry} not found.`);
39
+
40
+ if (typeof window !== 'undefined') {
41
+ // Web 环境: 使用 Blob URL
42
+ const code = typeof entryFile.content === 'string'
43
+ ? entryFile.content
44
+ : new TextDecoder().decode(entryFile.content);
45
+ const blob = new Blob([code], { type: 'text/javascript' });
46
+ const url = URL.createObjectURL(blob);
47
+ try {
48
+ const module = await import(url);
49
+ return module.default || module;
50
+ } finally {
51
+ URL.revokeObjectURL(url);
52
+ }
53
+ } else {
54
+ // Node.js 环境: 优先从磁盘路径加载 (支持断点调试和完整模块解析)
55
+ if (baseDir) {
56
+ const path = await import('path');
57
+ const fullPath = path.join(baseDir, metadata.name, metadata.entry);
58
+ const module = await import(`file://${fullPath}`);
59
+ return module.default || module;
60
+ }
61
+
62
+ // 如果没有 baseDir (如内存模式),回退到 data URI
63
+ const code = typeof entryFile.content === 'string'
64
+ ? entryFile.content
65
+ : new TextDecoder().decode(entryFile.content);
66
+ const base64Code = Buffer.from(code).toString('base64');
67
+ const dataUri = `data:text/javascript;base64,${base64Code}`;
68
+ const module = await import(dataUri);
69
+ return module.default || module;
70
+ }
71
+ }
72
+
73
+ /**
74
+ * 加载脚本代理 (Python, Bash)
75
+ */
76
+ private static async loadScriptProxy(metadata: SkillMetadata, files: SkillFile[], baseDir: string): Promise<ISkill> {
77
+ const { spawn } = await import('child_process');
78
+ const path = await import('path');
79
+
80
+ // 脚本代理 Skill
81
+ return {
82
+ name: metadata.name,
83
+ description: metadata.description,
84
+ tools: [{
85
+ name: metadata.name,
86
+ description: metadata.description,
87
+ parameters: metadata.parameters || z.any(),
88
+ execute: async (params: any) => {
89
+ const scriptPath = path.join(baseDir, metadata.name, metadata.entry);
90
+
91
+ return new Promise((resolve) => {
92
+ const runtime = metadata.runtime === 'python' ? 'python3' : 'bash';
93
+ const child = spawn(runtime, [scriptPath]);
94
+
95
+ // 发送参数
96
+ child.stdin.write(JSON.stringify(params));
97
+ child.stdin.end();
98
+
99
+ let stdout = '';
100
+ let stderr = '';
101
+ child.stdout.on('data', (data) => stdout += data);
102
+ child.stderr.on('data', (data) => stderr += data);
103
+
104
+ child.on('close', (code) => {
105
+ if (code !== 0) {
106
+ resolve({ success: false, error: `Script exited with code ${code}: ${stderr}` });
107
+ } else {
108
+ try {
109
+ const result = JSON.parse(stdout);
110
+ resolve({ success: true, data: result });
111
+ } catch {
112
+ resolve({ success: true, data: stdout.trim() });
113
+ }
114
+ }
115
+ });
116
+ });
117
+ }
118
+ }]
119
+ };
120
+ }
121
+
122
+ /**
123
+ * 加载 WebAssembly 技能 (示意实现)
124
+ */
125
+ private static async loadWasm(metadata: SkillMetadata, files: SkillFile[]): Promise<ISkill> {
126
+ const entryFile = files.find(f => f.path === metadata.entry);
127
+ if (!entryFile) throw new Error(`WASM entry ${metadata.entry} not found.`);
128
+
129
+ const buffer = typeof entryFile.content === 'string'
130
+ ? new TextEncoder().encode(entryFile.content)
131
+ : entryFile.content;
132
+
133
+ const wasmModule = await WebAssembly.instantiate(buffer);
134
+ const exports = (wasmModule as any).instance?.exports || (wasmModule as any).exports;
135
+
136
+ return {
137
+ name: metadata.name,
138
+ description: metadata.description,
139
+ tools: [{
140
+ name: metadata.name,
141
+ description: metadata.description,
142
+ parameters: z.any(),
143
+ execute: async (params: any) => {
144
+ // 根据 WASM 导出函数执行逻辑
145
+ if (exports.run) {
146
+ return { success: true, data: exports.run(params) };
147
+ }
148
+ return { success: false, error: 'WASM module has no run() export' };
149
+ }
150
+ }]
151
+ };
152
+ }
153
+ }
@@ -0,0 +1,139 @@
1
+ import { ISkillStore, SkillFile, SkillMetadata } from '../../interfaces/index.js';
2
+
3
+ /**
4
+ * 前端实现:基于 IndexedDB 的持久化存储
5
+ * 数据库名: JS_AGENT_DB
6
+ * Store 1: skill_metadata (Key: name)
7
+ * Store 2: skill_files (Key: [skillName, filePath])
8
+ */
9
+ export class WebIndexedDbSkillStore implements ISkillStore {
10
+ private dbName = 'JS_AGENT_DB';
11
+ private metaStore = 'skill_metadata';
12
+ private fileStore = 'skill_files';
13
+ private db: IDBDatabase | null = null;
14
+
15
+ constructor() {
16
+ if (typeof indexedDB === 'undefined') {
17
+ console.warn('IndexedDB is not supported in this environment.');
18
+ }
19
+ }
20
+
21
+ private async getDB(): Promise<IDBDatabase> {
22
+ if (this.db) return this.db;
23
+
24
+ return new Promise((resolve, reject) => {
25
+ const request = indexedDB.open(this.dbName, 1);
26
+
27
+ request.onupgradeneeded = (event) => {
28
+ const db = (event.target as IDBOpenDBRequest).result;
29
+ if (!db.objectStoreNames.contains(this.metaStore)) {
30
+ db.createObjectStore(this.metaStore, { keyPath: 'name' });
31
+ }
32
+ if (!db.objectStoreNames.contains(this.fileStore)) {
33
+ db.createObjectStore(this.fileStore, { keyPath: ['skillName', 'path'] });
34
+ }
35
+ };
36
+
37
+ request.onsuccess = (event) => {
38
+ this.db = (event.target as IDBOpenDBRequest).result;
39
+ resolve(this.db!);
40
+ };
41
+
42
+ request.onerror = (event) => reject((event.target as IDBOpenDBRequest).error);
43
+ });
44
+ }
45
+
46
+ async saveSkill(metadata: SkillMetadata, files: SkillFile[]): Promise<void> {
47
+ const db = await this.getDB();
48
+ const tx = db.transaction([this.metaStore, this.fileStore], 'readwrite');
49
+
50
+ // 1. 保存元数据
51
+ tx.objectStore(this.metaStore).put(metadata);
52
+
53
+ // 2. 保存文件 (批量写入)
54
+ const fileStore = tx.objectStore(this.fileStore);
55
+ for (const file of files) {
56
+ fileStore.put({
57
+ skillName: metadata.name,
58
+ path: file.path,
59
+ content: file.content
60
+ });
61
+ }
62
+
63
+ return new Promise((resolve, reject) => {
64
+ tx.oncomplete = () => resolve();
65
+ tx.onerror = () => reject(tx.error);
66
+ });
67
+ }
68
+
69
+ async getSkillFiles(skillName: string): Promise<SkillFile[]> {
70
+ const db = await this.getDB();
71
+ const tx = db.transaction(this.fileStore, 'readonly');
72
+ const store = tx.objectStore(this.fileStore);
73
+ const index = store.openCursor(IDBKeyRange.bound([skillName, ''], [skillName, '\uffff']));
74
+
75
+ const files: SkillFile[] = [];
76
+ return new Promise((resolve, reject) => {
77
+ index.onsuccess = (event) => {
78
+ const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result;
79
+ if (cursor) {
80
+ files.push({
81
+ path: cursor.value.path,
82
+ content: cursor.value.content
83
+ });
84
+ cursor.continue();
85
+ } else {
86
+ resolve(files);
87
+ }
88
+ };
89
+ index.onerror = () => reject(tx.error);
90
+ });
91
+ }
92
+
93
+ async getSkillMetadata(skillName: string): Promise<SkillMetadata | null> {
94
+ const db = await this.getDB();
95
+ const tx = db.transaction(this.metaStore, 'readonly');
96
+ const request = tx.objectStore(this.metaStore).get(skillName);
97
+
98
+ return new Promise((resolve, reject) => {
99
+ request.onsuccess = () => resolve(request.result || null);
100
+ request.onerror = () => reject(tx.error);
101
+ });
102
+ }
103
+
104
+ async listSkills(): Promise<SkillMetadata[]> {
105
+ const db = await this.getDB();
106
+ const tx = db.transaction(this.metaStore, 'readonly');
107
+ const request = tx.objectStore(this.metaStore).getAll();
108
+
109
+ return new Promise((resolve, reject) => {
110
+ request.onsuccess = () => resolve(request.result || []);
111
+ request.onerror = () => reject(tx.error);
112
+ });
113
+ }
114
+
115
+ async deleteSkill(skillName: string): Promise<void> {
116
+ const db = await this.getDB();
117
+ const tx = db.transaction([this.metaStore, this.fileStore], 'readwrite');
118
+
119
+ // 1. 删除元数据
120
+ tx.objectStore(this.metaStore).delete(skillName);
121
+
122
+ // 2. 删除所有关联文件
123
+ const fileStore = tx.objectStore(this.fileStore);
124
+ const index = fileStore.openCursor(IDBKeyRange.bound([skillName, ''], [skillName, '\uffff']));
125
+
126
+ index.onsuccess = (event) => {
127
+ const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result;
128
+ if (cursor) {
129
+ cursor.delete();
130
+ cursor.continue();
131
+ }
132
+ };
133
+
134
+ return new Promise((resolve, reject) => {
135
+ tx.oncomplete = () => resolve();
136
+ tx.onerror = () => reject(tx.error);
137
+ });
138
+ }
139
+ }
@@ -0,0 +1,106 @@
1
+ import { IVectorStore } from '../../interfaces/index.js';
2
+
3
+ export interface WebIndexedDbVectorStoreOptions {
4
+ dbName?: string;
5
+ storeName?: string;
6
+ }
7
+
8
+ export class WebIndexedDbVectorStore implements IVectorStore {
9
+ private dbName: string;
10
+ private storeName: string;
11
+ private db: IDBDatabase | null = null;
12
+
13
+ constructor(options: WebIndexedDbVectorStoreOptions = {}) {
14
+ this.dbName = options.dbName || 'js-agent-memory';
15
+ this.storeName = options.storeName || 'vector-store';
16
+ }
17
+
18
+ private async getDB(): Promise<IDBDatabase> {
19
+ if (this.db) return this.db;
20
+
21
+ return new Promise((resolve, reject) => {
22
+ const request = indexedDB.open(this.dbName, 1);
23
+
24
+ request.onupgradeneeded = (event: any) => {
25
+ const db = event.target.result;
26
+ if (!db.objectStoreNames.contains(this.storeName)) {
27
+ db.createObjectStore(this.storeName, { autoIncrement: true });
28
+ }
29
+ };
30
+
31
+ request.onsuccess = (event: any) => {
32
+ this.db = event.target.result;
33
+ resolve(this.db!);
34
+ };
35
+
36
+ request.onerror = (event: any) => {
37
+ reject(event.target.error);
38
+ };
39
+ });
40
+ }
41
+
42
+ async add(text: string, embedding: number[], metadata?: Record<string, any>): Promise<void> {
43
+ const db = await this.getDB();
44
+ return new Promise((resolve, reject) => {
45
+ const transaction = db.transaction([this.storeName], 'readwrite');
46
+ const store = transaction.objectStore(this.storeName);
47
+ const request = store.add({ text, embedding, metadata, timestamp: Date.now() });
48
+
49
+ request.onsuccess = () => resolve();
50
+ request.onerror = (event: any) => reject(event.target.error);
51
+ });
52
+ }
53
+
54
+ async getAll(): Promise<Array<{ text: string; embedding: number[]; metadata?: Record<string, any> }>> {
55
+ const db = await this.getDB();
56
+ return new Promise((resolve, reject) => {
57
+ const transaction = db.transaction([this.storeName], 'readonly');
58
+ const store = transaction.objectStore(this.storeName);
59
+ const request = store.getAll();
60
+
61
+ request.onsuccess = (event: any) => resolve(event.target.result);
62
+ request.onerror = (event: any) => reject(event.target.error);
63
+ });
64
+ }
65
+
66
+ async search(queryEmbedding: number[], topK: number = 3): Promise<Array<{ text: string; score: number; metadata?: Record<string, any> }>> {
67
+ const items = await this.getAll();
68
+ const scoredItems = items.map(item => ({
69
+ ...item,
70
+ score: this.cosineSimilarity(queryEmbedding, item.embedding)
71
+ }));
72
+
73
+ return scoredItems
74
+ .sort((a, b) => b.score - a.score)
75
+ .slice(0, topK)
76
+ .map(({ text, score, metadata }) => ({ text, score, metadata }));
77
+ }
78
+
79
+ async searchByKeyword(keyword: string, topK: number = 3): Promise<Array<{ text: string; score: number; metadata?: Record<string, any> }>> {
80
+ const items = await this.getAll();
81
+ const lowKeyword = keyword.toLowerCase();
82
+
83
+ return items
84
+ .filter(item => item.text.toLowerCase().includes(lowKeyword))
85
+ .map(item => ({
86
+ text: item.text,
87
+ score: 1.0,
88
+ metadata: item.metadata
89
+ }))
90
+ .slice(0, topK);
91
+ }
92
+
93
+ private cosineSimilarity(vecA: number[], vecB: number[]): number {
94
+ if (vecA.length !== vecB.length) return 0;
95
+ let dotProduct = 0;
96
+ let normA = 0;
97
+ let normB = 0;
98
+ for (let i = 0; i < vecA.length; i++) {
99
+ dotProduct += vecA[i] * vecB[i];
100
+ normA += vecA[i] * vecA[i];
101
+ normB += vecB[i] * vecB[i];
102
+ }
103
+ const magnitude = Math.sqrt(normA) * Math.sqrt(normB);
104
+ return magnitude === 0 ? 0 : dotProduct / magnitude;
105
+ }
106
+ }
@@ -0,0 +1,22 @@
1
+ export * from './WebIndexedDbSkillStore.js';
2
+ export * from './WebIndexedDbVectorStore.js';
3
+ export * from './SkillLoader.js';
4
+
5
+ // 我们不在这里使用 top-level await,以保持对旧版浏览器的兼容性
6
+ // 如果需要 NodeFsSkillStore,用户可以直接从 ./NodeFsSkillStore.js 导入
7
+ // 或者在运行时通过动态 import 获取
8
+ export const getNodeFsSkillStore = async () => {
9
+ if (typeof process !== 'undefined' && process.versions?.node) {
10
+ const { NodeFsSkillStore } = await import('./NodeFsSkillStore.js');
11
+ return NodeFsSkillStore;
12
+ }
13
+ return null;
14
+ };
15
+
16
+ export const getNodeFsVectorStore = async () => {
17
+ if (typeof process !== 'undefined' && process.versions?.node) {
18
+ const { NodeFsVectorStore } = await import('./NodeFsVectorStore.js');
19
+ return NodeFsVectorStore;
20
+ }
21
+ return null;
22
+ };
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './interfaces/index.js';
2
+ export * from './core/index.js';
@@ -0,0 +1,46 @@
1
+ export type AgentEventType =
2
+ | 'start'
3
+ | 'think'
4
+ | 'tool.call'
5
+ | 'tool.call.delta'
6
+ | 'tool.progress'
7
+ | 'tool.result'
8
+ | 'tool.require_approval' // ✨ 新增:人机协作审批事件
9
+ | 'task.plan'
10
+ | 'task.update'
11
+ | 'memory.update'
12
+ | 'memory.usage'
13
+ | 'memory.add'
14
+ | 'agent.done'
15
+ | 'agent.error';
16
+
17
+ // 定义外部给出的审批结果
18
+ export interface ApprovalResult {
19
+ approved: boolean; // 用户是否同意
20
+ feedback?: string; // 用户的文字反馈(特别是拒绝时,如 "路径错了,应该是 /tmp")
21
+ modifiedArgs?: any; // 进阶:用户修正后的参数
22
+ }
23
+
24
+ // 审批事件的 Payload
25
+ export interface ToolApprovalPayload {
26
+ toolCallId: string; // 唯一标识这次特定的调用
27
+ toolName: string;
28
+ arguments: any;
29
+ resolve: (result: ApprovalResult) => void;
30
+ reject: (error: Error) => void;
31
+ }
32
+
33
+ export interface IAgentEvent<T = any> {
34
+ id: string; // 唯一 ID,用于追踪、去重或回放
35
+ type: AgentEventType;
36
+ payload: T;
37
+ timestamp: number;
38
+ agentId?: string; // 所属 Agent ID
39
+ traceId?: string; // 追踪 ID,关联同一请求的多次事件
40
+ }
41
+
42
+ export interface IEventEmitter {
43
+ on<T = any>(event: AgentEventType, listener: (payload: T) => void): void;
44
+ off<T = any>(event: AgentEventType, listener: (payload: T) => void): void;
45
+ emit<T = any>(event: AgentEventType, payload: T): void;
46
+ }
@@ -0,0 +1,22 @@
1
+ import { LLMMessage } from './ILLMProvider.js';
2
+ import { TaskList } from './IPlanner.js';
3
+
4
+ export interface IAgentState {
5
+ history: LLMMessage[];
6
+ taskList?: TaskList;
7
+ skills: {
8
+ active: string[];
9
+ registered: string[];
10
+ };
11
+ tools: string[];
12
+ config: {
13
+ model: string;
14
+ routerModel?: string;
15
+ enableDynamicSkills: boolean;
16
+ maxIterations: number;
17
+ };
18
+ metadata: {
19
+ version: string;
20
+ exportedAt: string;
21
+ };
22
+ }
@@ -0,0 +1,47 @@
1
+ export interface LLMMessage {
2
+ role: 'system' | 'user' | 'assistant' | 'tool';
3
+ content: string;
4
+ name?: string;
5
+ tool_call_id?: string;
6
+ toolCalls?: Array<{
7
+ id: string;
8
+ type: 'function';
9
+ function: {
10
+ name: string;
11
+ arguments: string;
12
+ };
13
+ }>;
14
+ }
15
+
16
+ export interface LLMOptions {
17
+ model: string;
18
+ temperature?: number;
19
+ max_tokens?: number;
20
+ stream?: boolean;
21
+ tools?: any[];
22
+ intent?: 'plan' | 'replan' | 'execute';
23
+ }
24
+
25
+ export interface LLMResponse {
26
+ content: string;
27
+ toolCalls?: Array<{
28
+ id: string;
29
+ type: 'function';
30
+ function: {
31
+ name: string;
32
+ arguments: string;
33
+ };
34
+ }>;
35
+ }
36
+
37
+ export interface LLMResponseChunk {
38
+ content?: string;
39
+ toolCalls?: any[]; // Delta tool calls or full tool calls
40
+ }
41
+
42
+ export interface ILLMProvider {
43
+ generate(messages: LLMMessage[], options: LLMOptions): Promise<LLMResponse>;
44
+ stream?(messages: LLMMessage[], options: LLMOptions, onChunk: (chunk: LLMResponseChunk) => void): Promise<LLMResponse>;
45
+ embed?(text: string | string[]): Promise<number[][]>;
46
+ }
47
+
@@ -0,0 +1,16 @@
1
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
2
+
3
+ export interface LogContext {
4
+ traceId?: string;
5
+ agentId?: string;
6
+ iteration?: number;
7
+ toolName?: string;
8
+ rawPayload?: any; // Raw LLM response/request
9
+ stack?: string; // Error stack
10
+ latency?: number; // Latency monitoring
11
+ [key: string]: any; // Extended fields
12
+ }
13
+
14
+ export interface ILogger {
15
+ log(level: LogLevel, message: string, context?: LogContext): void | Promise<void>;
16
+ }
@@ -0,0 +1,29 @@
1
+ import { LLMMessage } from './ILLMProvider.js';
2
+
3
+ export interface MemoryOptions {
4
+ limit?: number;
5
+ metadata?: Record<string, any>;
6
+ }
7
+
8
+ export interface IMemory {
9
+ add(message: LLMMessage): Promise<void>;
10
+ getHistory(): Promise<LLMMessage[]>;
11
+ clear(): Promise<void>;
12
+ getContext?(input: string): Promise<string>;
13
+ }
14
+
15
+ export interface IVectorStore {
16
+ add(text: string, embedding: number[], metadata?: Record<string, any>): Promise<void>;
17
+ search(queryEmbedding: number[], topK?: number): Promise<Array<{ text: string; score: number; metadata?: Record<string, any> }>>;
18
+ searchByKeyword?(keyword: string, topK?: number): Promise<Array<{ text: string; score: number; metadata?: Record<string, any> }>>;
19
+ }
20
+
21
+ export interface IEmbedder {
22
+ embed(text: string): Promise<number[]>;
23
+ }
24
+
25
+ export interface ILongTermMemory extends IMemory {
26
+ remember(input: string): Promise<void>;
27
+ recall(query: string): Promise<string[]>;
28
+ }
29
+
@@ -0,0 +1,22 @@
1
+ import { ITool } from './ITool.js';
2
+
3
+ export interface Task {
4
+ id: string;
5
+ goal: string;
6
+ criteria: string;
7
+ dependsOn: string[];
8
+ status: 'pending' | 'in_progress' | 'completed' | 'failed';
9
+ result?: any;
10
+ error?: string;
11
+ }
12
+
13
+ export interface TaskList {
14
+ tasks: Task[];
15
+ isCompleted: boolean;
16
+ response?: string;
17
+ }
18
+
19
+ export interface IPlanner {
20
+ plan(input: string, tools: ITool[], context?: string, onChunk?: (chunk: string) => void): Promise<TaskList>;
21
+ replan(input: string, tools: ITool[], currentTaskList: TaskList, errorContext: string, onChunk?: (chunk: string) => void): Promise<TaskList>;
22
+ }
@@ -0,0 +1,9 @@
1
+ import { ITool } from './ITool.js';
2
+
3
+ export interface ISkill {
4
+ name: string;
5
+ description?: string;
6
+ tools: ITool[];
7
+ onInit?(context: any): void | Promise<void>;
8
+ systemPrompt?(context: any): string | Promise<string>;
9
+ }
@@ -0,0 +1,60 @@
1
+ import { ZodSchema } from 'zod';
2
+
3
+ /**
4
+ * 技能支持的运行环境
5
+ */
6
+ export type SkillRuntime = 'javascript' | 'python' | 'bash' | 'wasm';
7
+
8
+ /**
9
+ * 技能元数据规范 (metadata.json)
10
+ */
11
+ export interface SkillMetadata {
12
+ name: string;
13
+ description: string;
14
+ version: string;
15
+ runtime: SkillRuntime;
16
+ entry: string; // 入口文件路径,如 index.js 或 main.py
17
+ parameters?: ZodSchema; // 参数定义的 Zod Schema (持久化时可能需要序列化为 JSON)
18
+ author?: 'human' | 'agent';
19
+ createdAt: string;
20
+ updatedAt: string;
21
+ }
22
+
23
+ /**
24
+ * 技能文件信息
25
+ */
26
+ export interface SkillFile {
27
+ path: string; // 相对技能根目录的路径,如 index.js, utils/helper.py
28
+ content: string | Uint8Array; // 文件内容 (字符串或二进制)
29
+ }
30
+
31
+ /**
32
+ * 统一的技能存储接口
33
+ * 屏蔽 Node.js (FileSystem) 和 Web (IndexedDB) 的差异
34
+ */
35
+ export interface ISkillStore {
36
+ /**
37
+ * 保存一个完整的技能包 (含多个文件)
38
+ */
39
+ saveSkill(metadata: SkillMetadata, files: SkillFile[]): Promise<void>;
40
+
41
+ /**
42
+ * 获取指定技能的所有文件
43
+ */
44
+ getSkillFiles(skillName: string): Promise<SkillFile[]>;
45
+
46
+ /**
47
+ * 获取指定技能的元数据
48
+ */
49
+ getSkillMetadata(skillName: string): Promise<SkillMetadata | null>;
50
+
51
+ /**
52
+ * 列出所有已存储技能的元数据
53
+ */
54
+ listSkills(): Promise<SkillMetadata[]>;
55
+
56
+ /**
57
+ * 删除一个技能及其所有文件
58
+ */
59
+ deleteSkill(skillName: string): Promise<void>;
60
+ }