Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qjclaw-dmg
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
AI-甘富林
qjclaw-dmg
Commits
e1298d9f
Commit
e1298d9f
authored
Apr 20, 2026
by
AI-甘富林
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(chat): preserve streaming conversation when switching sessions
parent
6dec17bf
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
999 additions
and
135 deletions
+999
-135
ipc.ts
apps/desktop/src/main/ipc.ts
+577
-66
project-store.ts
apps/desktop/src/main/services/project-store.ts
+11
-0
App.tsx
apps/ui/src/App.tsx
+277
-66
index.ts
packages/shared-types/src/index.ts
+134
-3
No files found.
apps/desktop/src/main/ipc.ts
View file @
e1298d9f
This diff is collapsed.
Click to expand it.
apps/desktop/src/main/services/project-store.ts
View file @
e1298d9f
...
@@ -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
);
...
...
apps/ui/src/App.tsx
View file @
e1298d9f
This diff is collapsed.
Click to expand it.
packages/shared-types/src/index.ts
View file @
e1298d9f
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
:
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment