首页布局优化前

This commit is contained in:
iven
2026-03-17 23:26:16 +08:00
parent 74dbf42644
commit e262200f1e
89 changed files with 2266 additions and 2120 deletions

View File

@@ -207,7 +207,25 @@ export const useChatStore = create<ChatState>()(
return { currentAgent: agent };
}
// Save current conversation before switching
const conversations = upsertActiveConversation([...state.conversations], state);
// Try to find existing conversation for this agent
const agentConversation = conversations.find(c => c.agentId === agent.id);
if (agentConversation) {
// Restore the agent's previous conversation
return {
conversations,
currentAgent: agent,
messages: [...agentConversation.messages],
sessionKey: agentConversation.sessionKey,
isStreaming: false,
currentConversationId: agentConversation.id,
};
}
// No existing conversation, start fresh
return {
conversations,
currentAgent: agent,
@@ -627,7 +645,7 @@ export const useChatStore = create<ChatState>()(
partialize: (state) => ({
conversations: state.conversations,
currentModel: state.currentModel,
messages: state.messages,
currentAgentId: state.currentAgent?.id,
currentConversationId: state.currentConversationId,
}),
onRehydrateStorage: () => (state) => {
@@ -642,6 +660,15 @@ export const useChatStore = create<ChatState>()(
}
}
}
// Restore messages from current conversation if exists
if (state?.currentConversationId && state.conversations) {
const currentConv = state.conversations.find(c => c.id === state.currentConversationId);
if (currentConv) {
state.messages = [...currentConv.messages];
state.sessionKey = currentConv.sessionKey;
}
}
},
},
),

View File

@@ -150,11 +150,27 @@ interface RawApproval {
request_type?: string;
handId?: string;
hand_id?: string;
hand_name?: string;
handName?: string;
run_id?: string;
runId?: string;
requester?: string;
requested_by?: string;
requested_at?: string;
requestedAt?: string;
reason?: string;
description?: string;
action?: string;
params?: Record<string, unknown>;
status?: string;
createdAt?: string;
created_at?: string;
responded_at?: string;
respondedAt?: string;
responded_by?: string;
respondedBy?: string;
response_reason?: string;
responseReason?: string;
details?: Record<string, unknown>;
metadata?: Record<string, unknown>;
}
@@ -173,6 +189,7 @@ interface RawSession {
updated_at?: string;
messageCount?: number;
message_count?: number;
metadata?: Record<string, unknown>;
}
interface RawSessionMessage {
@@ -184,6 +201,7 @@ interface RawSessionMessage {
createdAt?: string;
created_at?: string;
metadata?: Record<string, unknown>;
tokens?: { input?: number; output?: number };
}
interface RawWorkflowRun {
@@ -202,6 +220,8 @@ interface RawWorkflowRun {
totalSteps?: number;
total_steps?: number;
error?: string;
step?: string;
result?: unknown;
}
// === OpenFang Types ===
@@ -780,21 +800,22 @@ export const useGatewayStore = create<GatewayStore>((set, get) => {
try {
const result = await get().client.listClones();
// API 可能返回数组,也可能返回 {clones: [...]} 或 {agents: [...]}
const clones = Array.isArray(result) ? result : (result?.clones || result?.agents || []);
set({ clones });
useChatStore.getState().syncAgents(clones);
let clones = Array.isArray(result) ? result : (result?.clones || result?.agents || []);
// Set default agent ID if we have agents and none is set
console.log('[Gateway] Loaded agents:', clones.length, clones.map((c: { id?: string; name?: string }) => ({ id: c.id, name: c.name })));
// Set default agent ID if we have agents
if (clones.length > 0 && clones[0].id) {
const client = get().client;
const currentDefault = client.getDefaultAgentId();
// Only set if the default doesn't exist in the list
const defaultExists = clones.some((c) => c.id === currentDefault);
if (!defaultExists) {
client.setDefaultAgentId(clones[0].id);
}
client.setDefaultAgentId(clones[0].id);
console.log('[Gateway] Set default agent ID:', clones[0].id);
}
} catch { /* ignore if method not available */ }
set({ clones });
useChatStore.getState().syncAgents(clones);
} catch (err) {
console.warn('[Gateway] Failed to load clones:', err);
}
},
createClone: async (opts) => {
@@ -1084,7 +1105,7 @@ export const useGatewayStore = create<GatewayStore>((set, get) => {
set({ localGateway: status, localGatewayBusy: false });
return status;
} catch (err: unknown) {
const message = err?.message || '读取本地 Gateway 状态失败';
const message = err instanceof Error ? err.message : '读取本地 Gateway 状态失败';
const nextStatus = {
...get().localGateway,
supported: true,
@@ -1108,7 +1129,7 @@ export const useGatewayStore = create<GatewayStore>((set, get) => {
set({ localGateway: status, localGatewayBusy: false });
return status;
} catch (err: unknown) {
const message = err?.message || '启动本地 Gateway 失败';
const message = err instanceof Error ? err.message : '启动本地 Gateway 失败';
const nextStatus = {
...get().localGateway,
supported: true,
@@ -1132,7 +1153,7 @@ export const useGatewayStore = create<GatewayStore>((set, get) => {
set({ localGateway: status, localGatewayBusy: false });
return status;
} catch (err: unknown) {
const message = err?.message || '停止本地 Gateway 失败';
const message = err instanceof Error ? err.message : '停止本地 Gateway 失败';
const nextStatus = {
...get().localGateway,
supported: true,
@@ -1156,7 +1177,7 @@ export const useGatewayStore = create<GatewayStore>((set, get) => {
set({ localGateway: status, localGatewayBusy: false });
return status;
} catch (err: unknown) {
const message = err?.message || '重启本地 Gateway 失败';
const message = err instanceof Error ? err.message : '重启本地 Gateway 失败';
const nextStatus = {
...get().localGateway,
supported: true,
@@ -1522,13 +1543,13 @@ export const useGatewayStore = create<GatewayStore>((set, get) => {
const approvals: Approval[] = (result?.approvals || []).map((a: RawApproval) => ({
id: a.id || a.approval_id || '',
handName: a.hand_name || a.handName || '',
runId: a.run_id || a.runId || '',
status: a.status || 'pending',
runId: a.run_id || a.runId,
status: (a.status || 'pending') as ApprovalStatus,
requestedAt: a.requested_at || a.requestedAt || new Date().toISOString(),
requestedBy: a.requested_by || a.requestedBy || '',
reason: a.reason || a.description || '',
action: a.action || 'execute',
params: a.params || {},
requestedBy: a.requested_by || a.requester,
reason: a.reason || a.description,
action: a.action,
params: a.params,
respondedAt: a.responded_at || a.respondedAt,
respondedBy: a.responded_by || a.respondedBy,
responseReason: a.response_reason || a.responseReason,
@@ -1553,15 +1574,17 @@ export const useGatewayStore = create<GatewayStore>((set, get) => {
loadSessions: async (opts?: { limit?: number; offset?: number }) => {
try {
const result = await get().client.listSessions(opts);
const sessions: Session[] = (result?.sessions || []).map((s: RawSession) => ({
id: s.id,
agentId: s.agent_id,
createdAt: s.created_at,
updatedAt: s.updated_at,
messageCount: s.message_count,
status: s.status,
metadata: s.metadata,
}));
const sessions: Session[] = (result?.sessions || [])
.filter((s: RawSession) => s.id || s.session_id) // Filter out sessions without IDs
.map((s: RawSession) => ({
id: s.id || s.session_id || '',
agentId: s.agent_id || s.agentId || '',
createdAt: s.created_at || s.createdAt || new Date().toISOString(),
updatedAt: s.updated_at || s.updatedAt,
messageCount: s.message_count || s.messageCount,
status: s.status as Session['status'],
metadata: s.metadata,
}));
set({ sessions });
} catch {
/* ignore if sessions API not available */
@@ -1631,10 +1654,10 @@ export const useGatewayStore = create<GatewayStore>((set, get) => {
try {
const result = await get().client.getSessionMessages(sessionId, opts);
const messages: SessionMessage[] = (result?.messages || []).map((m: RawSessionMessage) => ({
id: m.id,
role: m.role,
content: m.content,
createdAt: m.created_at,
id: m.id || m.message_id || '',
role: (m.role || 'user') as 'user' | 'assistant' | 'system',
content: m.content || '',
createdAt: m.created_at || m.createdAt || new Date().toISOString(),
tokens: m.tokens,
}));
set(state => ({
@@ -1668,13 +1691,10 @@ export const useGatewayStore = create<GatewayStore>((set, get) => {
try {
const result = await get().client.listWorkflowRuns(workflowId, opts);
const runs: WorkflowRun[] = (result?.runs || []).map((r: RawWorkflowRun) => ({
runId: r.runId || r.run_id,
status: r.status,
startedAt: r.startedAt || r.started_at,
completedAt: r.completedAt || r.completed_at,
step: r.step,
runId: r.runId || r.run_id || r.id || '',
status: r.status || 'unknown',
step: r.step || r.currentStep?.toString(),
result: r.result,
error: r.error,
}));
// Store runs by workflow ID
set(state => ({