Inline thread runtime parts

This commit is contained in:
murashit 2026-06-16 03:50:59 +09:00
parent 8fa983a227
commit 6cecf9a8be
2 changed files with 44 additions and 156 deletions

View file

@ -1,135 +0,0 @@
import type { AppServerClient } from "../../../../app-server/connection/client";
import type { ThreadOperations } from "../../../threads/thread-operations";
import type { ThreadTitleService } from "../../../threads/thread-title-service";
import type { GoalActions } from "./goal-actions";
import type { ChatResumeWorkTracker, ChatViewDeferredTasks } from "../lifecycle";
import type { ChatStateStore } from "../state/store";
import type { AutoTitleController } from "./auto-title-controller";
import { ThreadRenameEditorController } from "./rename-editor-controller";
import { createThreadManagementActions, type ThreadManagementActions, type ThreadManagementActionsHost } from "./thread-management-actions";
import { createThreadLifecycleParts } from "./lifecycle-parts";
interface ThreadPartsContext {
settingsRef: { readonly vaultPath: string };
workspace: {
focusThreadInOpenView: (threadId: string) => Promise<boolean>;
openThreadInNewView: (threadId: string) => Promise<unknown>;
};
threadCatalog: {
refreshFromOpenSurface(): void;
};
state: {
stateStore: ChatStateStore;
};
client: {
getClient: () => AppServerClient | null;
ensureConnected: () => Promise<void>;
};
lifecycle: {
deferredTasks: ChatViewDeferredTasks;
resumeWork: ChatResumeWorkTracker;
getOpened: () => boolean;
getClosing: () => boolean;
};
thread: {
fetchActiveThreads: () => Promise<void>;
notifyIdentityChanged: () => void;
refreshTabHeader: () => void;
};
status: {
set: (status: string) => void;
addSystemMessage: (text: string) => void;
};
liveState: {
refresh: () => void;
};
scroll: {
preservePosition: () => void;
forceBottom: () => void;
};
goals: GoalActions;
autoTitle: AutoTitleController;
operations: ThreadOperations;
titleService: ThreadTitleService;
}
export function createThreadParts(context: ThreadPartsContext) {
const {
settingsRef,
workspace,
threadCatalog,
state,
thread,
status,
liveState,
scroll,
client,
lifecycle,
goals,
autoTitle,
operations,
titleService,
} = context;
const stateStore = state.stateStore;
const currentClient = client.getClient;
const rename = new ThreadRenameEditorController({
stateStore,
ensureConnected: client.ensureConnected,
addSystemMessage: status.addSystemMessage,
operations,
titleService,
});
const threadLifecycle = createThreadLifecycleParts({
settingsRef,
stateStore,
client: {
currentClient,
ensureConnected: client.ensureConnected,
},
lifecycle,
thread: {
notifyIdentityChanged: thread.notifyIdentityChanged,
refreshTabHeader: thread.refreshTabHeader,
},
status,
liveState,
scroll,
goals,
resetThreadTurnPresence: (hadTurns) => {
autoTitle.resetThreadTurnPresence(hadTurns);
},
});
const { history, restoration, resume, identity } = threadLifecycle;
const createManagementActions = (composer: { setText: (text: string) => void }): ThreadManagementActions => {
const threadManagementHost: ThreadManagementActionsHost = {
stateStore,
vaultPath: settingsRef.vaultPath,
operations,
ensureConnected: client.ensureConnected,
currentClient,
addSystemMessage: status.addSystemMessage,
setStatus: status.set,
setComposerText: composer.setText,
openThreadInNewView: (threadId) => workspace.openThreadInNewView(threadId),
openThreadInCurrentPanel: (threadId) => resume.resumeThread(threadId),
notifyActiveThreadIdentityChanged: () => {
thread.notifyIdentityChanged();
},
refreshAfterThreadMutation: async () => {
await thread.fetchActiveThreads();
threadCatalog.refreshFromOpenSurface();
},
};
return createThreadManagementActions(threadManagementHost);
};
return {
history,
createManagementActions,
restoration,
resume,
identity,
rename,
};
}

View file

@ -18,11 +18,16 @@ import { AutoTitleController } from "../application/threads/auto-title-controlle
import { createGoalActions, createThreadGoalSyncActions } from "../application/threads/goal-actions";
import type { HistoryController } from "../application/threads/history-controller";
import type { IdentitySync } from "../application/threads/identity-sync";
import { activeThreadRenameTitleContext, type ThreadRenameEditorController } from "../application/threads/rename-editor-controller";
import {
activeThreadRenameTitleContext,
ThreadRenameEditorController,
type ThreadRenameEditorController as ThreadRenameEditorControllerInstance,
} from "../application/threads/rename-editor-controller";
import type { RestorationController } from "../application/threads/restoration-controller";
import type { ResumeController } from "../application/threads/resume-controller";
import { createThreadParts } from "../application/threads/composition";
import { createSelectionActions } from "../application/threads/selection-actions";
import { createThreadLifecycleParts } from "../application/threads/lifecycle-parts";
import { createThreadManagementActions, type ThreadManagementActionsHost } from "../application/threads/thread-management-actions";
import type { ComposerSubmitActions } from "../application/conversation/composer-submit-actions";
import { createConversationTurnActions } from "../application/conversation/composition";
import { createChatConnectionBundle, type ChatConnectionBundle } from "./connection-bundle";
@ -114,7 +119,7 @@ export interface ChatPanelRuntimeParts {
resume: ResumeController;
restoration: RestorationController;
identity: IdentitySync;
rename: ThreadRenameEditorController;
rename: ThreadRenameEditorControllerInstance;
};
toolbar: {
panels: ToolbarPanelActions;
@ -285,12 +290,19 @@ export function createChatPanelRuntime(context: ChatPanelRuntimeContext): ChatPa
context.refreshLiveState();
},
});
const threadParts = createThreadParts({
const rename = new ThreadRenameEditorController({
stateStore,
ensureConnected,
addSystemMessage: status.addSystemMessage,
operations: threadOperations,
titleService,
});
const threadLifecycle = createThreadLifecycleParts({
settingsRef: environment.plugin.settingsRef,
workspace: environment.plugin.workspace,
threadCatalog: environment.plugin.threadCatalog,
state: {
stateStore,
stateStore,
client: {
currentClient,
ensureConnected,
},
lifecycle: {
deferredTasks: context.deferredTasks,
@ -298,13 +310,7 @@ export function createChatPanelRuntime(context: ChatPanelRuntimeContext): ChatPa
getOpened: () => context.opened(),
getClosing: () => context.closing(),
},
client: {
getClient: currentClient,
ensureConnected,
},
status,
thread: {
fetchActiveThreads,
notifyIdentityChanged: () => {
context.notifyActiveThreadIdentityChanged();
},
@ -312,6 +318,7 @@ export function createChatPanelRuntime(context: ChatPanelRuntimeContext): ChatPa
context.refreshTabHeader();
},
},
status,
liveState: {
refresh: () => {
context.refreshLiveState();
@ -326,11 +333,11 @@ export function createChatPanelRuntime(context: ChatPanelRuntimeContext): ChatPa
},
},
goals,
autoTitle,
operations: threadOperations,
titleService,
resetThreadTurnPresence: (hadTurns) => {
autoTitle.resetThreadTurnPresence(hadTurns);
},
});
const { history, identity, restoration, resume, rename } = threadParts;
const { history, identity, restoration, resume } = threadLifecycle;
const composerSurface: ChatPanelComposerSurface = {
thread: {
restoredPlaceholder: () => restoration.placeholder(),
@ -368,11 +375,27 @@ export function createChatPanelRuntime(context: ChatPanelRuntimeContext): ChatPa
messageStreamScrollBridge.repinMessageStreamToBottomIfPinned();
},
});
const threadActions = threadParts.createManagementActions({
setText: (text) => {
const threadManagementHost: ThreadManagementActionsHost = {
stateStore,
vaultPath: environment.plugin.settingsRef.vaultPath,
operations: threadOperations,
ensureConnected,
currentClient,
addSystemMessage: status.addSystemMessage,
setStatus: status.set,
setComposerText: (text) => {
composerController.setDraft(text, { focus: true });
},
});
openThreadInNewView: (threadId) => environment.plugin.workspace.openThreadInNewView(threadId),
openThreadInCurrentPanel: (threadId) => resume.resumeThread(threadId),
notifyActiveThreadIdentityChanged: () => {
context.notifyActiveThreadIdentityChanged();
},
refreshAfterThreadMutation: async () => {
await fetchActiveThreads();
},
};
const threadActions = createThreadManagementActions(threadManagementHost);
const toolbarPanels = createToolbarPanelActions({
stateStore,
threadActions,