my-ai-chat-framework 1.1.0 → 2.0.0

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.
@@ -1,126 +1,32 @@
1
- /**
2
- * 简单的事件发射器类
3
- * 实现观察者模式,允许对象监听和触发事件
4
- */
5
- class EventEmitter {
6
- constructor() {
7
- //存储事件和对应的回调数组
8
- //结构:
9
- // { 'event_name': [ callback1, callback2 ] }
10
- this.events = {}
11
- }
12
-
13
- /**
14
- * 监听事件
15
- * @param {string} eventName - 要注册的事件名称
16
- * @param {Function} callback - 事件触发时执行的回调函数
17
- */
18
- //实现一个监听事件的方法
19
- on(eventName, callback) {
20
- //1.如果没有事件数组,先创建
21
- if (!this.events[eventName]) {
22
- this.events[eventName] = []
23
- }
24
-
25
- //2.给数组添加(push)事件
26
- this.events[eventName].push(callback)
27
-
28
- //返回一个取消键听得函数(方便实用)
29
- return () => this.off(eventName, callback)
30
- }
31
-
32
- /**
33
- * 触发事件
34
- * @param {string} eventName --要触发的事件名称
35
- * @param {any} data --传递给回调函数的数据
36
- */
37
- emit(eventName, data) {
38
- //获取这个事件的所有回调函数
39
- const callbacks = this.events[eventName]
40
-
41
- //仅在有回调函数时调用他们,否则提前退出(可以这么写吧?少一层嵌套)
42
- if (!callbacks) return
43
-
44
- //使用slice()创建副本,放置在循环中修改数组导致问题
45
- const callbakesCopy = callbacks.slice()
46
-
47
- for (let i = 0; i < callbakesCopy.length; i++) {
48
- try {
49
- //执行回调函数,并传入数据
50
- callbakesCopy[i](data)
51
- } catch (error) {
52
- // 如果某个回调出错,不影响其他回调
53
- console.error(`事件 ${eventName} 的回调函数执行出错:`, error)
54
- }
55
- }
56
- }
57
-
58
- /**
59
- * 取消监听事件
60
- * @param {string} eventName --要取消的事件名称
61
- * @param {Function} callback --要移除的回调函数
62
- */
63
- off(eventName, callback) {
64
- const callbacks = this.events[eventName]
65
-
66
- //判断一下防止报错
67
- if (!callbacks) return
68
-
69
- //过滤掉要移除的回调函数
70
- this.events[eventName] = callbacks.filter(item => item !== callback)
71
-
72
- // 如果这个事件没有监听器了,删除这个事件
73
- if (this.events[eventName].length === 0) {
74
- delete this.events[eventName]
75
- }
76
- }
77
-
78
- /**
79
- * 只监听一次事件(触发后自动取消)
80
- * @param {string} eventName - 事件名称
81
- * @param {Function} callback - 回调函数
82
- */
83
- once(evenName, callback) {
84
- // 创建一个包装函数,执行完成后自动取消
85
- const onceCallback = (data) => {
86
- //先取消监听
87
- this.off(evenName, onceCallback)
88
- //在执行原回调
89
- callback(data)
90
- }
91
-
92
- //监听包装后的函数
93
- this.on(evenName, onceCallback)
94
-
95
- //返回取消函数
96
- return () => this.off(evenName, onceCallback)
97
- }
98
-
99
- /**
100
- * 移除某个事件的所有监听器
101
- * @param {string} eventName - 事件名称
102
- */
103
- removeAllListeners(eventName) {
104
- if (eventName) {
105
- // 移除指定事件的所有监听器
106
- delete this.events[eventName]
107
- } else {
108
- // 如果没有指定事件名,移除所有事件的监听器
109
- this.events = {}
110
- }
111
- }
112
-
113
- /**
114
- * 获取某个事件的所有监听器数量
115
- * @param {string} eventName - 事件名称
116
- * @returns {number} 监听器数量
117
- */
118
- listenerCount(eventName) {
119
- const callbacks = this.events[eventName]
120
- return callbacks ? callbacks.length : 0
121
- }
122
-
123
- }
124
-
125
- //导出EventEmiter类
126
- export default EventEmitter
1
+ /**
2
+ * 极简事件发射器
3
+ */
4
+ export class EventEmitter {
5
+ constructor() {
6
+ this._events = new Map();
7
+ }
8
+
9
+ on(event, handler) {
10
+ if (!this._events.has(event)) this._events.set(event, []);
11
+ this._events.get(event).push(handler);
12
+ return () => this.off(event, handler);
13
+ }
14
+
15
+ off(event, handler) {
16
+ if (!this._events.has(event)) return;
17
+ const handlers = this._events.get(event).filter(h => h !== handler);
18
+ if (handlers.length) this._events.set(event, handlers);
19
+ else this._events.delete(event);
20
+ }
21
+
22
+ emit(event, data) {
23
+ if (!this._events.has(event)) return;
24
+ for (const handler of this._events.get(event)) {
25
+ try {
26
+ handler(data);
27
+ } catch (err) {
28
+ console.error(`事件 ${event} 处理出错:`, err);
29
+ }
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * 消息存储 - 极简实现
3
+ * 每条消息格式:
4
+ * {
5
+ * id?: string,
6
+ * role: 'user'|'assistant'|'system'|'tool',
7
+ * content: string,
8
+ * toolCalls?: Array,
9
+ * toolCallId?: string,
10
+ * timestamp?: number,
11
+ * metadata?: any
12
+ * }
13
+ */
14
+ export class MessageStore {
15
+ constructor() {
16
+ this._messages = [];
17
+ this._idCounter = 0;
18
+ }
19
+
20
+ add(message) {
21
+ const msg = {
22
+ id: message.id || `msg_${Date.now()}_${++this._idCounter}`,
23
+ timestamp: message.timestamp || Date.now(),
24
+ ...message
25
+ };
26
+ this._messages.push(msg);
27
+ return msg;
28
+ }
29
+
30
+ addUser(content, metadata = {}) {
31
+ return this.add({ role: 'user', content, metadata });
32
+ }
33
+
34
+ addAssistant(content, metadata = {}) {
35
+ return this.add({ role: 'assistant', content, metadata });
36
+ }
37
+
38
+ addSystem(content, metadata = {}) {
39
+ return this.add({ role: 'system', content, metadata });
40
+ }
41
+
42
+ addTool(content, toolCallId, metadata = {}) {
43
+ return this.add({ role: 'tool', content, toolCallId, metadata });
44
+ }
45
+
46
+ getLast() {
47
+ return this._messages[this._messages.length - 1] || null;
48
+ }
49
+
50
+ getAll() {
51
+ return [...this._messages];
52
+ }
53
+
54
+ clear() {
55
+ this._messages = [];
56
+ }
57
+
58
+ // 撤回最后一条助手消息及其后的所有消息(用于工具调用循环)
59
+ undoToLastAssistant() {
60
+ let lastAssistantIndex = -1;
61
+ for (let i = this._messages.length - 1; i >= 0; i--) {
62
+ if (this._messages[i].role === 'assistant') {
63
+ lastAssistantIndex = i;
64
+ break;
65
+ }
66
+ }
67
+ if (lastAssistantIndex >= 0) {
68
+ const removed = this._messages.splice(lastAssistantIndex + 1);
69
+ return removed;
70
+ }
71
+ return [];
72
+ }
73
+ }