mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 06:57:10 +00:00
156 lines
5.8 KiB
TypeScript
156 lines
5.8 KiB
TypeScript
import type { AppServerClient } from "../../../../app-server/connection/client";
|
|
import type { CodexInput } from "../../../../domain/chat/input";
|
|
import type { LocalIdSource } from "../../../../shared/id/local-id";
|
|
import type { MessageStreamNoticeSection } from "../../domain/message-stream/items";
|
|
import type { ChatRuntimeSettingsActions } from "../runtime/settings-actions";
|
|
import type { ChatStateStore } from "../state/store";
|
|
import type { GoalActions } from "../threads/goal-actions";
|
|
import type { ThreadManagementActions } from "../threads/thread-management-actions";
|
|
import { type ComposerSubmitActions, type ComposerSubmitActionsHost, submitComposer } from "./composer-submit-actions";
|
|
import { implementPlan, type PlanImplementationHost } from "./plan-implementation";
|
|
import { executeSlashCommandWithState, type SlashCommandExecutorHost } from "./slash-command-executor";
|
|
import { createTurnSubmissionActions } from "./turn-submission-actions";
|
|
|
|
export interface ConversationTurnActionsContext {
|
|
vaultPath: string;
|
|
stateStore: ChatStateStore;
|
|
localItemIds: LocalIdSource;
|
|
client: {
|
|
currentClient: () => AppServerClient | null;
|
|
connectedClient: () => Promise<AppServerClient | null>;
|
|
};
|
|
status: {
|
|
set: (status: string) => void;
|
|
addSystemMessage: (text: string) => void;
|
|
addStructuredSystemMessage: (text: string, details: MessageStreamNoticeSection[]) => void;
|
|
};
|
|
runtime: {
|
|
connectionDiagnosticDetails: () => MessageStreamNoticeSection[];
|
|
modelStatusLines: () => string[];
|
|
effortStatusLines: () => string[];
|
|
statusSummaryLines: () => string[];
|
|
toolInventoryDetails: () => MessageStreamNoticeSection[];
|
|
};
|
|
thread: {
|
|
ensureRestoredThreadLoaded: () => Promise<boolean>;
|
|
startNewThread: () => Promise<void>;
|
|
selectThread: (threadId: string) => Promise<void>;
|
|
notifyIdentityChanged: () => void;
|
|
resetTurnPresence: (hadTurns: boolean) => void;
|
|
};
|
|
composer: {
|
|
codexInput: (text: string) => CodexInput;
|
|
trimmedDraft: () => string;
|
|
setDraft: (text: string, options?: { focus?: boolean; clearSuggestions?: boolean }) => void;
|
|
};
|
|
scroll: {
|
|
showLatest: () => void;
|
|
};
|
|
}
|
|
|
|
export interface ConversationTurnActionsRefs {
|
|
threadStarter: ConversationThreadStarter;
|
|
runtimeSettings: ChatRuntimeSettingsActions;
|
|
threadActions: ThreadManagementActions;
|
|
reconnectPanel: () => Promise<void>;
|
|
goals: GoalActions;
|
|
}
|
|
|
|
interface ConversationThreadStarter {
|
|
startThread: (preview?: string, options?: { syncGoal?: boolean }) => Promise<{ threadId: string } | null>;
|
|
}
|
|
|
|
interface PlanImplementation {
|
|
implement: (itemId: string) => Promise<void>;
|
|
}
|
|
|
|
export interface ConversationTurnActions {
|
|
planImplementation: PlanImplementation;
|
|
composerSubmit: ComposerSubmitActions;
|
|
}
|
|
|
|
export function createConversationTurnActions(
|
|
context: ConversationTurnActionsContext,
|
|
refs: ConversationTurnActionsRefs,
|
|
): ConversationTurnActions {
|
|
const { vaultPath, stateStore, localItemIds, client, status, runtime, thread, composer, scroll } = context;
|
|
const turnSubmission = createTurnSubmissionActions({
|
|
stateStore,
|
|
vaultPath,
|
|
localItemIds,
|
|
connectedClient: client.connectedClient,
|
|
ensureRestoredThreadLoaded: thread.ensureRestoredThreadLoaded,
|
|
startThread: (preview) => refs.threadStarter.startThread(preview),
|
|
notifyActiveThreadIdentityChanged: thread.notifyIdentityChanged,
|
|
resetThreadTurnPresence: thread.resetTurnPresence,
|
|
applyPendingThreadSettings: () => refs.runtimeSettings.applyPendingThreadSettings(),
|
|
codexInput: composer.codexInput,
|
|
setDraft: composer.setDraft,
|
|
setStatus: status.set,
|
|
addSystemMessage: status.addSystemMessage,
|
|
});
|
|
const slashCommandExecutorHost: SlashCommandExecutorHost = {
|
|
stateStore,
|
|
currentClient: client.currentClient,
|
|
codexInput: composer.codexInput,
|
|
startNewThread: thread.startNewThread,
|
|
startThreadForGoal: (objective) => startThreadForGoal(refs.threadStarter, objective),
|
|
resumeThread: thread.selectThread,
|
|
threadActions: refs.threadActions,
|
|
reconnect: refs.reconnectPanel,
|
|
runtimeSettings: refs.runtimeSettings,
|
|
goals: refs.goals,
|
|
addSystemMessage: status.addSystemMessage,
|
|
addStructuredSystemMessage: status.addStructuredSystemMessage,
|
|
setStatus: status.set,
|
|
statusSummaryLines: runtime.statusSummaryLines,
|
|
connectionDiagnosticDetails: runtime.connectionDiagnosticDetails,
|
|
toolInventoryDetails: runtime.toolInventoryDetails,
|
|
modelStatusLines: runtime.modelStatusLines,
|
|
effortStatusLines: runtime.effortStatusLines,
|
|
};
|
|
const planImplementationHost: PlanImplementationHost = {
|
|
stateStore,
|
|
connectedClient: client.connectedClient,
|
|
sendTurnText: (text) => turnSubmission.sendTurnText(text),
|
|
requestDefaultCollaborationModeForNextTurn: () => {
|
|
refs.runtimeSettings.requestDefaultCollaborationModeForNextTurn();
|
|
},
|
|
};
|
|
const composerSubmitHost: ComposerSubmitActionsHost = {
|
|
stateStore,
|
|
composer: {
|
|
get trimmedDraft() {
|
|
return composer.trimmedDraft();
|
|
},
|
|
setDraft: composer.setDraft,
|
|
},
|
|
slashCommandExecutor: {
|
|
execute: (command, args) => executeSlashCommandWithState(slashCommandExecutorHost, command, args),
|
|
},
|
|
turnSubmission,
|
|
connection: {
|
|
connectedClient: client.connectedClient,
|
|
currentClient: client.currentClient,
|
|
},
|
|
status: {
|
|
setStatus: status.set,
|
|
addSystemMessage: status.addSystemMessage,
|
|
},
|
|
scroll,
|
|
};
|
|
|
|
return {
|
|
planImplementation: {
|
|
implement: (itemId) => implementPlan(planImplementationHost, itemId),
|
|
},
|
|
composerSubmit: {
|
|
submit: () => submitComposer(composerSubmitHost),
|
|
},
|
|
};
|
|
}
|
|
|
|
async function startThreadForGoal(starter: ConversationThreadStarter, objective: string): Promise<string | null> {
|
|
const response = await starter.startThread(objective, { syncGoal: false });
|
|
return response?.threadId ?? null;
|
|
}
|