@nextclaw/ui 0.11.0 → 0.11.2
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/CHANGELOG.md +16 -2
- package/dist/assets/{ChannelsList-BqsOYnXz.js → ChannelsList-CKl1Zg8f.js} +3 -3
- package/dist/assets/ChatPage-BJgO27mk.js +37 -0
- package/dist/assets/{DocBrowser-BmL0QXBZ.js → DocBrowser-DYRBs4-z.js} +1 -1
- package/dist/assets/{LogoBadge-C1HiPZPf.js → LogoBadge-33Qlv3Hg.js} +1 -1
- package/dist/assets/MarketplacePage-B8BZVtjV.js +49 -0
- package/dist/assets/{McpMarketplacePage-CLHFnNBd.js → McpMarketplacePage-BRuE5fJJ.js} +2 -2
- package/dist/assets/{ModelConfig-LQSR58tc.js → ModelConfig-BiFblwO-.js} +1 -1
- package/dist/assets/ProvidersList-9goRgHE4.js +1 -0
- package/dist/assets/RemoteAccessPage-5vCxZPS6.js +1 -0
- package/dist/assets/RuntimeConfig-BmDFHBdW.js +1 -0
- package/dist/assets/{SearchConfig-Chzo_JGs.js → SearchConfig-CJx5CKwG.js} +1 -1
- package/dist/assets/{SecretsConfig-CEIbjZYA.js → SecretsConfig-B91efXoK.js} +2 -2
- package/dist/assets/SessionsConfig-CbFPVmx3.js +2 -0
- package/dist/assets/index-BtAuUyww.css +1 -0
- package/dist/assets/index-COJomMe9.js +8 -0
- package/dist/assets/{label-GACO2RzW.js → label-BnSDpjhL.js} +1 -1
- package/dist/assets/ncp-session-adapter-w8ZHprab.js +1 -0
- package/dist/assets/{page-layout-DjXaK3A3.js → page-layout-B1RIu5-r.js} +1 -1
- package/dist/assets/popover-ChzbCIfO.js +1 -0
- package/dist/assets/security-config-eYa6Ovfa.js +1 -0
- package/dist/assets/skeleton-D4Eyop0R.js +1 -0
- package/dist/assets/{status-dot-IWEBezqb.js → status-dot-CrCw5tkJ.js} +1 -1
- package/dist/assets/{switch-DCHAJSrA.js → switch-C3vVTpfU.js} +1 -1
- package/dist/assets/tabs-custom-Ilrgt6n1.js +1 -0
- package/dist/assets/useConfirmDialog-BeaFLDO8.js +1 -0
- package/dist/assets/{vendor-CNhxtHCf.js → vendor-waGu-koL.js} +101 -86
- package/dist/index.html +3 -3
- package/package.json +5 -5
- package/src/App.test.tsx +42 -10
- package/src/App.tsx +5 -40
- package/src/api/api-base.test.ts +37 -0
- package/src/api/api-base.ts +0 -4
- package/src/api/config.ts +2 -270
- package/src/api/types.ts +0 -117
- package/src/components/chat/ChatPage.tsx +1 -11
- package/src/components/chat/ChatSidebar.test.tsx +1 -50
- package/src/components/chat/ChatSidebar.tsx +0 -5
- package/src/components/chat/README.md +2 -0
- package/src/components/chat/adapters/chat-message.adapter.test.ts +71 -4
- package/src/components/chat/adapters/chat-message.adapter.ts +195 -78
- package/src/components/chat/chat-attachment-upload-limit.test.ts +41 -0
- package/src/components/chat/chat-session-display.ts +9 -0
- package/src/components/chat/chat-session-label.service.ts +3 -12
- package/src/components/chat/chat-session-preference-sync.test.ts +10 -13
- package/src/components/chat/chat-stream/types.ts +4 -57
- package/src/components/chat/containers/chat-message-list.container.tsx +7 -0
- package/src/components/chat/ncp/NcpChatPage.tsx +3 -3
- package/src/components/chat/useHydratedNcpAgent.test.tsx +77 -0
- package/src/components/config/README.md +2 -0
- package/src/components/config/SessionsConfig.tsx +152 -132
- package/src/hooks/use-auth.test.ts +3 -3
- package/src/hooks/use-auth.ts +16 -4
- package/src/hooks/use-realtime-query-bridge.ts +0 -24
- package/src/hooks/useConfig.ts +10 -137
- package/src/lib/i18n.chat.ts +7 -0
- package/src/lib/session-run-status.ts +1 -63
- package/src/vite-env.d.ts +1 -0
- package/vite.config.ts +4 -4
- package/dist/assets/ChatPage-CJBYKR-Y.js +0 -38
- package/dist/assets/MarketplacePage-BIRP0NRS.js +0 -49
- package/dist/assets/ProvidersList-CwI-mxah.js +0 -1
- package/dist/assets/RemoteAccessPage-Cw5BqZb6.js +0 -1
- package/dist/assets/RuntimeConfig-DbowSRAb.js +0 -1
- package/dist/assets/SessionsConfig-BR8GfGWL.js +0 -2
- package/dist/assets/chat-message-CPG7zxRR.js +0 -3
- package/dist/assets/index-j6A_-1b6.js +0 -8
- package/dist/assets/index-kaPUhd-8.css +0 -1
- package/dist/assets/popover-DTaFiTmU.js +0 -1
- package/dist/assets/security-config-Dk-yoKvK.js +0 -1
- package/dist/assets/skeleton-Dm2xOBSA.js +0 -1
- package/dist/assets/tabs-custom-DKSbDSB9.js +0 -1
- package/dist/assets/useConfirmDialog-ByJ8A8n7.js +0 -1
- package/src/api/config.stream.test.ts +0 -115
- package/src/components/chat/chat-chain.test.ts +0 -22
- package/src/components/chat/chat-chain.ts +0 -23
- package/src/components/chat/chat-page-data.ts +0 -171
- package/src/components/chat/chat-page-runtime.ts +0 -190
- package/src/components/chat/chat-stream/nextbot-parsers.ts +0 -52
- package/src/components/chat/chat-stream/nextbot-runtime-agent.ts +0 -413
- package/src/components/chat/chat-stream/stream-event-adapter.ts +0 -98
- package/src/components/chat/chat-stream/transport.ts +0 -253
- package/src/components/chat/legacy/LegacyChatPage.tsx +0 -223
- package/src/components/chat/managers/chat-input.manager.ts +0 -228
- package/src/components/chat/managers/chat-thread.manager.ts +0 -87
- package/src/components/chat/presenter/chat.presenter.ts +0 -32
- package/src/components/chat/useChatRuntimeController.ts +0 -134
package/src/hooks/use-auth.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
2
3
|
import {
|
|
3
4
|
fetchAuthStatus,
|
|
4
5
|
loginAuth,
|
|
@@ -7,11 +8,13 @@ import {
|
|
|
7
8
|
updateAuthEnabled,
|
|
8
9
|
updateAuthPassword
|
|
9
10
|
} from '@/api/config';
|
|
11
|
+
import type { AuthStatusView } from '@/api/types';
|
|
10
12
|
import { toast } from 'sonner';
|
|
11
13
|
import { t } from '@/lib/i18n';
|
|
12
14
|
|
|
13
|
-
const AUTH_STATUS_BOOTSTRAP_MAX_RETRIES =
|
|
14
|
-
|
|
15
|
+
const AUTH_STATUS_BOOTSTRAP_MAX_RETRIES = 40;
|
|
16
|
+
const AUTH_STATUS_BOOTSTRAP_TIMEOUT_MS = 400;
|
|
17
|
+
export const AUTH_STATUS_BOOTSTRAP_RETRY_DELAY_MS = 250;
|
|
15
18
|
|
|
16
19
|
export function isTransientAuthStatusBootstrapError(error: unknown): boolean {
|
|
17
20
|
if (!(error instanceof Error)) {
|
|
@@ -40,14 +43,23 @@ export function shouldRetryAuthStatusBootstrap(failureCount: number, error: unkn
|
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
export function useAuthStatus() {
|
|
43
|
-
|
|
46
|
+
const [bootstrapSettled, setBootstrapSettled] = useState(false);
|
|
47
|
+
const query = useQuery<AuthStatusView>({
|
|
44
48
|
queryKey: ['auth-status'],
|
|
45
|
-
queryFn: fetchAuthStatus,
|
|
49
|
+
queryFn: () => fetchAuthStatus({ timeoutMs: bootstrapSettled ? 5_000 : AUTH_STATUS_BOOTSTRAP_TIMEOUT_MS }),
|
|
46
50
|
staleTime: 5_000,
|
|
47
51
|
retry: shouldRetryAuthStatusBootstrap,
|
|
48
52
|
retryDelay: AUTH_STATUS_BOOTSTRAP_RETRY_DELAY_MS,
|
|
49
53
|
refetchOnWindowFocus: true
|
|
50
54
|
});
|
|
55
|
+
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (query.isSuccess && !bootstrapSettled) {
|
|
58
|
+
setBootstrapSettled(true);
|
|
59
|
+
}
|
|
60
|
+
}, [bootstrapSettled, query.isSuccess]);
|
|
61
|
+
|
|
62
|
+
return query;
|
|
51
63
|
}
|
|
52
64
|
|
|
53
65
|
function invalidateProtectedQueries(queryClient: ReturnType<typeof useQueryClient>): Promise<unknown[]> {
|
|
@@ -34,14 +34,11 @@ function invalidateSessionQueries(queryClient: QueryClient | undefined, sessionK
|
|
|
34
34
|
if (!queryClient) {
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
|
-
queryClient.invalidateQueries({ queryKey: ['sessions'] });
|
|
38
37
|
queryClient.invalidateQueries({ queryKey: ['ncp-sessions'] });
|
|
39
38
|
if (sessionKey && sessionKey.trim().length > 0) {
|
|
40
|
-
queryClient.invalidateQueries({ queryKey: ['session-history', sessionKey.trim()] });
|
|
41
39
|
queryClient.invalidateQueries({ queryKey: ['ncp-session-messages', sessionKey.trim()] });
|
|
42
40
|
return;
|
|
43
41
|
}
|
|
44
|
-
queryClient.invalidateQueries({ queryKey: ['session-history'] });
|
|
45
42
|
queryClient.invalidateQueries({ queryKey: ['ncp-session-messages'] });
|
|
46
43
|
}
|
|
47
44
|
|
|
@@ -55,23 +52,6 @@ function handleConfigUpdatedEvent(queryClient: QueryClient | undefined, path: st
|
|
|
55
52
|
invalidateMarketplaceQueries(queryClient, path);
|
|
56
53
|
}
|
|
57
54
|
|
|
58
|
-
function handleRunUpdatedEvent(queryClient: QueryClient | undefined, payload: { run: { sessionKey?: string; runId?: string } }): void {
|
|
59
|
-
if (!queryClient) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const { sessionKey, runId } = payload.run;
|
|
63
|
-
queryClient.invalidateQueries({ queryKey: ['chat-runs'] });
|
|
64
|
-
if (sessionKey) {
|
|
65
|
-
queryClient.invalidateQueries({ queryKey: ['sessions'] });
|
|
66
|
-
queryClient.invalidateQueries({ queryKey: ['session-history', sessionKey] });
|
|
67
|
-
} else {
|
|
68
|
-
queryClient.invalidateQueries({ queryKey: ['session-history'] });
|
|
69
|
-
}
|
|
70
|
-
if (runId) {
|
|
71
|
-
queryClient.invalidateQueries({ queryKey: ['chat-run', runId] });
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
55
|
function handleRealtimeEvent(
|
|
76
56
|
queryClient: QueryClient | undefined,
|
|
77
57
|
setConnectionStatus: SetConnectionStatus,
|
|
@@ -90,10 +70,6 @@ function handleRealtimeEvent(
|
|
|
90
70
|
handleConfigUpdatedEvent(queryClient, configPath);
|
|
91
71
|
return;
|
|
92
72
|
}
|
|
93
|
-
if (event.type === 'run.updated') {
|
|
94
|
-
handleRunUpdatedEvent(queryClient, event.payload);
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
73
|
if (event.type === 'session.updated') {
|
|
98
74
|
invalidateSessionQueries(queryClient, event.payload.sessionKey);
|
|
99
75
|
return;
|
package/src/hooks/useConfig.ts
CHANGED
|
@@ -17,21 +17,12 @@ import {
|
|
|
17
17
|
updateRuntime,
|
|
18
18
|
updateSecrets,
|
|
19
19
|
executeConfigAction,
|
|
20
|
-
fetchSessions,
|
|
21
|
-
fetchSessionHistory,
|
|
22
|
-
updateSession,
|
|
23
|
-
deleteSession,
|
|
24
|
-
sendChatTurn,
|
|
25
|
-
fetchChatRun,
|
|
26
|
-
fetchChatRuns,
|
|
27
|
-
fetchChatCapabilities,
|
|
28
|
-
fetchChatSessionTypes,
|
|
29
20
|
fetchCronJobs,
|
|
30
21
|
deleteCronJob,
|
|
31
22
|
setCronJobEnabled,
|
|
32
23
|
runCronJob
|
|
33
24
|
} from '@/api/config';
|
|
34
|
-
import { deleteNcpSession, fetchNcpSessionMessages, fetchNcpSessions } from '@/api/ncp-session';
|
|
25
|
+
import { deleteNcpSession, fetchNcpSessionMessages, fetchNcpSessions, updateNcpSession } from '@/api/ncp-session';
|
|
35
26
|
import { toast } from 'sonner';
|
|
36
27
|
import { t } from '@/lib/i18n';
|
|
37
28
|
|
|
@@ -234,25 +225,6 @@ export function useExecuteConfigAction() {
|
|
|
234
225
|
});
|
|
235
226
|
}
|
|
236
227
|
|
|
237
|
-
|
|
238
|
-
export function useSessions(params: { q?: string; limit?: number; activeMinutes?: number }) {
|
|
239
|
-
return useQuery({
|
|
240
|
-
queryKey: ['sessions', params],
|
|
241
|
-
queryFn: () => fetchSessions(params),
|
|
242
|
-
staleTime: 10_000
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export function useSessionHistory(key: string | null, limit = 200) {
|
|
247
|
-
return useQuery({
|
|
248
|
-
queryKey: ['session-history', key, limit],
|
|
249
|
-
queryFn: () => fetchSessionHistory(key as string, limit),
|
|
250
|
-
enabled: Boolean(key),
|
|
251
|
-
staleTime: 5_000,
|
|
252
|
-
retry: false
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
|
|
256
228
|
export function useNcpSessions(params?: { limit?: number }) {
|
|
257
229
|
return useQuery({
|
|
258
230
|
queryKey: ['ncp-sessions', params?.limit ?? null],
|
|
@@ -276,31 +248,14 @@ export function useNcpSessionMessages(sessionId: string | null, limit = 200) {
|
|
|
276
248
|
});
|
|
277
249
|
}
|
|
278
250
|
|
|
279
|
-
export function
|
|
280
|
-
const queryClient = useQueryClient();
|
|
281
|
-
|
|
282
|
-
return useMutation({
|
|
283
|
-
mutationFn: ({ key, data }: { key: string; data: Parameters<typeof updateSession>[1] }) =>
|
|
284
|
-
updateSession(key, data),
|
|
285
|
-
onSuccess: (_data, variables) => {
|
|
286
|
-
queryClient.invalidateQueries({ queryKey: ['sessions'] });
|
|
287
|
-
queryClient.invalidateQueries({ queryKey: ['session-history', variables.key] });
|
|
288
|
-
toast.success(t('configSavedApplied'));
|
|
289
|
-
},
|
|
290
|
-
onError: (error: Error) => {
|
|
291
|
-
toast.error(t('configSaveFailed') + ': ' + error.message);
|
|
292
|
-
}
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
export function useDeleteSession() {
|
|
251
|
+
export function useDeleteNcpSession() {
|
|
297
252
|
const queryClient = useQueryClient();
|
|
298
253
|
|
|
299
254
|
return useMutation({
|
|
300
|
-
mutationFn: ({
|
|
255
|
+
mutationFn: ({ sessionId }: { sessionId: string }) => deleteNcpSession(sessionId),
|
|
301
256
|
onSuccess: () => {
|
|
302
|
-
queryClient.invalidateQueries({ queryKey: ['sessions'] });
|
|
303
|
-
queryClient.invalidateQueries({ queryKey: ['session-
|
|
257
|
+
queryClient.invalidateQueries({ queryKey: ['ncp-sessions'] });
|
|
258
|
+
queryClient.invalidateQueries({ queryKey: ['ncp-session-messages'] });
|
|
304
259
|
toast.success(t('configSavedApplied'));
|
|
305
260
|
},
|
|
306
261
|
onError: (error: Error) => {
|
|
@@ -309,14 +264,15 @@ export function useDeleteSession() {
|
|
|
309
264
|
});
|
|
310
265
|
}
|
|
311
266
|
|
|
312
|
-
export function
|
|
267
|
+
export function useUpdateNcpSession() {
|
|
313
268
|
const queryClient = useQueryClient();
|
|
314
269
|
|
|
315
270
|
return useMutation({
|
|
316
|
-
mutationFn: ({ sessionId }: { sessionId: string }) =>
|
|
317
|
-
|
|
271
|
+
mutationFn: ({ sessionId, data }: { sessionId: string; data: Parameters<typeof updateNcpSession>[1] }) =>
|
|
272
|
+
updateNcpSession(sessionId, data),
|
|
273
|
+
onSuccess: (_data, variables) => {
|
|
318
274
|
queryClient.invalidateQueries({ queryKey: ['ncp-sessions'] });
|
|
319
|
-
queryClient.invalidateQueries({ queryKey: ['ncp-session-messages'] });
|
|
275
|
+
queryClient.invalidateQueries({ queryKey: ['ncp-session-messages', variables.sessionId] });
|
|
320
276
|
toast.success(t('configSavedApplied'));
|
|
321
277
|
},
|
|
322
278
|
onError: (error: Error) => {
|
|
@@ -325,89 +281,6 @@ export function useDeleteNcpSession() {
|
|
|
325
281
|
});
|
|
326
282
|
}
|
|
327
283
|
|
|
328
|
-
export function useSendChatTurn() {
|
|
329
|
-
return useMutation({
|
|
330
|
-
mutationFn: ({ data }: { data: Parameters<typeof sendChatTurn>[0] }) =>
|
|
331
|
-
sendChatTurn(data),
|
|
332
|
-
onError: (error: Error) => {
|
|
333
|
-
toast.error(t('chatSendFailed') + ': ' + error.message);
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
export function useChatCapabilities(params?: { sessionKey?: string | null; agentId?: string | null }) {
|
|
339
|
-
const sessionKey = params?.sessionKey?.trim() || undefined;
|
|
340
|
-
const agentId = params?.agentId?.trim() || undefined;
|
|
341
|
-
return useQuery({
|
|
342
|
-
queryKey: ['chat-capabilities', sessionKey ?? null, agentId ?? null],
|
|
343
|
-
queryFn: async () => {
|
|
344
|
-
try {
|
|
345
|
-
return await fetchChatCapabilities({ sessionKey, agentId });
|
|
346
|
-
} catch {
|
|
347
|
-
return { stopSupported: false };
|
|
348
|
-
}
|
|
349
|
-
},
|
|
350
|
-
staleTime: 10_000,
|
|
351
|
-
retry: false
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
export function useChatSessionTypes() {
|
|
356
|
-
return useQuery({
|
|
357
|
-
queryKey: ['chat-session-types'],
|
|
358
|
-
queryFn: fetchChatSessionTypes,
|
|
359
|
-
staleTime: 10_000,
|
|
360
|
-
retry: false
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
export function useChatRuns(params?: {
|
|
365
|
-
sessionKey?: string | null;
|
|
366
|
-
states?: Array<'queued' | 'running' | 'completed' | 'failed' | 'aborted'>;
|
|
367
|
-
limit?: number;
|
|
368
|
-
syncActiveStates?: boolean;
|
|
369
|
-
isLocallyRunning?: boolean;
|
|
370
|
-
}) {
|
|
371
|
-
const sessionKey = params?.sessionKey?.trim() || undefined;
|
|
372
|
-
const states = Array.isArray(params?.states) && params.states.length > 0 ? params.states : undefined;
|
|
373
|
-
const isActiveStatesQuery = Boolean(states?.some((state) => state === 'queued' || state === 'running'));
|
|
374
|
-
const shouldSyncActiveStates = Boolean(params?.syncActiveStates && isActiveStatesQuery);
|
|
375
|
-
return useQuery({
|
|
376
|
-
queryKey: ['chat-runs', sessionKey ?? null, states ?? null, params?.limit ?? null],
|
|
377
|
-
queryFn: () => fetchChatRuns({
|
|
378
|
-
...(sessionKey ? { sessionKey } : {}),
|
|
379
|
-
...(states ? { states } : {}),
|
|
380
|
-
...(typeof params?.limit === 'number' ? { limit: params.limit } : {})
|
|
381
|
-
}),
|
|
382
|
-
enabled: Boolean(sessionKey) || Boolean(states),
|
|
383
|
-
staleTime: 5_000,
|
|
384
|
-
refetchInterval: (query) => {
|
|
385
|
-
if (!shouldSyncActiveStates) {
|
|
386
|
-
return false;
|
|
387
|
-
}
|
|
388
|
-
if (params?.isLocallyRunning) {
|
|
389
|
-
return 800;
|
|
390
|
-
}
|
|
391
|
-
const { data } = query.state;
|
|
392
|
-
const hasActiveRuns = Array.isArray(data?.runs) && data.runs.length > 0;
|
|
393
|
-
return hasActiveRuns ? 800 : false;
|
|
394
|
-
},
|
|
395
|
-
refetchIntervalInBackground: false,
|
|
396
|
-
retry: false
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
export function useChatRun(runId: string | null) {
|
|
401
|
-
const normalizedRunId = runId?.trim() || null;
|
|
402
|
-
return useQuery({
|
|
403
|
-
queryKey: ['chat-run', normalizedRunId],
|
|
404
|
-
queryFn: () => fetchChatRun(normalizedRunId as string),
|
|
405
|
-
enabled: Boolean(normalizedRunId),
|
|
406
|
-
staleTime: 5_000,
|
|
407
|
-
retry: false
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
|
|
411
284
|
export function useCronJobs(params: { all?: boolean } = { all: true }) {
|
|
412
285
|
return useQuery({
|
|
413
286
|
queryKey: ['cron', params],
|
package/src/lib/i18n.chat.ts
CHANGED
|
@@ -70,10 +70,17 @@ export const CHAT_LABELS: Record<string, { zh: string; en: string }> = {
|
|
|
70
70
|
chatRoleMessage: { zh: '消息', en: 'Message' },
|
|
71
71
|
chatToolCall: { zh: '工具调用', en: 'Tool Call' },
|
|
72
72
|
chatToolResult: { zh: '工具结果', en: 'Tool Result' },
|
|
73
|
+
chatToolInput: { zh: '输入摘要', en: 'Input Summary' },
|
|
74
|
+
chatToolCallId: { zh: '调用 ID', en: 'Call ID' },
|
|
73
75
|
chatToolWorkflow: { zh: '工具工作流', en: 'Tool Workflow' },
|
|
74
76
|
chatToolWorkflowDetails: { zh: '展开查看参数和结果', en: 'Expand to view params and results' },
|
|
75
77
|
chatToolOutput: { zh: '查看输出', en: 'View Output' },
|
|
76
78
|
chatToolNoOutput: { zh: '无输出(执行完成)', en: 'No output (completed)' },
|
|
79
|
+
chatToolStatusPreparing: { zh: '准备中', en: 'Preparing' },
|
|
80
|
+
chatToolStatusRunning: { zh: '执行中', en: 'Running' },
|
|
81
|
+
chatToolStatusCompleted: { zh: '已完成', en: 'Completed' },
|
|
82
|
+
chatToolStatusFailed: { zh: '失败', en: 'Failed' },
|
|
83
|
+
chatToolStatusCancelled: { zh: '已取消', en: 'Cancelled' },
|
|
77
84
|
chatReasoning: { zh: '推理过程', en: 'Reasoning' },
|
|
78
85
|
chatImageAttachment: { zh: '图片附件', en: 'Image attachment' },
|
|
79
86
|
chatFileAttachment: { zh: '文件附件', en: 'File attachment' },
|
|
@@ -1,63 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export type SessionRunStatus = Extract<ChatRunState, 'queued' | 'running'>;
|
|
4
|
-
|
|
5
|
-
const RUN_STATUS_PRIORITY: Record<SessionRunStatus, number> = {
|
|
6
|
-
queued: 1,
|
|
7
|
-
running: 2
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
function toSessionRunStatus(state: ChatRunState): SessionRunStatus | null {
|
|
11
|
-
if (state === 'queued' || state === 'running') {
|
|
12
|
-
return state;
|
|
13
|
-
}
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function toComparableTimestamp(value?: string): number {
|
|
18
|
-
const parsed = Date.parse(value ?? '');
|
|
19
|
-
return Number.isFinite(parsed) ? parsed : 0;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function shouldReplaceRun(current: ChatRunView, next: ChatRunView): boolean {
|
|
23
|
-
const currentStatus = toSessionRunStatus(current.state);
|
|
24
|
-
const nextStatus = toSessionRunStatus(next.state);
|
|
25
|
-
if (!currentStatus || !nextStatus) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
const currentPriority = RUN_STATUS_PRIORITY[currentStatus];
|
|
29
|
-
const nextPriority = RUN_STATUS_PRIORITY[nextStatus];
|
|
30
|
-
if (nextPriority !== currentPriority) {
|
|
31
|
-
return nextPriority > currentPriority;
|
|
32
|
-
}
|
|
33
|
-
return toComparableTimestamp(next.requestedAt) >= toComparableTimestamp(current.requestedAt);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function buildActiveRunBySessionKey(runs: readonly ChatRunView[]): Map<string, ChatRunView> {
|
|
37
|
-
const map = new Map<string, ChatRunView>();
|
|
38
|
-
for (const run of runs) {
|
|
39
|
-
const key = run.sessionKey?.trim();
|
|
40
|
-
if (!key || !toSessionRunStatus(run.state)) {
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
const current = map.get(key);
|
|
44
|
-
if (!current || shouldReplaceRun(current, run)) {
|
|
45
|
-
map.set(key, run);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return map;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function buildSessionRunStatusByKey(
|
|
52
|
-
activeRunBySessionKey: ReadonlyMap<string, ChatRunView>
|
|
53
|
-
): Map<string, SessionRunStatus> {
|
|
54
|
-
const map = new Map<string, SessionRunStatus>();
|
|
55
|
-
for (const [sessionKey, run] of activeRunBySessionKey.entries()) {
|
|
56
|
-
const status = toSessionRunStatus(run.state);
|
|
57
|
-
if (!status) {
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
map.set(sessionKey, status);
|
|
61
|
-
}
|
|
62
|
-
return map;
|
|
63
|
-
}
|
|
1
|
+
export type SessionRunStatus = 'queued' | 'running';
|
package/src/vite-env.d.ts
CHANGED
package/vite.config.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { defineConfig, splitVendorChunkPlugin } from 'vite';
|
|
|
2
2
|
import react from '@vitejs/plugin-react';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
const
|
|
5
|
+
const devProxyApiBase = process.env.VITE_DEV_PROXY_API_BASE ?? 'http://127.0.0.1:18792';
|
|
6
|
+
const devProxyWsBase = devProxyApiBase.replace(/^http/i, 'ws');
|
|
7
7
|
|
|
8
8
|
export default defineConfig({
|
|
9
9
|
plugins: [react(), splitVendorChunkPlugin()],
|
|
@@ -20,11 +20,11 @@ export default defineConfig({
|
|
|
20
20
|
strictPort: true,
|
|
21
21
|
proxy: {
|
|
22
22
|
'/api': {
|
|
23
|
-
target:
|
|
23
|
+
target: devProxyApiBase,
|
|
24
24
|
changeOrigin: true
|
|
25
25
|
},
|
|
26
26
|
'/ws': {
|
|
27
|
-
target:
|
|
27
|
+
target: devProxyWsBase,
|
|
28
28
|
ws: true
|
|
29
29
|
}
|
|
30
30
|
}
|