Commit e1298d9f authored by AI-甘富林's avatar AI-甘富林

fix(chat): preserve streaming conversation when switching sessions

parent 6dec17bf
This diff is collapsed.
...@@ -712,6 +712,17 @@ export class ProjectStoreService { ...@@ -712,6 +712,17 @@ export class ProjectStoreService {
await writeJsonFile(await this.getSessionMessagesPath(sessionId), messages); await writeJsonFile(await this.getSessionMessagesPath(sessionId), messages);
} }
async upsertSessionMessage(sessionId: string, message: ChatMessage): Promise<void> {
const messages = await this.listSessionMessages(sessionId);
const existingIndex = messages.findIndex((entry) => entry.id === message.id);
if (existingIndex >= 0) {
messages[existingIndex] = message;
} else {
messages.push(message);
}
await writeJsonFile(await this.getSessionMessagesPath(sessionId), messages);
}
async listCurrentProjectSkills(): Promise<WorkspaceSkillSummary[]> { async listCurrentProjectSkills(): Promise<WorkspaceSkillSummary[]> {
const project = await this.getActiveProject(); const project = await this.getActiveProject();
return this.listProjectSkills(project.id); return this.listProjectSkills(project.id);
......
This diff is collapsed.
export const IPC_CHANNELS = { export const IPC_CHANNELS = {
workspaceGetSummary: "workspace:get-summary", workspaceGetSummary: "workspace:get-summary",
workspaceWarmup: "workspace:warmup", workspaceWarmup: "workspace:warmup",
windowMinimize: "window:minimize",
windowMaximize: "window:maximize",
windowClose: "window:close",
gatewayStatus: "gateway:status", gatewayStatus: "gateway:status",
gatewayConnect: "gateway:connect", gatewayConnect: "gateway:connect",
gatewayDisconnect: "gateway:disconnect", gatewayDisconnect: "gateway:disconnect",
...@@ -20,6 +23,7 @@ ...@@ -20,6 +23,7 @@
configSave: "config:save", configSave: "config:save",
projectsList: "projects:list", projectsList: "projects:list",
projectsSetActive: "projects:set-active", projectsSetActive: "projects:set-active",
projectsResolveIntent: "projects:resolve-intent",
skillCatalogList: "skill-catalog:list", skillCatalogList: "skill-catalog:list",
chatListSessions: "chat:list-sessions", chatListSessions: "chat:list-sessions",
chatListSessionsByProject: "chat:list-sessions-by-project", chatListSessionsByProject: "chat:list-sessions-by-project",
...@@ -27,6 +31,7 @@ ...@@ -27,6 +31,7 @@
chatCreateSessionForProject: "chat:create-session-for-project", chatCreateSessionForProject: "chat:create-session-for-project",
chatCloseSession: "chat:close-session", chatCloseSession: "chat:close-session",
chatListMessages: "chat:list-messages", chatListMessages: "chat:list-messages",
chatPickImageAttachment: "chat:pick-image-attachment",
chatSendPrompt: "chat:send-prompt", chatSendPrompt: "chat:send-prompt",
chatStreamPrompt: "chat:stream-prompt", chatStreamPrompt: "chat:stream-prompt",
chatStreamEvent: "chat:stream-event", chatStreamEvent: "chat:stream-event",
...@@ -38,6 +43,7 @@ ...@@ -38,6 +43,7 @@
profileGetSummary: "profile:get-summary", profileGetSummary: "profile:get-summary",
creditsGetSummary: "credits:get-summary", creditsGetSummary: "credits:get-summary",
skillsList: "skills:list", skillsList: "skills:list",
expertsList: "experts:list",
modelConfigGetSummary: "model-config:get-summary", modelConfigGetSummary: "model-config:get-summary",
systemGetSummary: "system:get-summary" systemGetSummary: "system:get-summary"
} as const; } as const;
...@@ -66,6 +72,7 @@ export type SetupMode = "employee-key" | "direct-provider"; ...@@ -66,6 +72,7 @@ export type SetupMode = "employee-key" | "direct-provider";
export type ChatLaunchState = "unbound" | "starting" | "ready" | "error"; export type ChatLaunchState = "unbound" | "starting" | "ready" | "error";
export type WorkspaceStartupPhase = "idle" | "syncing-config" | "syncing-projects" | "starting-runtime" | "connecting-gateway" | "ready" | "error"; export type WorkspaceStartupPhase = "idle" | "syncing-config" | "syncing-projects" | "starting-runtime" | "connecting-gateway" | "ready" | "error";
export type SkillDownloadState = "pending" | "downloading" | "ready" | "failed" | "removed"; export type SkillDownloadState = "pending" | "downloading" | "ready" | "failed" | "removed";
export type ExpertEntryMode = "standalone" | "home-chat-shortcut";
export type DailyReportDeliveryState = "draft" | "sent" | "failed"; export type DailyReportDeliveryState = "draft" | "sent" | "failed";
export interface WorkspaceWarmupResult { export interface WorkspaceWarmupResult {
...@@ -256,6 +263,17 @@ export interface WorkspaceSkillSummary { ...@@ -256,6 +263,17 @@ export interface WorkspaceSkillSummary {
lastError?: string; lastError?: string;
} }
export interface ExpertDefinition {
id: string;
name: string;
entryMode: ExpertEntryMode;
description?: string;
starterPrompt?: string;
promptFile?: string;
promptAvailable: boolean;
projectMatchKeywords: string[];
}
export interface PluginSummary { export interface PluginSummary {
id: string; id: string;
name: string; name: string;
...@@ -349,6 +367,16 @@ export interface ProjectSummary { ...@@ -349,6 +367,16 @@ export interface ProjectSummary {
defaultEntryType?: ProjectPackageEntryType; defaultEntryType?: ProjectPackageEntryType;
} }
export interface ProjectIntentSuggestion {
projectId: string;
projectName: string;
projectDisplayName: string;
score: number;
confidence: "low" | "medium" | "high";
reason: string;
matchedAliases: string[];
}
export interface ProjectSessionSummary extends SessionSummary { export interface ProjectSessionSummary extends SessionSummary {
projectId: string; projectId: string;
} }
...@@ -386,6 +414,18 @@ export interface ProjectSessionState { ...@@ -386,6 +414,18 @@ export interface ProjectSessionState {
draft: string; draft: string;
} }
export interface ChatAttachment {
kind: "image";
name: string;
mimeType: string;
localPath: string;
}
export interface ProjectResolvedAttachment extends ChatAttachment {
projectPath: string;
relativeProjectPath: string;
}
export interface ProjectExecutionRequest { export interface ProjectExecutionRequest {
sessionId: string; sessionId: string;
projectId: string; projectId: string;
...@@ -393,6 +433,7 @@ export interface ProjectExecutionRequest { ...@@ -393,6 +433,7 @@ export interface ProjectExecutionRequest {
userPrompt: string; userPrompt: string;
context: ProjectContextSnapshot; context: ProjectContextSnapshot;
selectedSkillId: string | null; selectedSkillId: string | null;
attachments?: ProjectResolvedAttachment[];
projectConfig?: ProjectPackageConfig | null; projectConfig?: ProjectPackageConfig | null;
} }
...@@ -418,9 +459,12 @@ export interface ChatMessage { ...@@ -418,9 +459,12 @@ export interface ChatMessage {
role: MessageRole; role: MessageRole;
content: string; content: string;
createdAt: string; createdAt: string;
streamState?: "streaming" | "error";
statusLabel?: string;
statusDetail?: string;
} }
export type ChatExecutionPolicySource = "cloud-default" | "cloud-skill-binding" | "local-fallback"; export type ChatExecutionPolicySource = "cloud-default" | "cloud-skill-binding" | "local-fallback" | "client-config";
export type ChatExecutionRoutingMode = ModelRoutingMode | SkillModelBindingMode | "fallback"; export type ChatExecutionRoutingMode = ModelRoutingMode | SkillModelBindingMode | "fallback";
export interface ChatExecutionPolicy { export interface ChatExecutionPolicy {
...@@ -437,6 +481,8 @@ export interface ChatStreamPromptResult { ...@@ -437,6 +481,8 @@ export interface ChatStreamPromptResult {
requestId: string; requestId: string;
sessionId: string; sessionId: string;
runId?: string; runId?: string;
userMessageId?: string;
assistantMessageId: string;
executionPolicy?: ChatExecutionPolicy; executionPolicy?: ChatExecutionPolicy;
} }
...@@ -482,6 +528,7 @@ export interface ChatStreamErrorEvent { ...@@ -482,6 +528,7 @@ export interface ChatStreamErrorEvent {
sessionId: string; sessionId: string;
runId?: string; runId?: string;
message: string; message: string;
errorCategory?: string;
} }
export type ChatStreamEvent = ChatStreamStartedEvent | ChatStreamStatusEvent | ChatStreamDeltaEvent | ChatStreamCompletedEvent | ChatStreamErrorEvent; export type ChatStreamEvent = ChatStreamStartedEvent | ChatStreamStatusEvent | ChatStreamDeltaEvent | ChatStreamCompletedEvent | ChatStreamErrorEvent;
...@@ -494,6 +541,60 @@ export interface PromptResult { ...@@ -494,6 +541,60 @@ export interface PromptResult {
executionPolicy?: ChatExecutionPolicy; executionPolicy?: ChatExecutionPolicy;
} }
export interface ModelEndpointConfig {
baseUrl: string;
apiKeyConfigured: boolean;
modelId?: string;
}
export interface DigitalHumanModelConfig {
volcRegion: string;
volcService: string;
volcHost: string;
volcScheme: string;
ttsVoice: string;
qiniuBucket: string;
qiniuDomain: string;
qiniuKeyPrefix: string;
volcAccessKeyConfigured: boolean;
volcSecretKeyConfigured: boolean;
qiniuAccessKeyConfigured: boolean;
qiniuSecretKeyConfigured: boolean;
}
export interface ExpertModelConfig {
image: ModelEndpointConfig;
video: ModelEndpointConfig;
copywriting: ModelEndpointConfig;
digitalHuman: DigitalHumanModelConfig;
}
export const FIXED_EXPERT_MODEL_ENDPOINTS = {
copywriting: {
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
modelId: "qwen3.5-plus"
},
image: {
baseUrl: "https://ark.cn-beijing.volces.com/api/v3/images/generations",
modelId: "doubao-seedream-5-0-260128"
},
video: {
baseUrl: "https://ark.cn-beijing.volces.com/api/v3",
modelId: "doubao-seedance-2-0-260128"
}
} as const;
export const FIXED_DIGITAL_HUMAN_CONFIG = {
volcRegion: "cn-north-1",
volcService: "cv",
volcHost: "visual.volcengineapi.com",
volcScheme: "https",
ttsVoice: "zh-CN-YunxiNeural",
qiniuBucket: "alketas",
qiniuDomain: "http://tcwwu6wg4.hd-bkt.clouddn.com",
qiniuKeyPrefix: "omnihuman"
} as const;
export interface AppConfig { export interface AppConfig {
setupMode: SetupMode; setupMode: SetupMode;
provider: string; provider: string;
...@@ -507,6 +608,7 @@ export interface AppConfig { ...@@ -507,6 +608,7 @@ export interface AppConfig {
cloudApiBaseUrl: string; cloudApiBaseUrl: string;
runtimeCloudApiBaseUrl: string; runtimeCloudApiBaseUrl: string;
runtimeMode: RuntimeModePreference; runtimeMode: RuntimeModePreference;
expertModelConfig: ExpertModelConfig;
} }
export interface DiagnosticsExportResult { export interface DiagnosticsExportResult {
...@@ -515,6 +617,19 @@ export interface DiagnosticsExportResult { ...@@ -515,6 +617,19 @@ export interface DiagnosticsExportResult {
startupLogPath?: string; startupLogPath?: string;
} }
export interface ModelEndpointInput {
baseUrl?: string;
apiKey?: string;
modelId?: string;
}
export interface DigitalHumanModelInput {
volcAccessKey?: string;
volcSecretKey?: string;
qiniuAccessKey?: string;
qiniuSecretKey?: string;
}
export interface SaveConfigInput { export interface SaveConfigInput {
setupMode: SetupMode; setupMode: SetupMode;
provider: string; provider: string;
...@@ -528,6 +643,12 @@ export interface SaveConfigInput { ...@@ -528,6 +643,12 @@ export interface SaveConfigInput {
cloudApiBaseUrl: string; cloudApiBaseUrl: string;
runtimeCloudApiBaseUrl: string; runtimeCloudApiBaseUrl: string;
runtimeMode: RuntimeModePreference; runtimeMode: RuntimeModePreference;
expertModelConfig?: {
image?: ModelEndpointInput;
video?: ModelEndpointInput;
copywriting?: ModelEndpointInput;
digitalHuman?: DigitalHumanModelInput;
};
} }
export interface AuthSessionSummary { export interface AuthSessionSummary {
...@@ -651,6 +772,11 @@ export interface DesktopApi { ...@@ -651,6 +772,11 @@ export interface DesktopApi {
getSummary(): Promise<WorkspaceSummary>; getSummary(): Promise<WorkspaceSummary>;
warmup(): Promise<WorkspaceWarmupResult>; warmup(): Promise<WorkspaceWarmupResult>;
}; };
window: {
minimize(): Promise<void>;
maximize(): Promise<void>;
close(): Promise<void>;
};
gateway: { gateway: {
status(): Promise<GatewayStatus>; status(): Promise<GatewayStatus>;
connect(): Promise<GatewayStatus>; connect(): Promise<GatewayStatus>;
...@@ -681,6 +807,7 @@ export interface DesktopApi { ...@@ -681,6 +807,7 @@ export interface DesktopApi {
projects: { projects: {
list(): Promise<ProjectSummary[]>; list(): Promise<ProjectSummary[]>;
setActive(projectId: string): Promise<WorkspaceSummary>; setActive(projectId: string): Promise<WorkspaceSummary>;
resolveIntent(prompt: string, currentProjectId?: string): Promise<ProjectIntentSuggestion | null>;
}; };
skillCatalog: { skillCatalog: {
list(): Promise<SkillCatalogItem[]>; list(): Promise<SkillCatalogItem[]>;
...@@ -699,6 +826,9 @@ export interface DesktopApi { ...@@ -699,6 +826,9 @@ export interface DesktopApi {
skills: { skills: {
list(): Promise<SkillSummary[]>; list(): Promise<SkillSummary[]>;
}; };
experts: {
list(): Promise<ExpertDefinition[]>;
};
modelConfig: { modelConfig: {
getSummary(): Promise<ModelConfigSummary>; getSummary(): Promise<ModelConfigSummary>;
}; };
...@@ -712,8 +842,9 @@ export interface DesktopApi { ...@@ -712,8 +842,9 @@ export interface DesktopApi {
createSessionForProject(projectId: string, title?: string): Promise<ProjectSessionSummary>; createSessionForProject(projectId: string, title?: string): Promise<ProjectSessionSummary>;
closeSession(sessionId: string): Promise<ProjectSessionSummary[]>; closeSession(sessionId: string): Promise<ProjectSessionSummary[]>;
listMessages(sessionId: string): Promise<ChatMessage[]>; listMessages(sessionId: string): Promise<ChatMessage[]>;
sendPrompt(sessionId: string, prompt: string, skillId?: string): Promise<PromptResult>; pickImageAttachment(): Promise<ChatAttachment | null>;
streamPrompt(sessionId: string, prompt: string, skillId?: string): Promise<ChatStreamPromptResult>; sendPrompt(sessionId: string, prompt: string, skillId?: string, attachments?: ChatAttachment[]): Promise<PromptResult>;
streamPrompt(sessionId: string, prompt: string, skillId?: string, attachments?: ChatAttachment[]): Promise<ChatStreamPromptResult>;
onStreamEvent(listener: ChatStreamListener): () => void; onStreamEvent(listener: ChatStreamListener): () => void;
}; };
diagnostics: { diagnostics: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment