@ray-js/t-agent 0.0.9-beta-2 → 0.0.9-beta-4

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/README-zh_CN.md CHANGED
@@ -572,6 +572,10 @@ ui 插件的主要事件如下,你还可以自由地注册需要的事件:
572
572
  - `payload.blocks: InputBlock[]` 输入块
573
573
  - `setInputBlocks` 设置输入块到 MessageInput 输入框
574
574
  - `payload.blocks: InputBlock[]` 输入块
575
+ - `sessionChange`: 会话数据变化
576
+ - `payload.key: string`: 会话数据 key
577
+ - `payload.value: any`: 会话数据 value
578
+ - `payload.oldValue: any`: 会话数据旧值
575
579
 
576
580
  > 注意,这里的 ChatMessageObject 是一个消息对象,不是 ChatMessage 类型,
577
581
  > 它包含了消息的一些属性和方法,这是为了避免在 UI 层修改消息对象,导致 ChatAgent 中的消息对象不一致。
@@ -1151,7 +1155,7 @@ const MyComponent = () => {
1151
1155
  import { useTileProps } from '@ray-js/t-agent-ui-ray';
1152
1156
 
1153
1157
  const MyTilePart = () => {
1154
- const { message, agent, tile, emitEvent } = useTileProps();
1158
+ const { message, agent, tile, emitTileEvent } = useTileProps();
1155
1159
 
1156
1160
  return <div>My Tile</div>;
1157
1161
  };
@@ -1236,8 +1240,8 @@ import {
1236
1240
  import { View, Text, Button } from '@ray-js/ray';
1237
1241
 
1238
1242
  const MyCard: ChatCardComponent<{ title: string }, { clicked: boolean }> = props => {
1239
- // 如果你需要拿到 agent、message、tile、emitEvent 等属性,可以使用 useTileProps
1240
- const { message, agent, tile, emitEvent } = useTileProps();
1243
+ // 如果你需要拿到 agent、message、tile、emitTileEvent 等属性,可以使用 useTileProps
1244
+ const { message, agent, tile, emitTileEvent } = useTileProps();
1241
1245
  const { card, setCardState } = props;
1242
1246
  const { cardData, cardState, cardCode } = card as ChatCardObject<{ title: string }>;
1243
1247
 
package/README.md CHANGED
@@ -567,6 +567,10 @@ The main events of the UI plugin are as follows, and you can freely register add
567
567
  - `payload.blocks: InputBlock[]`: Input blocks
568
568
  - `setInputBlocks`: Set input blocks in MessageInput
569
569
  - `payload.blocks: InputBlock[]`: Input blocks
570
+ - `sessionChange`: Session data changes
571
+ - `payload.key: string`: Session key
572
+ - `payload.value: any`: Session value
573
+ - `payload.oldValue: any`: Old session value
570
574
 
571
575
  > Note: `ChatMessageObject` here is a message object, not a `ChatMessage` type.
572
576
  > It contains various attributes and methods to ensure changes are made in the ChatAgent, avoiding conflicts with the UI layer.
@@ -1146,7 +1150,7 @@ Get the `TileProps` object in the tile component; if it's a tile, you can direct
1146
1150
  import { useTileProps } from '@ray-js/t-agent-ui-ray';
1147
1151
 
1148
1152
  const MyTilePart = () => {
1149
- const { message, agent, tile, emitEvent } = useTileProps();
1153
+ const { message, agent, tile, emitTileEvent } = useTileProps();
1150
1154
 
1151
1155
  return <div>My Tile</div>;
1152
1156
  };
@@ -1231,8 +1235,8 @@ import {
1231
1235
  import { View, Text, Button } from '@ray-js/ray';
1232
1236
 
1233
1237
  const MyCard: ChatCardComponent<{ title: string }, { clicked: boolean }> = props => {
1234
- // If you need to access attributes like agent, message, tile, emitEvent, use useTileProps
1235
- const { message, agent, tile, emitEvent } = useTileProps();
1238
+ // If you need to access attributes like agent, message, tile, emitTileEvent, use useTileProps
1239
+ const { message, agent, tile, emitTileEvent } = useTileProps();
1236
1240
  const { card, setCardState } = props;
1237
1241
  const { cardData, cardState, cardCode } = card as ChatCardObject<{ title: string }>;
1238
1242
 
@@ -1,4 +1,5 @@
1
1
  import ChatAgent from './ChatAgent';
2
+ import ChatSession from './ChatSession';
2
3
  import StreamResponse from './StreamResponse';
3
4
  import ChatTile from './ChatTile';
4
5
  import ChatBubbleTile from './ChatBubbleTile';
@@ -7,6 +8,6 @@ import { generateId, safeParseJSON, isAbortError, shuffleWithSeed } from './util
7
8
  import Logger, { getLogger } from './Logger';
8
9
  import { Emitter, EmitterEvent } from './Emitter';
9
10
  export { createHooks, Hookable } from 'hookable';
10
- export { ChatAgent, StreamResponse, ChatTile, ChatBubbleTile, ChatMessage, generateId, safeParseJSON, getLogger, Logger, Emitter, EmitterEvent, isAbortError, shuffleWithSeed, };
11
+ export { ChatAgent, ChatSession, StreamResponse, ChatTile, ChatBubbleTile, ChatMessage, generateId, safeParseJSON, getLogger, Logger, Emitter, EmitterEvent, isAbortError, shuffleWithSeed, };
11
12
  export * from './createChatAgent';
12
13
  export * from './types';
@@ -1,4 +1,5 @@
1
1
  import ChatAgent from './ChatAgent';
2
+ import ChatSession from './ChatSession';
2
3
  import StreamResponse from './StreamResponse';
3
4
  import ChatTile from './ChatTile';
4
5
  import ChatBubbleTile from './ChatBubbleTile';
@@ -7,6 +8,6 @@ import { generateId, safeParseJSON, isAbortError, shuffleWithSeed } from './util
7
8
  import Logger, { getLogger } from './Logger';
8
9
  import { Emitter, EmitterEvent } from './Emitter';
9
10
  export { createHooks, Hookable } from 'hookable';
10
- export { ChatAgent, StreamResponse, ChatTile, ChatBubbleTile, ChatMessage, generateId, safeParseJSON, getLogger, Logger, Emitter, EmitterEvent, isAbortError, shuffleWithSeed };
11
+ export { ChatAgent, ChatSession, StreamResponse, ChatTile, ChatBubbleTile, ChatMessage, generateId, safeParseJSON, getLogger, Logger, Emitter, EmitterEvent, isAbortError, shuffleWithSeed };
11
12
  export * from './createChatAgent';
12
13
  export * from './types';
@@ -1,5 +1,5 @@
1
1
  export declare function generateId(length?: number): string;
2
- export declare function deepCloneToPlainObject(obj: any): any;
2
+ export declare function deepCloneToPlainObject(obj: any, visited?: WeakMap<object, any>): any;
3
3
  export declare function safeParseJSON<T = any>(str: any): T | undefined;
4
4
  export declare function deepMerge(target: any, source: any): any;
5
5
  export declare function isAbortError(reason: any): any;
@@ -1,6 +1,6 @@
1
- import "core-js/modules/esnext.iterator.constructor.js";
2
- import "core-js/modules/esnext.iterator.filter.js";
3
- import "core-js/modules/esnext.iterator.map.js";
1
+ import "core-js/modules/es.regexp.constructor.js";
2
+ import "core-js/modules/es.regexp.dot-all.js";
3
+ import "core-js/modules/es.regexp.exec.js";
4
4
  import "core-js/modules/web.dom-collections.iterator.js";
5
5
  /* eslint no-bitwise: 0 */
6
6
 
@@ -15,34 +15,76 @@ export function generateId() {
15
15
  return result;
16
16
  }
17
17
  export function deepCloneToPlainObject(obj) {
18
- // 判断是否是对象或数组
19
- if (obj === null || typeof obj !== 'object') {
20
- return undefined;
21
- }
18
+ let visited = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new WeakMap();
19
+ // 如果是 null,直接返回 null
20
+ if (obj === null) return null;
21
+
22
+ // 如果是基本类型(数字、字符串、布尔等),直接返回自身;函数在 JSON 中会被忽略
23
+ if (typeof obj !== 'object') return obj;
24
+ if (typeof obj === 'function') return undefined;
22
25
 
23
- // 如果是 Date 或其他不可直接 JSON 化的类型
26
+ // 如果对象已被处理过,直接返回缓存结果,防止循环引用
27
+ if (visited.has(obj)) return visited.get(obj);
28
+
29
+ // 处理 Date:转成 ISO 字符串
24
30
  if (obj instanceof Date) {
25
31
  return obj.toISOString();
26
32
  }
27
- if (obj instanceof Array) {
28
- return obj.map(item => deepCloneToPlainObject(item)).filter(item => item !== undefined); // 移除 undefined 项
33
+
34
+ // 处理 RegExp:转换为字符串表示形式
35
+ if (obj instanceof RegExp) {
36
+ return obj.toString();
29
37
  }
30
- if (obj instanceof Object) {
31
- const plainObject = {};
32
- for (const key in obj) {
33
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
34
- const value = deepCloneToPlainObject(obj[key]);
35
- if (value !== undefined) {
36
- // 只添加可以转换的值
37
- plainObject[key] = value;
38
- }
38
+
39
+ // 处理数组:保留结构,将 undefined 转为 null(符合 JSON.stringify 行为)
40
+ if (Array.isArray(obj)) {
41
+ const clonedArr = new Array(obj.length);
42
+ visited.set(obj, clonedArr);
43
+ for (let i = 0; i < obj.length; i++) {
44
+ if (i in obj) {
45
+ const clonedValue = deepCloneToPlainObject(obj[i], visited);
46
+ clonedArr[i] = clonedValue === undefined ? null : clonedValue;
47
+ } else {
48
+ // 对于稀疏数组,补成 null
49
+ clonedArr[i] = null;
39
50
  }
40
51
  }
41
- return plainObject;
52
+ return clonedArr;
42
53
  }
43
54
 
44
- // 如果遇到其他类型,直接忽略返回 undefined
45
- return undefined;
55
+ // 处理 Map:转换为数组的键值对;注意 JSON 不能直接表示 Map,所以这里转成数组
56
+ if (obj instanceof Map) {
57
+ const clonedMap = [];
58
+ visited.set(obj, clonedMap);
59
+ for (const [key, value] of obj.entries()) {
60
+ clonedMap.push([deepCloneToPlainObject(key, visited), deepCloneToPlainObject(value, visited)]);
61
+ }
62
+ return clonedMap;
63
+ }
64
+
65
+ // 处理 Set:转换为数组
66
+ if (obj instanceof Set) {
67
+ const clonedSet = [];
68
+ visited.set(obj, clonedSet);
69
+ for (const value of obj.values()) {
70
+ clonedSet.push(deepCloneToPlainObject(value, visited));
71
+ }
72
+ return clonedSet;
73
+ }
74
+
75
+ // 处理普通对象
76
+ const clonedObj = {};
77
+ visited.set(obj, clonedObj);
78
+ for (const key in obj) {
79
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
80
+ const clonedValue = deepCloneToPlainObject(obj[key], visited);
81
+ // JSON.stringify 会忽略 undefined 属性,这里保持一致
82
+ if (clonedValue !== undefined) {
83
+ clonedObj[key] = clonedValue;
84
+ }
85
+ }
86
+ }
87
+ return clonedObj;
46
88
  }
47
89
  export function safeParseJSON(str) {
48
90
  if (str && typeof str === 'string') {
@@ -28,6 +28,13 @@ export function withUI() {
28
28
  };
29
29
  emitEvent('messageChange', detail);
30
30
  }, 'after');
31
+ agent.session.onChange((key, value, oldValue) => {
32
+ emitEvent('sessionChange', {
33
+ key,
34
+ value,
35
+ oldValue
36
+ });
37
+ });
31
38
  return {
32
39
  ui: {
33
40
  emitter,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/t-agent",
3
- "version": "0.0.9-beta-2",
3
+ "version": "0.0.9-beta-4",
4
4
  "author": "Tuya.inc",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -26,5 +26,5 @@
26
26
  "build": "ray build --type=component --output dist",
27
27
  "clean": "rimraf ./dist"
28
28
  },
29
- "gitHead": "45f4f153fe2ce1e218a74f9bd3df726cf4e06d63"
29
+ "gitHead": "328a8616b0356cbaef02d7a4ad46ee0c077d04be"
30
30
  }