mirror of
https://github.com/lobehub/lobehub
synced 2026-04-21 09:37:28 +00:00
🐛 fix(cc): persist workingDirectory when CC topic is created (#13956)
Hetero-agent topic creation went through `aiChat.sendMessageInServer`'s `newTopic` payload, which had no metadata field, so the topic row was inserted with `metadata.workingDirectory = NULL`. Today the only writer is the post-execution `updateTopicMetadata` in `heterogeneousAgentExecutor` — that never lands when CC is cancelled or errors before completion, and in the meantime the topic is missed by By-Project grouping and `--resume` cwd verification has nothing to compare against. Source the cwd at the start of the hetero branch and thread it through `newTopic.metadata`, so the binding is set at insert time. The post-exec update still runs to record `ccSessionId` (and is now a no-op for cwd). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
30e93ada67
commit
f38dcc4cfc
3 changed files with 19 additions and 3 deletions
|
|
@ -8,7 +8,7 @@ import { PageSelectionSchema } from './message/ui/params';
|
|||
import type { OpenAIChatMessage } from './openai/chat';
|
||||
import type { LobeUniformTool } from './tool';
|
||||
import { LobeUniformToolSchema } from './tool';
|
||||
import type { ChatTopic } from './topic';
|
||||
import type { ChatTopic, ChatTopicMetadata } from './topic';
|
||||
import type { ChatThreadType } from './topic/thread';
|
||||
import { ThreadType } from './topic/thread';
|
||||
|
||||
|
|
@ -66,6 +66,14 @@ export interface SendMessageServerParams {
|
|||
*/
|
||||
newThread?: CreateThreadWithMessageParams;
|
||||
newTopic?: {
|
||||
/**
|
||||
* Topic metadata persisted at creation time. For CC/heterogeneous
|
||||
* agents this carries `workingDirectory` so the topic is bound to a
|
||||
* project from the moment it's created (used by By-Project grouping
|
||||
* and CC `--resume` cwd verification), instead of waiting for the
|
||||
* post-execution metadata write which can be skipped on cancel/error.
|
||||
*/
|
||||
metadata?: ChatTopicMetadata;
|
||||
title?: string;
|
||||
topicMessageIds?: string[];
|
||||
};
|
||||
|
|
@ -111,6 +119,7 @@ export const AiSendMessageServerSchema = z.object({
|
|||
newThread: CreateThreadWithMessageSchema.optional(),
|
||||
newTopic: z
|
||||
.object({
|
||||
metadata: z.custom<ChatTopicMetadata>().optional(),
|
||||
title: z.string().optional(),
|
||||
topicMessageIds: z.array(z.string()).optional(),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ export const aiChatRouter = router({
|
|||
agentId: input.agentId,
|
||||
groupId: input.groupId,
|
||||
messages: input.newTopic.topicMessageIds,
|
||||
metadata: input.newTopic.metadata,
|
||||
sessionId,
|
||||
title: input.newTopic.title,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -347,6 +347,13 @@ export class ConversationLifecycleActionImpl {
|
|||
const agentConfig = agentSelectors.getAgentConfigById(agentId)(getAgentStoreState());
|
||||
const heterogeneousProvider = agentConfig?.agencyConfig?.heterogeneousProvider;
|
||||
if (isDesktop && heterogeneousProvider?.type === 'claude-code') {
|
||||
// Resolve cwd up-front so the new topic is bound to a project at
|
||||
// creation time. Otherwise the row stays NULL until the post-execution
|
||||
// metadata write — which never lands on cancel/error and meanwhile
|
||||
// makes By-Project grouping miss the topic and `--resume` unsafe.
|
||||
const workingDirectory =
|
||||
agentByIdSelectors.getAgentWorkingDirectoryById(agentId)(getAgentStoreState());
|
||||
|
||||
// Persist messages to DB first (same as client mode)
|
||||
let heteroData: SendMessageServerResponse | undefined;
|
||||
try {
|
||||
|
|
@ -358,6 +365,7 @@ export class ConversationLifecycleActionImpl {
|
|||
newAssistantMessage: { model, provider: 'claude-code' },
|
||||
newTopic: !operationContext.topicId
|
||||
? {
|
||||
metadata: workingDirectory ? { workingDirectory } : undefined,
|
||||
title: message.slice(0, 20) || t('defaultTitle', { ns: 'topic' }),
|
||||
topicMessageIds: messages.map((m) => m.id),
|
||||
}
|
||||
|
|
@ -437,8 +445,6 @@ export class ConversationLifecycleActionImpl {
|
|||
|
||||
try {
|
||||
const { executeHeterogeneousAgent } = await import('./heterogeneousAgentExecutor');
|
||||
const workingDirectory =
|
||||
agentByIdSelectors.getAgentWorkingDirectoryById(agentId)(getAgentStoreState());
|
||||
// Extract imageList from the persisted user message (chatUploadFileList
|
||||
// may already be cleared by this point, so we read from DB instead)
|
||||
const userMsg = heteroData.messages.find((m: any) => m.id === heteroData.userMessageId);
|
||||
|
|
|
|||
Loading…
Reference in a new issue