@aix-chat/core 0.1.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.
- package/dist/bridge/ChatBridge.d.ts +111 -0
- package/dist/bridge/ChatBridge.js +273 -0
- package/dist/bridge/index.d.ts +16 -0
- package/dist/bridge/index.js +25 -0
- package/dist/domain/block.d.ts +7 -0
- package/dist/domain/block.js +1 -0
- package/dist/domain/chat.d.ts +77 -0
- package/dist/domain/chat.js +265 -0
- package/dist/domain/conversation.d.ts +17 -0
- package/dist/domain/conversation.js +1 -0
- package/dist/domain/index.d.ts +7 -0
- package/dist/domain/index.js +2 -0
- package/dist/domain/message.d.ts +38 -0
- package/dist/domain/message.js +1 -0
- package/dist/domain/status.d.ts +10 -0
- package/dist/domain/status.js +30 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +31 -0
- package/dist/types/blocks.d.ts +78 -0
- package/dist/types/blocks.js +1 -0
- package/dist/types/context.d.ts +22 -0
- package/dist/types/context.js +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.js +6 -0
- package/dist/types/interaction.d.ts +46 -0
- package/dist/types/interaction.js +1 -0
- package/dist/types/message.d.ts +39 -0
- package/dist/types/message.js +1 -0
- package/dist/types/openclaw-blocks.d.ts +77 -0
- package/dist/types/openclaw-blocks.js +1 -0
- package/dist/types/panel.d.ts +71 -0
- package/dist/types/panel.js +1 -0
- package/dist/types/protocol.d.ts +48 -0
- package/dist/types/protocol.js +1 -0
- package/dist/types/provider.d.ts +15 -0
- package/dist/types/provider.js +1 -0
- package/dist/utils/EventEmitter.d.ts +18 -0
- package/dist/utils/EventEmitter.js +65 -0
- package/dist/utils/InteractionBuffer.d.ts +17 -0
- package/dist/utils/InteractionBuffer.js +64 -0
- package/package.json +85 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
3
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
5
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
6
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
7
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
8
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
9
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
10
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
11
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
|
12
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
13
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
14
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
15
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
16
|
+
/** 一个完整的对话轮次:用户消息 + (可选)AI 回应 */
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Chat — 核心交互实体
|
|
20
|
+
*
|
|
21
|
+
* 职责:
|
|
22
|
+
* - 接管 Provider 的 onMessage / onComplete / onError 回调
|
|
23
|
+
* - 维护消息列表与请求状态
|
|
24
|
+
* - 提供 subscribe / getSnapshot 供 React hooks 订阅
|
|
25
|
+
* - 支持 Turn 级重试(retry)
|
|
26
|
+
* - 通过 onComplete / onError 向外透传会话级事件
|
|
27
|
+
*
|
|
28
|
+
* 不负责:
|
|
29
|
+
* - WebSocket 连接管理(ConnectionStatus 由 hooks 层管理)
|
|
30
|
+
* - 历史分页加载
|
|
31
|
+
* - Provider 的创建与生命周期
|
|
32
|
+
*/
|
|
33
|
+
export var Chat = /*#__PURE__*/function () {
|
|
34
|
+
function Chat(provider) {
|
|
35
|
+
_classCallCheck(this, Chat);
|
|
36
|
+
_defineProperty(this, "provider", void 0);
|
|
37
|
+
/** 会话完成后的外部回调(由 useSessions 等注入) */
|
|
38
|
+
_defineProperty(this, "onComplete", void 0);
|
|
39
|
+
/** 会话出错后的外部回调 */
|
|
40
|
+
_defineProperty(this, "onError", void 0);
|
|
41
|
+
_defineProperty(this, "onMessage", void 0);
|
|
42
|
+
_defineProperty(this, "_messages", []);
|
|
43
|
+
_defineProperty(this, "_isRequesting", false);
|
|
44
|
+
_defineProperty(this, "_error", void 0);
|
|
45
|
+
_defineProperty(this, "_lastInput", void 0);
|
|
46
|
+
_defineProperty(this, "_listeners", new Set());
|
|
47
|
+
this.provider = provider;
|
|
48
|
+
this._wireCallbacks();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ── 内部 callback 接管 ──────────────────────────────────
|
|
52
|
+
_createClass(Chat, [{
|
|
53
|
+
key: "_wireCallbacks",
|
|
54
|
+
value: function _wireCallbacks() {
|
|
55
|
+
var _this = this;
|
|
56
|
+
this.provider.onMessage = function (msg) {
|
|
57
|
+
var _this$onMessage;
|
|
58
|
+
var idx = _this._messages.findIndex(function (m) {
|
|
59
|
+
return m.id === msg.id;
|
|
60
|
+
});
|
|
61
|
+
if (idx >= 0) {
|
|
62
|
+
_this._messages = _this._messages.map(function (m, i) {
|
|
63
|
+
return i === idx ? _objectSpread(_objectSpread({}, m), msg) : m;
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
_this._messages = [].concat(_toConsumableArray(_this._messages), [msg]);
|
|
67
|
+
}
|
|
68
|
+
(_this$onMessage = _this.onMessage) === null || _this$onMessage === void 0 || _this$onMessage.call(_this, msg);
|
|
69
|
+
_this._notify();
|
|
70
|
+
};
|
|
71
|
+
this.provider.onComplete = function (msgs) {
|
|
72
|
+
var _this$onComplete;
|
|
73
|
+
_this._isRequesting = false;
|
|
74
|
+
if (msgs !== null && msgs !== void 0 && msgs.length) {
|
|
75
|
+
var last = msgs[msgs.length - 1];
|
|
76
|
+
_this._messages = _this._messages.map(function (m) {
|
|
77
|
+
return m.id === last.id ? _objectSpread(_objectSpread({}, m), {}, {
|
|
78
|
+
status: 'done'
|
|
79
|
+
}) : m;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
_this._notify();
|
|
83
|
+
(_this$onComplete = _this.onComplete) === null || _this$onComplete === void 0 || _this$onComplete.call(_this, _this._messages);
|
|
84
|
+
};
|
|
85
|
+
this.provider.onError = function (error) {
|
|
86
|
+
var _this$onError;
|
|
87
|
+
_this._isRequesting = false;
|
|
88
|
+
_this._error = error;
|
|
89
|
+
_this._notify();
|
|
90
|
+
(_this$onError = _this.onError) === null || _this$onError === void 0 || _this$onError.call(_this, error);
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ── 公开操作 ────────────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 发起请求
|
|
98
|
+
* 调用后 isRequesting = true,Provider 回调驱动后续状态转换
|
|
99
|
+
*/
|
|
100
|
+
}, {
|
|
101
|
+
key: "send",
|
|
102
|
+
value: function send(input, assistantMessageId) {
|
|
103
|
+
var _this2 = this;
|
|
104
|
+
if (this._isRequesting) return;
|
|
105
|
+
this._isRequesting = true;
|
|
106
|
+
this._error = undefined;
|
|
107
|
+
this._lastInput = input;
|
|
108
|
+
this._notify();
|
|
109
|
+
this.provider.request(input, assistantMessageId).catch(function (err) {
|
|
110
|
+
// provider.onError 通常已处理,此处作为最后保障
|
|
111
|
+
if (_this2._isRequesting) {
|
|
112
|
+
var _this2$onError;
|
|
113
|
+
_this2._isRequesting = false;
|
|
114
|
+
_this2._error = err instanceof Error ? err : new Error(String(err));
|
|
115
|
+
_this2._notify();
|
|
116
|
+
(_this2$onError = _this2.onError) === null || _this2$onError === void 0 || _this2$onError.call(_this2, _this2._error);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** 中止当前请求 */
|
|
122
|
+
}, {
|
|
123
|
+
key: "abort",
|
|
124
|
+
value: function abort() {
|
|
125
|
+
this.provider.abort();
|
|
126
|
+
// isRequesting 由 onError / onComplete 回调置 false
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Turn 级重试
|
|
131
|
+
*
|
|
132
|
+
* 找到最后一个 Turn,如果其 assistant message 处于 error / aborted 状态,
|
|
133
|
+
* 则删除该 assistant message,使用相同的 input 重新发送。
|
|
134
|
+
*
|
|
135
|
+
* Turn 从 messages 数组中派生,不额外存储。
|
|
136
|
+
*/
|
|
137
|
+
}, {
|
|
138
|
+
key: "retry",
|
|
139
|
+
value: function retry() {
|
|
140
|
+
var _turn$assistantMessag;
|
|
141
|
+
if (this._isRequesting || !this._lastInput) return;
|
|
142
|
+
var turn = this._getLastTurn();
|
|
143
|
+
if (!turn) return;
|
|
144
|
+
var assistantStatus = (_turn$assistantMessag = turn.assistantMessage) === null || _turn$assistantMessag === void 0 ? void 0 : _turn$assistantMessag.status;
|
|
145
|
+
if (assistantStatus !== 'error' && assistantStatus !== 'aborted') return;
|
|
146
|
+
|
|
147
|
+
// 删除最后一个用户消息之后的所有 assistant 消息(清理失败的回应)
|
|
148
|
+
var userMsgIdx = this._messages.findIndex(function (m) {
|
|
149
|
+
return m.id === turn.userMessage.id;
|
|
150
|
+
});
|
|
151
|
+
if (userMsgIdx < 0) return;
|
|
152
|
+
this._messages = this._messages.slice(0, userMsgIdx + 1);
|
|
153
|
+
|
|
154
|
+
// 用相同的 input 重新发送
|
|
155
|
+
this.send(this._lastInput);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** 是否可以重试(最后一个 Turn 有失败的 assistant message) */
|
|
159
|
+
}, {
|
|
160
|
+
key: "canRetry",
|
|
161
|
+
value: function canRetry() {
|
|
162
|
+
var _turn$assistantMessag2;
|
|
163
|
+
if (this._isRequesting || !this._lastInput) return false;
|
|
164
|
+
var turn = this._getLastTurn();
|
|
165
|
+
var status = turn === null || turn === void 0 || (_turn$assistantMessag2 = turn.assistantMessage) === null || _turn$assistantMessag2 === void 0 ? void 0 : _turn$assistantMessag2.status;
|
|
166
|
+
return status === 'error' || status === 'aborted';
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** 手动添加一条消息(如用户消息、历史消息) */
|
|
170
|
+
}, {
|
|
171
|
+
key: "addMessage",
|
|
172
|
+
value: function addMessage(message) {
|
|
173
|
+
this._messages = [].concat(_toConsumableArray(this._messages), [message]);
|
|
174
|
+
this._notify();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** 批量设置消息列表(如加载历史、清空) */
|
|
178
|
+
}, {
|
|
179
|
+
key: "setMessages",
|
|
180
|
+
value: function setMessages(messages) {
|
|
181
|
+
this._messages = messages;
|
|
182
|
+
this._notify();
|
|
183
|
+
}
|
|
184
|
+
}, {
|
|
185
|
+
key: "getMessages",
|
|
186
|
+
value: function getMessages() {
|
|
187
|
+
return this._messages;
|
|
188
|
+
}
|
|
189
|
+
}, {
|
|
190
|
+
key: "getIsRequesting",
|
|
191
|
+
value: function getIsRequesting() {
|
|
192
|
+
return this._isRequesting;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ── React 订阅接口 ───────────────────────────────────────
|
|
196
|
+
}, {
|
|
197
|
+
key: "getSnapshot",
|
|
198
|
+
value: function getSnapshot() {
|
|
199
|
+
return {
|
|
200
|
+
messages: this._messages,
|
|
201
|
+
isRequesting: this._isRequesting,
|
|
202
|
+
error: this._error,
|
|
203
|
+
canRetry: this.canRetry()
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* 订阅状态变更,返回取消订阅函数
|
|
209
|
+
* 适用于 useSyncExternalStore / useEffect 场景
|
|
210
|
+
*/
|
|
211
|
+
}, {
|
|
212
|
+
key: "subscribe",
|
|
213
|
+
value: function subscribe(listener) {
|
|
214
|
+
var _this3 = this;
|
|
215
|
+
this._listeners.add(listener);
|
|
216
|
+
return function () {
|
|
217
|
+
return _this3._listeners.delete(listener);
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// ── 生命周期 ─────────────────────────────────────────────
|
|
222
|
+
|
|
223
|
+
/** 清理所有订阅和 Provider 回调,防止内存泄漏 */
|
|
224
|
+
}, {
|
|
225
|
+
key: "destroy",
|
|
226
|
+
value: function destroy() {
|
|
227
|
+
this._listeners.clear();
|
|
228
|
+
this.provider.onMessage = undefined;
|
|
229
|
+
this.provider.onComplete = undefined;
|
|
230
|
+
this.provider.onError = undefined;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// ── 私有工具 ─────────────────────────────────────────────
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* 从消息列表中派生最后一个 Turn
|
|
237
|
+
* Turn = 最后一条 user 消息 + 其后的 assistant 消息(若有)
|
|
238
|
+
*/
|
|
239
|
+
}, {
|
|
240
|
+
key: "_getLastTurn",
|
|
241
|
+
value: function _getLastTurn() {
|
|
242
|
+
for (var i = this._messages.length - 1; i >= 0; i--) {
|
|
243
|
+
if (this._messages[i].role === 'user') {
|
|
244
|
+
var userMessage = this._messages[i];
|
|
245
|
+
var assistantMessage = this._messages.slice(i + 1).find(function (m) {
|
|
246
|
+
return m.role === 'assistant';
|
|
247
|
+
});
|
|
248
|
+
return {
|
|
249
|
+
userMessage: userMessage,
|
|
250
|
+
assistantMessage: assistantMessage
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
}, {
|
|
257
|
+
key: "_notify",
|
|
258
|
+
value: function _notify() {
|
|
259
|
+
this._listeners.forEach(function (l) {
|
|
260
|
+
return l();
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}]);
|
|
264
|
+
return Chat;
|
|
265
|
+
}();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation — 会话元数据实体
|
|
3
|
+
* 管理层概念:会话的存在、命名、排序
|
|
4
|
+
* 不包含消息内容(消息由 Chat/MessageStore 管理)
|
|
5
|
+
*/
|
|
6
|
+
export interface Conversation {
|
|
7
|
+
/** 会话唯一标识 */
|
|
8
|
+
key: string;
|
|
9
|
+
/** 会话标题 */
|
|
10
|
+
title?: string;
|
|
11
|
+
/** 创建时间戳 */
|
|
12
|
+
createdAt?: number;
|
|
13
|
+
/** 最后活跃时间戳 */
|
|
14
|
+
lastActiveAt?: number;
|
|
15
|
+
/** 扩展字段 */
|
|
16
|
+
[key: string]: any;
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { Block } from './block';
|
|
2
|
+
export type { ChatMessage, MessageRole } from './message';
|
|
3
|
+
export type { MessageStatus } from './status';
|
|
4
|
+
export { canTransition, isTerminal, isActive } from './status';
|
|
5
|
+
export type { Conversation } from './conversation';
|
|
6
|
+
export { Chat } from './chat';
|
|
7
|
+
export type { ChatSnapshot } from './chat';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Block } from './block';
|
|
2
|
+
import type { MessageStatus } from './status';
|
|
3
|
+
/** 消息角色 */
|
|
4
|
+
export type MessageRole = 'user' | 'assistant' | 'system';
|
|
5
|
+
/** 附件类型 */
|
|
6
|
+
export type AttachmentType = 'image' | 'file';
|
|
7
|
+
/** 消息附件(后端协议格式) */
|
|
8
|
+
export interface MessageAttachment {
|
|
9
|
+
/** 附件类型: 'file' | 'image' */
|
|
10
|
+
type: AttachmentType;
|
|
11
|
+
/** 文件名称 */
|
|
12
|
+
fileName: string;
|
|
13
|
+
/** MIME 类型 */
|
|
14
|
+
mimeType: string;
|
|
15
|
+
/** 文件内容(Base64 编码) */
|
|
16
|
+
content: string;
|
|
17
|
+
}
|
|
18
|
+
/** 聊天消息 — 协议无关的领域实体 */
|
|
19
|
+
export interface ChatMessage {
|
|
20
|
+
/** 消息 ID */
|
|
21
|
+
id: string;
|
|
22
|
+
/** 消息角色 */
|
|
23
|
+
role: MessageRole;
|
|
24
|
+
/** 文本内容 */
|
|
25
|
+
content: string;
|
|
26
|
+
/** 消息状态 */
|
|
27
|
+
status: MessageStatus;
|
|
28
|
+
/** 所属会话 key */
|
|
29
|
+
sessionKey?: string;
|
|
30
|
+
/** 结构化内容块(Parser 输出) */
|
|
31
|
+
blocks?: Block[];
|
|
32
|
+
/** 消息附件列表(图片、文件等) */
|
|
33
|
+
attachments?: MessageAttachment[];
|
|
34
|
+
/** 创建时间戳(用于排序) */
|
|
35
|
+
createdAt?: number;
|
|
36
|
+
/** 扩展字段 */
|
|
37
|
+
extra?: Record<string, any>;
|
|
38
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MessageStatus — 消息生命周期状态机
|
|
3
|
+
*/
|
|
4
|
+
export type MessageStatus = 'history' | 'pending' | 'streaming' | 'done' | 'error' | 'aborted';
|
|
5
|
+
/** 判断状态转换是否合法 */
|
|
6
|
+
export declare function canTransition(from: MessageStatus, to: MessageStatus): boolean;
|
|
7
|
+
/** 是否为终态(不可再转换) */
|
|
8
|
+
export declare function isTerminal(status: MessageStatus): boolean;
|
|
9
|
+
/** 是否为活跃状态(正在处理中) */
|
|
10
|
+
export declare function isActive(status: MessageStatus): boolean;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MessageStatus — 消息生命周期状态机
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// 已中止,可重试
|
|
6
|
+
|
|
7
|
+
var VALID_TRANSITIONS = {
|
|
8
|
+
history: [],
|
|
9
|
+
pending: ['streaming', 'done', 'error', 'aborted'],
|
|
10
|
+
streaming: ['done', 'error', 'aborted'],
|
|
11
|
+
done: [],
|
|
12
|
+
error: ['pending'],
|
|
13
|
+
aborted: ['pending']
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/** 判断状态转换是否合法 */
|
|
17
|
+
export function canTransition(from, to) {
|
|
18
|
+
var _VALID_TRANSITIONS$fr, _VALID_TRANSITIONS$fr2;
|
|
19
|
+
return (_VALID_TRANSITIONS$fr = (_VALID_TRANSITIONS$fr2 = VALID_TRANSITIONS[from]) === null || _VALID_TRANSITIONS$fr2 === void 0 ? void 0 : _VALID_TRANSITIONS$fr2.includes(to)) !== null && _VALID_TRANSITIONS$fr !== void 0 ? _VALID_TRANSITIONS$fr : false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** 是否为终态(不可再转换) */
|
|
23
|
+
export function isTerminal(status) {
|
|
24
|
+
return VALID_TRANSITIONS[status].length === 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** 是否为活跃状态(正在处理中) */
|
|
28
|
+
export function isActive(status) {
|
|
29
|
+
return status === 'pending' || status === 'streaming';
|
|
30
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { ChatBridge, chatBridgeHelper, EventEmitter } from './bridge';
|
|
2
|
+
export type { ChatBridgeConfig, BridgeInputRef, BridgeHandler } from './bridge';
|
|
3
|
+
export type { Block } from './domain/block';
|
|
4
|
+
export type { ChatMessage, MessageRole, MessageAttachment, AttachmentType } from './domain/message';
|
|
5
|
+
export type { MessageStatus } from './domain/status';
|
|
6
|
+
export { canTransition, isTerminal, isActive } from './domain/status';
|
|
7
|
+
export type { Conversation as DomainConversation } from './domain/conversation';
|
|
8
|
+
export { Chat } from './domain/chat';
|
|
9
|
+
export type { ChatSnapshot } from './domain/chat';
|
|
10
|
+
export type { ToolCallInfo, ApprovalRequestDetail, ApprovalRequestPayload, } from './types/message';
|
|
11
|
+
export type { OpenClawBlock, TextBlock, ThinkingBlock, ToolExecutionBlock, ToolStep, ToolStatus, ApprovalBlock, ApprovalStatus, ImageBlock, } from './types/openclaw-blocks';
|
|
12
|
+
export type { AlertBlock, AlertSeverity, AlertVariant, } from './types/blocks';
|
|
13
|
+
export type { ParseResult } from './types/protocol';
|
|
14
|
+
export type { ChatProvider } from './types/provider';
|
|
15
|
+
export type { PanelTab, PanelAction, PanelActionEvent, PanelHandle, } from './types/panel';
|
|
16
|
+
export type { InteractionRecord, InteractionSource, InteractionAction, } from './types/interaction';
|
|
17
|
+
export type { AixContext } from './types/context';
|
|
18
|
+
export { InteractionBuffer } from './utils/InteractionBuffer';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// @aix-chat/core
|
|
3
|
+
//
|
|
4
|
+
// 职责:
|
|
5
|
+
// domain/ — 领域模型(Chat、Message、MessageStatus)
|
|
6
|
+
// bridge/ — 命令式控制(ChatBridge)
|
|
7
|
+
// types/ — 公共类型契约(ChatProvider 接口、ParseResult、OpenClawBlock 等)
|
|
8
|
+
// ============================================================
|
|
9
|
+
|
|
10
|
+
// ── Bridge(命令式聊天控制,纯 JS,无 React 依赖)────────────
|
|
11
|
+
export { ChatBridge, chatBridgeHelper, EventEmitter } from "./bridge";
|
|
12
|
+
|
|
13
|
+
// ── domain(领域模型)────────────────────────────────────────
|
|
14
|
+
|
|
15
|
+
export { canTransition, isTerminal, isActive } from "./domain/status";
|
|
16
|
+
export { Chat } from "./domain/chat";
|
|
17
|
+
|
|
18
|
+
// ── 公共类型 ────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
// ── OpenClaw block 类型(ui 渲染契约)───────────────────────
|
|
21
|
+
|
|
22
|
+
// ── 协议无关的通用 Block 类型 ────────────────────────────────
|
|
23
|
+
|
|
24
|
+
// ── 协议解析结果(ui/useOpenClawRun 使用)────────────────────
|
|
25
|
+
|
|
26
|
+
// ── Provider 接口(Chat 实体依赖)────────────────────────────
|
|
27
|
+
|
|
28
|
+
// ── Panel / Interaction / Context 类型(副屏体系)────────────
|
|
29
|
+
|
|
30
|
+
// ── 工具类 ────────────────────────────────────────────────────
|
|
31
|
+
export { InteractionBuffer } from "./utils/InteractionBuffer";
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { Block } from '../domain/block';
|
|
2
|
+
/**
|
|
3
|
+
* 系统提示的严重程度枚举。
|
|
4
|
+
*
|
|
5
|
+
* 用于驱动 `SystemNotice`(UI) 与 `AlertBlock`(数据) 的视觉表达与默认图标。
|
|
6
|
+
*
|
|
7
|
+
* - `info` — 中性信息提示(默认蓝色,ℹ 图标)
|
|
8
|
+
* - `success` — 成功反馈(绿色,✓ 图标)
|
|
9
|
+
* - `warning` — 警告提示(橙色,⚠ 图标)
|
|
10
|
+
* - `error` — 错误/失败(红色,✕ 图标)
|
|
11
|
+
* - `neutral` — 弱化中性(灰色,无图标)
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export type AlertSeverity = 'info' | 'success' | 'warning' | 'error' | 'neutral';
|
|
16
|
+
/**
|
|
17
|
+
* 系统提示的视觉变体。
|
|
18
|
+
*
|
|
19
|
+
* - `inline` — 居中、无气泡、字号小、颜色淡。适合"已切换模型"、"上下文已截断" 等
|
|
20
|
+
* 中性事件,融入消息流不打断阅读。
|
|
21
|
+
* - `alert` — 卡片形态、带边框/淡色背景,可挂载 `action`。适合"请求失败 [重试]"、
|
|
22
|
+
* "工具调用超时" 等需要被用户注意或操作的事件。
|
|
23
|
+
*
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
export type AlertVariant = 'inline' | 'alert';
|
|
27
|
+
/**
|
|
28
|
+
* 协议无关的"系统提示"内容块。
|
|
29
|
+
*
|
|
30
|
+
* 可以作为:
|
|
31
|
+
* 1. 独立 `ChatMessage`(role='system') 的 `blocks` 数组里的一员,渲染到消息流;
|
|
32
|
+
* 2. 嵌入 `ChatMessage`(role='assistant') 的 `blocks` 中,用于"AI 回答到一半
|
|
33
|
+
* 发生异常"的内联提示场景。
|
|
34
|
+
*
|
|
35
|
+
* UI 侧由 `@aix-chat/ui` 的 `SystemNotice` 组件渲染(已注册到
|
|
36
|
+
* `MessageRenderer` 的内置 renderers,所有 preset 自动支持)。
|
|
37
|
+
*
|
|
38
|
+
* @public
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* const alertBlock: AlertBlock = {
|
|
43
|
+
* type: 'alert',
|
|
44
|
+
* severity: 'warning',
|
|
45
|
+
* content: '工具调用超时,请重试',
|
|
46
|
+
* variant: 'alert',
|
|
47
|
+
* action: { label: '重试', actionId: 'retry-tool-call' },
|
|
48
|
+
* };
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export interface AlertBlock extends Block {
|
|
52
|
+
/** Block 判别字段,固定为 `'alert'` */
|
|
53
|
+
type: 'alert';
|
|
54
|
+
/**
|
|
55
|
+
* 严重程度,决定默认配色与图标。
|
|
56
|
+
* @see AlertSeverity
|
|
57
|
+
*/
|
|
58
|
+
severity: AlertSeverity;
|
|
59
|
+
/** 提示文案(纯文本,不解析 Markdown) */
|
|
60
|
+
content: string;
|
|
61
|
+
/**
|
|
62
|
+
* 视觉变体。未传时由渲染层默认为 `'inline'`。
|
|
63
|
+
* @see AlertVariant
|
|
64
|
+
*/
|
|
65
|
+
variant?: AlertVariant;
|
|
66
|
+
/**
|
|
67
|
+
* 可选的可序列化 action 描述。
|
|
68
|
+
*
|
|
69
|
+
* 区别于 React 节点形态的 action,这里使用 `{ label, actionId }` 以便穿越
|
|
70
|
+
* SSE/WS 协议持久化。消费方在 UI 层将 `actionId` 映射到具体的点击处理。
|
|
71
|
+
*/
|
|
72
|
+
action?: {
|
|
73
|
+
/** 按钮显示文案 */
|
|
74
|
+
label: string;
|
|
75
|
+
/** 业务侧自定义的 action 标识,消费方据此分发回调 */
|
|
76
|
+
actionId: string;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { InteractionRecord } from './interaction';
|
|
2
|
+
import type { PanelTab } from './panel';
|
|
3
|
+
/**
|
|
4
|
+
* 发消息时注入 Agent 的上下文包。
|
|
5
|
+
* 通过 PanelHandle.flushContext() 获取,注入到 ChatProvider.request() 的 panelContext 字段。
|
|
6
|
+
*/
|
|
7
|
+
export interface AixContext {
|
|
8
|
+
/**
|
|
9
|
+
* 副屏当前状态快照。
|
|
10
|
+
*/
|
|
11
|
+
panelState: {
|
|
12
|
+
tabs: Pick<PanelTab, 'id' | 'type' | 'title'>[];
|
|
13
|
+
activeTabId: string | null;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* 用户交互记录缓冲,flush 后清空。
|
|
17
|
+
*
|
|
18
|
+
* @internal SDK 提供积累机制,但数据由业务组件通过 onInteraction 自行上报。
|
|
19
|
+
* 当前阶段不作为平台能力对外推广,按需使用。
|
|
20
|
+
*/
|
|
21
|
+
interactions: InteractionRecord[];
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface InteractionSource {
|
|
2
|
+
/** 来源类型 */
|
|
3
|
+
type: 'panel' | 'aix-ui' | string;
|
|
4
|
+
/** 来源 panel ID(type==='panel' 时) */
|
|
5
|
+
panel?: string;
|
|
6
|
+
/** 目标元素,如 "node:xxx" */
|
|
7
|
+
target?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface InteractionAction {
|
|
10
|
+
/** 动词,如 "select"、"edit"、"delete" */
|
|
11
|
+
verb: string;
|
|
12
|
+
/** 主体描述,如 "node"、"edge" */
|
|
13
|
+
subject: string;
|
|
14
|
+
/** 操作参数 */
|
|
15
|
+
params?: Record<string, any>;
|
|
16
|
+
/** 操作前快照 */
|
|
17
|
+
before?: any;
|
|
18
|
+
/** 操作后快照 */
|
|
19
|
+
after?: any;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 用户交互记录协议
|
|
23
|
+
*
|
|
24
|
+
* 每条独立保留(不聚合),聚合后注入 provider.request() 的 panelContext 字段。
|
|
25
|
+
* description 由业务方生成,Agent 直接读取。
|
|
26
|
+
*/
|
|
27
|
+
export interface InteractionRecord {
|
|
28
|
+
id: string;
|
|
29
|
+
timestamp: number;
|
|
30
|
+
source: InteractionSource;
|
|
31
|
+
action: InteractionAction;
|
|
32
|
+
/** 自然语言描述,Agent 直接读取 */
|
|
33
|
+
description: string;
|
|
34
|
+
/**
|
|
35
|
+
* 操作发生时组件的当前状态快照。
|
|
36
|
+
* 业务组件用此字段上报整体状态(如当前选中节点列表、表单当前值等)。
|
|
37
|
+
* Agent 通过最近一条记录的 snapshot 了解组件当前状态。
|
|
38
|
+
*/
|
|
39
|
+
snapshot?: Record<string, any>;
|
|
40
|
+
/**
|
|
41
|
+
* 本次操作的附加结构化数据(比 action.params 更细)。
|
|
42
|
+
* 用于描述操作本身,而非组件整体状态。
|
|
43
|
+
* SDK 不解析,原样透传给 Agent。
|
|
44
|
+
*/
|
|
45
|
+
data?: Record<string, any>;
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type { Block } from '../domain/block';
|
|
2
|
+
export type { ChatMessage, MessageRole } from '../domain/message';
|
|
3
|
+
export type { MessageStatus } from '../domain/status';
|
|
4
|
+
/**
|
|
5
|
+
* 工具调用信息(ParseResult 引用)
|
|
6
|
+
*/
|
|
7
|
+
export interface ToolCallInfo {
|
|
8
|
+
id: string;
|
|
9
|
+
toolName: string;
|
|
10
|
+
phase: 'start' | 'result';
|
|
11
|
+
arguments?: any;
|
|
12
|
+
success?: boolean;
|
|
13
|
+
result?: any;
|
|
14
|
+
error?: any;
|
|
15
|
+
startTime?: number;
|
|
16
|
+
endTime?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 审批请求详情(ParseResult 引用)
|
|
20
|
+
*/
|
|
21
|
+
export interface ApprovalRequestDetail {
|
|
22
|
+
command?: string;
|
|
23
|
+
cwd?: string;
|
|
24
|
+
host?: string;
|
|
25
|
+
security?: string;
|
|
26
|
+
ask?: string;
|
|
27
|
+
agentId?: string;
|
|
28
|
+
resolvedPath?: string;
|
|
29
|
+
sessionKey?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 审批请求信息(ParseResult 引用)
|
|
33
|
+
*/
|
|
34
|
+
export interface ApprovalRequestPayload {
|
|
35
|
+
id: string;
|
|
36
|
+
request: ApprovalRequestDetail;
|
|
37
|
+
createdAtMs?: number;
|
|
38
|
+
expiresAtMs?: number;
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|