mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 17:30:31 +00:00
Clarify chat module ownership
This commit is contained in:
parent
8c80930124
commit
e6daf9db11
24 changed files with 160 additions and 157 deletions
|
|
@ -90,12 +90,10 @@ const pureChatModelRestrictions = [
|
|||
},
|
||||
];
|
||||
const chatImperativeDomBridgeFiles = [
|
||||
"src/features/chat/chat-message-renderer.ts",
|
||||
"src/features/chat/markdown-message-renderer.ts",
|
||||
"src/features/chat/rendered-markdown-links.ts",
|
||||
"src/features/chat/ui/composer.tsx",
|
||||
"src/features/chat/ui/goal-banner.tsx",
|
||||
"src/features/chat/ui/message-stream.tsx",
|
||||
"src/features/chat/ui/message-stream/markdown-renderer.ts",
|
||||
"src/features/chat/ui/message-stream/rendered-markdown-links.ts",
|
||||
"src/features/chat/ui/message-stream/**/*.tsx",
|
||||
"src/features/chat/ui/scroll.ts",
|
||||
"src/features/chat/ui/shell.tsx",
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
import type { App, EventRef } from "obsidian";
|
||||
|
||||
import { composerBoundaryScrollDirection, type ComposerBoundaryScrollAction } from "./composer/boundary-scroll";
|
||||
import { isComposerSendKey, type SendShortcut } from "../../shared/ui/keyboard";
|
||||
import { textareaCursorAtVisualBoundary } from "../../shared/ui/textarea-caret";
|
||||
import { noteCandidates as appNoteCandidates, resolveWikiLinkMention as resolveAppWikiLinkMention } from "./composer/obsidian-context";
|
||||
import type { UserInput } from "../../../generated/app-server/v2/UserInput";
|
||||
import { isComposerSendKey, type SendShortcut } from "../../../shared/ui/keyboard";
|
||||
import { textareaCursorAtVisualBoundary } from "../../../shared/ui/textarea-caret";
|
||||
import { chatTurnBusy, type ChatAction, type ChatState, type ChatStateStore } from "../chat-state";
|
||||
import type { ComposerMetaViewModel } from "../panel/model";
|
||||
import { renderComposerShell, syncComposerHeight } from "../ui/composer";
|
||||
import { composerBoundaryScrollDirection, type ComposerBoundaryScrollAction } from "./boundary-scroll";
|
||||
import { noteCandidates as appNoteCandidates, resolveWikiLinkMention as resolveAppWikiLinkMention } from "./obsidian-context";
|
||||
import {
|
||||
activeComposerSuggestions,
|
||||
applyComposerSuggestionInsertion,
|
||||
|
|
@ -12,12 +16,8 @@ import {
|
|||
nextComposerSuggestionIndex,
|
||||
type ComposerSuggestion,
|
||||
type NoteCandidate,
|
||||
} from "./composer/suggestions";
|
||||
import { userInputWithWikiLinkMentionsAndSkills } from "./composer/wikilink-context";
|
||||
import type { UserInput } from "../../generated/app-server/v2/UserInput";
|
||||
import { renderComposerShell, syncComposerHeight } from "./ui/composer";
|
||||
import { chatTurnBusy, type ChatAction, type ChatState, type ChatStateStore } from "./chat-state";
|
||||
import type { ComposerMetaViewModel } from "./panel/model";
|
||||
} from "./suggestions";
|
||||
import { userInputWithWikiLinkMentionsAndSkills } from "./wikilink-context";
|
||||
|
||||
export interface ChatComposerControllerOptions {
|
||||
app: App;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import type { ComponentChild as UiNode } from "preact";
|
||||
|
||||
import type { ApprovalAction, PendingApproval } from "../../requests/approvals/model";
|
||||
import type { ChatController } from "../../chat-controller";
|
||||
import type { ChatInboundController } from "../../inbound/controller";
|
||||
import { pendingRequestFocusSignature } from "../../requests/view-model";
|
||||
import { pendingRequestMessageNode } from "../../ui/pending-request-message";
|
||||
import { userInputDraftKey, userInputOtherDraftKey } from "../../requests/user-input/drafts";
|
||||
|
|
@ -10,7 +10,7 @@ import type { PendingRequestStatePort } from "../state-ports";
|
|||
|
||||
export interface PendingRequestControllerHost {
|
||||
state: PendingRequestStatePort;
|
||||
controller: ChatController;
|
||||
controller: ChatInboundController;
|
||||
composerHasFocus: () => boolean;
|
||||
refreshLiveState: () => void;
|
||||
render: () => void;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import type { AppServerClient } from "../../app-server/client";
|
||||
import { requestedServiceTierRequestValue, type RequestedServiceTier } from "../../app-server/service-tier";
|
||||
import type { ReasoningEffort } from "../../generated/app-server/ReasoningEffort";
|
||||
import type { ModeKind } from "../../generated/app-server/ModeKind";
|
||||
import type { ApprovalsReviewer } from "../../generated/app-server/v2/ApprovalsReviewer";
|
||||
import type { ThreadSettingsUpdateParams } from "../../generated/app-server/v2/ThreadSettingsUpdateParams";
|
||||
import { collaborationModeToggleMessage, nextCollaborationMode } from "../../runtime/collaboration-mode";
|
||||
import { readRuntimeConfig } from "../../runtime/config";
|
||||
import type { AppServerClient } from "../../../../app-server/client";
|
||||
import { requestedServiceTierRequestValue, type RequestedServiceTier } from "../../../../app-server/service-tier";
|
||||
import type { ModeKind } from "../../../../generated/app-server/ModeKind";
|
||||
import type { ReasoningEffort } from "../../../../generated/app-server/ReasoningEffort";
|
||||
import type { ApprovalsReviewer } from "../../../../generated/app-server/v2/ApprovalsReviewer";
|
||||
import type { ThreadSettingsUpdateParams } from "../../../../generated/app-server/v2/ThreadSettingsUpdateParams";
|
||||
import { collaborationModeToggleMessage, nextCollaborationMode } from "../../../../runtime/collaboration-mode";
|
||||
import { readRuntimeConfig } from "../../../../runtime/config";
|
||||
import {
|
||||
autoReviewActive,
|
||||
fastModeActive,
|
||||
|
|
@ -13,9 +13,9 @@ import {
|
|||
pendingRuntimeSettingPayload,
|
||||
requestedTurnRuntimeSettings,
|
||||
type RuntimeSnapshot,
|
||||
} from "../../runtime/state";
|
||||
import { modelOverrideMessage, reasoningEffortOverrideMessage } from "../../runtime/settings";
|
||||
import type { ChatAction, ChatState, ChatStateStore } from "./chat-state";
|
||||
} from "../../../../runtime/state";
|
||||
import { modelOverrideMessage, reasoningEffortOverrideMessage } from "../../../../runtime/settings";
|
||||
import type { ChatAction, ChatState, ChatStateStore } from "../../chat-state";
|
||||
|
||||
type ThreadSettingsUpdate = Omit<ThreadSettingsUpdateParams, "threadId">;
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ import type { CodexPanelSettings } from "../../../../settings/model";
|
|||
import { chatTurnBusy, type ChatAction, type ChatState, type ChatStateStore } from "../../chat-state";
|
||||
import { turnsAfterTurnId } from "../../fork";
|
||||
import { rollbackCandidateFromItems } from "../../rollback";
|
||||
import type { ThreadHistoryLoader } from "../../thread-history";
|
||||
import type { ThreadHistoryController } from "./thread-history-controller";
|
||||
|
||||
export interface ChatThreadActionControllerHost {
|
||||
stateStore: ChatStateStore;
|
||||
|
|
@ -17,7 +17,7 @@ export interface ChatThreadActionControllerHost {
|
|||
archiveAdapter: () => ArchiveExportAdapter;
|
||||
ensureConnected: () => Promise<void>;
|
||||
currentClient: () => AppServerClient | null;
|
||||
history: ThreadHistoryLoader;
|
||||
history: ThreadHistoryController;
|
||||
addSystemMessage: (text: string) => void;
|
||||
setStatus: (status: string) => void;
|
||||
setComposerText: (text: string) => void;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import type { AppServerClient } from "../../app-server/client";
|
||||
import type { JsonValue } from "../../generated/app-server/serde_json/JsonValue";
|
||||
import type { ThreadGoal } from "../../generated/app-server/v2/ThreadGoal";
|
||||
import type { ThreadGoalStatus } from "../../generated/app-server/v2/ThreadGoalStatus";
|
||||
import type { ChatStateStore } from "./chat-state";
|
||||
import type { GoalDisplayItem } from "./display/types";
|
||||
import { goalChangeItem } from "./goal-messages";
|
||||
import type { AppServerClient } from "../../../../app-server/client";
|
||||
import type { JsonValue } from "../../../../generated/app-server/serde_json/JsonValue";
|
||||
import type { ThreadGoal } from "../../../../generated/app-server/v2/ThreadGoal";
|
||||
import type { ThreadGoalStatus } from "../../../../generated/app-server/v2/ThreadGoalStatus";
|
||||
import type { ChatStateStore } from "../../chat-state";
|
||||
import type { GoalDisplayItem } from "../../display/types";
|
||||
import { goalChangeItem } from "../../goal-messages";
|
||||
|
||||
export interface ChatGoalControllerHost {
|
||||
export interface ChatThreadGoalControllerHost {
|
||||
stateStore: ChatStateStore;
|
||||
currentClient: () => AppServerClient | null;
|
||||
ensureConnected: () => Promise<void>;
|
||||
|
|
@ -16,8 +16,8 @@ export interface ChatGoalControllerHost {
|
|||
refreshLiveState: () => void;
|
||||
}
|
||||
|
||||
export class ChatGoalController {
|
||||
constructor(private readonly host: ChatGoalControllerHost) {}
|
||||
export class ChatThreadGoalController {
|
||||
constructor(private readonly host: ChatThreadGoalControllerHost) {}
|
||||
|
||||
activeGoal(): ThreadGoal | null {
|
||||
return this.host.stateStore.getState().activeThread.goal;
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
import type { AppServerClient } from "../../app-server/client";
|
||||
import { displayItemsFromTurns } from "./display/thread-items";
|
||||
import type { ChatAction, ChatState, ChatStateStore } from "./chat-state";
|
||||
import type { TurnsPage } from "../../generated/app-server/v2/TurnsPage";
|
||||
import type { AppServerClient } from "../../../../app-server/client";
|
||||
import type { TurnsPage } from "../../../../generated/app-server/v2/TurnsPage";
|
||||
import type { ChatAction, ChatState, ChatStateStore } from "../../chat-state";
|
||||
import { displayItemsFromTurns } from "../../display/thread-items";
|
||||
|
||||
export interface ThreadHistoryLoaderHost {
|
||||
export interface ThreadHistoryControllerHost {
|
||||
stateStore: ChatStateStore;
|
||||
currentClient: () => AppServerClient | null;
|
||||
render: () => void;
|
||||
|
|
@ -20,10 +20,10 @@ type ThreadHistoryLoadLifecycleEvent =
|
|||
| { type: "finished"; load: ActiveThreadHistoryLoad }
|
||||
| { type: "invalidated" };
|
||||
|
||||
export class ThreadHistoryLoader {
|
||||
export class ThreadHistoryController {
|
||||
private lifecycle: ThreadHistoryLoadLifecycleState = { kind: "idle" };
|
||||
|
||||
constructor(private readonly host: ThreadHistoryLoaderHost) {}
|
||||
constructor(private readonly host: ThreadHistoryControllerHost) {}
|
||||
|
||||
private get state(): ChatState {
|
||||
return this.host.stateStore.getState();
|
||||
|
|
@ -3,7 +3,7 @@ import type { ThreadTokenUsage } from "../../../../generated/app-server/v2/Threa
|
|||
import type { DisplayItem } from "../../display/types";
|
||||
import type { RestoredThreadController } from "./restored-thread-controller";
|
||||
import type { ThreadActivationResponse } from "../../thread-resume";
|
||||
import type { ThreadHistoryLoader } from "../../thread-history";
|
||||
import type { ThreadHistoryController } from "./thread-history-controller";
|
||||
import type { ChatResumeWorkTracker, ActiveChatResume } from "../../panel/lifecycle";
|
||||
import type { ThreadLifecycleStatePort } from "../state-ports";
|
||||
|
||||
|
|
@ -11,7 +11,7 @@ export interface ThreadResumeControllerHost {
|
|||
state: ThreadLifecycleStatePort;
|
||||
vaultPath: string;
|
||||
resumeWork: ChatResumeWorkTracker;
|
||||
history: ThreadHistoryLoader;
|
||||
history: ThreadHistoryController;
|
||||
restoredThread: RestoredThreadController;
|
||||
currentClient: () => AppServerClient | null;
|
||||
ensureConnected: () => Promise<void>;
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
import { approvalResponse, type ApprovalAction, type PendingApproval } from "./requests/approvals/model";
|
||||
import { createStructuredSystemItem, createSystemItem } from "./display/system";
|
||||
import type { DisplayDetailSection } from "./display/types";
|
||||
import type { RequestId } from "../../generated/app-server/RequestId";
|
||||
import type { ServerNotification } from "../../generated/app-server/ServerNotification";
|
||||
import type { ServerRequest } from "../../generated/app-server/ServerRequest";
|
||||
import type { Turn } from "../../generated/app-server/v2/Turn";
|
||||
import { activeTurnId, type ChatAction, type ChatState, type ChatStateStore } from "./chat-state";
|
||||
import { userInputResponse, type PendingUserInput } from "./requests/user-input/model";
|
||||
import { classifyAppServerLog } from "./app-server-logs";
|
||||
import { routeServerRequest } from "./inbound/routing";
|
||||
import { createApprovalResultItem, createUserInputResultItem } from "./requests/view-model";
|
||||
import { planChatNotification, type ChatNotificationEffect } from "./inbound/notification-plan";
|
||||
import type { RequestId } from "../../../generated/app-server/RequestId";
|
||||
import type { ServerNotification } from "../../../generated/app-server/ServerNotification";
|
||||
import type { ServerRequest } from "../../../generated/app-server/ServerRequest";
|
||||
import type { Turn } from "../../../generated/app-server/v2/Turn";
|
||||
import { classifyAppServerLog } from "../app-server-logs";
|
||||
import { activeTurnId, type ChatAction, type ChatState, type ChatStateStore } from "../chat-state";
|
||||
import { createStructuredSystemItem, createSystemItem } from "../display/system";
|
||||
import type { DisplayDetailSection } from "../display/types";
|
||||
import { approvalResponse, type ApprovalAction, type PendingApproval } from "../requests/approvals/model";
|
||||
import { userInputResponse, type PendingUserInput } from "../requests/user-input/model";
|
||||
import { createApprovalResultItem, createUserInputResultItem } from "../requests/view-model";
|
||||
import { planChatNotification, type ChatNotificationEffect } from "./notification-plan";
|
||||
import { routeServerRequest } from "./routing";
|
||||
|
||||
export interface ChatControllerActions {
|
||||
export interface ChatInboundControllerActions {
|
||||
refreshThreads: () => void;
|
||||
refreshRateLimits: () => void;
|
||||
refreshSkills: (forceReload?: boolean) => void;
|
||||
|
|
@ -25,10 +25,10 @@ export interface ChatControllerActions {
|
|||
rejectServerRequest: (requestId: RequestId, code: number, message: string) => boolean;
|
||||
}
|
||||
|
||||
export class ChatController {
|
||||
export class ChatInboundController {
|
||||
constructor(
|
||||
private readonly store: ChatStateStore,
|
||||
private readonly actions: ChatControllerActions,
|
||||
private readonly actions: ChatInboundControllerActions,
|
||||
) {}
|
||||
|
||||
private get state(): ChatState {
|
||||
|
|
@ -6,16 +6,15 @@ import { currentModel } from "../../../runtime/state";
|
|||
import { ChatAppServerDiagnosticsController } from "../app-server/diagnostics-controller";
|
||||
import { ChatAppServerMetadataController } from "../app-server/metadata-controller";
|
||||
import { ChatAppServerThreadController } from "../app-server/thread-controller";
|
||||
import { ChatComposerController } from "../chat-composer-controller";
|
||||
import { ChatController } from "../chat-controller";
|
||||
import { ChatMessageRenderer } from "../chat-message-renderer";
|
||||
import { ChatComposerController } from "../composer/controller";
|
||||
import { ChatInboundController } from "../inbound/controller";
|
||||
import type { ChatState } from "../chat-state";
|
||||
import { ChatGoalController } from "../goal-controller";
|
||||
import { ChatRuntimeSettingsController } from "../runtime-settings-controller";
|
||||
import { ChatThreadGoalController } from "../controllers/thread/thread-goal-controller";
|
||||
import { ChatRuntimeSettingsController } from "../controllers/runtime/runtime-settings-controller";
|
||||
import { ChatThreadActionController } from "../controllers/thread/thread-actions-controller";
|
||||
import { ThreadHistoryLoader } from "../thread-history";
|
||||
import { ThreadHistoryController } from "../controllers/thread/thread-history-controller";
|
||||
import { ThreadRenameController } from "../controllers/thread/thread-rename-controller";
|
||||
import { ToolbarPanelController } from "../toolbar-panel-controller";
|
||||
import { ToolbarPanelController } from "./toolbar-controller";
|
||||
import { AppServerWarmupController } from "../controllers/connection/app-server-warmup-controller";
|
||||
import { ChatConnectionController } from "../controllers/connection/connection-controller";
|
||||
import { ChatReconnectController } from "../controllers/connection/reconnect-controller";
|
||||
|
|
@ -40,6 +39,7 @@ import { ThreadSelectionController } from "../controllers/thread/thread-selectio
|
|||
import { ChatViewOpenCloseController } from "../controllers/view/view-open-close-controller";
|
||||
import { ChatViewRenderController } from "../controllers/view/view-render-controller";
|
||||
import { ChatViewStateController } from "../controllers/view/view-state-controller";
|
||||
import { ChatMessageRenderer } from "../ui/message-stream";
|
||||
import type { ChatViewControllerPorts } from "./controller-ports";
|
||||
|
||||
export interface ChatViewControllers {
|
||||
|
|
@ -50,7 +50,7 @@ export interface ChatViewControllers {
|
|||
warmup: AppServerWarmupController;
|
||||
};
|
||||
inbound: {
|
||||
controller: ChatController;
|
||||
controller: ChatInboundController;
|
||||
};
|
||||
appServer: {
|
||||
threads: ChatAppServerThreadController;
|
||||
|
|
@ -58,7 +58,7 @@ export interface ChatViewControllers {
|
|||
diagnostics: ChatAppServerDiagnosticsController;
|
||||
};
|
||||
thread: {
|
||||
history: ThreadHistoryLoader;
|
||||
history: ThreadHistoryController;
|
||||
resume: ThreadResumeController;
|
||||
actions: ChatThreadActionController;
|
||||
restored: RestoredThreadController;
|
||||
|
|
@ -68,7 +68,7 @@ export interface ChatViewControllers {
|
|||
};
|
||||
runtime: {
|
||||
settings: ChatRuntimeSettingsController;
|
||||
goals: ChatGoalController;
|
||||
goals: ChatThreadGoalController;
|
||||
};
|
||||
requests: {
|
||||
pending: PendingRequestController;
|
||||
|
|
@ -94,16 +94,16 @@ type ControllerRef<T> = () => T;
|
|||
export function createChatViewControllers(ports: ChatViewControllerPorts): ChatViewControllers {
|
||||
const context = createControllerContext(ports);
|
||||
let connection!: ConnectionManager;
|
||||
let controller!: ChatController;
|
||||
let controller!: ChatInboundController;
|
||||
let appServerThreads!: ChatAppServerThreadController;
|
||||
let appServerMetadata!: ChatAppServerMetadataController;
|
||||
let appServerDiagnostics!: ChatAppServerDiagnosticsController;
|
||||
let connectionController!: ChatConnectionController;
|
||||
let history!: ThreadHistoryLoader;
|
||||
let history!: ThreadHistoryController;
|
||||
let threadResume!: ThreadResumeController;
|
||||
let threadActions!: ChatThreadActionController;
|
||||
let runtimeSettings!: ChatRuntimeSettingsController;
|
||||
let goals!: ChatGoalController;
|
||||
let goals!: ChatThreadGoalController;
|
||||
let restoredThread!: RestoredThreadController;
|
||||
let threadIdentity!: ThreadIdentityController;
|
||||
let threadRename!: ThreadRenameController;
|
||||
|
|
@ -294,8 +294,8 @@ function createSubmissionControllerGroup(
|
|||
threadActions: ControllerRef<ChatThreadActionController>;
|
||||
threadRename: ControllerRef<ThreadRenameController>;
|
||||
reconnectActions: ControllerRef<ChatReconnectController>;
|
||||
goals: ControllerRef<ChatGoalController>;
|
||||
history: ControllerRef<ThreadHistoryLoader>;
|
||||
goals: ControllerRef<ChatThreadGoalController>;
|
||||
history: ControllerRef<ThreadHistoryController>;
|
||||
pendingRequests: ControllerRef<PendingRequestController>;
|
||||
},
|
||||
) {
|
||||
|
|
@ -474,7 +474,7 @@ function createSubmissionControllerGroup(
|
|||
function createConnectionLifecycleControllerGroup(
|
||||
context: ControllerContext,
|
||||
refs: {
|
||||
controller: ControllerRef<ChatController>;
|
||||
controller: ControllerRef<ChatInboundController>;
|
||||
connectionController: ControllerRef<ChatConnectionController>;
|
||||
composerController: ControllerRef<ChatComposerController>;
|
||||
messageRenderer: ControllerRef<ChatMessageRenderer>;
|
||||
|
|
@ -557,7 +557,7 @@ function createAppServerControllerGroup(
|
|||
context: ControllerContext,
|
||||
refs: {
|
||||
connection: ControllerRef<ConnectionManager>;
|
||||
goals: ControllerRef<ChatGoalController>;
|
||||
goals: ControllerRef<ChatThreadGoalController>;
|
||||
},
|
||||
) {
|
||||
const { plugin, runtime, effects, stateStore } = context;
|
||||
|
|
@ -605,7 +605,7 @@ function createInboundController(
|
|||
) {
|
||||
const { plugin, thread, effects, stateStore } = context;
|
||||
|
||||
return new ChatController(stateStore, {
|
||||
return new ChatInboundController(stateStore, {
|
||||
refreshThreads: () => {
|
||||
void thread.refreshThreads();
|
||||
},
|
||||
|
|
@ -675,7 +675,7 @@ function createRequestThreadToolbarControllerGroup(
|
|||
context: ControllerContext,
|
||||
refs: {
|
||||
connection: ControllerRef<ConnectionManager>;
|
||||
controller: ControllerRef<ChatController>;
|
||||
controller: ControllerRef<ChatInboundController>;
|
||||
composerController: ControllerRef<ChatComposerController>;
|
||||
},
|
||||
) {
|
||||
|
|
@ -690,7 +690,7 @@ function createRequestThreadToolbarControllerGroup(
|
|||
refreshLiveState: effects.liveState.refresh,
|
||||
render: effects.render.now,
|
||||
});
|
||||
const history = new ThreadHistoryLoader({
|
||||
const history = new ThreadHistoryController({
|
||||
stateStore,
|
||||
currentClient,
|
||||
render: effects.render.now,
|
||||
|
|
@ -761,7 +761,7 @@ function createRequestThreadToolbarControllerGroup(
|
|||
collaborationModeLabel: runtime.collaborationModeLabel,
|
||||
addSystemMessage: effects.status.addSystemMessage,
|
||||
});
|
||||
const goals = new ChatGoalController({
|
||||
const goals = new ChatThreadGoalController({
|
||||
stateStore,
|
||||
currentClient,
|
||||
ensureConnected: effects.client.ensureConnected,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { ChatAction, ChatState, ChatStateStore } from "./chat-state";
|
||||
import type { ChatThreadActionController } from "./controllers/thread/thread-actions-controller";
|
||||
import type { ChatViewRenderScheduleOptions } from "./panel/lifecycle";
|
||||
import type { ChatAction, ChatState, ChatStateStore } from "../chat-state";
|
||||
import type { ChatThreadActionController } from "../controllers/thread/thread-actions-controller";
|
||||
import type { ChatViewRenderScheduleOptions } from "./lifecycle";
|
||||
|
||||
export interface ToolbarPanelControllerHost {
|
||||
stateStore: ChatStateStore;
|
||||
|
|
@ -1,10 +1,6 @@
|
|||
export {
|
||||
createMessageStreamContext,
|
||||
type ChatMessageStreamActionPort,
|
||||
type ChatMessageStreamContextPort,
|
||||
type ChatMessageStreamRequestPort,
|
||||
} from "./context-builder";
|
||||
export { createMessageStreamContextPort } from "./context-port";
|
||||
export { messageStreamBlocks } from "./blocks";
|
||||
export { renderMessageStreamBlocks } from "./render";
|
||||
export { ChatMessageRenderer } from "./renderer";
|
||||
export { bindRenderedWikiLinks, type RenderedMarkdownLinkContext } from "./rendered-markdown-links";
|
||||
export type { MessageStreamBlock } from "./context";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { MarkdownRenderer, type App, type Component } from "obsidian";
|
||||
|
||||
import { notifyMessageContentRendered } from "../message-content-events";
|
||||
import { bindRenderedMarkdownFileLinks, bindRenderedWikiLinks } from "./rendered-markdown-links";
|
||||
import { notifyMessageContentRendered } from "./ui/message-content-events";
|
||||
|
||||
export interface MarkdownMessageRendererOptions {
|
||||
app: App;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { Notice, type App } from "obsidian";
|
||||
|
||||
import { isAbsoluteFileHref, vaultFileLinkTarget, vaultRelativeFileLinkTarget } from "./markdown-file-links";
|
||||
import { isAbsoluteFileHref, vaultFileLinkTarget, vaultRelativeFileLinkTarget } from "../../markdown-file-links";
|
||||
|
||||
export interface RenderedMarkdownLinkContext {
|
||||
app: App;
|
||||
|
|
@ -1,20 +1,20 @@
|
|||
import type { App, Component } from "obsidian";
|
||||
|
||||
import { copyTextWithNotice } from "../../shared/ui/clipboard";
|
||||
import { copyTextWithNotice } from "../../../../shared/ui/clipboard";
|
||||
import { unmountUiRoot } from "../../../../shared/ui/ui-root";
|
||||
import type { ChatAction, ChatState, ChatStateStore } from "../../chat-state";
|
||||
import type { ComposerBoundaryScrollAction } from "../../composer/boundary-scroll";
|
||||
import { MessageScrollController, type MessageScrollIntent } from "../scroll";
|
||||
import { messageStreamBlocks } from "./blocks";
|
||||
import {
|
||||
createMessageStreamContext,
|
||||
createMessageStreamContextPort,
|
||||
messageStreamBlocks,
|
||||
renderMessageStreamBlocks,
|
||||
type ChatMessageStreamActionPort,
|
||||
type ChatMessageStreamContextPort,
|
||||
type ChatMessageStreamRequestPort,
|
||||
} from "./ui/message-stream";
|
||||
import type { ComposerBoundaryScrollAction } from "./composer/boundary-scroll";
|
||||
import { MessageScrollController, type MessageScrollIntent } from "./ui/scroll";
|
||||
import { MarkdownMessageRenderer } from "./markdown-message-renderer";
|
||||
import { type ChatAction, type ChatState, type ChatStateStore } from "./chat-state";
|
||||
import { unmountUiRoot } from "../../shared/ui/ui-root";
|
||||
} from "./context-builder";
|
||||
import { createMessageStreamContextPort } from "./context-port";
|
||||
import { MarkdownMessageRenderer } from "./markdown-renderer";
|
||||
import { renderMessageStreamBlocks } from "./render";
|
||||
|
||||
interface ChatMessageRendererObsidianPort {
|
||||
app: App;
|
||||
|
|
@ -3,10 +3,10 @@
|
|||
import type { App } from "obsidian";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { ChatComposerController } from "../../../src/features/chat/chat-composer-controller";
|
||||
import { createChatStateStore } from "../../../src/features/chat/chat-state";
|
||||
import type { SkillMetadata } from "../../../src/generated/app-server/v2/SkillMetadata";
|
||||
import { installObsidianDomShims } from "../../support/dom";
|
||||
import { ChatComposerController } from "../../../../src/features/chat/composer/controller";
|
||||
import { createChatStateStore } from "../../../../src/features/chat/chat-state";
|
||||
import type { SkillMetadata } from "../../../../src/generated/app-server/v2/SkillMetadata";
|
||||
import { installObsidianDomShims } from "../../../support/dom";
|
||||
|
||||
installObsidianDomShims();
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { ChatController } from "../../../../../src/features/chat/chat-controller";
|
||||
import { ChatInboundController } from "../../../../../src/features/chat/inbound/controller";
|
||||
import { createChatState, createChatStateStore } from "../../../../../src/features/chat/chat-state";
|
||||
import { createPendingRequestStatePort } from "../../../../../src/features/chat/controllers/state-ports";
|
||||
import { PendingRequestController } from "../../../../../src/features/chat/controllers/requests/pending-request-controller";
|
||||
|
|
@ -18,7 +18,7 @@ describe("PendingRequestController", () => {
|
|||
const respondToServerRequest = vi.fn().mockReturnValue(true);
|
||||
const refreshLiveState = vi.fn();
|
||||
const render = vi.fn();
|
||||
const controller = new ChatController(stateStore, {
|
||||
const controller = new ChatInboundController(stateStore, {
|
||||
refreshThreads: vi.fn(),
|
||||
refreshRateLimits: vi.fn(),
|
||||
refreshSkills: vi.fn(),
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { ChatRuntimeSettingsController } from "../../../src/features/chat/runtime-settings-controller";
|
||||
import { createChatState, createChatStateStore, type ActiveThreadSettingsAppliedAction } from "../../../src/features/chat/chat-state";
|
||||
import type { AppServerClient } from "../../../src/app-server/client";
|
||||
import type { Model } from "../../../src/generated/app-server/v2/Model";
|
||||
import { ChatRuntimeSettingsController } from "../../../../../src/features/chat/controllers/runtime/runtime-settings-controller";
|
||||
import { createChatState, createChatStateStore, type ActiveThreadSettingsAppliedAction } from "../../../../../src/features/chat/chat-state";
|
||||
import type { AppServerClient } from "../../../../../src/app-server/client";
|
||||
import type { Model } from "../../../../../src/generated/app-server/v2/Model";
|
||||
|
||||
describe("ChatRuntimeSettingsController", () => {
|
||||
it("applies pending runtime overrides through thread settings and commits them", async () => {
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import type { AppServerClient } from "../../../src/app-server/client";
|
||||
import { ChatGoalController } from "../../../src/features/chat/goal-controller";
|
||||
import { createChatState, createChatStateStore } from "../../../src/features/chat/chat-state";
|
||||
import type { ThreadGoal } from "../../../src/generated/app-server/v2/ThreadGoal";
|
||||
import type { AppServerClient } from "../../../../../src/app-server/client";
|
||||
import { ChatThreadGoalController } from "../../../../../src/features/chat/controllers/thread/thread-goal-controller";
|
||||
import { createChatState, createChatStateStore } from "../../../../../src/features/chat/chat-state";
|
||||
import type { ThreadGoal } from "../../../../../src/generated/app-server/v2/ThreadGoal";
|
||||
|
||||
describe("ChatGoalController", () => {
|
||||
describe("ChatThreadGoalController", () => {
|
||||
it("syncs the active thread goal into chat state", async () => {
|
||||
const state = createChatState();
|
||||
state.activeThread.id = "thread";
|
||||
|
|
@ -14,7 +14,7 @@ describe("ChatGoalController", () => {
|
|||
const client = { getThreadGoal: vi.fn().mockResolvedValue({ goal: currentGoal }) } as unknown as AppServerClient;
|
||||
const render = vi.fn();
|
||||
const refreshLiveState = vi.fn();
|
||||
const controller = new ChatGoalController({
|
||||
const controller = new ChatThreadGoalController({
|
||||
stateStore,
|
||||
currentClient: () => client,
|
||||
ensureConnected: vi.fn().mockResolvedValue(undefined),
|
||||
|
|
@ -37,7 +37,7 @@ describe("ChatGoalController", () => {
|
|||
const stateStore = createChatStateStore(state);
|
||||
const addSystemMessage = vi.fn();
|
||||
const client = { getThreadGoal: vi.fn().mockRejectedValue(new Error("offline")) } as unknown as AppServerClient;
|
||||
const controller = new ChatGoalController({
|
||||
const controller = new ChatThreadGoalController({
|
||||
stateStore,
|
||||
currentClient: () => client,
|
||||
ensureConnected: vi.fn().mockResolvedValue(undefined),
|
||||
|
|
@ -69,7 +69,7 @@ describe("ChatGoalController", () => {
|
|||
} as unknown as AppServerClient;
|
||||
const addSystemMessage = vi.fn();
|
||||
const addGoalEvent = vi.fn();
|
||||
const controller = new ChatGoalController({
|
||||
const controller = new ChatThreadGoalController({
|
||||
stateStore,
|
||||
currentClient: () => client,
|
||||
ensureConnected: vi.fn().mockResolvedValue(undefined),
|
||||
|
|
@ -102,7 +102,7 @@ describe("ChatGoalController", () => {
|
|||
const client = { setThreadGoal, injectThreadItems } as unknown as AppServerClient;
|
||||
const addSystemMessage = vi.fn();
|
||||
const addGoalEvent = vi.fn();
|
||||
const controller = new ChatGoalController({
|
||||
const controller = new ChatThreadGoalController({
|
||||
stateStore,
|
||||
currentClient: () => client,
|
||||
ensureConnected: vi.fn().mockResolvedValue(undefined),
|
||||
|
|
@ -142,7 +142,7 @@ describe("ChatGoalController", () => {
|
|||
const injectThreadItems = vi.fn().mockResolvedValue({});
|
||||
const client = { setThreadGoal, injectThreadItems } as unknown as AppServerClient;
|
||||
const addGoalEvent = vi.fn();
|
||||
const controller = new ChatGoalController({
|
||||
const controller = new ChatThreadGoalController({
|
||||
stateStore,
|
||||
currentClient: () => client,
|
||||
ensureConnected: vi.fn().mockResolvedValue(undefined),
|
||||
|
|
@ -167,7 +167,7 @@ describe("ChatGoalController", () => {
|
|||
const client = { setThreadGoal } as unknown as AppServerClient;
|
||||
const addSystemMessage = vi.fn();
|
||||
const addGoalEvent = vi.fn();
|
||||
const controller = new ChatGoalController({
|
||||
const controller = new ChatThreadGoalController({
|
||||
stateStore,
|
||||
currentClient: () => client,
|
||||
ensureConnected: vi.fn().mockResolvedValue(undefined),
|
||||
|
|
@ -190,7 +190,7 @@ describe("ChatGoalController", () => {
|
|||
const currentGoal = goal();
|
||||
const client = { getThreadGoal: vi.fn().mockResolvedValue({ goal: currentGoal }) } as unknown as AppServerClient;
|
||||
const addSystemMessage = vi.fn();
|
||||
const controller = new ChatGoalController({
|
||||
const controller = new ChatThreadGoalController({
|
||||
stateStore,
|
||||
currentClient: () => client,
|
||||
ensureConnected: vi.fn().mockResolvedValue(undefined),
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { createChatState, createChatStateStore } from "../../../src/features/chat/chat-state";
|
||||
import { ThreadHistoryLoader } from "../../../src/features/chat/thread-history";
|
||||
import type { AppServerClient } from "../../../src/app-server/client";
|
||||
import type { ThreadItem } from "../../../src/generated/app-server/v2/ThreadItem";
|
||||
import type { Turn } from "../../../src/generated/app-server/v2/Turn";
|
||||
import { deferred } from "../../support/async";
|
||||
import { createChatState, createChatStateStore } from "../../../../../src/features/chat/chat-state";
|
||||
import { ThreadHistoryController } from "../../../../../src/features/chat/controllers/thread/thread-history-controller";
|
||||
import type { AppServerClient } from "../../../../../src/app-server/client";
|
||||
import type { ThreadItem } from "../../../../../src/generated/app-server/v2/ThreadItem";
|
||||
import type { Turn } from "../../../../../src/generated/app-server/v2/Turn";
|
||||
import { deferred } from "../../../../support/async";
|
||||
|
||||
describe("ThreadHistoryLoader", () => {
|
||||
describe("ThreadHistoryController", () => {
|
||||
it("keeps the latest history load when an older request resolves later", async () => {
|
||||
const first = deferred<ThreadTurnsListResponse>();
|
||||
const second = deferred<ThreadTurnsListResponse>();
|
||||
|
|
@ -98,7 +98,7 @@ function historyFixture(options: { threadTurnsList: ReturnType<typeof vi.fn> })
|
|||
const stateStore = createChatStateStore(state);
|
||||
const dispatch = vi.spyOn(stateStore, "dispatch");
|
||||
const addSystemMessage = vi.fn();
|
||||
const loader = new ThreadHistoryLoader({
|
||||
const loader = new ThreadHistoryController({
|
||||
stateStore,
|
||||
currentClient: () =>
|
||||
({
|
||||
|
|
@ -6,7 +6,7 @@ import type { RestoredThreadController } from "../../../../../src/features/chat/
|
|||
import { createThreadLifecycleStatePort } from "../../../../../src/features/chat/controllers/state-ports";
|
||||
import type { ThreadActivationResponse } from "../../../../../src/features/chat/thread-resume";
|
||||
import { ThreadResumeController } from "../../../../../src/features/chat/controllers/thread/thread-resume-controller";
|
||||
import type { ThreadHistoryLoader } from "../../../../../src/features/chat/thread-history";
|
||||
import type { ThreadHistoryController } from "../../../../../src/features/chat/controllers/thread/thread-history-controller";
|
||||
import { ChatResumeWorkTracker } from "../../../../../src/features/chat/panel/lifecycle";
|
||||
import type { ThreadItem } from "../../../../../src/generated/app-server/v2/ThreadItem";
|
||||
import type { Thread } from "../../../../../src/generated/app-server/v2/Thread";
|
||||
|
|
@ -65,7 +65,7 @@ function createController(
|
|||
state: createThreadLifecycleStatePort(stateStore),
|
||||
vaultPath: "/vault",
|
||||
resumeWork: new ChatResumeWorkTracker(() => undefined),
|
||||
history: { loadLatest, applyLatestPage } as unknown as ThreadHistoryLoader,
|
||||
history: { loadLatest, applyLatestPage } as unknown as ThreadHistoryController,
|
||||
restoredThread: { clear: restoredClear } as unknown as RestoredThreadController,
|
||||
currentClient: () => client,
|
||||
ensureConnected: vi.fn().mockResolvedValue(undefined),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { ChatController } from "../../../src/features/chat/chat-controller";
|
||||
import { attachHookRunsToTurn } from "../../../src/features/chat/hook-display";
|
||||
import { ChatInboundController } from "../../../../src/features/chat/inbound/controller";
|
||||
import { attachHookRunsToTurn } from "../../../../src/features/chat/hook-display";
|
||||
import {
|
||||
activeTurnId,
|
||||
chatReducer,
|
||||
|
|
@ -11,17 +11,17 @@ import {
|
|||
type ChatAction,
|
||||
type ChatState,
|
||||
type ChatStateStore,
|
||||
} from "../../../src/features/chat/chat-state";
|
||||
import type { ServerNotification } from "../../../src/generated/app-server/ServerNotification";
|
||||
import type { ServerRequest } from "../../../src/generated/app-server/ServerRequest";
|
||||
import type { Thread } from "../../../src/generated/app-server/v2/Thread";
|
||||
import type { Turn } from "../../../src/generated/app-server/v2/Turn";
|
||||
} from "../../../../src/features/chat/chat-state";
|
||||
import type { ServerNotification } from "../../../../src/generated/app-server/ServerNotification";
|
||||
import type { ServerRequest } from "../../../../src/generated/app-server/ServerRequest";
|
||||
import type { Thread } from "../../../../src/generated/app-server/v2/Thread";
|
||||
import type { Turn } from "../../../../src/generated/app-server/v2/Turn";
|
||||
|
||||
function controllerForState(
|
||||
state = createChatState(),
|
||||
actions: Partial<ConstructorParameters<typeof ChatController>[1]> = {},
|
||||
): ChatController {
|
||||
return new ChatController(testStoreForState(state), {
|
||||
actions: Partial<ConstructorParameters<typeof ChatInboundController>[1]> = {},
|
||||
): ChatInboundController {
|
||||
return new ChatInboundController(testStoreForState(state), {
|
||||
refreshThreads: vi.fn(),
|
||||
refreshRateLimits: vi.fn(),
|
||||
refreshSkills: vi.fn(),
|
||||
|
|
@ -54,7 +54,7 @@ function expectPresent<T>(value: T | null | undefined): T {
|
|||
return value;
|
||||
}
|
||||
|
||||
describe("ChatController", () => {
|
||||
describe("ChatInboundController", () => {
|
||||
describe("active turn routing", () => {
|
||||
it("applies matching streaming deltas as assistant markdown", () => {
|
||||
const state = createChatState();
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { createChatState, createChatStateStore } from "../../../src/features/chat/chat-state";
|
||||
import { ToolbarPanelController } from "../../../src/features/chat/toolbar-panel-controller";
|
||||
import type { ChatThreadActionController } from "../../../src/features/chat/controllers/thread/thread-actions-controller";
|
||||
import { createChatState, createChatStateStore } from "../../../../src/features/chat/chat-state";
|
||||
import { ToolbarPanelController } from "../../../../src/features/chat/panel/toolbar-controller";
|
||||
import type { ChatThreadActionController } from "../../../../src/features/chat/controllers/thread/thread-actions-controller";
|
||||
|
||||
describe("ToolbarPanelController", () => {
|
||||
it("tracks archive confirmation and delegates archive actions", async () => {
|
||||
|
|
@ -3,11 +3,20 @@
|
|||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { TFile } from "obsidian";
|
||||
|
||||
import { ChatMessageRenderer } from "../../../src/features/chat/chat-message-renderer";
|
||||
import { chatReducer, createChatState, type ChatAction, type ChatState, type ChatStateStore } from "../../../src/features/chat/chat-state";
|
||||
import { bindRenderedWikiLinks, type RenderedMarkdownLinkContext } from "../../../src/features/chat/rendered-markdown-links";
|
||||
import { installObsidianDomShims } from "../../support/dom";
|
||||
import { notices } from "../../mocks/obsidian";
|
||||
import {
|
||||
chatReducer,
|
||||
createChatState,
|
||||
type ChatAction,
|
||||
type ChatState,
|
||||
type ChatStateStore,
|
||||
} from "../../../../../src/features/chat/chat-state";
|
||||
import {
|
||||
ChatMessageRenderer,
|
||||
bindRenderedWikiLinks,
|
||||
type RenderedMarkdownLinkContext,
|
||||
} from "../../../../../src/features/chat/ui/message-stream";
|
||||
import { notices } from "../../../../mocks/obsidian";
|
||||
import { installObsidianDomShims } from "../../../../support/dom";
|
||||
|
||||
installObsidianDomShims();
|
||||
|
||||
Loading…
Reference in a new issue