@autobe/ui 0.30.2 → 0.30.4-dev.20260324
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/LICENSE +661 -661
- package/README.md +261 -0
- package/lib/components/AutoBeChatMain.d.ts +6 -0
- package/lib/components/AutoBeChatMain.js +46 -37
- package/lib/components/AutoBeChatMain.js.map +1 -1
- package/lib/components/AutoBeConfigModal.js +9 -9
- package/lib/components/events/AutoBeEventMovie.js +0 -4
- package/lib/components/events/AutoBeEventMovie.js.map +1 -1
- package/lib/components/events/AutoBeProgressEventMovie.js +0 -10
- package/lib/components/events/AutoBeProgressEventMovie.js.map +1 -1
- package/lib/components/upload/AutoBeChatUploadBox.d.ts +1 -0
- package/lib/components/upload/AutoBeChatUploadBox.js +11 -16
- package/lib/components/upload/AutoBeChatUploadBox.js.map +1 -1
- package/lib/context/AutoBeAgentContext.js +78 -30
- package/lib/context/AutoBeAgentContext.js.map +1 -1
- package/lib/context/SearchParamsContext.js +1 -1
- package/lib/context/SearchParamsContext.js.map +1 -1
- package/lib/structure/AutoBeListener.d.ts +1 -0
- package/lib/structure/AutoBeListener.js +9 -11
- package/lib/structure/AutoBeListener.js.map +1 -1
- package/package.json +2 -2
- package/src/components/AutoBeAssistantMessageMovie.tsx +22 -22
- package/src/components/AutoBeChatMain.tsx +394 -376
- package/src/components/AutoBeChatSidebar.tsx +414 -414
- package/src/components/AutoBeConfigButton.tsx +83 -83
- package/src/components/AutoBeConfigModal.tsx +443 -443
- package/src/components/AutoBeStatusButton.tsx +75 -75
- package/src/components/AutoBeStatusModal.tsx +486 -486
- package/src/components/AutoBeUserMessageMovie.tsx +27 -27
- package/src/components/common/ActionButton.tsx +205 -205
- package/src/components/common/ActionButtonGroup.tsx +80 -80
- package/src/components/common/AutoBeConfigInput.tsx +185 -185
- package/src/components/common/ChatBubble.tsx +119 -119
- package/src/components/common/Collapsible.tsx +95 -95
- package/src/components/common/CompactSessionIndicator.tsx +73 -73
- package/src/components/common/CompactSessionList.tsx +82 -82
- package/src/components/common/openai/OpenAIContent.tsx +53 -53
- package/src/components/common/openai/OpenAIUserAudioContent.tsx +70 -70
- package/src/components/common/openai/OpenAIUserFileContent.tsx +76 -76
- package/src/components/common/openai/OpenAIUserImageContent.tsx +34 -34
- package/src/components/common/openai/OpenAIUserTextContent.tsx +15 -15
- package/src/components/events/AutoBeCompleteEventMovie.tsx +402 -402
- package/src/components/events/AutoBeCorrectEventMovie.tsx +354 -354
- package/src/components/events/AutoBeEventGroupMovie.tsx +18 -18
- package/src/components/events/AutoBeEventMovie.tsx +154 -158
- package/src/components/events/AutoBeProgressEventMovie.tsx +207 -217
- package/src/components/events/AutoBeScenarioEventMovie.tsx +135 -135
- package/src/components/events/AutoBeStartEventMovie.tsx +82 -82
- package/src/components/events/AutoBeValidateEventMovie.tsx +249 -249
- package/src/components/events/README.md +300 -300
- package/src/components/events/common/CollapsibleEventGroup.tsx +211 -211
- package/src/components/events/common/EventCard.tsx +61 -61
- package/src/components/events/common/EventContent.tsx +31 -31
- package/src/components/events/common/EventHeader.tsx +85 -85
- package/src/components/events/common/EventIcon.tsx +82 -82
- package/src/components/events/common/ProgressBar.tsx +64 -64
- package/src/components/events/groups/CorrectEventGroup.tsx +183 -183
- package/src/components/events/groups/ValidateEventGroup.tsx +143 -143
- package/src/components/events/utils/eventGrouper.tsx +116 -116
- package/src/components/upload/AutoBeChatUploadBox.tsx +433 -425
- package/src/components/upload/AutoBeChatUploadSendButton.tsx +66 -66
- package/src/components/upload/AutoBeFileUploadBox.tsx +123 -123
- package/src/components/upload/AutoBeVoiceRecoderButton.tsx +100 -100
- package/src/context/AutoBeAgentContext.tsx +301 -245
- package/src/context/AutoBeAgentSessionList.tsx +58 -58
- package/src/context/SearchParamsContext.tsx +49 -49
- package/src/icons/Receipt.tsx +74 -74
- package/src/structure/AutoBeListener.ts +368 -373
- package/tsconfig.json +9 -9
|
@@ -1,245 +1,301 @@
|
|
|
1
|
-
import { IAutoBeRpcService, IAutoBeTokenUsageJson } from "@autobe/interface";
|
|
2
|
-
import {
|
|
3
|
-
ReactNode,
|
|
4
|
-
createContext,
|
|
5
|
-
useCallback,
|
|
6
|
-
useContext,
|
|
7
|
-
useEffect,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
| "
|
|
35
|
-
| "
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
1
|
+
import { IAutoBeRpcService, IAutoBeTokenUsageJson } from "@autobe/interface";
|
|
2
|
+
import {
|
|
3
|
+
ReactNode,
|
|
4
|
+
createContext,
|
|
5
|
+
useCallback,
|
|
6
|
+
useContext,
|
|
7
|
+
useEffect,
|
|
8
|
+
useRef,
|
|
9
|
+
useState,
|
|
10
|
+
} from "react";
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
AutoBeListener,
|
|
14
|
+
AutoBeListenerState,
|
|
15
|
+
IAutoBeAgentSessionStorageStrategy,
|
|
16
|
+
IAutoBeEventGroup,
|
|
17
|
+
} from "../structure";
|
|
18
|
+
import { IAutoBeConfig } from "../types/config";
|
|
19
|
+
import { useAutoBeAgentSessionList } from "./AutoBeAgentSessionList";
|
|
20
|
+
import { useSearchParams } from "./SearchParamsContext";
|
|
21
|
+
|
|
22
|
+
export interface IAutoBeServiceData {
|
|
23
|
+
service: IAutoBeRpcService;
|
|
24
|
+
listener: AutoBeListener;
|
|
25
|
+
close: () => void | Promise<void>;
|
|
26
|
+
sessionId: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type AutoBeServiceFactory = (
|
|
30
|
+
config: IAutoBeConfig,
|
|
31
|
+
) => Promise<IAutoBeServiceData>;
|
|
32
|
+
|
|
33
|
+
export type AutoBeConnectionStatus =
|
|
34
|
+
| "disconnected"
|
|
35
|
+
| "connecting"
|
|
36
|
+
| "connected";
|
|
37
|
+
|
|
38
|
+
interface AutoBeAgentContextType {
|
|
39
|
+
// Service state
|
|
40
|
+
connectionStatus: AutoBeConnectionStatus;
|
|
41
|
+
|
|
42
|
+
// Service data (available when ready)
|
|
43
|
+
eventGroups: IAutoBeEventGroup[];
|
|
44
|
+
tokenUsage: IAutoBeTokenUsageJson | null;
|
|
45
|
+
state: AutoBeListenerState | null;
|
|
46
|
+
service: IAutoBeRpcService | null;
|
|
47
|
+
listener: AutoBeListener | null;
|
|
48
|
+
|
|
49
|
+
// Service management
|
|
50
|
+
getAutoBeService: (config?: IAutoBeConfig) => Promise<IAutoBeServiceData>;
|
|
51
|
+
resetService: () => void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const AutoBeAgentContext = createContext<AutoBeAgentContextType | null>(null);
|
|
55
|
+
|
|
56
|
+
export function AutoBeAgentProvider({
|
|
57
|
+
children,
|
|
58
|
+
serviceFactory,
|
|
59
|
+
storageStrategy,
|
|
60
|
+
}: {
|
|
61
|
+
serviceFactory: AutoBeServiceFactory;
|
|
62
|
+
children: ReactNode;
|
|
63
|
+
storageStrategy: IAutoBeAgentSessionStorageStrategy;
|
|
64
|
+
}) {
|
|
65
|
+
// Service state
|
|
66
|
+
const [connectionStatus, setConnectionStatus] =
|
|
67
|
+
useState<AutoBeConnectionStatus>("disconnected");
|
|
68
|
+
|
|
69
|
+
// Service data
|
|
70
|
+
const { searchParams, setSearchParams } = useSearchParams();
|
|
71
|
+
// Use URL parameter for conversation ID - enables bookmark/share support
|
|
72
|
+
const activeConversationId = searchParams.get("session-id") ?? null;
|
|
73
|
+
|
|
74
|
+
const [tokenUsage, setTokenUsage] = useState<IAutoBeTokenUsageJson | null>(
|
|
75
|
+
null,
|
|
76
|
+
);
|
|
77
|
+
const [eventGroups, setEventGroups] = useState<IAutoBeEventGroup[]>([]);
|
|
78
|
+
|
|
79
|
+
// Store service instance in a ref to avoid React dev mode inspecting
|
|
80
|
+
// the TGrid driver Proxy (which crashes on Symbol property access).
|
|
81
|
+
// connectionStatus state changes drive re-renders instead.
|
|
82
|
+
const serviceInstanceRef = useRef<IAutoBeServiceData | null>(null);
|
|
83
|
+
|
|
84
|
+
const { refreshSessionList } = useAutoBeAgentSessionList();
|
|
85
|
+
// Context-scoped service getter
|
|
86
|
+
const getAutoBeService = useCallback(
|
|
87
|
+
async (
|
|
88
|
+
config: IAutoBeConfig = {} as IAutoBeConfig,
|
|
89
|
+
): Promise<IAutoBeServiceData> => {
|
|
90
|
+
// Return existing instance if available
|
|
91
|
+
if (serviceInstanceRef.current && connectionStatus === "connected") {
|
|
92
|
+
return serviceInstanceRef.current;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Prevent multiple concurrent creations
|
|
96
|
+
if (connectionStatus === "connecting") {
|
|
97
|
+
throw new Error("Service is already connecting. Please wait.");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!serviceFactory) {
|
|
101
|
+
throw new Error("No service factory provided. Cannot create service.");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
setConnectionStatus("connecting");
|
|
106
|
+
|
|
107
|
+
// Create new service instance
|
|
108
|
+
const newServiceData = await serviceFactory({
|
|
109
|
+
...config,
|
|
110
|
+
sessionId: activeConversationId,
|
|
111
|
+
});
|
|
112
|
+
// Wrap the TGrid driver proxy to handle Symbol access from
|
|
113
|
+
// React dev-mode's render logging without crashing.
|
|
114
|
+
newServiceData.service = wrapServiceProxy(newServiceData.service);
|
|
115
|
+
serviceInstanceRef.current = newServiceData;
|
|
116
|
+
|
|
117
|
+
setSearchParams((sp) => {
|
|
118
|
+
const newSp = new URLSearchParams(sp);
|
|
119
|
+
newSp.set("session-id", newServiceData.sessionId);
|
|
120
|
+
return newSp;
|
|
121
|
+
});
|
|
122
|
+
setConnectionStatus("connected");
|
|
123
|
+
|
|
124
|
+
return newServiceData;
|
|
125
|
+
} catch (error) {
|
|
126
|
+
setConnectionStatus("disconnected");
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
[
|
|
131
|
+
serviceFactory,
|
|
132
|
+
connectionStatus,
|
|
133
|
+
activeConversationId,
|
|
134
|
+
searchParams,
|
|
135
|
+
],
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// Reset service (for reconnection, etc.)
|
|
139
|
+
const resetService = useCallback(() => {
|
|
140
|
+
serviceInstanceRef.current = null;
|
|
141
|
+
setConnectionStatus("disconnected");
|
|
142
|
+
setEventGroups([]);
|
|
143
|
+
setTokenUsage(null);
|
|
144
|
+
}, []);
|
|
145
|
+
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
// Close existing connection when switching sessions,
|
|
148
|
+
// but skip if the current service already owns this session
|
|
149
|
+
// (happens when getAutoBeService just created it and set the URL).
|
|
150
|
+
const prev = serviceInstanceRef.current;
|
|
151
|
+
if (prev) {
|
|
152
|
+
if (prev.sessionId === activeConversationId) {
|
|
153
|
+
// Same session — do not tear down the connection we just created
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
void Promise.resolve(prev.close()).catch(() => {});
|
|
157
|
+
serviceInstanceRef.current = null;
|
|
158
|
+
setConnectionStatus("disconnected");
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Clear stale events immediately
|
|
162
|
+
setEventGroups([]);
|
|
163
|
+
setTokenUsage(null);
|
|
164
|
+
|
|
165
|
+
if (activeConversationId === null) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
storageStrategy
|
|
170
|
+
.getSession({
|
|
171
|
+
id: activeConversationId,
|
|
172
|
+
})
|
|
173
|
+
.then((v) => {
|
|
174
|
+
if (v === null) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
refreshSessionList();
|
|
178
|
+
// Avoid wiping live websocket replay events with empty storage data.
|
|
179
|
+
// Some strategies only persist histories/token usage and leave events
|
|
180
|
+
// empty, so replacing current groups here can erase already-delivered
|
|
181
|
+
// replay messages such as early userMessage events.
|
|
182
|
+
if (v.events.length > 0) {
|
|
183
|
+
setEventGroups(v.events);
|
|
184
|
+
}
|
|
185
|
+
setTokenUsage(v.tokenUsage);
|
|
186
|
+
})
|
|
187
|
+
.catch(console.error);
|
|
188
|
+
}, [activeConversationId]);
|
|
189
|
+
|
|
190
|
+
// Register listener when service connects
|
|
191
|
+
useEffect(() => {
|
|
192
|
+
const instance = serviceInstanceRef.current;
|
|
193
|
+
if (connectionStatus !== "connected" || instance === null) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const onEvent = async (e: IAutoBeEventGroup[]) => {
|
|
198
|
+
setEventGroups(e);
|
|
199
|
+
setTimeout(() => {
|
|
200
|
+
instance.service
|
|
201
|
+
.getTokenUsage()
|
|
202
|
+
.then(setTokenUsage)
|
|
203
|
+
.catch(() => {});
|
|
204
|
+
}, 0);
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
instance.listener.on(onEvent);
|
|
208
|
+
|
|
209
|
+
instance.service
|
|
210
|
+
.getTokenUsage()
|
|
211
|
+
.then(setTokenUsage)
|
|
212
|
+
.catch(() => {});
|
|
213
|
+
|
|
214
|
+
return () => {
|
|
215
|
+
instance.listener.off(onEvent);
|
|
216
|
+
};
|
|
217
|
+
}, [connectionStatus]);
|
|
218
|
+
|
|
219
|
+
useEffect(() => {
|
|
220
|
+
const instance = serviceInstanceRef.current;
|
|
221
|
+
if (activeConversationId === null || connectionStatus !== "connected" || instance === null) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const originConversate = instance.service.conversate;
|
|
226
|
+
instance.service.conversate = async (content) => {
|
|
227
|
+
const result = await originConversate(content);
|
|
228
|
+
await storageStrategy.appendHistory({
|
|
229
|
+
id: activeConversationId,
|
|
230
|
+
history: result,
|
|
231
|
+
});
|
|
232
|
+
return result;
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
const registerEvent = async (e: IAutoBeEventGroup[]) => {
|
|
236
|
+
await storageStrategy.appendEvent({
|
|
237
|
+
id: activeConversationId,
|
|
238
|
+
events: e,
|
|
239
|
+
});
|
|
240
|
+
await storageStrategy.setTokenUsage({
|
|
241
|
+
id: activeConversationId,
|
|
242
|
+
tokenUsage: await instance.service.getTokenUsage(),
|
|
243
|
+
});
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
instance.listener.on(registerEvent);
|
|
247
|
+
return () => {
|
|
248
|
+
instance.service.conversate = originConversate;
|
|
249
|
+
instance.listener.off(registerEvent);
|
|
250
|
+
};
|
|
251
|
+
}, [activeConversationId, connectionStatus]);
|
|
252
|
+
|
|
253
|
+
const currentInstance = serviceInstanceRef.current;
|
|
254
|
+
|
|
255
|
+
return (
|
|
256
|
+
<AutoBeAgentContext.Provider
|
|
257
|
+
value={{
|
|
258
|
+
// Service state
|
|
259
|
+
connectionStatus,
|
|
260
|
+
|
|
261
|
+
// Service data
|
|
262
|
+
eventGroups,
|
|
263
|
+
tokenUsage,
|
|
264
|
+
state: currentInstance?.listener?.getState() ?? null,
|
|
265
|
+
service: currentInstance?.service ?? null,
|
|
266
|
+
listener: currentInstance?.listener ?? null,
|
|
267
|
+
|
|
268
|
+
// Service management
|
|
269
|
+
getAutoBeService,
|
|
270
|
+
resetService,
|
|
271
|
+
}}
|
|
272
|
+
>
|
|
273
|
+
{children}
|
|
274
|
+
</AutoBeAgentContext.Provider>
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function useAutoBeAgent() {
|
|
279
|
+
const context = useContext(AutoBeAgentContext);
|
|
280
|
+
if (!context) {
|
|
281
|
+
throw new Error("useAutoBeAgent must be used within a AutoBeAgentProvider");
|
|
282
|
+
}
|
|
283
|
+
return context;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Wrap a TGrid driver Proxy into a plain object so that React dev-mode
|
|
288
|
+
* render logging never touches the Proxy (which crashes on Symbol
|
|
289
|
+
* property access: "Cannot convert a Symbol value to a string").
|
|
290
|
+
*/
|
|
291
|
+
function wrapServiceProxy(
|
|
292
|
+
service: IAutoBeRpcService,
|
|
293
|
+
): IAutoBeRpcService {
|
|
294
|
+
return {
|
|
295
|
+
conversate: (content) => service.conversate(content),
|
|
296
|
+
getFiles: (options) => service.getFiles(options),
|
|
297
|
+
getHistories: () => service.getHistories(),
|
|
298
|
+
getTokenUsage: () => service.getTokenUsage(),
|
|
299
|
+
getPhase: () => service.getPhase(),
|
|
300
|
+
};
|
|
301
|
+
}
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ReactNode,
|
|
3
|
-
createContext,
|
|
4
|
-
useCallback,
|
|
5
|
-
useContext,
|
|
6
|
-
useEffect,
|
|
7
|
-
useState,
|
|
8
|
-
} from "react";
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
IAutoBeAgentSession,
|
|
12
|
-
IAutoBeAgentSessionStorageStrategy,
|
|
13
|
-
} from "../structure";
|
|
14
|
-
|
|
15
|
-
interface AutoBeAgentSessionListContextType {
|
|
16
|
-
sessionList: IAutoBeAgentSession[];
|
|
17
|
-
refreshSessionList: () => Promise<void>;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const AutoBeAgentSessionListContext =
|
|
21
|
-
createContext<AutoBeAgentSessionListContextType | null>(null);
|
|
22
|
-
|
|
23
|
-
export function AutoBeAgentSessionListProvider({
|
|
24
|
-
children,
|
|
25
|
-
storageStrategy,
|
|
26
|
-
}: {
|
|
27
|
-
storageStrategy: IAutoBeAgentSessionStorageStrategy;
|
|
28
|
-
children: ReactNode;
|
|
29
|
-
}) {
|
|
30
|
-
const [sessionList, setSessionList] = useState<IAutoBeAgentSession[]>([]);
|
|
31
|
-
|
|
32
|
-
const refreshSessionList = useCallback(async () => {
|
|
33
|
-
await storageStrategy.getSessionList().then(setSessionList);
|
|
34
|
-
}, [storageStrategy]);
|
|
35
|
-
|
|
36
|
-
useEffect(() => {
|
|
37
|
-
refreshSessionList();
|
|
38
|
-
}, [storageStrategy]);
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<AutoBeAgentSessionListContext.Provider
|
|
42
|
-
value={{
|
|
43
|
-
sessionList,
|
|
44
|
-
refreshSessionList,
|
|
45
|
-
}}
|
|
46
|
-
>
|
|
47
|
-
{children}
|
|
48
|
-
</AutoBeAgentSessionListContext.Provider>
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function useAutoBeAgentSessionList() {
|
|
53
|
-
const context = useContext(AutoBeAgentSessionListContext);
|
|
54
|
-
if (!context) {
|
|
55
|
-
throw new Error("useAutoBeAgent must be used within a AutoBeAgentProvider");
|
|
56
|
-
}
|
|
57
|
-
return context;
|
|
58
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
ReactNode,
|
|
3
|
+
createContext,
|
|
4
|
+
useCallback,
|
|
5
|
+
useContext,
|
|
6
|
+
useEffect,
|
|
7
|
+
useState,
|
|
8
|
+
} from "react";
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
IAutoBeAgentSession,
|
|
12
|
+
IAutoBeAgentSessionStorageStrategy,
|
|
13
|
+
} from "../structure";
|
|
14
|
+
|
|
15
|
+
interface AutoBeAgentSessionListContextType {
|
|
16
|
+
sessionList: IAutoBeAgentSession[];
|
|
17
|
+
refreshSessionList: () => Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const AutoBeAgentSessionListContext =
|
|
21
|
+
createContext<AutoBeAgentSessionListContextType | null>(null);
|
|
22
|
+
|
|
23
|
+
export function AutoBeAgentSessionListProvider({
|
|
24
|
+
children,
|
|
25
|
+
storageStrategy,
|
|
26
|
+
}: {
|
|
27
|
+
storageStrategy: IAutoBeAgentSessionStorageStrategy;
|
|
28
|
+
children: ReactNode;
|
|
29
|
+
}) {
|
|
30
|
+
const [sessionList, setSessionList] = useState<IAutoBeAgentSession[]>([]);
|
|
31
|
+
|
|
32
|
+
const refreshSessionList = useCallback(async () => {
|
|
33
|
+
await storageStrategy.getSessionList().then(setSessionList);
|
|
34
|
+
}, [storageStrategy]);
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
refreshSessionList();
|
|
38
|
+
}, [storageStrategy]);
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<AutoBeAgentSessionListContext.Provider
|
|
42
|
+
value={{
|
|
43
|
+
sessionList,
|
|
44
|
+
refreshSessionList,
|
|
45
|
+
}}
|
|
46
|
+
>
|
|
47
|
+
{children}
|
|
48
|
+
</AutoBeAgentSessionListContext.Provider>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function useAutoBeAgentSessionList() {
|
|
53
|
+
const context = useContext(AutoBeAgentSessionListContext);
|
|
54
|
+
if (!context) {
|
|
55
|
+
throw new Error("useAutoBeAgent must be used within a AutoBeAgentProvider");
|
|
56
|
+
}
|
|
57
|
+
return context;
|
|
58
|
+
}
|