feat: improve interactivity by predict sessions

This commit is contained in:
d-kimsuon
2025-10-15 01:18:14 +09:00
parent c7d89d47cd
commit 0259e71b44
15 changed files with 186 additions and 84 deletions

View File

@@ -2,6 +2,7 @@ import prexit from "prexit";
import { ulid } from "ulid";
import type { Config } from "../../config/config";
import { eventBus } from "../events/EventBus";
import { predictSessionsDatabase } from "../session/PredictSessionsDatabase";
import { ClaudeCodeExecutor } from "./ClaudeCodeExecutor";
import { createMessageGenerator } from "./createMessageGenerator";
import type {
@@ -168,9 +169,20 @@ export class ClaudeCodeTaskController {
);
if (existingTask) {
console.log(
`Alive task for session(id=${currentSession.sessionId}) continued.`,
);
const result = await this.continueTask(existingTask, message);
return result;
} else {
if (currentSession.sessionId === undefined) {
console.log(`New task started.`);
} else {
console.log(
`New task started for existing session(id=${currentSession.sessionId}).`,
);
}
const result = await this.startTask(currentSession, message);
return result;
}
@@ -188,7 +200,7 @@ export class ClaudeCodeTaskController {
projectId: string;
sessionId?: string;
},
message: string,
userMessage: string,
) {
const {
generateMessages,
@@ -196,7 +208,7 @@ export class ClaudeCodeTaskController {
setFirstMessagePromise,
resolveFirstMessage,
awaitFirstMessage,
} = createMessageGenerator(message);
} = createMessageGenerator(userMessage);
const task: PendingClaudeCodeTask = {
status: "pending",
@@ -252,43 +264,62 @@ export class ClaudeCodeTaskController {
});
}
// 初回の system message だとまだ history ファイルが作成されていないので
if (message.type === "user" || message.type === "assistant") {
// 本来は message.uuid の存在チェックをしたいが、古いバージョンでは存在しないことがある
if (!resolved) {
console.log(
"[DEBUG startTask] 10. Resolving task for first time",
);
const runningTask: RunningClaudeCodeTask = {
status: "running",
id: task.id,
projectId: task.projectId,
cwd: task.cwd,
generateMessages: task.generateMessages,
setNextMessage: task.setNextMessage,
resolveFirstMessage: task.resolveFirstMessage,
setFirstMessagePromise: task.setFirstMessagePromise,
awaitFirstMessage: task.awaitFirstMessage,
onMessageHandlers: task.onMessageHandlers,
userMessageId: message.uuid,
sessionId: message.session_id,
abortController: abortController,
};
this.tasks.push(runningTask);
console.log(
"[DEBUG startTask] 11. About to call aliveTaskResolve",
);
aliveTaskResolve(runningTask);
resolved = true;
console.log(
"[DEBUG startTask] 12. aliveTaskResolve called, resolved=true",
);
}
resolveFirstMessage();
if (
message.type === "system" &&
message.subtype === "init" &&
currentSession.sessionId === undefined
) {
// because it takes time for the Claude Code file to be updated, simulate the message
predictSessionsDatabase.createPredictSession({
id: message.session_id,
jsonlFilePath: message.session_id,
conversations: [
{
type: "user",
message: {
role: "user",
content: userMessage,
},
isSidechain: false,
userType: "external",
cwd: message.cwd,
sessionId: message.session_id,
version: this.claudeCode.version?.toString() ?? "unknown",
uuid: message.uuid,
timestamp: new Date().toISOString(),
parentUuid: null,
},
],
meta: {
firstCommand: null,
lastModifiedAt: new Date().toISOString(),
messageCount: 0,
},
});
}
if (!resolved) {
const runningTask: RunningClaudeCodeTask = {
status: "running",
id: task.id,
projectId: task.projectId,
cwd: task.cwd,
generateMessages: task.generateMessages,
setNextMessage: task.setNextMessage,
resolveFirstMessage: task.resolveFirstMessage,
setFirstMessagePromise: task.setFirstMessagePromise,
awaitFirstMessage: task.awaitFirstMessage,
onMessageHandlers: task.onMessageHandlers,
sessionId: message.session_id,
abortController: abortController,
};
this.tasks.push(runningTask);
aliveTaskResolve(runningTask);
resolved = true;
}
resolveFirstMessage();
await Promise.all(
task.onMessageHandlers.map(async (onMessageHandler) => {
await onMessageHandler(message);
@@ -302,6 +333,7 @@ export class ClaudeCodeTaskController {
});
resolved = true;
setFirstMessagePromise();
predictSessionsDatabase.deletePredictSession(currentTask.sessionId);
}
}
@@ -372,7 +404,6 @@ export class ClaudeCodeTaskController {
awaitFirstMessage: task.awaitFirstMessage,
onMessageHandlers: task.onMessageHandlers,
baseSessionId: task.baseSessionId,
userMessageId: task.userMessageId,
});
}