From 31e30b637a75a32d5ad7f704af3f35bbc6fcfe19 Mon Sep 17 00:00:00 2001 From: murashit Date: Fri, 12 Jun 2026 15:28:21 +0900 Subject: [PATCH] Group app-server connection, protocol, and turn projections --- src/app-server/{ => connection}/client.ts | 94 +++--- .../{ => connection}/connection-manager.ts | 6 +- .../{types.ts => connection/rpc-messages.ts} | 10 +- .../{ => connection}/short-lived-client.ts | 0 src/app-server/{ => connection}/transport.ts | 2 +- src/app-server/{ => protocol}/catalog.ts | 4 +- src/app-server/{ => protocol}/diagnostics.ts | 0 .../{ => protocol}/initialization.ts | 2 +- .../{ => protocol}/request-input.ts | 2 +- .../{ => protocol}/runtime-config.ts | 2 +- .../{ => protocol}/runtime-metrics.ts | 25 +- .../{ => protocol}/runtime-policy.ts | 0 src/app-server/{ => protocol}/thread-goal.ts | 6 +- .../{ => protocol}/thread-settings.ts | 12 +- src/app-server/{ => protocol}/thread.ts | 2 +- src/app-server/{ => protocol}/turn-history.ts | 0 src/app-server/{ => protocol}/turn.ts | 31 +- .../ephemeral-structured-turn.ts | 20 +- .../{ => services}/resource-operations.ts | 10 +- .../{ => services}/rollout-token-usage.ts | 2 +- .../{ => services}/shared-cache-state.ts | 10 +- src/app-server/{ => services}/shared-cache.ts | 4 +- .../{ => services}/thread-activation.ts | 6 +- src/features/chat/chat-host.ts | 2 +- src/features/chat/composition-actions.ts | 2 +- src/features/chat/composition-ports.ts | 4 +- src/features/chat/composition.ts | 2 +- src/features/chat/connection/composition.ts | 4 +- .../chat/connection/connection-controller.ts | 6 +- .../connection/server-actions/diagnostics.ts | 9 +- .../chat/connection/server-actions/host.ts | 4 +- .../connection/server-actions/metadata.ts | 23 +- .../chat/connection/server-actions/threads.ts | 2 +- .../chat/conversation/composer/controller.ts | 2 +- .../conversation/composer/wikilink-context.ts | 2 +- src/features/chat/conversation/composition.ts | 2 +- .../conversation/pending-requests/state.ts | 2 +- .../turns/composer-submit-actions.ts | 4 +- .../turns/optimistic-turn-start.ts | 2 +- .../conversation/turns/plan-implementation.ts | 2 +- .../turns/slash-command-execution.ts | 4 +- .../turns/slash-command-handler.ts | 8 +- .../turns/turn-submission-controller.ts | 4 +- src/features/chat/display/items/goal.ts | 2 +- .../chat/display/items/user-message.ts | 2 +- .../chat/display/status/diagnostics.ts | 4 +- src/features/chat/display/status/runtime.ts | 4 +- src/features/chat/display/turn-items.ts | 297 +++++++++++++----- .../chat/panel/cached-app-server-state.ts | 2 +- src/features/chat/panel/composition.ts | 2 +- .../chat/protocol/inbound/controller.ts | 4 +- .../protocol/inbound/notification-plan.ts | 8 +- src/features/chat/protocol/inbound/routing.ts | 2 +- .../chat/protocol/server-requests/approval.ts | 2 +- .../protocol/server-requests/responder.ts | 2 +- .../protocol/server-requests/user-input.ts | 4 +- src/features/chat/runtime/effective.ts | 4 +- src/features/chat/runtime/settings-actions.ts | 8 +- src/features/chat/runtime/snapshot.ts | 6 +- src/features/chat/runtime/state.ts | 4 +- .../chat/runtime/thread-settings-update.ts | 6 +- src/features/chat/state/actions.ts | 4 +- src/features/chat/state/reducer.ts | 18 +- src/features/chat/threads/action-context.ts | 2 +- src/features/chat/threads/archive-actions.ts | 6 +- .../chat/threads/auto-title-controller.ts | 2 +- src/features/chat/threads/composition.ts | 6 +- src/features/chat/threads/goal-actions.ts | 4 +- .../chat/threads/history-controller.ts | 4 +- src/features/chat/threads/rename-actions.ts | 2 +- .../chat/threads/rename-controller.ts | 9 +- .../chat/threads/resume-controller.ts | 4 +- src/features/chat/threads/resume.ts | 4 +- src/features/chat/threads/rollback-actions.ts | 2 +- src/features/chat/ui/goal-banner.tsx | 2 +- src/features/chat/view.ts | 4 +- src/features/selection-rewrite/runner.ts | 6 +- src/features/thread-picker/modal.ts | 4 +- src/features/thread-title/generation.ts | 8 +- src/features/threads-view/view.ts | 17 +- src/main.ts | 4 +- src/settings/app-server-data.ts | 4 +- src/settings/tab.ts | 6 +- src/workspace/thread-surface-coordinator.ts | 2 +- tests/app-server/app-server-client.test.ts | 8 +- .../app-server/app-server-diagnostics.test.ts | 4 +- tests/app-server/catalog.test.ts | 2 +- tests/app-server/connection-manager.test.ts | 8 +- .../ephemeral-structured-turn.test.ts | 6 +- tests/app-server/request-input.test.ts | 2 +- tests/app-server/resource-operations.test.ts | 4 +- tests/app-server/rollout-token-usage.test.ts | 2 +- tests/app-server/runtime-metrics.test.ts | 66 ++++ tests/app-server/shared-cache-state.test.ts | 8 +- tests/app-server/shared-cache.test.ts | 8 +- tests/app-server/thread-activation.test.ts | 2 +- tests/app-server/thread-goal.test.ts | 2 +- tests/app-server/thread-settings.test.ts | 4 +- tests/app-server/turn.test.ts | 31 +- .../connection/connection-controller.test.ts | 4 +- .../server-actions/server-actions.test.ts | 12 +- .../pending-requests/controller.test.ts | 2 +- .../turns/composer-submit-actions.test.ts | 2 +- .../turns/plan-implementation.test.ts | 2 +- .../turns/slash-command-execution.test.ts | 2 +- .../turns/slash-command-handler.test.ts | 4 +- .../turns/turn-submission-controller.test.ts | 4 +- tests/features/chat/diagnostics.test.ts | 2 +- .../chat/display/display-model.test.ts | 2 +- .../features/chat/display/items/goal.test.ts | 2 +- tests/features/chat/mcp-status.test.ts | 2 +- .../panel/cached-app-server-state.test.ts | 6 +- .../chat/protocol/inbound/controller.test.ts | 4 +- .../chat/protocol/inbound/routing.test.ts | 2 +- .../protocol/server-requests/approval.test.ts | 2 +- .../server-requests/responder.test.ts | 2 +- .../server-requests/user-input.test.ts | 2 +- .../chat/runtime/settings-actions.test.ts | 4 +- tests/features/chat/state-reducer.test.ts | 2 +- tests/features/chat/threads/actions.test.ts | 4 +- .../threads/auto-title-controller.test.ts | 2 +- .../chat/threads/goal-actions.test.ts | 4 +- .../chat/threads/history-controller.test.ts | 4 +- .../chat/threads/rename-controller.test.ts | 4 +- .../chat/threads/resume-controller.test.ts | 6 +- tests/features/chat/threads/resume.test.ts | 2 +- .../chat/ui/renderers/goal-banner.test.tsx | 2 +- tests/features/chat/view-connection.test.ts | 10 +- tests/features/chat/view-model.test.ts | 6 +- .../selection-rewrite.test.ts | 8 +- .../thread-title/thread-title.test.ts | 10 +- tests/features/threads-view/view.test.ts | 4 +- tests/main.test.ts | 4 +- tests/runtime/runtime-settings.test.ts | 2 +- tests/settings/settings-lifecycle.test.ts | 2 +- tests/settings/settings-tab.test.ts | 8 +- 136 files changed, 704 insertions(+), 426 deletions(-) rename src/app-server/{ => connection}/client.ts (81%) rename src/app-server/{ => connection}/connection-manager.ts (95%) rename src/app-server/{types.ts => connection/rpc-messages.ts} (65%) rename src/app-server/{ => connection}/short-lived-client.ts (100%) rename src/app-server/{ => connection}/transport.ts (98%) rename src/app-server/{ => protocol}/catalog.ts (97%) rename src/app-server/{ => protocol}/diagnostics.ts (100%) rename src/app-server/{ => protocol}/initialization.ts (89%) rename src/app-server/{ => protocol}/request-input.ts (95%) rename src/app-server/{ => protocol}/runtime-config.ts (99%) rename src/app-server/{ => protocol}/runtime-metrics.ts (69%) rename src/app-server/{ => protocol}/runtime-policy.ts (100%) rename src/app-server/{ => protocol}/thread-goal.ts (89%) rename src/app-server/{ => protocol}/thread-settings.ts (69%) rename src/app-server/{ => protocol}/thread.ts (94%) rename src/app-server/{ => protocol}/turn-history.ts (100%) rename src/app-server/{ => protocol}/turn.ts (70%) rename src/app-server/{ => services}/ephemeral-structured-turn.ts (93%) rename src/app-server/{ => services}/resource-operations.ts (92%) rename src/app-server/{ => services}/rollout-token-usage.ts (97%) rename src/app-server/{ => services}/shared-cache-state.ts (95%) rename src/app-server/{ => services}/shared-cache.ts (96%) rename src/app-server/{ => services}/thread-activation.ts (85%) create mode 100644 tests/app-server/runtime-metrics.test.ts diff --git a/src/app-server/client.ts b/src/app-server/connection/client.ts similarity index 81% rename from src/app-server/client.ts rename to src/app-server/connection/client.ts index cb877c69..1f384ded 100644 --- a/src/app-server/client.ts +++ b/src/app-server/connection/client.ts @@ -1,51 +1,51 @@ -import type { InitializeResponse } from "../generated/app-server/InitializeResponse"; -import type { CollaborationMode } from "../generated/app-server/CollaborationMode"; -import type { RequestId } from "../generated/app-server/RequestId"; -import type { ReasoningEffort } from "../generated/app-server/ReasoningEffort"; -import type { ApprovalsReviewer } from "../generated/app-server/v2/ApprovalsReviewer"; -import type { ConfigReadResponse } from "../generated/app-server/v2/ConfigReadResponse"; -import type { ConfigWriteResponse } from "../generated/app-server/v2/ConfigWriteResponse"; -import type { FsReadFileResponse } from "../generated/app-server/v2/FsReadFileResponse"; -import type { GetAccountRateLimitsResponse } from "../generated/app-server/v2/GetAccountRateLimitsResponse"; -import type { HookTrustStatus } from "../generated/app-server/v2/HookTrustStatus"; -import type { HooksListResponse } from "../generated/app-server/v2/HooksListResponse"; -import type { CollaborationModeListResponse } from "../generated/app-server/v2/CollaborationModeListResponse"; -import type { ListMcpServerStatusParams } from "../generated/app-server/v2/ListMcpServerStatusParams"; -import type { ListMcpServerStatusResponse } from "../generated/app-server/v2/ListMcpServerStatusResponse"; -import type { ModelListResponse } from "../generated/app-server/v2/ModelListResponse"; -import type { ModelProviderCapabilitiesReadResponse } from "../generated/app-server/v2/ModelProviderCapabilitiesReadResponse"; -import type { SkillsListResponse } from "../generated/app-server/v2/SkillsListResponse"; -import type { ThreadArchiveResponse } from "../generated/app-server/v2/ThreadArchiveResponse"; -import type { ThreadForkResponse } from "../generated/app-server/v2/ThreadForkResponse"; -import type { ThreadGoalClearResponse } from "../generated/app-server/v2/ThreadGoalClearResponse"; -import type { ThreadGoalGetResponse } from "../generated/app-server/v2/ThreadGoalGetResponse"; -import type { ThreadGoalSetResponse } from "../generated/app-server/v2/ThreadGoalSetResponse"; -import type { ThreadInjectItemsResponse } from "../generated/app-server/v2/ThreadInjectItemsResponse"; -import type { ThreadListResponse } from "../generated/app-server/v2/ThreadListResponse"; -import type { ThreadReadResponse } from "../generated/app-server/v2/ThreadReadResponse"; -import type { ThreadResumeResponse } from "../generated/app-server/v2/ThreadResumeResponse"; -import type { ThreadRollbackResponse } from "../generated/app-server/v2/ThreadRollbackResponse"; -import type { ThreadSetNameResponse } from "../generated/app-server/v2/ThreadSetNameResponse"; -import type { ThreadSettingsUpdateResponse } from "../generated/app-server/v2/ThreadSettingsUpdateResponse"; -import type { ThreadCompactStartResponse } from "../generated/app-server/v2/ThreadCompactStartResponse"; -import type { SortDirection } from "../generated/app-server/v2/SortDirection"; -import type { ThreadStartResponse } from "../generated/app-server/v2/ThreadStartResponse"; -import type { ThreadTurnsListResponse } from "../generated/app-server/v2/ThreadTurnsListResponse"; -import type { ThreadUnarchiveResponse } from "../generated/app-server/v2/ThreadUnarchiveResponse"; -import type { TurnItemsView } from "../generated/app-server/v2/TurnItemsView"; -import type { TurnInterruptResponse } from "../generated/app-server/v2/TurnInterruptResponse"; -import type { TurnStartResponse } from "../generated/app-server/v2/TurnStartResponse"; -import type { TurnSteerResponse } from "../generated/app-server/v2/TurnSteerResponse"; -import type { UserInput } from "../generated/app-server/v2/UserInput"; -import { CLIENT_VERSION } from "../constants"; +import type { InitializeResponse } from "../../generated/app-server/InitializeResponse"; +import type { CollaborationMode } from "../../generated/app-server/CollaborationMode"; +import type { RequestId } from "../../generated/app-server/RequestId"; +import type { ReasoningEffort } from "../../generated/app-server/ReasoningEffort"; +import type { ApprovalsReviewer } from "../../generated/app-server/v2/ApprovalsReviewer"; +import type { ConfigReadResponse } from "../../generated/app-server/v2/ConfigReadResponse"; +import type { ConfigWriteResponse } from "../../generated/app-server/v2/ConfigWriteResponse"; +import type { FsReadFileResponse } from "../../generated/app-server/v2/FsReadFileResponse"; +import type { GetAccountRateLimitsResponse } from "../../generated/app-server/v2/GetAccountRateLimitsResponse"; +import type { HookTrustStatus } from "../../generated/app-server/v2/HookTrustStatus"; +import type { HooksListResponse } from "../../generated/app-server/v2/HooksListResponse"; +import type { CollaborationModeListResponse } from "../../generated/app-server/v2/CollaborationModeListResponse"; +import type { ListMcpServerStatusParams } from "../../generated/app-server/v2/ListMcpServerStatusParams"; +import type { ListMcpServerStatusResponse } from "../../generated/app-server/v2/ListMcpServerStatusResponse"; +import type { ModelListResponse } from "../../generated/app-server/v2/ModelListResponse"; +import type { ModelProviderCapabilitiesReadResponse } from "../../generated/app-server/v2/ModelProviderCapabilitiesReadResponse"; +import type { SkillsListResponse } from "../../generated/app-server/v2/SkillsListResponse"; +import type { ThreadArchiveResponse } from "../../generated/app-server/v2/ThreadArchiveResponse"; +import type { ThreadForkResponse } from "../../generated/app-server/v2/ThreadForkResponse"; +import type { ThreadGoalClearResponse } from "../../generated/app-server/v2/ThreadGoalClearResponse"; +import type { ThreadGoalGetResponse } from "../../generated/app-server/v2/ThreadGoalGetResponse"; +import type { ThreadGoalSetResponse } from "../../generated/app-server/v2/ThreadGoalSetResponse"; +import type { ThreadInjectItemsResponse } from "../../generated/app-server/v2/ThreadInjectItemsResponse"; +import type { ThreadListResponse } from "../../generated/app-server/v2/ThreadListResponse"; +import type { ThreadReadResponse } from "../../generated/app-server/v2/ThreadReadResponse"; +import type { ThreadResumeResponse } from "../../generated/app-server/v2/ThreadResumeResponse"; +import type { ThreadRollbackResponse } from "../../generated/app-server/v2/ThreadRollbackResponse"; +import type { ThreadSetNameResponse } from "../../generated/app-server/v2/ThreadSetNameResponse"; +import type { ThreadSettingsUpdateResponse } from "../../generated/app-server/v2/ThreadSettingsUpdateResponse"; +import type { ThreadCompactStartResponse } from "../../generated/app-server/v2/ThreadCompactStartResponse"; +import type { SortDirection } from "../../generated/app-server/v2/SortDirection"; +import type { ThreadStartResponse } from "../../generated/app-server/v2/ThreadStartResponse"; +import type { ThreadTurnsListResponse } from "../../generated/app-server/v2/ThreadTurnsListResponse"; +import type { ThreadUnarchiveResponse } from "../../generated/app-server/v2/ThreadUnarchiveResponse"; +import type { TurnItemsView } from "../../generated/app-server/v2/TurnItemsView"; +import type { TurnInterruptResponse } from "../../generated/app-server/v2/TurnInterruptResponse"; +import type { TurnStartResponse } from "../../generated/app-server/v2/TurnStartResponse"; +import type { TurnSteerResponse } from "../../generated/app-server/v2/TurnSteerResponse"; +import type { UserInput } from "../../generated/app-server/v2/UserInput"; +import { CLIENT_VERSION } from "../../constants"; import { StdioAppServerTransport, type AppServerTransport, type AppServerTransportHandlers } from "./transport"; -import type { ClientRequestMethod, ClientRequestParams, PendingRequest, RpcError, RpcInboundMessage, RpcOutboundMessage } from "./types"; -import type { ServerNotification } from "../generated/app-server/ServerNotification"; -import type { ServerRequest } from "../generated/app-server/ServerRequest"; -import type { JsonValue } from "../generated/app-server/serde_json/JsonValue"; -import { toAppServerUserInput, type CodexInput } from "./request-input"; -import { appServerThreadGoalUpdate, type ThreadGoalUpdate } from "./thread-goal"; -import type { ServiceTierRequest, ThreadSettingsUpdate } from "./thread-settings"; +import type { ClientRequestMethod, ClientRequestParams, PendingRequest, RpcError, RpcInboundMessage, RpcOutboundMessage } from "./rpc-messages"; +import type { ServerNotification } from "../../generated/app-server/ServerNotification"; +import type { ServerRequest } from "../../generated/app-server/ServerRequest"; +import type { JsonValue } from "../../generated/app-server/serde_json/JsonValue"; +import { toAppServerUserInput, type CodexInput } from "../protocol/request-input"; +import { appServerThreadGoalUpdate, type ThreadGoalUpdate } from "../protocol/thread-goal"; +import type { ServiceTierRequest, ThreadSettingsUpdate } from "../protocol/thread-settings"; const DEFAULT_REQUEST_TIMEOUT_MS = 120_000; const MAX_SUPPRESSED_ORPHAN_RESPONSES = 256; diff --git a/src/app-server/connection-manager.ts b/src/app-server/connection/connection-manager.ts similarity index 95% rename from src/app-server/connection-manager.ts rename to src/app-server/connection/connection-manager.ts index 68b369ab..b2621fa3 100644 --- a/src/app-server/connection-manager.ts +++ b/src/app-server/connection/connection-manager.ts @@ -1,7 +1,7 @@ -import type { ServerNotification } from "../generated/app-server/ServerNotification"; -import type { ServerRequest } from "../generated/app-server/ServerRequest"; +import type { ServerNotification } from "../../generated/app-server/ServerNotification"; +import type { ServerRequest } from "../../generated/app-server/ServerRequest"; import { AppServerClient, type AppServerClientHandlers } from "./client"; -import { appServerInitializationFromResponse, type AppServerInitialization } from "./initialization"; +import { appServerInitializationFromResponse, type AppServerInitialization } from "../protocol/initialization"; export interface ConnectionManagerHandlers { onNotification: (notification: ServerNotification) => void; diff --git a/src/app-server/types.ts b/src/app-server/connection/rpc-messages.ts similarity index 65% rename from src/app-server/types.ts rename to src/app-server/connection/rpc-messages.ts index 029ee472..1e80d7a1 100644 --- a/src/app-server/types.ts +++ b/src/app-server/connection/rpc-messages.ts @@ -1,8 +1,8 @@ -import type { ClientNotification } from "../generated/app-server/ClientNotification"; -import type { ClientRequest } from "../generated/app-server/ClientRequest"; -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 { ClientNotification } from "../../generated/app-server/ClientNotification"; +import type { ClientRequest } from "../../generated/app-server/ClientRequest"; +import type { RequestId } from "../../generated/app-server/RequestId"; +import type { ServerNotification } from "../../generated/app-server/ServerNotification"; +import type { ServerRequest } from "../../generated/app-server/ServerRequest"; export type { RequestId, ServerNotification, ServerRequest }; diff --git a/src/app-server/short-lived-client.ts b/src/app-server/connection/short-lived-client.ts similarity index 100% rename from src/app-server/short-lived-client.ts rename to src/app-server/connection/short-lived-client.ts diff --git a/src/app-server/transport.ts b/src/app-server/connection/transport.ts similarity index 98% rename from src/app-server/transport.ts rename to src/app-server/connection/transport.ts index 9e265236..fb22fec7 100644 --- a/src/app-server/transport.ts +++ b/src/app-server/connection/transport.ts @@ -1,7 +1,7 @@ import { spawn, type ChildProcessWithoutNullStreams } from "child_process"; import * as readline from "readline"; -import type { RpcOutboundMessage } from "./types"; +import type { RpcOutboundMessage } from "./rpc-messages"; export interface AppServerTransport { start(): void; diff --git a/src/app-server/catalog.ts b/src/app-server/protocol/catalog.ts similarity index 97% rename from src/app-server/catalog.ts rename to src/app-server/protocol/catalog.ts index 7ab7539e..a8f8b042 100644 --- a/src/app-server/catalog.ts +++ b/src/app-server/protocol/catalog.ts @@ -1,5 +1,5 @@ -import type { AppServerHookOperation } from "./client"; -import type { HookItem, ModelMetadata, SkillMetadata } from "../domain/catalog/metadata"; +import type { AppServerHookOperation } from "../connection/client"; +import type { HookItem, ModelMetadata, SkillMetadata } from "../../domain/catalog/metadata"; export interface CatalogModel { id: string; diff --git a/src/app-server/diagnostics.ts b/src/app-server/protocol/diagnostics.ts similarity index 100% rename from src/app-server/diagnostics.ts rename to src/app-server/protocol/diagnostics.ts diff --git a/src/app-server/initialization.ts b/src/app-server/protocol/initialization.ts similarity index 89% rename from src/app-server/initialization.ts rename to src/app-server/protocol/initialization.ts index a64c167d..acb21822 100644 --- a/src/app-server/initialization.ts +++ b/src/app-server/protocol/initialization.ts @@ -1,4 +1,4 @@ -import type { InitializeResponse as AppServerInitializeResponse } from "../generated/app-server/InitializeResponse"; +import type { InitializeResponse as AppServerInitializeResponse } from "../../generated/app-server/InitializeResponse"; export interface AppServerInitialization { userAgent: string; diff --git a/src/app-server/request-input.ts b/src/app-server/protocol/request-input.ts similarity index 95% rename from src/app-server/request-input.ts rename to src/app-server/protocol/request-input.ts index d7a4f9de..a90b46fa 100644 --- a/src/app-server/request-input.ts +++ b/src/app-server/protocol/request-input.ts @@ -1,4 +1,4 @@ -import type { UserInput } from "../generated/app-server/v2/UserInput"; +import type { UserInput } from "../../generated/app-server/v2/UserInput"; export interface RequestMention { name: string; diff --git a/src/app-server/runtime-config.ts b/src/app-server/protocol/runtime-config.ts similarity index 99% rename from src/app-server/runtime-config.ts rename to src/app-server/protocol/runtime-config.ts index 4c52635a..558aa552 100644 --- a/src/app-server/runtime-config.ts +++ b/src/app-server/protocol/runtime-config.ts @@ -7,7 +7,7 @@ import { type ApprovalsReviewer, type ServiceTier, } from "./runtime-policy"; -import { normalizeReasoningEffort, type ReasoningEffort } from "../domain/catalog/metadata"; +import { normalizeReasoningEffort, type ReasoningEffort } from "../../domain/catalog/metadata"; type ReasoningSummary = "auto" | "concise" | "detailed" | "none"; type Verbosity = "low" | "medium" | "high"; diff --git a/src/app-server/runtime-metrics.ts b/src/app-server/protocol/runtime-metrics.ts similarity index 69% rename from src/app-server/runtime-metrics.ts rename to src/app-server/protocol/runtime-metrics.ts index 5bab2184..ae320a00 100644 --- a/src/app-server/runtime-metrics.ts +++ b/src/app-server/protocol/runtime-metrics.ts @@ -1,8 +1,9 @@ -import type { RateLimitSnapshot as AppServerRateLimitSnapshot } from "../generated/app-server/v2/RateLimitSnapshot"; -import type { RateLimitWindow as AppServerRateLimitWindow } from "../generated/app-server/v2/RateLimitWindow"; -import type { SpendControlLimitSnapshot as AppServerSpendControlLimitSnapshot } from "../generated/app-server/v2/SpendControlLimitSnapshot"; -import type { ThreadTokenUsage as AppServerThreadTokenUsage } from "../generated/app-server/v2/ThreadTokenUsage"; -import type { TokenUsageBreakdown as AppServerTokenUsageBreakdown } from "../generated/app-server/v2/TokenUsageBreakdown"; +import type { GetAccountRateLimitsResponse as AppServerAccountRateLimitsResponse } from "../../generated/app-server/v2/GetAccountRateLimitsResponse"; +import type { RateLimitSnapshot as AppServerRateLimitSnapshot } from "../../generated/app-server/v2/RateLimitSnapshot"; +import type { RateLimitWindow as AppServerRateLimitWindow } from "../../generated/app-server/v2/RateLimitWindow"; +import type { SpendControlLimitSnapshot as AppServerSpendControlLimitSnapshot } from "../../generated/app-server/v2/SpendControlLimitSnapshot"; +import type { ThreadTokenUsage as AppServerThreadTokenUsage } from "../../generated/app-server/v2/ThreadTokenUsage"; +import type { TokenUsageBreakdown as AppServerTokenUsageBreakdown } from "../../generated/app-server/v2/TokenUsageBreakdown"; export interface RateLimitSnapshot { limitId: string | null; @@ -51,6 +52,14 @@ export function rateLimitSnapshotFromAppServerSnapshot(snapshot: AppServerRateLi }; } +export function rateLimitSnapshotFromAccountRateLimitsResponse(response: AppServerAccountRateLimitsResponse): RateLimitSnapshot { + return rateLimitSnapshotFromAppServerSnapshot(accountRateLimitSnapshotFromResponse(response)); +} + +export function accountRateLimitsSummaryFromResponse(response: AppServerAccountRateLimitsResponse): string { + return response.rateLimitsByLimitId ? `${String(Object.keys(response.rateLimitsByLimitId).length)} limits` : "available"; +} + export function threadTokenUsageFromAppServerUsage(usage: AppServerThreadTokenUsage): ThreadTokenUsage { return { total: tokenUsageBreakdownFromAppServerBreakdown(usage.total), @@ -59,6 +68,12 @@ export function threadTokenUsageFromAppServerUsage(usage: AppServerThreadTokenUs }; } +function accountRateLimitSnapshotFromResponse(response: AppServerAccountRateLimitsResponse): AppServerRateLimitSnapshot { + const snapshots = response.rateLimitsByLimitId; + const codexRateLimit = snapshots && Object.hasOwn(snapshots, "codex") ? snapshots["codex"] : undefined; + return codexRateLimit ?? response.rateLimits; +} + function rateLimitWindowFromAppServerWindow(window: AppServerRateLimitWindow): RateLimitWindow { return { usedPercent: window.usedPercent, diff --git a/src/app-server/runtime-policy.ts b/src/app-server/protocol/runtime-policy.ts similarity index 100% rename from src/app-server/runtime-policy.ts rename to src/app-server/protocol/runtime-policy.ts diff --git a/src/app-server/thread-goal.ts b/src/app-server/protocol/thread-goal.ts similarity index 89% rename from src/app-server/thread-goal.ts rename to src/app-server/protocol/thread-goal.ts index 73c562fa..e935a4da 100644 --- a/src/app-server/thread-goal.ts +++ b/src/app-server/protocol/thread-goal.ts @@ -1,6 +1,6 @@ -import type { ThreadGoal as AppServerThreadGoal } from "../generated/app-server/v2/ThreadGoal"; -import type { ThreadGoalStatus as AppServerThreadGoalStatus } from "../generated/app-server/v2/ThreadGoalStatus"; -import type { JsonValue } from "../generated/app-server/serde_json/JsonValue"; +import type { ThreadGoal as AppServerThreadGoal } from "../../generated/app-server/v2/ThreadGoal"; +import type { ThreadGoalStatus as AppServerThreadGoalStatus } from "../../generated/app-server/v2/ThreadGoalStatus"; +import type { JsonValue } from "../../generated/app-server/serde_json/JsonValue"; export type ThreadGoalStatus = "active" | "paused" | "blocked" | "usageLimited" | "budgetLimited" | "complete"; diff --git a/src/app-server/thread-settings.ts b/src/app-server/protocol/thread-settings.ts similarity index 69% rename from src/app-server/thread-settings.ts rename to src/app-server/protocol/thread-settings.ts index e02f3314..237e6f8c 100644 --- a/src/app-server/thread-settings.ts +++ b/src/app-server/protocol/thread-settings.ts @@ -1,9 +1,9 @@ -import type { CollaborationMode } from "../generated/app-server/CollaborationMode"; -import type { ModeKind } from "../generated/app-server/ModeKind"; -import type { Personality } from "../generated/app-server/Personality"; -import type { ReasoningEffort } from "../generated/app-server/ReasoningEffort"; -import type { ReasoningSummary } from "../generated/app-server/ReasoningSummary"; -import type { SandboxPolicy } from "../generated/app-server/v2/SandboxPolicy"; +import type { CollaborationMode } from "../../generated/app-server/CollaborationMode"; +import type { ModeKind } from "../../generated/app-server/ModeKind"; +import type { Personality } from "../../generated/app-server/Personality"; +import type { ReasoningEffort } from "../../generated/app-server/ReasoningEffort"; +import type { ReasoningSummary } from "../../generated/app-server/ReasoningSummary"; +import type { SandboxPolicy } from "../../generated/app-server/v2/SandboxPolicy"; import type { ApprovalPolicy, ApprovalsReviewer } from "./runtime-policy"; export type ServiceTierRequest = string | null | undefined; diff --git a/src/app-server/thread.ts b/src/app-server/protocol/thread.ts similarity index 94% rename from src/app-server/thread.ts rename to src/app-server/protocol/thread.ts index cfdcdcd0..87229a01 100644 --- a/src/app-server/thread.ts +++ b/src/app-server/protocol/thread.ts @@ -1,4 +1,4 @@ -import type { Thread } from "../domain/threads/model"; +import type { Thread } from "../../domain/threads/model"; export interface ThreadRecord { id: string; diff --git a/src/app-server/turn-history.ts b/src/app-server/protocol/turn-history.ts similarity index 100% rename from src/app-server/turn-history.ts rename to src/app-server/protocol/turn-history.ts diff --git a/src/app-server/turn.ts b/src/app-server/protocol/turn.ts similarity index 70% rename from src/app-server/turn.ts rename to src/app-server/protocol/turn.ts index 98d3d1ee..a59e5e21 100644 --- a/src/app-server/turn.ts +++ b/src/app-server/protocol/turn.ts @@ -1,13 +1,13 @@ -import type { FileUpdateChange as GeneratedFileUpdateChange } from "../generated/app-server/v2/FileUpdateChange"; -import type { ThreadItem as GeneratedTurnItem } from "../generated/app-server/v2/ThreadItem"; -import type { Turn as GeneratedTurnRecord } from "../generated/app-server/v2/Turn"; -import type { UserInput } from "../generated/app-server/v2/UserInput"; +import type { FileUpdateChange as GeneratedFileUpdateChange } from "../../generated/app-server/v2/FileUpdateChange"; +import type { ThreadItem as GeneratedTurnItem } from "../../generated/app-server/v2/ThreadItem"; +import type { Turn as GeneratedTurnRecord } from "../../generated/app-server/v2/Turn"; +import type { UserInput } from "../../generated/app-server/v2/UserInput"; import { conversationSummaryFromTranscriptEntries, nonEmptyConversationSummaries, type ThreadConversationSummary, type ThreadTranscriptEntry, -} from "../domain/threads/transcript"; +} from "../../domain/threads/transcript"; export type FileUpdateChange = GeneratedFileUpdateChange; export type TurnItem = GeneratedTurnItem; @@ -17,18 +17,37 @@ export function transcriptEntriesFromTurnRecord(turn: TurnRecord): ThreadTranscr return turn.items.flatMap((item) => transcriptEntriesFromTurnItem(item, turn)); } +export function transcriptEntriesFromTurnRecords(turns: readonly TurnRecord[]): ThreadTranscriptEntry[] { + return turns.flatMap(transcriptEntriesFromTurnRecord); +} + export function conversationSummaryFromTurnRecord(turn: TurnRecord): ThreadConversationSummary { return conversationSummaryFromTranscriptEntries(transcriptEntriesFromTurnRecord(turn)); } +export function conversationAssistantTextFromTurnRecord(turn: TurnRecord): string | null { + return conversationSummaryFromTurnRecord(turn).assistantText; +} + export function completedConversationSummaryFromTurnRecord(turn: TurnRecord): ThreadConversationSummary | null { if (turn.status !== "completed") return null; const summary = conversationSummaryFromTurnRecord(turn); return summary.userText && summary.assistantText ? summary : null; } +export function completedConversationSummariesFromTurnRecords(turns: readonly TurnRecord[]): ThreadConversationSummary[] { + return turns.flatMap((turn) => { + const summary = completedConversationSummaryFromTurnRecord(turn); + return summary ? [summary] : []; + }); +} + +export function conversationSummariesFromTurnRecords(turns: readonly TurnRecord[]): ThreadConversationSummary[] { + return nonEmptyConversationSummaries(turns.map(conversationSummaryFromTurnRecord)); +} + export function chronologicalConversationSummariesFromTurnRecords(turns: readonly TurnRecord[]): ThreadConversationSummary[] { - return nonEmptyConversationSummaries(chronologicalTurnRecords(turns).map(conversationSummaryFromTurnRecord)); + return conversationSummariesFromTurnRecords(chronologicalTurnRecords(turns)); } export function turnUserItemText(item: Extract): string { diff --git a/src/app-server/ephemeral-structured-turn.ts b/src/app-server/services/ephemeral-structured-turn.ts similarity index 93% rename from src/app-server/ephemeral-structured-turn.ts rename to src/app-server/services/ephemeral-structured-turn.ts index 35cc224d..6c6e6009 100644 --- a/src/app-server/ephemeral-structured-turn.ts +++ b/src/app-server/services/ephemeral-structured-turn.ts @@ -3,16 +3,16 @@ import { type AppServerClientHandlers, type AppServerStartEphemeralThreadOptions, type AppServerStartStructuredTurnOptions, -} from "./client"; -import { abortablePromise, throwIfAbortSignalAborted } from "../shared/lifecycle/abortable"; -import type { InitializeResponse } from "../generated/app-server/InitializeResponse"; -import type { RequestId } from "../generated/app-server/RequestId"; -import type { ServerNotification } from "../generated/app-server/ServerNotification"; -import type { JsonValue } from "../generated/app-server/serde_json/JsonValue"; -import type { ModelListResponse } from "../generated/app-server/v2/ModelListResponse"; -import type { ThreadStartResponse } from "../generated/app-server/v2/ThreadStartResponse"; -import type { TurnStartResponse } from "../generated/app-server/v2/TurnStartResponse"; -import type { TurnItem, TurnRecord } from "./turn"; +} from "../connection/client"; +import { abortablePromise, throwIfAbortSignalAborted } from "../../shared/lifecycle/abortable"; +import type { InitializeResponse } from "../../generated/app-server/InitializeResponse"; +import type { RequestId } from "../../generated/app-server/RequestId"; +import type { ServerNotification } from "../../generated/app-server/ServerNotification"; +import type { JsonValue } from "../../generated/app-server/serde_json/JsonValue"; +import type { ModelListResponse } from "../../generated/app-server/v2/ModelListResponse"; +import type { ThreadStartResponse } from "../../generated/app-server/v2/ThreadStartResponse"; +import type { TurnStartResponse } from "../../generated/app-server/v2/TurnStartResponse"; +import type { TurnItem, TurnRecord } from "../protocol/turn"; export type StructuredTurnOutputSchema = JsonValue; diff --git a/src/app-server/resource-operations.ts b/src/app-server/services/resource-operations.ts similarity index 92% rename from src/app-server/resource-operations.ts rename to src/app-server/services/resource-operations.ts index 63ff3760..754ec4b4 100644 --- a/src/app-server/resource-operations.ts +++ b/src/app-server/services/resource-operations.ts @@ -1,13 +1,13 @@ -import type { AppServerClient } from "./client"; +import type { AppServerClient } from "../connection/client"; import { appServerHookOperationFromHookItem, hookItemsFromCatalogHooks, modelMetadataFromCatalogModels, skillMetadataFromCatalogSkills, -} from "./catalog"; -import { threadFromThreadRecord, threadsFromThreadRecords } from "./thread"; -import type { HookItem, ModelMetadata, SkillMetadata } from "../domain/catalog/metadata"; -import type { Thread } from "../domain/threads/model"; +} from "../protocol/catalog"; +import { threadFromThreadRecord, threadsFromThreadRecords } from "../protocol/thread"; +import type { HookItem, ModelMetadata, SkillMetadata } from "../../domain/catalog/metadata"; +import type { Thread } from "../../domain/threads/model"; export interface HookData { hooks: HookItem[]; diff --git a/src/app-server/rollout-token-usage.ts b/src/app-server/services/rollout-token-usage.ts similarity index 97% rename from src/app-server/rollout-token-usage.ts rename to src/app-server/services/rollout-token-usage.ts index 90f4aaf0..49a8695b 100644 --- a/src/app-server/rollout-token-usage.ts +++ b/src/app-server/services/rollout-token-usage.ts @@ -1,4 +1,4 @@ -import type { ThreadTokenUsage, TokenUsageBreakdown } from "./runtime-metrics"; +import type { ThreadTokenUsage, TokenUsageBreakdown } from "../protocol/runtime-metrics"; export const ROLLOUT_TOKEN_USAGE_READ_TIMEOUT_MS = 2_000; export const ROLLOUT_TOKEN_USAGE_MAX_BASE64_BYTES = 12 * 1024 * 1024; diff --git a/src/app-server/shared-cache-state.ts b/src/app-server/services/shared-cache-state.ts similarity index 95% rename from src/app-server/shared-cache-state.ts rename to src/app-server/services/shared-cache-state.ts index fc12993e..109754cb 100644 --- a/src/app-server/shared-cache-state.ts +++ b/src/app-server/services/shared-cache-state.ts @@ -1,8 +1,8 @@ -import type { Diagnostics } from "./diagnostics"; -import type { RateLimitSnapshot } from "./runtime-metrics"; -import { cloneRuntimeConfigSnapshot, type RuntimeConfigSnapshot } from "./runtime-config"; -import type { Thread } from "../domain/threads/model"; -import type { ModelMetadata, SkillMetadata } from "../domain/catalog/metadata"; +import type { Diagnostics } from "../protocol/diagnostics"; +import type { RateLimitSnapshot } from "../protocol/runtime-metrics"; +import { cloneRuntimeConfigSnapshot, type RuntimeConfigSnapshot } from "../protocol/runtime-config"; +import type { Thread } from "../../domain/threads/model"; +import type { ModelMetadata, SkillMetadata } from "../../domain/catalog/metadata"; export interface SharedAppServerMetadata { runtimeConfig: RuntimeConfigSnapshot | null; diff --git a/src/app-server/shared-cache.ts b/src/app-server/services/shared-cache.ts similarity index 96% rename from src/app-server/shared-cache.ts rename to src/app-server/services/shared-cache.ts index d42a1f7b..31c1eae9 100644 --- a/src/app-server/shared-cache.ts +++ b/src/app-server/services/shared-cache.ts @@ -1,5 +1,5 @@ -import type { Thread } from "../domain/threads/model"; -import type { ModelMetadata } from "../domain/catalog/metadata"; +import type { Thread } from "../../domain/threads/model"; +import type { ModelMetadata } from "../../domain/catalog/metadata"; import { applySharedAppServerMetadata, applySharedModels, diff --git a/src/app-server/thread-activation.ts b/src/app-server/services/thread-activation.ts similarity index 85% rename from src/app-server/thread-activation.ts rename to src/app-server/services/thread-activation.ts index 3c92a544..b6e0d001 100644 --- a/src/app-server/thread-activation.ts +++ b/src/app-server/services/thread-activation.ts @@ -1,6 +1,6 @@ -import type { Thread } from "../domain/threads/model"; -import type { ActivePermissionProfile, ApprovalPolicy, ApprovalsReviewer, ServiceTier } from "./runtime-policy"; -import { threadFromThreadRecord, type ThreadRecord } from "./thread"; +import type { Thread } from "../../domain/threads/model"; +import type { ActivePermissionProfile, ApprovalPolicy, ApprovalsReviewer, ServiceTier } from "../protocol/runtime-policy"; +import { threadFromThreadRecord, type ThreadRecord } from "../protocol/thread"; export interface ThreadActivationSnapshot { thread: Thread; diff --git a/src/features/chat/chat-host.ts b/src/features/chat/chat-host.ts index d74486c2..3bd55fc3 100644 --- a/src/features/chat/chat-host.ts +++ b/src/features/chat/chat-host.ts @@ -1,5 +1,5 @@ import type { Thread } from "../../domain/threads/model"; -import type { SharedAppServerMetadata } from "../../app-server/shared-cache-state"; +import type { SharedAppServerMetadata } from "../../app-server/services/shared-cache-state"; import type { CodexPanelSettings } from "../../settings/model"; import type { ChatTurnDiffViewState } from "./turn-diff/model"; diff --git a/src/features/chat/composition-actions.ts b/src/features/chat/composition-actions.ts index 1b90d666..9f8719eb 100644 --- a/src/features/chat/composition-actions.ts +++ b/src/features/chat/composition-actions.ts @@ -1,4 +1,4 @@ -import type { AppServerClient } from "../../app-server/client"; +import type { AppServerClient } from "../../app-server/connection/client"; import type { DisplayDetailSection, DisplayItem } from "./display/types"; import type { ChatStateStore } from "./state/reducer"; import type { ChatViewRenderController } from "./panel/view-render-controller"; diff --git a/src/features/chat/composition-ports.ts b/src/features/chat/composition-ports.ts index 24cb9b85..66ddc460 100644 --- a/src/features/chat/composition-ports.ts +++ b/src/features/chat/composition-ports.ts @@ -1,8 +1,8 @@ import type { App, Component, EventRef } from "obsidian"; import type { ComponentChild as UiNode } from "preact"; -import type { AppServerClient } from "../../app-server/client"; -import type { SharedAppServerMetadata } from "../../app-server/shared-cache-state"; +import type { AppServerClient } from "../../app-server/connection/client"; +import type { SharedAppServerMetadata } from "../../app-server/services/shared-cache-state"; import type { ArchiveExportAdapter } from "../thread-export/archive-markdown"; import type { Thread } from "../../domain/threads/model"; import type { CodexPanelSettings } from "../../settings/model"; diff --git a/src/features/chat/composition.ts b/src/features/chat/composition.ts index 60885895..e022a9c9 100644 --- a/src/features/chat/composition.ts +++ b/src/features/chat/composition.ts @@ -1,4 +1,4 @@ -import { ConnectionManager } from "../../app-server/connection-manager"; +import { ConnectionManager } from "../../app-server/connection/connection-manager"; import type { ChatServerDiagnosticsActions } from "./connection/server-actions/diagnostics"; import type { ChatServerMetadataActions } from "./connection/server-actions/metadata"; import type { ChatServerThreadActions } from "./connection/server-actions/threads"; diff --git a/src/features/chat/connection/composition.ts b/src/features/chat/connection/composition.ts index 2023d26b..c5b967f1 100644 --- a/src/features/chat/connection/composition.ts +++ b/src/features/chat/connection/composition.ts @@ -1,9 +1,9 @@ import { Notice } from "obsidian"; -import type { ConnectionManager } from "../../../app-server/connection-manager"; +import type { ConnectionManager } from "../../../app-server/connection/connection-manager"; import type { RuntimeSnapshot } from "../runtime/snapshot"; import type { ChatState, ChatStateStore } from "../state/reducer"; -import type { SharedAppServerMetadata } from "../../../app-server/shared-cache-state"; +import type { SharedAppServerMetadata } from "../../../app-server/services/shared-cache-state"; import type { Thread } from "../../../domain/threads/model"; import type { CodexPanelSettings } from "../../../settings/model"; import { createChatServerDiagnosticsActions, type ChatServerDiagnosticsActions } from "./server-actions/diagnostics"; diff --git a/src/features/chat/connection/connection-controller.ts b/src/features/chat/connection/connection-controller.ts index e242e670..9dd24b63 100644 --- a/src/features/chat/connection/connection-controller.ts +++ b/src/features/chat/connection/connection-controller.ts @@ -1,6 +1,6 @@ -import { StaleConnectionError } from "../../../app-server/connection-manager"; -import type { AppServerClient } from "../../../app-server/client"; -import type { AppServerInitialization } from "../../../app-server/initialization"; +import { StaleConnectionError } from "../../../app-server/connection/connection-manager"; +import type { AppServerClient } from "../../../app-server/connection/client"; +import type { AppServerInitialization } from "../../../app-server/protocol/initialization"; import type { ChatStateStore } from "../state/reducer"; import type { ChatConnectionWorkTracker, ActiveChatConnection } from "../lifecycle"; diff --git a/src/features/chat/connection/server-actions/diagnostics.ts b/src/features/chat/connection/server-actions/diagnostics.ts index c73f1e97..effbdbc0 100644 --- a/src/features/chat/connection/server-actions/diagnostics.ts +++ b/src/features/chat/connection/server-actions/diagnostics.ts @@ -1,4 +1,4 @@ -import type { AppServerClient } from "../../../../app-server/client"; +import type { AppServerClient } from "../../../../app-server/connection/client"; import { diagnosticProbeError, diagnosticProbeOk, @@ -9,8 +9,9 @@ import { type DiagnosticProbeMethod, type McpServerStartupStatus, type McpServerStatusSummary, -} from "../../../../app-server/diagnostics"; -import type { SharedAppServerMetadata } from "../../../../app-server/shared-cache-state"; +} from "../../../../app-server/protocol/diagnostics"; +import { accountRateLimitsSummaryFromResponse } from "../../../../app-server/protocol/runtime-metrics"; +import type { SharedAppServerMetadata } from "../../../../app-server/services/shared-cache-state"; import { mcpStatusLines as buildMcpStatusLines } from "../../display/status/diagnostics"; import { cloneAppServerDiagnostics, type ChatServerActionHost } from "./host"; @@ -75,7 +76,7 @@ async function refreshDiagnosticProbes( probeDiagnostic( "account/rateLimits/read", () => client.readAccountRateLimits(), - (response) => (response.rateLimitsByLimitId ? `${String(Object.keys(response.rateLimitsByLimitId).length)} limits` : "available"), + accountRateLimitsSummaryFromResponse, ), ); } diff --git a/src/features/chat/connection/server-actions/host.ts b/src/features/chat/connection/server-actions/host.ts index e946e6d0..6df31c43 100644 --- a/src/features/chat/connection/server-actions/host.ts +++ b/src/features/chat/connection/server-actions/host.ts @@ -1,5 +1,5 @@ -import type { AppServerClient } from "../../../../app-server/client"; -import type { Diagnostics } from "../../../../app-server/diagnostics"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import type { Diagnostics } from "../../../../app-server/protocol/diagnostics"; import type { ChatStateStore } from "../../state/reducer"; export interface ChatServerActionHost { diff --git a/src/features/chat/connection/server-actions/metadata.ts b/src/features/chat/connection/server-actions/metadata.ts index 82bcdfe7..2d6cffcb 100644 --- a/src/features/chat/connection/server-actions/metadata.ts +++ b/src/features/chat/connection/server-actions/metadata.ts @@ -1,8 +1,11 @@ -import { type Diagnostics, diagnosticProbeError, diagnosticProbeOk } from "../../../../app-server/diagnostics"; -import { listModelMetadata, listSkillCatalog } from "../../../../app-server/resource-operations"; -import { runtimeConfigSnapshotFromAppServerConfig } from "../../../../app-server/runtime-config"; -import { rateLimitSnapshotFromAppServerSnapshot } from "../../../../app-server/runtime-metrics"; -import type { SharedAppServerMetadata } from "../../../../app-server/shared-cache-state"; +import { type Diagnostics, diagnosticProbeError, diagnosticProbeOk } from "../../../../app-server/protocol/diagnostics"; +import { listModelMetadata, listSkillCatalog } from "../../../../app-server/services/resource-operations"; +import { runtimeConfigSnapshotFromAppServerConfig } from "../../../../app-server/protocol/runtime-config"; +import { + accountRateLimitsSummaryFromResponse, + rateLimitSnapshotFromAccountRateLimitsResponse, +} from "../../../../app-server/protocol/runtime-metrics"; +import type { SharedAppServerMetadata } from "../../../../app-server/services/shared-cache-state"; import type { ModelMetadata, SkillMetadata } from "../../../../domain/catalog/metadata"; import { cloneAppServerDiagnostics, type ChatServerActionHost } from "./host"; @@ -263,15 +266,9 @@ async function loadRateLimitFromClient( ): Promise { try { const response = await client.readAccountRateLimits(); - const rateLimitsByLimitId = response.rateLimitsByLimitId; - const codexRateLimit = rateLimitsByLimitId && Object.hasOwn(rateLimitsByLimitId, "codex") ? rateLimitsByLimitId["codex"] : undefined; - const rateLimit = codexRateLimit ?? response.rateLimits; return { - data: rateLimitSnapshotFromAppServerSnapshot(rateLimit), - probe: diagnosticProbeOk( - "account/rateLimits/read", - response.rateLimitsByLimitId ? `${String(Object.keys(response.rateLimitsByLimitId).length)} limits` : "available", - ), + data: rateLimitSnapshotFromAccountRateLimitsResponse(response), + probe: diagnosticProbeOk("account/rateLimits/read", accountRateLimitsSummaryFromResponse(response)), }; } catch (error) { return { data: null, probe: diagnosticProbeError("account/rateLimits/read", error) }; diff --git a/src/features/chat/connection/server-actions/threads.ts b/src/features/chat/connection/server-actions/threads.ts index 4b1202ff..653e4990 100644 --- a/src/features/chat/connection/server-actions/threads.ts +++ b/src/features/chat/connection/server-actions/threads.ts @@ -1,4 +1,4 @@ -import { listThreads } from "../../../../app-server/resource-operations"; +import { listThreads } from "../../../../app-server/services/resource-operations"; import type { Thread } from "../../../../domain/threads/model"; import type { RuntimeSnapshot } from "../../runtime/snapshot"; import { runtimeConfigOrDefault } from "../../runtime/effective"; diff --git a/src/features/chat/conversation/composer/controller.ts b/src/features/chat/conversation/composer/controller.ts index cfcfab57..cca3f1b9 100644 --- a/src/features/chat/conversation/composer/controller.ts +++ b/src/features/chat/conversation/composer/controller.ts @@ -1,7 +1,7 @@ import type { App, EventRef } from "obsidian"; import type { ComponentChild as UiNode } from "preact"; -import type { CodexInput } from "../../../../app-server/request-input"; +import type { CodexInput } from "../../../../app-server/protocol/request-input"; import { isComposerSendKey, type SendShortcut } from "../../../../shared/ui/keyboard"; import { textareaCursorAtVisualBoundary } from "../../../../shared/ui/textarea-caret"; import { chatTurnBusy, type ChatAction, type ChatState, type ChatStateStore } from "../../state/reducer"; diff --git a/src/features/chat/conversation/composer/wikilink-context.ts b/src/features/chat/conversation/composer/wikilink-context.ts index 0c92407c..f85cae94 100644 --- a/src/features/chat/conversation/composer/wikilink-context.ts +++ b/src/features/chat/conversation/composer/wikilink-context.ts @@ -1,4 +1,4 @@ -import { codexTextInputWithMentions, type RequestMention } from "../../../../app-server/request-input"; +import { codexTextInputWithMentions, type RequestMention } from "../../../../app-server/protocol/request-input"; import type { SkillMetadata } from "../../../../domain/catalog/metadata"; import { parseObsidianWikiLink } from "../../../../shared/obsidian/wikilinks"; diff --git a/src/features/chat/conversation/composition.ts b/src/features/chat/conversation/composition.ts index e34dc953..4a9850ff 100644 --- a/src/features/chat/conversation/composition.ts +++ b/src/features/chat/conversation/composition.ts @@ -1,6 +1,6 @@ import type { App, Component } from "obsidian"; -import type { AppServerClient } from "../../../app-server/client"; +import type { AppServerClient } from "../../../app-server/connection/client"; import type { ChatServerThreadActions } from "../connection/server-actions/threads"; import { ChatComposerController } from "./composer/controller"; import { activeTurnId, type ChatState, type ChatStateStore } from "../state/reducer"; diff --git a/src/features/chat/conversation/pending-requests/state.ts b/src/features/chat/conversation/pending-requests/state.ts index 0d4f0251..6ead530c 100644 --- a/src/features/chat/conversation/pending-requests/state.ts +++ b/src/features/chat/conversation/pending-requests/state.ts @@ -1,5 +1,5 @@ import type { PendingApproval } from "../../protocol/server-requests/approval"; -import type { RequestId } from "../../../../app-server/types"; +import type { RequestId } from "../../../../app-server/connection/rpc-messages"; import { userInputDraftKey, userInputOtherDraftKey, type PendingUserInput } from "../../protocol/server-requests/user-input"; export interface ChatRequestState { diff --git a/src/features/chat/conversation/turns/composer-submit-actions.ts b/src/features/chat/conversation/turns/composer-submit-actions.ts index b081a8cc..cfdb8e15 100644 --- a/src/features/chat/conversation/turns/composer-submit-actions.ts +++ b/src/features/chat/conversation/turns/composer-submit-actions.ts @@ -1,5 +1,5 @@ -import type { AppServerClient } from "../../../../app-server/client"; -import type { CodexInput } from "../../../../app-server/request-input"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import type { CodexInput } from "../../../../app-server/protocol/request-input"; import { submissionStateSnapshot } from "../../state/selectors"; import type { ChatStateStore } from "../../state/reducer"; import { parseSlashCommand } from "../composer/suggestions"; diff --git a/src/features/chat/conversation/turns/optimistic-turn-start.ts b/src/features/chat/conversation/turns/optimistic-turn-start.ts index faec4b6f..65da849c 100644 --- a/src/features/chat/conversation/turns/optimistic-turn-start.ts +++ b/src/features/chat/conversation/turns/optimistic-turn-start.ts @@ -2,7 +2,7 @@ import type { PendingTurnStart } from "../../state/reducer"; import type { DisplayFileMention, DisplayItem, MessageDisplayItem } from "../../display/types"; import { fileMentionsFromInput, userMessageDisplayText } from "../../display/items/user-message"; import { attachHookRunsToTurn } from "../../state/message-stream-updates"; -import type { CodexInput } from "../../../../app-server/request-input"; +import type { CodexInput } from "../../../../app-server/protocol/request-input"; export interface LocalUserMessageParams { id: string; diff --git a/src/features/chat/conversation/turns/plan-implementation.ts b/src/features/chat/conversation/turns/plan-implementation.ts index 66d3c821..592c0441 100644 --- a/src/features/chat/conversation/turns/plan-implementation.ts +++ b/src/features/chat/conversation/turns/plan-implementation.ts @@ -1,4 +1,4 @@ -import type { AppServerClient } from "../../../../app-server/client"; +import type { AppServerClient } from "../../../../app-server/connection/client"; import { activeThreadId, canImplementPlan } from "../../state/selectors"; import type { ChatStateStore } from "../../state/reducer"; import type { DisplayItem } from "../../display/types"; diff --git a/src/features/chat/conversation/turns/slash-command-execution.ts b/src/features/chat/conversation/turns/slash-command-execution.ts index 53e2f16d..4154a075 100644 --- a/src/features/chat/conversation/turns/slash-command-execution.ts +++ b/src/features/chat/conversation/turns/slash-command-execution.ts @@ -1,5 +1,5 @@ -import type { CodexInput } from "../../../../app-server/request-input"; -import type { ThreadGoal, ThreadGoalStatus } from "../../../../app-server/thread-goal"; +import type { CodexInput } from "../../../../app-server/protocol/request-input"; +import type { ThreadGoal, ThreadGoalStatus } from "../../../../app-server/protocol/thread-goal"; import type { ReasoningEffort } from "../../../../domain/catalog/metadata"; import type { Thread } from "../../../../domain/threads/model"; import { getThreadTitle } from "../../../../domain/threads/model"; diff --git a/src/features/chat/conversation/turns/slash-command-handler.ts b/src/features/chat/conversation/turns/slash-command-handler.ts index da856d85..a03f45c9 100644 --- a/src/features/chat/conversation/turns/slash-command-handler.ts +++ b/src/features/chat/conversation/turns/slash-command-handler.ts @@ -1,6 +1,6 @@ -import type { AppServerClient } from "../../../../app-server/client"; -import { codexTextInputWithAttachments, type CodexInput } from "../../../../app-server/request-input"; -import { chronologicalConversationSummariesFromTurnRecords } from "../../../../app-server/turn"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import { codexTextInputWithAttachments, type CodexInput } from "../../../../app-server/protocol/request-input"; +import { chronologicalConversationSummariesFromTurnRecords } from "../../../../app-server/protocol/turn"; import { referencedThreadPromptBundle, referencedThreadTurns, REFERENCED_THREAD_TURN_LIMIT } from "../../../../domain/threads/reference"; import type { Thread } from "../../../../domain/threads/model"; import { @@ -12,7 +12,7 @@ import type { SlashCommandName } from "../composer/slash-commands"; import type { DisplayDetailSection } from "../../display/types"; import type { ReasoningEffort } from "../../../../domain/catalog/metadata"; import { findModelMetadataByIdOrName, supportedEffortsForModelMetadata } from "../../../../domain/catalog/metadata"; -import type { ThreadGoal, ThreadGoalStatus } from "../../../../app-server/thread-goal"; +import type { ThreadGoal, ThreadGoalStatus } from "../../../../app-server/protocol/thread-goal"; import { submissionStateSnapshot } from "../../state/selectors"; import type { ChatStateStore } from "../../state/reducer"; import { currentModel, runtimeConfigOrDefault } from "../../runtime/effective"; diff --git a/src/features/chat/conversation/turns/turn-submission-controller.ts b/src/features/chat/conversation/turns/turn-submission-controller.ts index 974dba52..a17623fd 100644 --- a/src/features/chat/conversation/turns/turn-submission-controller.ts +++ b/src/features/chat/conversation/turns/turn-submission-controller.ts @@ -1,5 +1,5 @@ -import type { AppServerClient } from "../../../../app-server/client"; -import type { CodexInput } from "../../../../app-server/request-input"; +import type { AppServerClient } from "../../../../app-server/connection/client"; +import type { CodexInput } from "../../../../app-server/protocol/request-input"; import type { ReferencedThreadDisplay } from "../../../../domain/threads/reference"; import { submissionStateSnapshot } from "../../state/selectors"; import type { ChatStateStore } from "../../state/reducer"; diff --git a/src/features/chat/display/items/goal.ts b/src/features/chat/display/items/goal.ts index fb6d6b58..b76f04ca 100644 --- a/src/features/chat/display/items/goal.ts +++ b/src/features/chat/display/items/goal.ts @@ -1,4 +1,4 @@ -import type { ThreadGoal, ThreadGoalStatus } from "../../../../app-server/thread-goal"; +import type { ThreadGoal, ThreadGoalStatus } from "../../../../app-server/protocol/thread-goal"; import { truncate } from "../../../../utils"; import type { GoalDisplayItem } from "../types"; diff --git a/src/features/chat/display/items/user-message.ts b/src/features/chat/display/items/user-message.ts index fe20e08e..e0f7f982 100644 --- a/src/features/chat/display/items/user-message.ts +++ b/src/features/chat/display/items/user-message.ts @@ -1,4 +1,4 @@ -import type { CodexInput, CodexInputItem } from "../../../../app-server/request-input"; +import type { CodexInput, CodexInputItem } from "../../../../app-server/protocol/request-input"; import type { DisplayFileMention } from "../types"; type TextRange = [number, number]; diff --git a/src/features/chat/display/status/diagnostics.ts b/src/features/chat/display/status/diagnostics.ts index a207e447..2f59a7fc 100644 --- a/src/features/chat/display/status/diagnostics.ts +++ b/src/features/chat/display/status/diagnostics.ts @@ -1,4 +1,4 @@ -import { DIAGNOSTIC_PROBE_METHODS, appServerIdentity, appServerPlatform } from "../../../../app-server/diagnostics"; +import { DIAGNOSTIC_PROBE_METHODS, appServerIdentity, appServerPlatform } from "../../../../app-server/protocol/diagnostics"; import { CLIENT_VERSION } from "../../../../constants"; import type { Diagnostics, @@ -6,7 +6,7 @@ import type { DiagnosticProbeResult, McpServerDiagnostic, McpServerStatusSummary, -} from "../../../../app-server/diagnostics"; +} from "../../../../app-server/protocol/diagnostics"; interface DiagnosticRow { label: string; diff --git a/src/features/chat/display/status/runtime.ts b/src/features/chat/display/status/runtime.ts index 534b57e7..4d70f9ac 100644 --- a/src/features/chat/display/status/runtime.ts +++ b/src/features/chat/display/status/runtime.ts @@ -1,5 +1,5 @@ -import type { RateLimitWindow, SpendControlLimitSnapshot, ThreadTokenUsage } from "../../../../app-server/runtime-metrics"; -import type { RuntimeConfigSnapshot } from "../../../../app-server/runtime-config"; +import type { RateLimitWindow, SpendControlLimitSnapshot, ThreadTokenUsage } from "../../../../app-server/protocol/runtime-metrics"; +import type { RuntimeConfigSnapshot } from "../../../../app-server/protocol/runtime-config"; import { jsonPreview } from "../../../../utils"; import { sortedModelMetadata } from "../../../../domain/catalog/metadata"; import { defaultEffortForModelMetadata } from "../../../../domain/catalog/metadata"; diff --git a/src/features/chat/display/turn-items.ts b/src/features/chat/display/turn-items.ts index 08d28aec..2dc4d99f 100644 --- a/src/features/chat/display/turn-items.ts +++ b/src/features/chat/display/turn-items.ts @@ -1,9 +1,9 @@ -import type { DisplayDetailSection, DisplayFileChange, DisplayItem, ExecutionState } from "./types"; -import type { HistoricalTurn } from "../../../app-server/turn-history"; -import type { FileUpdateChange, TurnItem } from "../../../app-server/turn"; +import type { DisplayDetailSection, DisplayFileChange, DisplayFileMention, DisplayItem, ExecutionState } from "./types"; +import type { HistoricalTurn } from "../../../app-server/protocol/turn-history"; +import type { FileUpdateChange, TurnItem } from "../../../app-server/protocol/turn"; import { definedProp, truncate } from "../../../utils"; -import { referencedThreadDisplayFromPrompt } from "../../../domain/threads/reference"; -import { turnUserItemText } from "../../../app-server/turn"; +import { referencedThreadDisplayFromPrompt, type ReferencedThreadDisplay } from "../../../domain/threads/reference"; +import { turnUserItemText } from "../../../app-server/protocol/turn"; import { agentDisplayItem } from "./items/agent"; import { pathRelativeToRoot } from "./details/path-labels"; import { normalizeProposedPlanMarkdown } from "./items/proposed-plan"; @@ -37,6 +37,54 @@ type ReviewModeItem = type ContextCompactionItem = Extract; type DisplayExecutionState = Exclude; type ExecutionStateByStatus = Readonly>; +interface BaseDisplayData { + id: string; +} + +interface UserMessageDisplayData extends BaseDisplayData { + text: string; + displayText: string; + clientId: string | null; + mentionedFiles: DisplayFileMention[]; + referencedThread: { + text: string; + displayText: string; + reference: ReferencedThreadDisplay; + } | null; +} + +interface MessageDisplayData extends BaseDisplayData { + text: string; +} + +interface ToolDisplayData extends BaseDisplayData { + text: string; + toolLabel?: string; + status?: string; + output?: string; + details?: DisplayDetailSection[]; + executionState?: ExecutionState; + summaryPath?: boolean; +} + +interface CommandDisplayData extends BaseDisplayData { + actionLabel: string; + text: string; + command: string; + cwd: string; + status: string; + exitCode?: number; + durationMs?: number; + output: string; + executionState: ExecutionState; +} + +interface FileChangeDisplayData extends BaseDisplayData { + text: string; + status: string; + changes: DisplayFileChange[]; + executionState: ExecutionState; +} const COMMAND_STATES = { inProgress: "running", @@ -109,102 +157,153 @@ export function displayItemFromTurnItem(item: TurnItem, turnId?: string): Displa } function userMessageDisplayItem(item: UserMessageItem, turnId?: string): DisplayItem { + return userMessageDisplayItemFromData(userMessageDisplayDataFromItem(item), turnId); +} + +function userMessageDisplayDataFromItem(item: UserMessageItem): UserMessageDisplayData { const text = turnUserItemText(item); - const displayText = userMessageDisplayText(text, item.content); - const mentionedFiles = fileMentionsFromInput(item.content); const referencedThread = referencedThreadDisplayFromPrompt(text); - if (referencedThread) { + return { + id: item.id, + text, + displayText: userMessageDisplayText(text, item.content), + clientId: item.clientId, + mentionedFiles: fileMentionsFromInput(item.content), + referencedThread: referencedThread + ? { + text: referencedThread.text, + displayText: userMessageDisplayText(referencedThread.text, item.content), + reference: referencedThread.reference, + } + : null, + }; +} + +function userMessageDisplayItemFromData(data: UserMessageDisplayData, turnId?: string): DisplayItem { + if (data.referencedThread) { return { - id: item.id, + id: data.id, kind: "message", messageKind: "user", role: "user", - text: userMessageDisplayText(referencedThread.text, item.content), - copyText: referencedThread.text, - referencedThread: referencedThread.reference, + text: data.referencedThread.displayText, + copyText: data.referencedThread.text, + referencedThread: data.referencedThread.reference, ...definedProp("turnId", turnId), - ...definedProp("clientId", item.clientId), - sourceItemId: item.id, - ...(mentionedFiles.length > 0 ? { mentionedFiles } : {}), + ...definedProp("clientId", data.clientId), + sourceItemId: data.id, + ...(data.mentionedFiles.length > 0 ? { mentionedFiles: data.mentionedFiles } : {}), }; } return { - id: item.id, + id: data.id, kind: "message", messageKind: "user", role: "user", - text: displayText, - copyText: text, + text: data.displayText, + copyText: data.text, ...definedProp("turnId", turnId), - ...definedProp("clientId", item.clientId), - sourceItemId: item.id, - ...(mentionedFiles.length > 0 ? { mentionedFiles } : {}), + ...definedProp("clientId", data.clientId), + sourceItemId: data.id, + ...(data.mentionedFiles.length > 0 ? { mentionedFiles: data.mentionedFiles } : {}), }; } function agentMessageDisplayItem(item: AgentMessageItem, turnId?: string): DisplayItem { + return assistantResponseDisplayItemFromData(agentMessageDisplayDataFromItem(item), turnId); +} + +function agentMessageDisplayDataFromItem(item: AgentMessageItem): MessageDisplayData { + return { id: item.id, text: item.text }; +} + +function assistantResponseDisplayItemFromData(data: MessageDisplayData, turnId?: string): DisplayItem { return { - id: item.id, + id: data.id, kind: "message", messageKind: "assistantResponse", role: "assistant", - text: item.text, - copyText: item.text, + text: data.text, + copyText: data.text, ...definedProp("turnId", turnId), - sourceItemId: item.id, + sourceItemId: data.id, messageState: "completed", }; } function planDisplayItem(item: PlanItem, turnId?: string): DisplayItem { + return proposedPlanDisplayItemFromData(planDisplayDataFromItem(item), turnId); +} + +function planDisplayDataFromItem(item: PlanItem): MessageDisplayData { const text = normalizeProposedPlanMarkdown(item.text); + return { id: item.id, text }; +} + +function proposedPlanDisplayItemFromData(data: MessageDisplayData, turnId?: string): DisplayItem { return { - id: item.id, + id: data.id, kind: "message", messageKind: "proposedPlan", role: "assistant", - text, - copyText: text, + text: data.text, + copyText: data.text, ...definedProp("turnId", turnId), - sourceItemId: item.id, + sourceItemId: data.id, messageState: "completed", }; } function hookPromptDisplayItem(item: HookPromptItem, turnId?: string): DisplayItem { + return hookPromptDisplayItemFromData(hookPromptDisplayDataFromItem(item), turnId); +} + +function hookPromptDisplayDataFromItem(item: HookPromptItem): MessageDisplayData { + return { id: item.id, text: item.fragments.map((fragment) => fragment.text).join("\n\n") || "Hook prompt" }; +} + +function hookPromptDisplayItemFromData(data: MessageDisplayData, turnId?: string): DisplayItem { return { - id: item.id, + id: data.id, kind: "hook", role: "tool", - text: item.fragments.map((fragment) => fragment.text).join("\n\n") || "Hook prompt", + text: data.text, ...definedProp("turnId", turnId), - sourceItemId: item.id, + sourceItemId: data.id, }; } function reasoningDisplayItem(item: ReasoningItem, turnId?: string): DisplayItem { + return reasoningDisplayItemFromData(reasoningDisplayDataFromItem(item), turnId); +} + +function reasoningDisplayDataFromItem(item: ReasoningItem): MessageDisplayData { + return { id: item.id, text: reasoningText(item) }; +} + +function reasoningDisplayItemFromData(data: MessageDisplayData, turnId?: string): DisplayItem { return { - id: item.id, + id: data.id, kind: "reasoning", role: "tool", - text: reasoningText(item), + text: data.text, ...definedProp("turnId", turnId), - sourceItemId: item.id, + sourceItemId: data.id, }; } function mcpToolCallDisplayItem(item: McpToolCallItem, turnId?: string): DisplayItem { + return toolDisplayItemFromData(mcpToolCallDisplayDataFromItem(item), turnId); +} + +function mcpToolCallDisplayDataFromItem(item: McpToolCallItem): ToolDisplayData { const name = `${item.server}.${item.tool}`; const target = jsonTargetLabel(item.arguments); const failure = item.error?.message ? truncate(item.error.message, 96) : failedStatusLabel(item.status); return { id: item.id, - kind: "tool", - role: "tool", text: compactToolSummary(null, target, statusQualifier(item.status, failure)), toolLabel: name, - ...definedProp("turnId", turnId), - sourceItemId: item.id, status: item.status, details: jsonDetails([ ["Arguments JSON", item.arguments], @@ -216,18 +315,35 @@ function mcpToolCallDisplayItem(item: McpToolCallItem, turnId?: string): Display }; } +function toolDisplayItemFromData(data: ToolDisplayData, turnId?: string): DisplayItem { + return { + id: data.id, + kind: "tool", + role: "tool", + text: data.text, + ...definedProp("toolLabel", data.toolLabel), + ...definedProp("summaryPath", data.summaryPath), + ...definedProp("turnId", turnId), + sourceItemId: data.id, + ...definedProp("status", data.status), + ...definedProp("details", data.details), + ...definedProp("output", data.output), + ...("executionState" in data ? { executionState: data.executionState } : {}), + }; +} + function dynamicToolCallDisplayItem(item: DynamicToolCallItem, turnId?: string): DisplayItem { + return toolDisplayItemFromData(dynamicToolCallDisplayDataFromItem(item), turnId); +} + +function dynamicToolCallDisplayDataFromItem(item: DynamicToolCallItem): ToolDisplayData { const name = `${item.namespace ? `${item.namespace}.` : ""}${item.tool}`; const target = jsonTargetLabel(item.arguments); const failure = item.success === false ? "failed" : failedStatusLabel(item.status); return { id: item.id, - kind: "tool", - role: "tool", text: compactToolSummary(null, target, statusQualifier(item.status, failure)), toolLabel: name, - ...definedProp("turnId", turnId), - sourceItemId: item.id, status: item.status, details: jsonDetails([ ["Arguments JSON", item.arguments], @@ -239,43 +355,43 @@ function dynamicToolCallDisplayItem(item: DynamicToolCallItem, turnId?: string): } function webSearchDisplayItem(item: WebSearchItem, turnId?: string): DisplayItem { + return toolDisplayItemFromData(webSearchDisplayDataFromItem(item), turnId); +} + +function webSearchDisplayDataFromItem(item: WebSearchItem): ToolDisplayData { return { id: item.id, - kind: "tool", - role: "tool", text: webSearchSummary(item), toolLabel: "web search", - ...definedProp("turnId", turnId), - sourceItemId: item.id, details: webSearchDetails(item), output: "", }; } function imageViewDisplayItem(item: ImageViewItem, turnId?: string): DisplayItem { + return toolDisplayItemFromData(imageViewDisplayDataFromItem(item), turnId); +} + +function imageViewDisplayDataFromItem(item: ImageViewItem): ToolDisplayData { return { id: item.id, - kind: "tool", - role: "tool", text: compactToolSummary(null, item.path), toolLabel: "imageView", summaryPath: true, - ...definedProp("turnId", turnId), - sourceItemId: item.id, }; } function imageGenerationDisplayItem(item: ImageGenerationItem, turnId?: string): DisplayItem { + return toolDisplayItemFromData(imageGenerationDisplayDataFromItem(item), turnId); +} + +function imageGenerationDisplayDataFromItem(item: ImageGenerationItem): ToolDisplayData { const target = item.savedPath ?? item.result; return { id: item.id, - kind: "tool", - role: "tool", text: compactToolSummary(null, target, statusQualifier(item.status, failedStatusLabel(item.status))), toolLabel: "imageGeneration", summaryPath: Boolean(item.savedPath), - ...definedProp("turnId", turnId), - sourceItemId: item.id, status: item.status, details: [ ...bodyDetail("Saved path", item.savedPath), @@ -288,26 +404,34 @@ function imageGenerationDisplayItem(item: ImageGenerationItem, turnId?: string): } function reviewModeDisplayItem(item: ReviewModeItem, turnId?: string): DisplayItem { + return toolDisplayItemFromData(reviewModeDisplayDataFromItem(item), turnId); +} + +function reviewModeDisplayDataFromItem(item: ReviewModeItem): ToolDisplayData { return { id: item.id, - kind: "tool", - role: "tool", text: item.type === "enteredReviewMode" ? "Entered review mode" : "Exited review mode", toolLabel: item.type, - ...definedProp("turnId", turnId), - sourceItemId: item.id, output: item.review, }; } function contextCompactionDisplayItem(item: ContextCompactionItem, turnId?: string): DisplayItem { + return contextCompactionDisplayItemFromData(contextCompactionDisplayDataFromItem(item), turnId); +} + +function contextCompactionDisplayDataFromItem(item: ContextCompactionItem): MessageDisplayData { + return { id: item.id, text: "Context compaction" }; +} + +function contextCompactionDisplayItemFromData(data: MessageDisplayData, turnId?: string): DisplayItem { return { - id: item.id, + id: data.id, kind: "contextCompaction", role: "tool", - text: "Context compaction", + text: data.text, ...definedProp("turnId", turnId), - sourceItemId: item.id, + sourceItemId: data.id, }; } @@ -452,6 +576,10 @@ function webSearchDetails(item: WebSearchItem): DisplayDetailSection[] { } function commandDisplayItem(item: CommandExecutionItem, turnId?: string): DisplayItem { + return commandDisplayItemFromData(commandDisplayDataFromItem(item), turnId); +} + +function commandDisplayDataFromItem(item: CommandExecutionItem): CommandDisplayData { const exitCode = typeof item.exitCode === "number" ? item.exitCode : undefined; const durationMs = typeof item.durationMs === "number" ? item.durationMs : undefined; const target = commandTargetLabel(item); @@ -461,12 +589,8 @@ function commandDisplayItem(item: CommandExecutionItem, turnId?: string): Displa : statusQualifier(item.status, failedStatusLabel(item.status)); return { id: item.id, - kind: "command", - role: "tool", actionLabel: commandActionLabel(item), text: compactToolSummary(null, target, qualifier), - ...definedProp("turnId", turnId), - sourceItemId: item.id, command: item.command, cwd: item.cwd, status: item.status, @@ -477,22 +601,55 @@ function commandDisplayItem(item: CommandExecutionItem, turnId?: string): Displa }; } +function commandDisplayItemFromData(data: CommandDisplayData, turnId?: string): DisplayItem { + return { + id: data.id, + kind: "command", + role: "tool", + actionLabel: data.actionLabel, + text: data.text, + ...definedProp("turnId", turnId), + sourceItemId: data.id, + command: data.command, + cwd: data.cwd, + status: data.status, + ...definedProp("exitCode", data.exitCode), + ...definedProp("durationMs", data.durationMs), + output: data.output, + executionState: data.executionState, + }; +} + function fileChangeDisplayItem(item: FileChangeItem, turnId?: string): DisplayItem { + return fileChangeDisplayItemFromData(fileChangeDisplayDataFromItem(item), turnId); +} + +function fileChangeDisplayDataFromItem(item: FileChangeItem): FileChangeDisplayData { const changes = normalizeFileChanges(item.changes); const qualifier = statusQualifier(item.status, failedStatusLabel(item.status)); return { id: item.id, - kind: "fileChange", - role: "tool", text: compactToolSummary(null, fileChangeTargetLabel(changes), qualifier), - ...definedProp("turnId", turnId), - sourceItemId: item.id, status: item.status, changes, executionState: patchApplyExecutionState(item.status), }; } +function fileChangeDisplayItemFromData(data: FileChangeDisplayData, turnId?: string): DisplayItem { + return { + id: data.id, + kind: "fileChange", + role: "tool", + text: data.text, + ...definedProp("turnId", turnId), + sourceItemId: data.id, + status: data.status, + changes: data.changes, + executionState: data.executionState, + }; +} + export function normalizeFileChanges(changes: FileUpdateChange[]): DisplayFileChange[] { return changes.map((change) => ({ kind: change.kind.type, diff --git a/src/features/chat/panel/cached-app-server-state.ts b/src/features/chat/panel/cached-app-server-state.ts index 37e71541..939c506c 100644 --- a/src/features/chat/panel/cached-app-server-state.ts +++ b/src/features/chat/panel/cached-app-server-state.ts @@ -1,4 +1,4 @@ -import type { SharedAppServerMetadata } from "../../../app-server/shared-cache-state"; +import type { SharedAppServerMetadata } from "../../../app-server/services/shared-cache-state"; import type { Thread } from "../../../domain/threads/model"; import type { ChatServerMetadataActions } from "../connection/server-actions/metadata"; import type { ChatServerThreadActions } from "../connection/server-actions/threads"; diff --git a/src/features/chat/panel/composition.ts b/src/features/chat/panel/composition.ts index 45a8b886..796512ea 100644 --- a/src/features/chat/panel/composition.ts +++ b/src/features/chat/panel/composition.ts @@ -1,4 +1,4 @@ -import type { ConnectionManager } from "../../../app-server/connection-manager"; +import type { ConnectionManager } from "../../../app-server/connection/connection-manager"; import type { ComponentChild as UiNode } from "preact"; import type { ChatStateStore } from "../state/reducer"; import type { CodexPanelSettings } from "../../../settings/model"; diff --git a/src/features/chat/protocol/inbound/controller.ts b/src/features/chat/protocol/inbound/controller.ts index 67f8f6c0..1a232daf 100644 --- a/src/features/chat/protocol/inbound/controller.ts +++ b/src/features/chat/protocol/inbound/controller.ts @@ -1,5 +1,5 @@ -import type { RequestId, ServerNotification, ServerRequest } from "../../../../app-server/types"; -import type { McpServerStartupStatus } from "../../../../app-server/diagnostics"; +import type { RequestId, ServerNotification, ServerRequest } from "../../../../app-server/connection/rpc-messages"; +import type { McpServerStartupStatus } from "../../../../app-server/protocol/diagnostics"; import type { ThreadConversationSummary } from "../../../../domain/threads/transcript"; import { classifyAppServerLog } from "./app-server-logs"; import { activeTurnId, type ChatAction, type ChatState, type ChatStateStore } from "../../state/reducer"; diff --git a/src/features/chat/protocol/inbound/notification-plan.ts b/src/features/chat/protocol/inbound/notification-plan.ts index 03a42b60..15a804b9 100644 --- a/src/features/chat/protocol/inbound/notification-plan.ts +++ b/src/features/chat/protocol/inbound/notification-plan.ts @@ -1,13 +1,13 @@ import { activeThreadSettingsAppliedAction } from "../../state/actions"; -import type { McpServerStartupStatus } from "../../../../app-server/diagnostics"; -import { threadTokenUsageFromAppServerUsage } from "../../../../app-server/runtime-metrics"; +import type { McpServerStartupStatus } from "../../../../app-server/protocol/diagnostics"; +import { threadTokenUsageFromAppServerUsage } from "../../../../app-server/protocol/runtime-metrics"; import { completedConversationSummaryFromTurnRecord, type FileUpdateChange, type TurnItem, type TurnRecord, -} from "../../../../app-server/turn"; -import type { ServerNotification } from "../../../../app-server/types"; +} from "../../../../app-server/protocol/turn"; +import type { ServerNotification } from "../../../../app-server/connection/rpc-messages"; import type { ThreadConversationSummary } from "../../../../domain/threads/transcript"; import { jsonPreview } from "../../../../utils"; import { activeTurnId, pendingTurnStart as pendingTurnStartForState, type ChatAction, type ChatState } from "../../state/reducer"; diff --git a/src/features/chat/protocol/inbound/routing.ts b/src/features/chat/protocol/inbound/routing.ts index 225fcc56..b637e762 100644 --- a/src/features/chat/protocol/inbound/routing.ts +++ b/src/features/chat/protocol/inbound/routing.ts @@ -1,4 +1,4 @@ -import type { ServerNotification, ServerRequest } from "../../../../app-server/types"; +import type { ServerNotification, ServerRequest } from "../../../../app-server/connection/rpc-messages"; import { toPendingApproval, type PendingApproval } from "../server-requests/approval"; import { toPendingUserInput, type PendingUserInput } from "../server-requests/user-input"; diff --git a/src/features/chat/protocol/server-requests/approval.ts b/src/features/chat/protocol/server-requests/approval.ts index c00b451b..193db1c5 100644 --- a/src/features/chat/protocol/server-requests/approval.ts +++ b/src/features/chat/protocol/server-requests/approval.ts @@ -1,6 +1,6 @@ import { jsonPreview } from "../../../../utils"; import { permissionRows } from "../../display/details/permission-rows"; -import type { RequestId } from "../../../../app-server/types"; +import type { RequestId } from "../../../../app-server/connection/rpc-messages"; type SimpleApprovalDecision = "accept" | "acceptForSession" | "decline" | "cancel"; export type CommandApprovalDecision = diff --git a/src/features/chat/protocol/server-requests/responder.ts b/src/features/chat/protocol/server-requests/responder.ts index 0fa8c5b2..27f5c833 100644 --- a/src/features/chat/protocol/server-requests/responder.ts +++ b/src/features/chat/protocol/server-requests/responder.ts @@ -1,4 +1,4 @@ -import type { AppServerClient } from "../../../../app-server/client"; +import type { AppServerClient } from "../../../../app-server/connection/client"; type RespondRequestId = Parameters[0]; type RejectRequestId = Parameters[0]; diff --git a/src/features/chat/protocol/server-requests/user-input.ts b/src/features/chat/protocol/server-requests/user-input.ts index 50dde9cb..134eef45 100644 --- a/src/features/chat/protocol/server-requests/user-input.ts +++ b/src/features/chat/protocol/server-requests/user-input.ts @@ -1,6 +1,6 @@ -import type { RequestId } from "../../../../app-server/types"; +import type { RequestId } from "../../../../app-server/connection/rpc-messages"; -export type { RequestId } from "../../../../app-server/types"; +export type { RequestId } from "../../../../app-server/connection/rpc-messages"; interface UserInputRequestLike { id: RequestId; diff --git a/src/features/chat/runtime/effective.ts b/src/features/chat/runtime/effective.ts index 5217272b..11de662d 100644 --- a/src/features/chat/runtime/effective.ts +++ b/src/features/chat/runtime/effective.ts @@ -1,6 +1,6 @@ -import { cloneRuntimeConfigSnapshot, emptyRuntimeConfigSnapshot, type RuntimeConfigSnapshot } from "../../../app-server/runtime-config"; +import { cloneRuntimeConfigSnapshot, emptyRuntimeConfigSnapshot, type RuntimeConfigSnapshot } from "../../../app-server/protocol/runtime-config"; import { findModelMetadataByIdOrName, type ModelMetadata } from "../../../domain/catalog/metadata"; -import type { ApprovalPolicy, ApprovalsReviewer } from "../../../app-server/runtime-policy"; +import type { ApprovalPolicy, ApprovalsReviewer } from "../../../app-server/protocol/runtime-policy"; import { supportedEffortsForModelMetadata, type ReasoningEffort } from "../../../domain/catalog/metadata"; import type { RuntimeSnapshot } from "./snapshot"; diff --git a/src/features/chat/runtime/settings-actions.ts b/src/features/chat/runtime/settings-actions.ts index e156aa11..1d00ed8e 100644 --- a/src/features/chat/runtime/settings-actions.ts +++ b/src/features/chat/runtime/settings-actions.ts @@ -1,7 +1,7 @@ -import type { AppServerClient } from "../../../app-server/client"; -import type { RuntimeConfigSnapshot } from "../../../app-server/runtime-config"; -import type { ApprovalsReviewer } from "../../../app-server/runtime-policy"; -import type { ThreadSettingsUpdate } from "../../../app-server/thread-settings"; +import type { AppServerClient } from "../../../app-server/connection/client"; +import type { RuntimeConfigSnapshot } from "../../../app-server/protocol/runtime-config"; +import type { ApprovalsReviewer } from "../../../app-server/protocol/runtime-policy"; +import type { ThreadSettingsUpdate } from "../../../app-server/protocol/thread-settings"; import type { ReasoningEffort } from "../../../domain/catalog/metadata"; import { autoReviewActive, fastModeActive, runtimeConfigOrDefault } from "./effective"; import { diff --git a/src/features/chat/runtime/snapshot.ts b/src/features/chat/runtime/snapshot.ts index d2980955..c3951ede 100644 --- a/src/features/chat/runtime/snapshot.ts +++ b/src/features/chat/runtime/snapshot.ts @@ -1,7 +1,7 @@ import type { ChatState } from "../state/reducer"; -import type { ActivePermissionProfile, RuntimeConfigSnapshot } from "../../../app-server/runtime-config"; -import type { RateLimitSnapshot, ThreadTokenUsage } from "../../../app-server/runtime-metrics"; -import type { ApprovalPolicy, ApprovalsReviewer, ServiceTier } from "../../../app-server/runtime-policy"; +import type { ActivePermissionProfile, RuntimeConfigSnapshot } from "../../../app-server/protocol/runtime-config"; +import type { RateLimitSnapshot, ThreadTokenUsage } from "../../../app-server/protocol/runtime-metrics"; +import type { ApprovalPolicy, ApprovalsReviewer, ServiceTier } from "../../../app-server/protocol/runtime-policy"; import type { ModelMetadata, ReasoningEffort } from "../../../domain/catalog/metadata"; import type { CollaborationMode, PendingRuntimeSetting, RequestedServiceTier } from "./pending-settings"; diff --git a/src/features/chat/runtime/state.ts b/src/features/chat/runtime/state.ts index 8350aff6..32d5bc16 100644 --- a/src/features/chat/runtime/state.ts +++ b/src/features/chat/runtime/state.ts @@ -4,8 +4,8 @@ import { type ApprovalPolicy, type ApprovalsReviewer, type ServiceTier, -} from "../../../app-server/runtime-policy"; -import type { ThreadSettingsUpdate } from "../../../app-server/thread-settings"; +} from "../../../app-server/protocol/runtime-policy"; +import type { ThreadSettingsUpdate } from "../../../app-server/protocol/thread-settings"; import { normalizeReasoningEffort, type ReasoningEffort } from "../../../domain/catalog/metadata"; import { resetRuntimeSettingToConfig, diff --git a/src/features/chat/runtime/thread-settings-update.ts b/src/features/chat/runtime/thread-settings-update.ts index e0411ab6..67a51486 100644 --- a/src/features/chat/runtime/thread-settings-update.ts +++ b/src/features/chat/runtime/thread-settings-update.ts @@ -1,7 +1,7 @@ -import { applyThreadSettingsValue, appServerCollaborationMode, type ThreadSettingsUpdate } from "../../../app-server/thread-settings"; -import type { ServiceTierRequest } from "../../../app-server/thread-settings"; +import { applyThreadSettingsValue, appServerCollaborationMode, type ThreadSettingsUpdate } from "../../../app-server/protocol/thread-settings"; +import type { ServiceTierRequest } from "../../../app-server/protocol/thread-settings"; import { currentModel, currentReasoningEffort, fastServiceTierRequestValue } from "./effective"; -import type { RuntimeConfigSnapshot } from "../../../app-server/runtime-config"; +import type { RuntimeConfigSnapshot } from "../../../app-server/protocol/runtime-config"; import type { RuntimeSnapshot } from "./snapshot"; import type { PendingRuntimeSetting } from "./pending-settings"; diff --git a/src/features/chat/state/actions.ts b/src/features/chat/state/actions.ts index d31e2dc7..a677af77 100644 --- a/src/features/chat/state/actions.ts +++ b/src/features/chat/state/actions.ts @@ -1,6 +1,6 @@ -import type { AppServerInitialization } from "../../../app-server/initialization"; +import type { AppServerInitialization } from "../../../app-server/protocol/initialization"; import type { Thread } from "../../../domain/threads/model"; -import { parseServiceTier, type ServiceTier } from "../../../app-server/runtime-policy"; +import { parseServiceTier, type ServiceTier } from "../../../app-server/protocol/runtime-policy"; import { normalizeReasoningEffort, type ReasoningEffort } from "../../../domain/catalog/metadata"; import type { ChatRuntimeState } from "../runtime/state"; import type { CollaborationMode } from "../runtime/pending-settings"; diff --git a/src/features/chat/state/reducer.ts b/src/features/chat/state/reducer.ts index d0531b11..04c97956 100644 --- a/src/features/chat/state/reducer.ts +++ b/src/features/chat/state/reducer.ts @@ -1,14 +1,14 @@ -import type { AppServerInitialization } from "../../../app-server/initialization"; +import type { AppServerInitialization } from "../../../app-server/protocol/initialization"; import type { ReasoningEffort } from "../../../domain/catalog/metadata"; import type { Thread } from "../../../domain/threads/model"; import type { ModelMetadata, SkillMetadata } from "../../../domain/catalog/metadata"; -import type { ThreadGoal } from "../../../app-server/thread-goal"; -import type { ThreadSettingsUpdate } from "../../../app-server/thread-settings"; -import type { ApprovalsReviewer } from "../../../app-server/runtime-policy"; -import type { Diagnostics } from "../../../app-server/diagnostics"; -import { createAppServerDiagnostics } from "../../../app-server/diagnostics"; -import type { RuntimeConfigSnapshot } from "../../../app-server/runtime-config"; -import type { RateLimitSnapshot, ThreadTokenUsage } from "../../../app-server/runtime-metrics"; +import type { ThreadGoal } from "../../../app-server/protocol/thread-goal"; +import type { ThreadSettingsUpdate } from "../../../app-server/protocol/thread-settings"; +import type { ApprovalsReviewer } from "../../../app-server/protocol/runtime-policy"; +import type { Diagnostics } from "../../../app-server/protocol/diagnostics"; +import { createAppServerDiagnostics } from "../../../app-server/protocol/diagnostics"; +import type { RuntimeConfigSnapshot } from "../../../app-server/protocol/runtime-config"; +import type { RateLimitSnapshot, ThreadTokenUsage } from "../../../app-server/protocol/runtime-metrics"; import type { CollaborationMode } from "../runtime/pending-settings"; import { commitPendingThreadSettingsRuntimeState, @@ -26,7 +26,7 @@ import { type ChatRuntimeState, } from "../runtime/state"; import type { RequestedServiceTier } from "../runtime/pending-settings"; -import type { RequestId } from "../../../app-server/types"; +import type { RequestId } from "../../../app-server/connection/rpc-messages"; import type { ComposerSuggestion } from "../conversation/composer/suggestions"; import { upsertDisplayItem } from "./message-stream-updates"; import type { DisplayItem } from "../display/types"; diff --git a/src/features/chat/threads/action-context.ts b/src/features/chat/threads/action-context.ts index 65c2cd34..c2c90cdb 100644 --- a/src/features/chat/threads/action-context.ts +++ b/src/features/chat/threads/action-context.ts @@ -1,4 +1,4 @@ -import type { AppServerClient } from "../../../app-server/client"; +import type { AppServerClient } from "../../../app-server/connection/client"; import type { ArchiveExportAdapter } from "../../thread-export/archive-markdown"; import type { CodexPanelSettings } from "../../../settings/model"; import type { ChatAction, ChatState, ChatStateStore } from "../state/reducer"; diff --git a/src/features/chat/threads/archive-actions.ts b/src/features/chat/threads/archive-actions.ts index 9d2c64b7..cbd4df0f 100644 --- a/src/features/chat/threads/archive-actions.ts +++ b/src/features/chat/threads/archive-actions.ts @@ -1,7 +1,7 @@ import { Notice } from "obsidian"; -import { threadFromThreadRecord } from "../../../app-server/thread"; -import { transcriptEntriesFromTurnRecord } from "../../../app-server/turn"; +import { threadFromThreadRecord } from "../../../app-server/protocol/thread"; +import { transcriptEntriesFromTurnRecords } from "../../../app-server/protocol/turn"; import { exportArchivedThreadMarkdown } from "../../thread-export/archive-markdown"; import { chatTurnBusy } from "../state/reducer"; import type { ChatThreadActionsHost } from "./action-context"; @@ -36,7 +36,7 @@ export async function archiveThreadOnServer( const result = await exportArchivedThreadMarkdown( { ...threadFromThreadRecord(response.thread, { archived: true }), - transcriptEntries: response.thread.turns.flatMap(transcriptEntriesFromTurnRecord), + transcriptEntries: transcriptEntriesFromTurnRecords(response.thread.turns), }, { ...settings, vaultPath: host.vaultPath }, host.archiveAdapter(), diff --git a/src/features/chat/threads/auto-title-controller.ts b/src/features/chat/threads/auto-title-controller.ts index da766a34..278f5c1a 100644 --- a/src/features/chat/threads/auto-title-controller.ts +++ b/src/features/chat/threads/auto-title-controller.ts @@ -1,4 +1,4 @@ -import type { AppServerClient } from "../../../app-server/client"; +import type { AppServerClient } from "../../../app-server/connection/client"; import type { Thread } from "../../../domain/threads/model"; import type { ThreadConversationSummary } from "../../../domain/threads/transcript"; import type { CodexPanelSettings } from "../../../settings/model"; diff --git a/src/features/chat/threads/composition.ts b/src/features/chat/threads/composition.ts index 7510d458..800b76ff 100644 --- a/src/features/chat/threads/composition.ts +++ b/src/features/chat/threads/composition.ts @@ -1,6 +1,6 @@ -import type { ConnectionManager } from "../../../app-server/connection-manager"; -import type { AppServerClient } from "../../../app-server/client"; -import { recoverRolloutTokenUsage } from "../../../app-server/rollout-token-usage"; +import type { ConnectionManager } from "../../../app-server/connection/connection-manager"; +import type { AppServerClient } from "../../../app-server/connection/client"; +import { recoverRolloutTokenUsage } from "../../../app-server/services/rollout-token-usage"; import type { ArchiveExportAdapter } from "../../thread-export/archive-markdown"; import { createChatThreadActions } from "./actions"; import { AutoTitleController } from "./auto-title-controller"; diff --git a/src/features/chat/threads/goal-actions.ts b/src/features/chat/threads/goal-actions.ts index 677c065b..dc7982a5 100644 --- a/src/features/chat/threads/goal-actions.ts +++ b/src/features/chat/threads/goal-actions.ts @@ -1,11 +1,11 @@ -import type { AppServerClient } from "../../../app-server/client"; +import type { AppServerClient } from "../../../app-server/connection/client"; import { appServerThreadGoalUserHistoryItem, threadGoalFromAppServerGoal, type ThreadGoal, type ThreadGoalStatus, type ThreadGoalUpdate, -} from "../../../app-server/thread-goal"; +} from "../../../app-server/protocol/thread-goal"; import type { ChatStateStore } from "../state/reducer"; import type { GoalDisplayItem } from "../display/types"; import { goalChangeItem } from "../display/items/goal"; diff --git a/src/features/chat/threads/history-controller.ts b/src/features/chat/threads/history-controller.ts index 5a844d45..630f3b30 100644 --- a/src/features/chat/threads/history-controller.ts +++ b/src/features/chat/threads/history-controller.ts @@ -1,5 +1,5 @@ -import type { AppServerClient } from "../../../app-server/client"; -import type { ThreadTurnsPage } from "../../../app-server/turn-history"; +import type { AppServerClient } from "../../../app-server/connection/client"; +import type { ThreadTurnsPage } from "../../../app-server/protocol/turn-history"; import type { ChatAction, ChatState, ChatStateStore } from "../state/reducer"; import { displayItemsFromTurns } from "../display/turn-items"; diff --git a/src/features/chat/threads/rename-actions.ts b/src/features/chat/threads/rename-actions.ts index 8b1b4966..7a896d48 100644 --- a/src/features/chat/threads/rename-actions.ts +++ b/src/features/chat/threads/rename-actions.ts @@ -1,4 +1,4 @@ -import type { AppServerClient } from "../../../app-server/client"; +import type { AppServerClient } from "../../../app-server/connection/client"; import type { ChatStateStore } from "../state/reducer"; export interface ThreadRenameActionsHost { diff --git a/src/features/chat/threads/rename-controller.ts b/src/features/chat/threads/rename-controller.ts index 594dc158..b89e98d1 100644 --- a/src/features/chat/threads/rename-controller.ts +++ b/src/features/chat/threads/rename-controller.ts @@ -1,5 +1,5 @@ -import type { AppServerClient } from "../../../app-server/client"; -import { completedConversationSummaryFromTurnRecord } from "../../../app-server/turn"; +import type { AppServerClient } from "../../../app-server/connection/client"; +import { completedConversationSummariesFromTurnRecords } from "../../../app-server/protocol/turn"; import { getThreadTitle } from "../../../domain/threads/model"; import type { Thread } from "../../../domain/threads/model"; import type { CodexPanelSettings } from "../../../settings/model"; @@ -158,10 +158,7 @@ export class RenameController { readTurns: async (id, cursor, limit, sortDirection) => { const response = await client.threadTurnsList(id, cursor, limit, sortDirection); return { - data: response.data.flatMap((turn) => { - const summary = completedConversationSummaryFromTurnRecord(turn); - return summary ? [summary] : []; - }), + data: completedConversationSummariesFromTurnRecords(response.data), nextCursor: response.nextCursor, }; }, diff --git a/src/features/chat/threads/resume-controller.ts b/src/features/chat/threads/resume-controller.ts index 8024940f..93f74f2f 100644 --- a/src/features/chat/threads/resume-controller.ts +++ b/src/features/chat/threads/resume-controller.ts @@ -1,5 +1,5 @@ -import type { AppServerClient } from "../../../app-server/client"; -import type { ThreadTokenUsage } from "../../../app-server/runtime-metrics"; +import type { AppServerClient } from "../../../app-server/connection/client"; +import type { ThreadTokenUsage } from "../../../app-server/protocol/runtime-metrics"; import { activeThreadId, canSwitchToThread, displayItemsEmpty, listedThreads } from "../state/selectors"; import type { ChatStateStore } from "../state/reducer"; import type { RestorationController } from "./restoration-controller"; diff --git a/src/features/chat/threads/resume.ts b/src/features/chat/threads/resume.ts index cfab86f6..46c4b0b0 100644 --- a/src/features/chat/threads/resume.ts +++ b/src/features/chat/threads/resume.ts @@ -1,8 +1,8 @@ -import { parseServiceTier } from "../../../app-server/runtime-policy"; +import { parseServiceTier } from "../../../app-server/protocol/runtime-policy"; import { upsertThread } from "../../../domain/threads/model"; import { normalizeReasoningEffort } from "../../../domain/catalog/metadata"; import type { Thread } from "../../../domain/threads/model"; -import { threadActivationSnapshotFromAppServerResponse, type ThreadActivationSnapshot } from "../../../app-server/thread-activation"; +import { threadActivationSnapshotFromAppServerResponse, type ThreadActivationSnapshot } from "../../../app-server/services/thread-activation"; import type { ChatRuntimeState } from "../runtime/state"; import type { DisplayItem } from "../display/types"; import type { ActiveThreadResumedAction } from "../state/actions"; diff --git a/src/features/chat/threads/rollback-actions.ts b/src/features/chat/threads/rollback-actions.ts index c0822ad6..09aba795 100644 --- a/src/features/chat/threads/rollback-actions.ts +++ b/src/features/chat/threads/rollback-actions.ts @@ -1,4 +1,4 @@ -import { threadFromThreadRecord } from "../../../app-server/thread"; +import { threadFromThreadRecord } from "../../../app-server/protocol/thread"; import { rollbackCandidateFromItems } from "../display/item-actions"; import { displayItemsFromTurns } from "../display/turn-items"; import { chatTurnBusy } from "../state/reducer"; diff --git a/src/features/chat/ui/goal-banner.tsx b/src/features/chat/ui/goal-banner.tsx index 986c7829..cef019fa 100644 --- a/src/features/chat/ui/goal-banner.tsx +++ b/src/features/chat/ui/goal-banner.tsx @@ -1,7 +1,7 @@ import type { ComponentChild as UiNode } from "preact"; import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "preact/hooks"; -import type { ThreadGoal, ThreadGoalStatus } from "../../../app-server/thread-goal"; +import type { ThreadGoal, ThreadGoalStatus } from "../../../app-server/protocol/thread-goal"; import { isComposerSendKey, type SendShortcut } from "../../../shared/ui/keyboard"; import { IconButton } from "../../../shared/ui/components"; import { syncTextareaHeight } from "../../../shared/ui/textarea-autogrow"; diff --git a/src/features/chat/view.ts b/src/features/chat/view.ts index 963fa0b5..e7f26223 100644 --- a/src/features/chat/view.ts +++ b/src/features/chat/view.ts @@ -1,6 +1,6 @@ import { ItemView, type ViewStateResult, type WorkspaceLeaf } from "obsidian"; -import type { AppServerClient } from "../../app-server/client"; +import type { AppServerClient } from "../../app-server/connection/client"; import { VIEW_TYPE_CODEX_PANEL } from "../../constants"; import type { DisplayDetailSection, DisplayItem } from "./display/types"; import type { ReasoningEffort } from "../../domain/catalog/metadata"; @@ -10,7 +10,7 @@ import type { RuntimeSnapshot } from "./runtime/snapshot"; import { collaborationModeLabel as formatCollaborationModeLabel } from "./runtime/pending-settings"; import { chatTurnBusy, createChatStateStore, type ChatState, type ChatAction } from "./state/reducer"; import type { OpenCodexPanelSnapshot } from "../../workspace/open-panel-snapshot"; -import type { SharedAppServerMetadata } from "../../app-server/shared-cache-state"; +import type { SharedAppServerMetadata } from "../../app-server/services/shared-cache-state"; import type { CodexChatHost } from "./chat-host"; import { createStructuredSystemItem, createSystemItem } from "./display/items/system"; import { diff --git a/src/features/selection-rewrite/runner.ts b/src/features/selection-rewrite/runner.ts index 96eca932..62ccde8c 100644 --- a/src/features/selection-rewrite/runner.ts +++ b/src/features/selection-rewrite/runner.ts @@ -4,10 +4,10 @@ import { type EphemeralStructuredTurnClientFactory, type EphemeralStructuredTurnRuntimeClient, type StructuredTurnOutputSchema, -} from "../../app-server/ephemeral-structured-turn"; -import { lastAgentMessageTextFromTurnRecord } from "../../app-server/turn"; +} from "../../app-server/services/ephemeral-structured-turn"; +import { lastAgentMessageTextFromTurnRecord } from "../../app-server/protocol/turn"; import type { ReasoningEffort } from "../../domain/catalog/metadata"; -import { modelMetadataFromCatalogModels } from "../../app-server/catalog"; +import { modelMetadataFromCatalogModels } from "../../app-server/protocol/catalog"; import type { ModelMetadata } from "../../domain/catalog/metadata"; import { runtimeOverride, validatedRuntimeOverrideForModelMetadata } from "../../domain/catalog/runtime-overrides"; import type { SelectionRewriteRuntimeSettings } from "./model"; diff --git a/src/features/thread-picker/modal.ts b/src/features/thread-picker/modal.ts index 048abfc0..c8f0979f 100644 --- a/src/features/thread-picker/modal.ts +++ b/src/features/thread-picker/modal.ts @@ -1,7 +1,7 @@ import { Notice, Platform, SuggestModal, type App } from "obsidian"; -import { listThreads } from "../../app-server/resource-operations"; -import { withShortLivedAppServerClient } from "../../app-server/short-lived-client"; +import { listThreads } from "../../app-server/services/resource-operations"; +import { withShortLivedAppServerClient } from "../../app-server/connection/short-lived-client"; import { getThreadTitle } from "../../domain/threads/model"; import type { Thread } from "../../domain/threads/model"; import type { CodexPanelSettings } from "../../settings/model"; diff --git a/src/features/thread-title/generation.ts b/src/features/thread-title/generation.ts index 708681dd..dd0e715c 100644 --- a/src/features/thread-title/generation.ts +++ b/src/features/thread-title/generation.ts @@ -1,12 +1,12 @@ -import { modelMetadataFromCatalogModels } from "../../app-server/catalog"; +import { modelMetadataFromCatalogModels } from "../../app-server/protocol/catalog"; import { runEphemeralStructuredTurn, type EphemeralStructuredTurnClient, type EphemeralStructuredTurnClientFactory, type EphemeralStructuredTurnRuntimeClient, type StructuredTurnOutputSchema, -} from "../../app-server/ephemeral-structured-turn"; -import { conversationSummaryFromTurnRecord, type TurnRecord } from "../../app-server/turn"; +} from "../../app-server/services/ephemeral-structured-turn"; +import { conversationAssistantTextFromTurnRecord, type TurnRecord } from "../../app-server/protocol/turn"; import type { ModelMetadata, ReasoningEffort } from "../../domain/catalog/metadata"; import { runtimeOverride, validatedRuntimeOverrideForModelMetadata } from "../../domain/catalog/runtime-overrides"; import { threadTitleFromGeneratedText, threadTitlePrompt, type ThreadTitleContext } from "./model"; @@ -73,7 +73,7 @@ export interface ThreadTitleRuntimeOverride { } export function threadTitleFromGenerationTurn(turn: TurnRecord): string | null { - const response = conversationSummaryFromTurnRecord(turn).assistantText; + const response = conversationAssistantTextFromTurnRecord(turn); return response ? threadTitleFromGeneratedText(response) : null; } diff --git a/src/features/threads-view/view.ts b/src/features/threads-view/view.ts index 92da05ac..30c26d6c 100644 --- a/src/features/threads-view/view.ts +++ b/src/features/threads-view/view.ts @@ -1,15 +1,15 @@ import { ItemView, Notice, type WorkspaceLeaf } from "obsidian"; -import type { AppServerClient } from "../../app-server/client"; -import { ConnectionManager, StaleConnectionError } from "../../app-server/connection-manager"; -import { listThreads } from "../../app-server/resource-operations"; -import { threadFromThreadRecord } from "../../app-server/thread"; +import type { AppServerClient } from "../../app-server/connection/client"; +import { ConnectionManager, StaleConnectionError } from "../../app-server/connection/connection-manager"; +import { listThreads } from "../../app-server/services/resource-operations"; +import { threadFromThreadRecord } from "../../app-server/protocol/thread"; import { VIEW_TYPE_CODEX_THREADS } from "../../constants"; import type { Thread } from "../../domain/threads/model"; import type { CodexPanelSettings } from "../../settings/model"; import { exportArchivedThreadMarkdown } from "../thread-export/archive-markdown"; import type { OpenCodexPanelSnapshot } from "../../workspace/open-panel-snapshot"; -import { completedConversationSummaryFromTurnRecord, transcriptEntriesFromTurnRecord } from "../../app-server/turn"; +import { completedConversationSummariesFromTurnRecords, transcriptEntriesFromTurnRecords } from "../../app-server/protocol/turn"; import { generateThreadTitleWithCodex } from "../thread-title/generation"; import { findThreadTitleContext, THREAD_TITLE_CONTEXT_UNAVAILABLE_MESSAGE } from "../thread-title/model"; import { renderThreadsView, unmountThreadsView } from "./renderer"; @@ -332,10 +332,7 @@ export class CodexThreadsView extends ItemView { readTurns: async (id, cursor, limit, sortDirection) => { const response = await client.threadTurnsList(id, cursor, limit, sortDirection); return { - data: response.data.flatMap((turn) => { - const summary = completedConversationSummaryFromTurnRecord(turn); - return summary ? [summary] : []; - }), + data: completedConversationSummariesFromTurnRecords(response.data), nextCursor: response.nextCursor, }; }, @@ -383,7 +380,7 @@ export class CodexThreadsView extends ItemView { const result = await exportArchivedThreadMarkdown( { ...threadFromThreadRecord(response.thread, { archived: true }), - transcriptEntries: response.thread.turns.flatMap(transcriptEntriesFromTurnRecord), + transcriptEntries: transcriptEntriesFromTurnRecords(response.thread.turns), }, { ...this.plugin.settings, vaultPath: this.plugin.vaultPath }, this.app.vault.adapter, diff --git a/src/main.ts b/src/main.ts index d849a325..4b97eb4d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,8 +7,8 @@ import type { CodexChatHost } from "./features/chat/chat-host"; import { CodexChatTurnDiffView } from "./features/chat/turn-diff/view"; import { openThreadPicker, type ThreadPickerHost } from "./features/thread-picker/modal"; import { CodexThreadsView, type CodexThreadsHost } from "./features/threads-view/view"; -import { SharedAppServerCache } from "./app-server/shared-cache"; -import type { SharedAppServerCacheContext } from "./app-server/shared-cache-state"; +import { SharedAppServerCache } from "./app-server/services/shared-cache"; +import type { SharedAppServerCacheContext } from "./app-server/services/shared-cache-state"; import { DEFAULT_SETTINGS, getVaultPath, normalizeSettings, settingsMatchNormalizedData, type CodexPanelSettings } from "./settings/model"; import { CodexPanelSettingTab, type CodexPanelSettingTabHost } from "./settings/tab"; import { persistedChatTurnDiffViewState, type ChatTurnDiffViewState } from "./features/chat/turn-diff/model"; diff --git a/src/settings/app-server-data.ts b/src/settings/app-server-data.ts index 171bb2ce..9b5e4e44 100644 --- a/src/settings/app-server-data.ts +++ b/src/settings/app-server-data.ts @@ -1,5 +1,5 @@ -import type { AppServerClient } from "../app-server/client"; -import { listHookData, listModelMetadata, listThreads, type HookData } from "../app-server/resource-operations"; +import type { AppServerClient } from "../app-server/connection/client"; +import { listHookData, listModelMetadata, listThreads, type HookData } from "../app-server/services/resource-operations"; import type { ModelMetadata } from "../domain/catalog/metadata"; import type { Thread } from "../domain/threads/model"; import { errorMessage } from "../utils"; diff --git a/src/settings/tab.ts b/src/settings/tab.ts index 3f455d51..b9d561c0 100644 --- a/src/settings/tab.ts +++ b/src/settings/tab.ts @@ -1,8 +1,8 @@ import { type App, Notice, type Plugin, PluginSettingTab, Setting, setIcon } from "obsidian"; -import type { AppServerClient } from "../app-server/client"; -import { restoreArchivedThread, setHookItemEnabled, trustHookItem } from "../app-server/resource-operations"; -import { withShortLivedAppServerClient } from "../app-server/short-lived-client"; +import type { AppServerClient } from "../app-server/connection/client"; +import { restoreArchivedThread, setHookItemEnabled, trustHookItem } from "../app-server/services/resource-operations"; +import { withShortLivedAppServerClient } from "../app-server/connection/short-lived-client"; import { DEFAULT_CODEX_PATH } from "../constants"; import type { ReasoningEffort } from "../domain/catalog/metadata"; import type { HookItem, ModelMetadata } from "../domain/catalog/metadata"; diff --git a/src/workspace/thread-surface-coordinator.ts b/src/workspace/thread-surface-coordinator.ts index a08d89ed..0e0963e7 100644 --- a/src/workspace/thread-surface-coordinator.ts +++ b/src/workspace/thread-surface-coordinator.ts @@ -4,7 +4,7 @@ import { VIEW_TYPE_CODEX_THREADS } from "../constants"; import { CodexThreadsView } from "../features/threads-view/view"; import type { ModelMetadata } from "../domain/catalog/metadata"; import type { Thread } from "../domain/threads/model"; -import type { SharedAppServerMetadata } from "../app-server/shared-cache-state"; +import type { SharedAppServerMetadata } from "../app-server/services/shared-cache-state"; import type { WorkspacePanelCoordinator } from "./panel-coordinator"; export interface ThreadSurfaceCoordinatorOptions { diff --git a/tests/app-server/app-server-client.test.ts b/tests/app-server/app-server-client.test.ts index 983c4875..d7d0eb81 100644 --- a/tests/app-server/app-server-client.test.ts +++ b/tests/app-server/app-server-client.test.ts @@ -1,9 +1,9 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { AppServerClient } from "../../src/app-server/client"; -import type { AppServerRpcError, AppServerStartStructuredTurnOptions, AppServerStartTurnOptions } from "../../src/app-server/client"; -import type { AppServerTransport, AppServerTransportHandlers } from "../../src/app-server/transport"; -import type { RpcOutboundMessage } from "../../src/app-server/types"; +import { AppServerClient } from "../../src/app-server/connection/client"; +import type { AppServerRpcError, AppServerStartStructuredTurnOptions, AppServerStartTurnOptions } from "../../src/app-server/connection/client"; +import type { AppServerTransport, AppServerTransportHandlers } from "../../src/app-server/connection/transport"; +import type { RpcOutboundMessage } from "../../src/app-server/connection/rpc-messages"; import type { InitializeResponse } from "../../src/generated/app-server/InitializeResponse"; import type { ServerRequest } from "../../src/generated/app-server/ServerRequest"; import manifest from "../../manifest.json"; diff --git a/tests/app-server/app-server-diagnostics.test.ts b/tests/app-server/app-server-diagnostics.test.ts index 2633a732..76b9846f 100644 --- a/tests/app-server/app-server-diagnostics.test.ts +++ b/tests/app-server/app-server-diagnostics.test.ts @@ -9,8 +9,8 @@ import { createAppServerDiagnostics, shortErrorMessage, upsertMcpServerDiagnostic, -} from "../../src/app-server/diagnostics"; -import type { InitializeDiagnostics } from "../../src/app-server/diagnostics"; +} from "../../src/app-server/protocol/diagnostics"; +import type { InitializeDiagnostics } from "../../src/app-server/protocol/diagnostics"; describe("app-server diagnostics", () => { it("formats initialize metadata", () => { diff --git a/tests/app-server/catalog.test.ts b/tests/app-server/catalog.test.ts index db7c8a24..95588817 100644 --- a/tests/app-server/catalog.test.ts +++ b/tests/app-server/catalog.test.ts @@ -5,7 +5,7 @@ import { hookItemsFromCatalogHooks, modelMetadataFromCatalogModels, skillMetadataFromCatalogSkills, -} from "../../src/app-server/catalog"; +} from "../../src/app-server/protocol/catalog"; import type { HookMetadata } from "../../src/generated/app-server/v2/HookMetadata"; import type { Model } from "../../src/generated/app-server/v2/Model"; import type { SkillMetadata } from "../../src/generated/app-server/v2/SkillMetadata"; diff --git a/tests/app-server/connection-manager.test.ts b/tests/app-server/connection-manager.test.ts index 1db24914..2a657f1a 100644 --- a/tests/app-server/connection-manager.test.ts +++ b/tests/app-server/connection-manager.test.ts @@ -1,9 +1,9 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; -import { AppServerClient } from "../../src/app-server/client"; -import { ConnectionManager, StaleConnectionError } from "../../src/app-server/connection-manager"; -import type { AppServerTransport, AppServerTransportHandlers } from "../../src/app-server/transport"; -import type { RpcOutboundMessage } from "../../src/app-server/types"; +import { AppServerClient } from "../../src/app-server/connection/client"; +import { ConnectionManager, StaleConnectionError } from "../../src/app-server/connection/connection-manager"; +import type { AppServerTransport, AppServerTransportHandlers } from "../../src/app-server/connection/transport"; +import type { RpcOutboundMessage } from "../../src/app-server/connection/rpc-messages"; class SilentTransport implements AppServerTransport { readonly sent: RpcOutboundMessage[] = []; diff --git a/tests/app-server/ephemeral-structured-turn.test.ts b/tests/app-server/ephemeral-structured-turn.test.ts index 632e549c..11436437 100644 --- a/tests/app-server/ephemeral-structured-turn.test.ts +++ b/tests/app-server/ephemeral-structured-turn.test.ts @@ -6,12 +6,12 @@ import { runEphemeralStructuredTurn, type EphemeralStructuredTurnClient, type EphemeralStructuredTurnClientFactory, -} from "../../src/app-server/ephemeral-structured-turn"; +} from "../../src/app-server/services/ephemeral-structured-turn"; import type { AppServerClientHandlers, AppServerStartEphemeralThreadOptions, AppServerStartStructuredTurnOptions, -} from "../../src/app-server/client"; +} from "../../src/app-server/connection/client"; import type { InitializeResponse } from "../../src/generated/app-server/InitializeResponse"; import type { RequestId } from "../../src/generated/app-server/RequestId"; import type { ServerNotification } from "../../src/generated/app-server/ServerNotification"; @@ -20,7 +20,7 @@ import type { ModelListResponse } from "../../src/generated/app-server/v2/ModelL import type { Thread as ThreadRecord } from "../../src/generated/app-server/v2/Thread"; import type { ThreadStartResponse } from "../../src/generated/app-server/v2/ThreadStartResponse"; import type { TurnStartResponse } from "../../src/generated/app-server/v2/TurnStartResponse"; -import type { TurnItem, TurnRecord } from "../../src/app-server/turn"; +import type { TurnItem, TurnRecord } from "../../src/app-server/protocol/turn"; describe("runEphemeralStructuredTurn", () => { it("fills completed turn items from item completion notifications", async () => { diff --git a/tests/app-server/request-input.test.ts b/tests/app-server/request-input.test.ts index 0ce632d9..b5137594 100644 --- a/tests/app-server/request-input.test.ts +++ b/tests/app-server/request-input.test.ts @@ -5,7 +5,7 @@ import { codexTextInputWithMentions, toAppServerUserInput, type CodexInput, -} from "../../src/app-server/request-input"; +} from "../../src/app-server/protocol/request-input"; describe("app-server request input", () => { it("builds text input with mentions and skills", () => { diff --git a/tests/app-server/resource-operations.test.ts b/tests/app-server/resource-operations.test.ts index fa258238..5542a576 100644 --- a/tests/app-server/resource-operations.test.ts +++ b/tests/app-server/resource-operations.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from "vitest"; -import type { AppServerClient } from "../../src/app-server/client"; -import { listHookData, listSkillCatalog, listThreads } from "../../src/app-server/resource-operations"; +import type { AppServerClient } from "../../src/app-server/connection/client"; +import { listHookData, listSkillCatalog, listThreads } from "../../src/app-server/services/resource-operations"; describe("app-server resource operations", () => { it("maps listed threads to domain threads with archive state", async () => { diff --git a/tests/app-server/rollout-token-usage.test.ts b/tests/app-server/rollout-token-usage.test.ts index 13030bf9..c1b10897 100644 --- a/tests/app-server/rollout-token-usage.test.ts +++ b/tests/app-server/rollout-token-usage.test.ts @@ -5,7 +5,7 @@ import { recoverRolloutTokenUsage, ROLLOUT_TOKEN_USAGE_MAX_BASE64_BYTES, ROLLOUT_TOKEN_USAGE_READ_TIMEOUT_MS, -} from "../../src/app-server/rollout-token-usage"; +} from "../../src/app-server/services/rollout-token-usage"; describe("rollout token usage recovery", () => { it("parses the last valid token_count event", () => { diff --git a/tests/app-server/runtime-metrics.test.ts b/tests/app-server/runtime-metrics.test.ts new file mode 100644 index 00000000..7ef7f2d9 --- /dev/null +++ b/tests/app-server/runtime-metrics.test.ts @@ -0,0 +1,66 @@ +import { describe, expect, it } from "vitest"; + +import { + accountRateLimitsSummaryFromResponse, + rateLimitSnapshotFromAccountRateLimitsResponse, +} from "../../src/app-server/protocol/runtime-metrics"; + +type AccountRateLimitsResponse = Parameters[0]; +type AppServerRateLimitSnapshot = AccountRateLimitsResponse["rateLimits"]; + +describe("app-server runtime metrics", () => { + it("projects the codex rate limit bucket when multi-bucket limits are available", () => { + expect( + rateLimitSnapshotFromAccountRateLimitsResponse({ + rateLimits: appServerRateLimitFixture("legacy", 12), + rateLimitsByLimitId: { + other: appServerRateLimitFixture("other", 34), + codex: appServerRateLimitFixture("codex", 56), + }, + }), + ).toMatchObject({ limitId: "codex", primary: { usedPercent: 56 } }); + }); + + it("falls back to the legacy rate limit snapshot when no codex bucket is available", () => { + expect( + rateLimitSnapshotFromAccountRateLimitsResponse({ + rateLimits: appServerRateLimitFixture("legacy", 12), + rateLimitsByLimitId: { + other: appServerRateLimitFixture("other", 34), + }, + }), + ).toMatchObject({ limitId: "legacy", primary: { usedPercent: 12 } }); + }); + + it("summarizes account rate limit response availability", () => { + expect( + accountRateLimitsSummaryFromResponse({ + rateLimits: appServerRateLimitFixture("legacy", 12), + rateLimitsByLimitId: { + codex: appServerRateLimitFixture("codex", 56), + other: appServerRateLimitFixture("other", 34), + }, + }), + ).toBe("2 limits"); + + expect( + accountRateLimitsSummaryFromResponse({ + rateLimits: appServerRateLimitFixture("legacy", 12), + rateLimitsByLimitId: null, + }), + ).toBe("available"); + }); +}); + +function appServerRateLimitFixture(limitId: string, usedPercent: number): AppServerRateLimitSnapshot { + return { + limitId, + limitName: limitId, + primary: { usedPercent, windowDurationMins: 300, resetsAt: null }, + secondary: null, + credits: null, + individualLimit: null, + planType: null, + rateLimitReachedType: null, + }; +} diff --git a/tests/app-server/shared-cache-state.test.ts b/tests/app-server/shared-cache-state.test.ts index 3eb32859..0c5f93a7 100644 --- a/tests/app-server/shared-cache-state.test.ts +++ b/tests/app-server/shared-cache-state.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it } from "vitest"; -import { createAppServerDiagnostics } from "../../src/app-server/diagnostics"; -import type { RateLimitSnapshot } from "../../src/app-server/runtime-metrics"; -import { emptyRuntimeConfigSnapshot } from "../../src/app-server/runtime-config"; +import { createAppServerDiagnostics } from "../../src/app-server/protocol/diagnostics"; +import type { RateLimitSnapshot } from "../../src/app-server/protocol/runtime-metrics"; +import { emptyRuntimeConfigSnapshot } from "../../src/app-server/protocol/runtime-config"; import { applySharedAppServerMetadata, applySharedModels, @@ -13,7 +13,7 @@ import { createSharedAppServerState, sharedAppServerCacheContextIsComplete, type SharedAppServerCacheContext, -} from "../../src/app-server/shared-cache-state"; +} from "../../src/app-server/services/shared-cache-state"; import type { ModelMetadata } from "../../src/domain/catalog/metadata"; import type { Thread } from "../../src/domain/threads/model"; diff --git a/tests/app-server/shared-cache.test.ts b/tests/app-server/shared-cache.test.ts index 5bbb221a..2e240629 100644 --- a/tests/app-server/shared-cache.test.ts +++ b/tests/app-server/shared-cache.test.ts @@ -1,9 +1,9 @@ import { describe, expect, it, vi } from "vitest"; -import { createAppServerDiagnostics, diagnosticProbeError, diagnosticProbeOk } from "../../src/app-server/diagnostics"; -import { SharedAppServerCache } from "../../src/app-server/shared-cache"; -import { emptyRuntimeConfigSnapshot, type RuntimeConfigSnapshot } from "../../src/app-server/runtime-config"; -import type { SharedAppServerCacheContext, SharedAppServerMetadata } from "../../src/app-server/shared-cache-state"; +import { createAppServerDiagnostics, diagnosticProbeError, diagnosticProbeOk } from "../../src/app-server/protocol/diagnostics"; +import { SharedAppServerCache } from "../../src/app-server/services/shared-cache"; +import { emptyRuntimeConfigSnapshot, type RuntimeConfigSnapshot } from "../../src/app-server/protocol/runtime-config"; +import type { SharedAppServerCacheContext, SharedAppServerMetadata } from "../../src/app-server/services/shared-cache-state"; import type { ModelMetadata } from "../../src/domain/catalog/metadata"; describe("SharedAppServerCache", () => { diff --git a/tests/app-server/thread-activation.test.ts b/tests/app-server/thread-activation.test.ts index 584973e1..bfdb578e 100644 --- a/tests/app-server/thread-activation.test.ts +++ b/tests/app-server/thread-activation.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; -import { threadActivationSnapshotFromAppServerResponse } from "../../src/app-server/thread-activation"; +import { threadActivationSnapshotFromAppServerResponse } from "../../src/app-server/services/thread-activation"; import type { ThreadResumeResponse } from "../../src/generated/app-server/v2/ThreadResumeResponse"; import type { Thread as ThreadRecord } from "../../src/generated/app-server/v2/Thread"; diff --git a/tests/app-server/thread-goal.test.ts b/tests/app-server/thread-goal.test.ts index 775cd5a2..71b77ca0 100644 --- a/tests/app-server/thread-goal.test.ts +++ b/tests/app-server/thread-goal.test.ts @@ -4,7 +4,7 @@ import { appServerThreadGoalUpdate, appServerThreadGoalUserHistoryItem, threadGoalFromAppServerGoal, -} from "../../src/app-server/thread-goal"; +} from "../../src/app-server/protocol/thread-goal"; describe("app-server thread goal model", () => { it("maps app-server goals into panel-owned goal snapshots", () => { diff --git a/tests/app-server/thread-settings.test.ts b/tests/app-server/thread-settings.test.ts index dcad4d82..2c229359 100644 --- a/tests/app-server/thread-settings.test.ts +++ b/tests/app-server/thread-settings.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from "vitest"; -import { appServerCollaborationMode, applyThreadSettingsValue, type ThreadSettingsUpdate } from "../../src/app-server/thread-settings"; -import { appServerApprovalsReviewerOrNull, parseServiceTier } from "../../src/app-server/runtime-policy"; +import { appServerCollaborationMode, applyThreadSettingsValue, type ThreadSettingsUpdate } from "../../src/app-server/protocol/thread-settings"; +import { appServerApprovalsReviewerOrNull, parseServiceTier } from "../../src/app-server/protocol/runtime-policy"; describe("app-server thread settings", () => { it("applies defined thread setting values and omits undefined values", () => { diff --git a/tests/app-server/turn.test.ts b/tests/app-server/turn.test.ts index 043de84f..bf4a5285 100644 --- a/tests/app-server/turn.test.ts +++ b/tests/app-server/turn.test.ts @@ -2,12 +2,15 @@ import { describe, expect, it } from "vitest"; import { chronologicalConversationSummariesFromTurnRecords, + completedConversationSummariesFromTurnRecords, completedConversationSummaryFromTurnRecord, + conversationAssistantTextFromTurnRecord, lastAgentMessageTextFromTurnRecord, + transcriptEntriesFromTurnRecords, transcriptEntriesFromTurnRecord, type TurnItem, type TurnRecord, -} from "../../src/app-server/turn"; +} from "../../src/app-server/protocol/turn"; describe("app-server turn records", () => { it("projects readable transcript entries without command log items", () => { @@ -44,6 +47,16 @@ describe("app-server turn records", () => { ).toBeNull(); }); + it("projects completed summaries from turn lists without exposing filtering logic to callers", () => { + expect( + completedConversationSummariesFromTurnRecords([ + turn([userMessage("u1", "依頼"), agentMessage("a1", "回答")], { id: "completed" }), + turn([userMessage("u2", "失敗した依頼"), agentMessage("a2", "失敗した回答")], { id: "failed", status: "failed" }), + turn([commandItem("cmd")], { id: "empty" }), + ]), + ).toEqual([{ userText: "依頼", assistantText: "回答" }]); + }); + it("returns chronological summaries and drops turns without conversation text", () => { expect( chronologicalConversationSummariesFromTurnRecords([ @@ -57,6 +70,22 @@ describe("app-server turn records", () => { ]); }); + it("projects transcript entries from turn lists", () => { + expect( + transcriptEntriesFromTurnRecords([ + turn([userMessage("u1", "先の依頼")], { id: "turn-1", startedAt: 10 }), + turn([agentMessage("a1", "後の回答")], { id: "turn-2", startedAt: 20, completedAt: 25 }), + ]), + ).toEqual([ + { kind: "user", text: "先の依頼", timestamp: 10 }, + { kind: "assistant", text: "後の回答", timestamp: 25 }, + ]); + }); + + it("extracts assistant-like conversation text for generated turn consumers", () => { + expect(conversationAssistantTextFromTurnRecord(turn([userMessage("u1", "依頼"), planItem("p1", "計画")]))).toBe("計画"); + }); + it("extracts the final non-empty agent message text from a turn", () => { expect( lastAgentMessageTextFromTurnRecord( diff --git a/tests/features/chat/connection/connection-controller.test.ts b/tests/features/chat/connection/connection-controller.test.ts index 801ffe16..046279aa 100644 --- a/tests/features/chat/connection/connection-controller.test.ts +++ b/tests/features/chat/connection/connection-controller.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from "vitest"; -import type { AppServerClient } from "../../../../src/app-server/client"; -import { emptyRuntimeConfigSnapshot } from "../../../../src/app-server/runtime-config"; +import type { AppServerClient } from "../../../../src/app-server/connection/client"; +import { emptyRuntimeConfigSnapshot } from "../../../../src/app-server/protocol/runtime-config"; import { createChatState, createChatStateStore } from "../../../../src/features/chat/state/reducer"; import { ChatConnectionController, diff --git a/tests/features/chat/connection/server-actions/server-actions.test.ts b/tests/features/chat/connection/server-actions/server-actions.test.ts index de8d3309..9caa6467 100644 --- a/tests/features/chat/connection/server-actions/server-actions.test.ts +++ b/tests/features/chat/connection/server-actions/server-actions.test.ts @@ -1,15 +1,15 @@ import { describe, expect, it, vi } from "vitest"; -import type { AppServerClient } from "../../../../../src/app-server/client"; -import type { McpServerStatus } from "../../../../../src/app-server/diagnostics"; -import { emptyRuntimeConfigSnapshot } from "../../../../../src/app-server/runtime-config"; -import type { RateLimitSnapshot } from "../../../../../src/app-server/runtime-metrics"; -import { threadFromThreadRecord } from "../../../../../src/app-server/thread"; +import type { AppServerClient } from "../../../../../src/app-server/connection/client"; +import type { McpServerStatus } from "../../../../../src/app-server/protocol/diagnostics"; +import { emptyRuntimeConfigSnapshot } from "../../../../../src/app-server/protocol/runtime-config"; +import type { RateLimitSnapshot } from "../../../../../src/app-server/protocol/runtime-metrics"; +import { threadFromThreadRecord } from "../../../../../src/app-server/protocol/thread"; import { createChatServerDiagnosticsActions } from "../../../../../src/features/chat/connection/server-actions/diagnostics"; import { createChatServerMetadataActions } from "../../../../../src/features/chat/connection/server-actions/metadata"; import { createChatServerThreadActions } from "../../../../../src/features/chat/connection/server-actions/threads"; import { createChatState, createChatStateStore } from "../../../../../src/features/chat/state/reducer"; -import type { CatalogModel, CatalogSkillMetadata } from "../../../../../src/app-server/catalog"; +import type { CatalogModel, CatalogSkillMetadata } from "../../../../../src/app-server/protocol/catalog"; type ThreadStartResponse = Awaited>; diff --git a/tests/features/chat/conversation/pending-requests/controller.test.ts b/tests/features/chat/conversation/pending-requests/controller.test.ts index 6bdfa1a0..638bfbd6 100644 --- a/tests/features/chat/conversation/pending-requests/controller.test.ts +++ b/tests/features/chat/conversation/pending-requests/controller.test.ts @@ -4,7 +4,7 @@ import { ChatInboundController } from "../../../../../src/features/chat/protocol import { createChatState, createChatStateStore } from "../../../../../src/features/chat/state/reducer"; import { PendingRequestController } from "../../../../../src/features/chat/conversation/pending-requests/controller"; import { toPendingUserInput } from "../../../../../src/features/chat/protocol/server-requests/user-input"; -import type { ServerRequest } from "../../../../../src/app-server/types"; +import type { ServerRequest } from "../../../../../src/app-server/connection/rpc-messages"; function expectPresent(value: T | null | undefined): T { if (value === null || value === undefined) throw new Error("Expected value to be present"); diff --git a/tests/features/chat/conversation/turns/composer-submit-actions.test.ts b/tests/features/chat/conversation/turns/composer-submit-actions.test.ts index 8d752c87..fc5cbb7e 100644 --- a/tests/features/chat/conversation/turns/composer-submit-actions.test.ts +++ b/tests/features/chat/conversation/turns/composer-submit-actions.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from "vitest"; -import type { AppServerClient } from "../../../../../src/app-server/client"; +import type { AppServerClient } from "../../../../../src/app-server/connection/client"; import { createChatState, createChatStateStore } from "../../../../../src/features/chat/state/reducer"; import { createComposerSubmitActions } from "../../../../../src/features/chat/conversation/turns/composer-submit-actions"; import type { Thread } from "../../../../../src/domain/threads/model"; diff --git a/tests/features/chat/conversation/turns/plan-implementation.test.ts b/tests/features/chat/conversation/turns/plan-implementation.test.ts index 9d36641a..9ac91f10 100644 --- a/tests/features/chat/conversation/turns/plan-implementation.test.ts +++ b/tests/features/chat/conversation/turns/plan-implementation.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from "vitest"; -import type { AppServerClient } from "../../../../../src/app-server/client"; +import type { AppServerClient } from "../../../../../src/app-server/connection/client"; import { createChatState, createChatStateStore, type ChatStateStore } from "../../../../../src/features/chat/state/reducer"; import { implementPlanCandidateFromState } from "../../../../../src/features/chat/state/selectors"; import { diff --git a/tests/features/chat/conversation/turns/slash-command-execution.test.ts b/tests/features/chat/conversation/turns/slash-command-execution.test.ts index 943a8857..ef1d45fb 100644 --- a/tests/features/chat/conversation/turns/slash-command-execution.test.ts +++ b/tests/features/chat/conversation/turns/slash-command-execution.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from "vitest"; -import type { ThreadGoal } from "../../../../../src/app-server/thread-goal"; +import type { ThreadGoal } from "../../../../../src/app-server/protocol/thread-goal"; import { slashCommandHelpLines, slashCommandHelpSections } from "../../../../../src/features/chat/conversation/composer/slash-commands"; import type { Thread } from "../../../../../src/domain/threads/model"; import { diff --git a/tests/features/chat/conversation/turns/slash-command-handler.test.ts b/tests/features/chat/conversation/turns/slash-command-handler.test.ts index 6945314e..8316968f 100644 --- a/tests/features/chat/conversation/turns/slash-command-handler.test.ts +++ b/tests/features/chat/conversation/turns/slash-command-handler.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from "vitest"; -import type { AppServerClient } from "../../../../../src/app-server/client"; -import type { CodexInput } from "../../../../../src/app-server/request-input"; +import type { AppServerClient } from "../../../../../src/app-server/connection/client"; +import type { CodexInput } from "../../../../../src/app-server/protocol/request-input"; import { createChatState, createChatStateStore } from "../../../../../src/features/chat/state/reducer"; import { createSlashCommandHandler, diff --git a/tests/features/chat/conversation/turns/turn-submission-controller.test.ts b/tests/features/chat/conversation/turns/turn-submission-controller.test.ts index 2ec039ad..8e56e77d 100644 --- a/tests/features/chat/conversation/turns/turn-submission-controller.test.ts +++ b/tests/features/chat/conversation/turns/turn-submission-controller.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from "vitest"; -import type { AppServerClient } from "../../../../../src/app-server/client"; -import type { CodexInput } from "../../../../../src/app-server/request-input"; +import type { AppServerClient } from "../../../../../src/app-server/connection/client"; +import type { CodexInput } from "../../../../../src/app-server/protocol/request-input"; import { createChatState, createChatStateStore } from "../../../../../src/features/chat/state/reducer"; import { TurnSubmissionController, diff --git a/tests/features/chat/diagnostics.test.ts b/tests/features/chat/diagnostics.test.ts index 174bff54..82f83d0e 100644 --- a/tests/features/chat/diagnostics.test.ts +++ b/tests/features/chat/diagnostics.test.ts @@ -6,7 +6,7 @@ import { createAppServerDiagnostics, upsertMcpServerDiagnostic, upsertMcpServerStatusDiagnostics, -} from "../../../src/app-server/diagnostics"; +} from "../../../src/app-server/protocol/diagnostics"; import { connectionDiagnosticSections, hasDiagnosticIssue } from "../../../src/features/chat/display/status/diagnostics"; describe("connection diagnostics", () => { diff --git a/tests/features/chat/display/display-model.test.ts b/tests/features/chat/display/display-model.test.ts index c07545b6..a23ad840 100644 --- a/tests/features/chat/display/display-model.test.ts +++ b/tests/features/chat/display/display-model.test.ts @@ -29,7 +29,7 @@ import { displayItemFromTurnItem, displayItemsFromTurns } from "../../../../src/ import { referencedThreadPrompt } from "../../../../src/domain/threads/reference"; import type { DisplayItem } from "../../../../src/features/chat/display/types"; import type { Thread } from "../../../../src/domain/threads/model"; -import type { TurnItem, TurnRecord } from "../../../../src/app-server/turn"; +import type { TurnItem, TurnRecord } from "../../../../src/app-server/protocol/turn"; function expectPresent(value: T | null | undefined): T { if (value === null || value === undefined) throw new Error("Expected value to be present"); diff --git a/tests/features/chat/display/items/goal.test.ts b/tests/features/chat/display/items/goal.test.ts index 6ffcb326..5733af22 100644 --- a/tests/features/chat/display/items/goal.test.ts +++ b/tests/features/chat/display/items/goal.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; -import type { ThreadGoal } from "../../../../../src/app-server/thread-goal"; +import type { ThreadGoal } from "../../../../../src/app-server/protocol/thread-goal"; import { goalChangeItem } from "../../../../../src/features/chat/display/items/goal"; describe("goal display items", () => { diff --git a/tests/features/chat/mcp-status.test.ts b/tests/features/chat/mcp-status.test.ts index 8b78679d..df51dfcd 100644 --- a/tests/features/chat/mcp-status.test.ts +++ b/tests/features/chat/mcp-status.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; -import type { McpServerStatusSummary } from "../../../src/app-server/diagnostics"; +import type { McpServerStatusSummary } from "../../../src/app-server/protocol/diagnostics"; import { mcpStatusLines } from "../../../src/features/chat/display/status/diagnostics"; function mcpServer(overrides: Partial = {}): McpServerStatusSummary { diff --git a/tests/features/chat/panel/cached-app-server-state.test.ts b/tests/features/chat/panel/cached-app-server-state.test.ts index 3e0e8ec4..d65ddab3 100644 --- a/tests/features/chat/panel/cached-app-server-state.test.ts +++ b/tests/features/chat/panel/cached-app-server-state.test.ts @@ -1,9 +1,9 @@ import { describe, expect, it, vi } from "vitest"; -import { createAppServerDiagnostics } from "../../../../src/app-server/diagnostics"; -import { emptyRuntimeConfigSnapshot } from "../../../../src/app-server/runtime-config"; +import { createAppServerDiagnostics } from "../../../../src/app-server/protocol/diagnostics"; +import { emptyRuntimeConfigSnapshot } from "../../../../src/app-server/protocol/runtime-config"; import { applyCachedSharedAppServerState } from "../../../../src/features/chat/panel/cached-app-server-state"; -import type { SharedAppServerMetadata } from "../../../../src/app-server/shared-cache-state"; +import type { SharedAppServerMetadata } from "../../../../src/app-server/services/shared-cache-state"; import type { Thread } from "../../../../src/domain/threads/model"; describe("cached app-server state", () => { diff --git a/tests/features/chat/protocol/inbound/controller.test.ts b/tests/features/chat/protocol/inbound/controller.test.ts index 41c9f719..4f35da4b 100644 --- a/tests/features/chat/protocol/inbound/controller.test.ts +++ b/tests/features/chat/protocol/inbound/controller.test.ts @@ -12,9 +12,9 @@ import { type ChatState, type ChatStateStore, } from "../../../../../src/features/chat/state/reducer"; -import type { ServerNotification, ServerRequest } from "../../../../../src/app-server/types"; +import type { ServerNotification, ServerRequest } from "../../../../../src/app-server/connection/rpc-messages"; import type { Thread as PanelThread } from "../../../../../src/domain/threads/model"; -import type { TurnRecord } from "../../../../../src/app-server/turn"; +import type { TurnRecord } from "../../../../../src/app-server/protocol/turn"; type ThreadStartedNotification = Extract; diff --git a/tests/features/chat/protocol/inbound/routing.test.ts b/tests/features/chat/protocol/inbound/routing.test.ts index 6e1bfd06..eb6397ae 100644 --- a/tests/features/chat/protocol/inbound/routing.test.ts +++ b/tests/features/chat/protocol/inbound/routing.test.ts @@ -7,7 +7,7 @@ import { routeServerNotification, routeServerRequest, } from "../../../../../src/features/chat/protocol/inbound/routing"; -import type { ServerNotification, ServerRequest } from "../../../../../src/app-server/types"; +import type { ServerNotification, ServerRequest } from "../../../../../src/app-server/connection/rpc-messages"; const activeScope = { activeThreadId: "thread-active", activeTurnId: "turn-active" }; diff --git a/tests/features/chat/protocol/server-requests/approval.test.ts b/tests/features/chat/protocol/server-requests/approval.test.ts index 99e296e8..534dac97 100644 --- a/tests/features/chat/protocol/server-requests/approval.test.ts +++ b/tests/features/chat/protocol/server-requests/approval.test.ts @@ -9,7 +9,7 @@ import { toPendingApproval, type CommandApprovalDecision, } from "../../../../../src/features/chat/protocol/server-requests/approval"; -import type { ServerRequest } from "../../../../../src/app-server/types"; +import type { ServerRequest } from "../../../../../src/app-server/connection/rpc-messages"; function expectPresent(value: T | null | undefined): T { if (value === null || value === undefined) throw new Error("Expected value to be present"); diff --git a/tests/features/chat/protocol/server-requests/responder.test.ts b/tests/features/chat/protocol/server-requests/responder.test.ts index 2609b42e..87570479 100644 --- a/tests/features/chat/protocol/server-requests/responder.test.ts +++ b/tests/features/chat/protocol/server-requests/responder.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from "vitest"; -import type { AppServerClient } from "../../../../../src/app-server/client"; +import type { AppServerClient } from "../../../../../src/app-server/connection/client"; import { rejectServerRequest, respondToServerRequest } from "../../../../../src/features/chat/protocol/server-requests/responder"; describe("server request responder", () => { diff --git a/tests/features/chat/protocol/server-requests/user-input.test.ts b/tests/features/chat/protocol/server-requests/user-input.test.ts index 3a4d3c22..738b3ff4 100644 --- a/tests/features/chat/protocol/server-requests/user-input.test.ts +++ b/tests/features/chat/protocol/server-requests/user-input.test.ts @@ -10,7 +10,7 @@ import { pendingRequestFocusSignature, pendingRequestsSignature, } from "../../../../../src/features/chat/conversation/pending-requests/signatures"; -import type { ServerRequest } from "../../../../../src/app-server/types"; +import type { ServerRequest } from "../../../../../src/app-server/connection/rpc-messages"; function expectPresent(value: T | null | undefined): T { if (value === null || value === undefined) throw new Error("Expected value to be present"); diff --git a/tests/features/chat/runtime/settings-actions.test.ts b/tests/features/chat/runtime/settings-actions.test.ts index 76bb530c..0e34b232 100644 --- a/tests/features/chat/runtime/settings-actions.test.ts +++ b/tests/features/chat/runtime/settings-actions.test.ts @@ -4,8 +4,8 @@ import { createChatRuntimeSettingsActions, type ChatRuntimeSettingsActions } fro import { createChatState, createChatStateStore, type ChatState } from "../../../../src/features/chat/state/reducer"; import { runtimeSnapshotForChatState } from "../../../../src/features/chat/runtime/snapshot"; import type { ActiveThreadSettingsAppliedAction } from "../../../../src/features/chat/state/actions"; -import type { AppServerClient } from "../../../../src/app-server/client"; -import { emptyRuntimeConfigSnapshot } from "../../../../src/app-server/runtime-config"; +import type { AppServerClient } from "../../../../src/app-server/connection/client"; +import { emptyRuntimeConfigSnapshot } from "../../../../src/app-server/protocol/runtime-config"; import type { ModelMetadata } from "../../../../src/domain/catalog/metadata"; describe("createChatRuntimeSettingsActions", () => { diff --git a/tests/features/chat/state-reducer.test.ts b/tests/features/chat/state-reducer.test.ts index b9b320ac..e7197d47 100644 --- a/tests/features/chat/state-reducer.test.ts +++ b/tests/features/chat/state-reducer.test.ts @@ -10,7 +10,7 @@ import { transitionChatTurnLifecycleState, type ChatState, } from "../../../src/features/chat/state/reducer"; -import type { ThreadGoal } from "../../../src/app-server/thread-goal"; +import type { ThreadGoal } from "../../../src/app-server/protocol/thread-goal"; import type { DisplayItem } from "../../../src/features/chat/display/types"; import type { Thread } from "../../../src/domain/threads/model"; diff --git a/tests/features/chat/threads/actions.test.ts b/tests/features/chat/threads/actions.test.ts index d2560bd3..6a92802d 100644 --- a/tests/features/chat/threads/actions.test.ts +++ b/tests/features/chat/threads/actions.test.ts @@ -1,7 +1,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; -import type { AppServerClient } from "../../../../src/app-server/client"; -import type { ThreadRecord } from "../../../../src/app-server/thread"; +import type { AppServerClient } from "../../../../src/app-server/connection/client"; +import type { ThreadRecord } from "../../../../src/app-server/protocol/thread"; import type { ArchiveExportAdapter } from "../../../../src/features/thread-export/archive-markdown"; import { createChatState, createChatStateStore } from "../../../../src/features/chat/state/reducer"; import { createChatThreadActions, type ChatThreadActionsHost } from "../../../../src/features/chat/threads/actions"; diff --git a/tests/features/chat/threads/auto-title-controller.test.ts b/tests/features/chat/threads/auto-title-controller.test.ts index 94badfd0..87ce2c74 100644 --- a/tests/features/chat/threads/auto-title-controller.test.ts +++ b/tests/features/chat/threads/auto-title-controller.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from "vitest"; -import type { AppServerClient } from "../../../../src/app-server/client"; +import type { AppServerClient } from "../../../../src/app-server/connection/client"; import { createChatStateStore } from "../../../../src/features/chat/state/reducer"; import { AutoTitleController } from "../../../../src/features/chat/threads/auto-title-controller"; import type { Thread } from "../../../../src/domain/threads/model"; diff --git a/tests/features/chat/threads/goal-actions.test.ts b/tests/features/chat/threads/goal-actions.test.ts index 039e1aeb..9545eafb 100644 --- a/tests/features/chat/threads/goal-actions.test.ts +++ b/tests/features/chat/threads/goal-actions.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from "vitest"; -import type { AppServerClient } from "../../../../src/app-server/client"; -import type { ThreadGoal } from "../../../../src/app-server/thread-goal"; +import type { AppServerClient } from "../../../../src/app-server/connection/client"; +import type { ThreadGoal } from "../../../../src/app-server/protocol/thread-goal"; import { createGoalActions } from "../../../../src/features/chat/threads/goal-actions"; import { createChatState, createChatStateStore } from "../../../../src/features/chat/state/reducer"; import { deferred } from "../../../support/async"; diff --git a/tests/features/chat/threads/history-controller.test.ts b/tests/features/chat/threads/history-controller.test.ts index 37b516cc..3cb00c3f 100644 --- a/tests/features/chat/threads/history-controller.test.ts +++ b/tests/features/chat/threads/history-controller.test.ts @@ -2,8 +2,8 @@ import { describe, expect, it, vi } from "vitest"; import { createChatState, createChatStateStore } from "../../../../src/features/chat/state/reducer"; import { HistoryController } from "../../../../src/features/chat/threads/history-controller"; -import type { AppServerClient } from "../../../../src/app-server/client"; -import type { TurnItem, TurnRecord } from "../../../../src/app-server/turn"; +import type { AppServerClient } from "../../../../src/app-server/connection/client"; +import type { TurnItem, TurnRecord } from "../../../../src/app-server/protocol/turn"; import { deferred } from "../../../support/async"; describe("HistoryController", () => { diff --git a/tests/features/chat/threads/rename-controller.test.ts b/tests/features/chat/threads/rename-controller.test.ts index 1658c0c2..ddd00281 100644 --- a/tests/features/chat/threads/rename-controller.test.ts +++ b/tests/features/chat/threads/rename-controller.test.ts @@ -2,9 +2,9 @@ import { describe, expect, it, vi } from "vitest"; import { createChatStateStore } from "../../../../src/features/chat/state/reducer"; import { RenameController } from "../../../../src/features/chat/threads/rename-controller"; -import type { AppServerClient } from "../../../../src/app-server/client"; +import type { AppServerClient } from "../../../../src/app-server/connection/client"; import type { Thread } from "../../../../src/domain/threads/model"; -import type { TurnItem, TurnRecord } from "../../../../src/app-server/turn"; +import type { TurnItem, TurnRecord } from "../../../../src/app-server/protocol/turn"; import { DEFAULT_SETTINGS } from "../../../../src/settings/model"; import { deferred } from "../../../support/async"; diff --git a/tests/features/chat/threads/resume-controller.test.ts b/tests/features/chat/threads/resume-controller.test.ts index 6246862e..57cf0c2b 100644 --- a/tests/features/chat/threads/resume-controller.test.ts +++ b/tests/features/chat/threads/resume-controller.test.ts @@ -1,14 +1,14 @@ import { describe, expect, it, vi } from "vitest"; -import type { AppServerClient } from "../../../../src/app-server/client"; +import type { AppServerClient } from "../../../../src/app-server/connection/client"; import { createChatState, createChatStateStore } from "../../../../src/features/chat/state/reducer"; import type { RestorationController } from "../../../../src/features/chat/threads/restoration-controller"; import { ResumeController } from "../../../../src/features/chat/threads/resume-controller"; import type { HistoryController } from "../../../../src/features/chat/threads/history-controller"; import { ChatResumeWorkTracker } from "../../../../src/features/chat/lifecycle"; import type { Thread as PanelThread } from "../../../../src/domain/threads/model"; -import type { ThreadTokenUsage } from "../../../../src/app-server/runtime-metrics"; -import type { TurnItem, TurnRecord } from "../../../../src/app-server/turn"; +import type { ThreadTokenUsage } from "../../../../src/app-server/protocol/runtime-metrics"; +import type { TurnItem, TurnRecord } from "../../../../src/app-server/protocol/turn"; type ThreadResumeResponse = Awaited>; diff --git a/tests/features/chat/threads/resume.test.ts b/tests/features/chat/threads/resume.test.ts index 885391a0..98c43c71 100644 --- a/tests/features/chat/threads/resume.test.ts +++ b/tests/features/chat/threads/resume.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; -import type { ThreadActivationSnapshot } from "../../../../src/app-server/thread-activation"; +import type { ThreadActivationSnapshot } from "../../../../src/app-server/services/thread-activation"; import { resumedThreadAction } from "../../../../src/features/chat/threads/resume"; import type { Thread } from "../../../../src/domain/threads/model"; diff --git a/tests/features/chat/ui/renderers/goal-banner.test.tsx b/tests/features/chat/ui/renderers/goal-banner.test.tsx index 75a3ba2b..4a11e01e 100644 --- a/tests/features/chat/ui/renderers/goal-banner.test.tsx +++ b/tests/features/chat/ui/renderers/goal-banner.test.tsx @@ -3,7 +3,7 @@ import { describe, expect, it, vi } from "vitest"; import { act } from "preact/test-utils"; -import type { ThreadGoal } from "../../../../../src/app-server/thread-goal"; +import type { ThreadGoal } from "../../../../../src/app-server/protocol/thread-goal"; import { goalBannerNode, type GoalBannerActions } from "../../../../../src/features/chat/ui/goal-banner"; import type { SendShortcut } from "../../../../../src/shared/ui/keyboard"; import { renderUiRoot } from "../../../../../src/shared/ui/ui-root"; diff --git a/tests/features/chat/view-connection.test.ts b/tests/features/chat/view-connection.test.ts index d3463892..4e132275 100644 --- a/tests/features/chat/view-connection.test.ts +++ b/tests/features/chat/view-connection.test.ts @@ -4,11 +4,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { DEFAULT_SETTINGS } from "../../../src/settings/model"; import type { CodexChatHost } from "../../../src/features/chat/chat-host"; -import { createAppServerDiagnostics } from "../../../src/app-server/diagnostics"; -import { emptyRuntimeConfigSnapshot } from "../../../src/app-server/runtime-config"; -import { threadFromThreadRecord, type ThreadRecord } from "../../../src/app-server/thread"; +import { createAppServerDiagnostics } from "../../../src/app-server/protocol/diagnostics"; +import { emptyRuntimeConfigSnapshot } from "../../../src/app-server/protocol/runtime-config"; +import { threadFromThreadRecord, type ThreadRecord } from "../../../src/app-server/protocol/thread"; import type { ChatState } from "../../../src/features/chat/state/reducer"; -import type { ServerNotification } from "../../../src/app-server/types"; +import type { ServerNotification } from "../../../src/app-server/connection/rpc-messages"; import { notices } from "../../mocks/obsidian"; import { deferred, waitForAsyncWork } from "../../support/async"; import { installObsidianDomShims } from "../../support/dom"; @@ -34,7 +34,7 @@ const connectionMock = vi.hoisted(() => { }; }); -vi.mock("../../../src/app-server/connection-manager", () => { +vi.mock("../../../src/app-server/connection/connection-manager", () => { class StaleConnectionError extends Error {} class ConnectionManager { diff --git a/tests/features/chat/view-model.test.ts b/tests/features/chat/view-model.test.ts index d48b9aed..5ea3fdeb 100644 --- a/tests/features/chat/view-model.test.ts +++ b/tests/features/chat/view-model.test.ts @@ -1,11 +1,11 @@ import { describe, expect, it, vi } from "vitest"; -import { createAppServerDiagnostics } from "../../../src/app-server/diagnostics"; +import { createAppServerDiagnostics } from "../../../src/app-server/protocol/diagnostics"; import { runtimeConfigSnapshotFromAppServerConfig, type ConfigReadResult, type RuntimeConfigSnapshot, -} from "../../../src/app-server/runtime-config"; +} from "../../../src/app-server/protocol/runtime-config"; import { createChatState } from "../../../src/features/chat/state/reducer"; import { composerMetaViewModel, composerPlaceholder } from "../../../src/features/chat/panel/regions/composer"; import { effortStatusLines, modelStatusLines, statusSummaryLines } from "../../../src/features/chat/display/status/runtime"; @@ -18,7 +18,7 @@ import type { Thread } from "../../../src/domain/threads/model"; import { chatPanelComposerMetaViewModel, chatPanelComposerPlaceholder } from "../../../src/features/chat/panel/regions/composer"; import { chatPanelGoalProps } from "../../../src/features/chat/panel/regions/goal"; import type { ChatPanelComposerPorts, ChatPanelGoalPorts } from "../../../src/features/chat/panel/regions/ports"; -import type { ThreadGoal } from "../../../src/app-server/thread-goal"; +import type { ThreadGoal } from "../../../src/app-server/protocol/thread-goal"; describe("chat view model", () => { it("builds toolbar rows from immutable chat state snapshots", () => { diff --git a/tests/features/selection-rewrite/selection-rewrite.test.ts b/tests/features/selection-rewrite/selection-rewrite.test.ts index 8a43faec..99cecbe8 100644 --- a/tests/features/selection-rewrite/selection-rewrite.test.ts +++ b/tests/features/selection-rewrite/selection-rewrite.test.ts @@ -25,10 +25,10 @@ import { type SelectionRewriteClient, type SelectionRewriteClientFactory, } from "../../../src/features/selection-rewrite/runner"; -import type { AppServerClient, AppServerClientHandlers, AppServerStartStructuredTurnOptions } from "../../../src/app-server/client"; -import type { AppServerInitialization } from "../../../src/app-server/initialization"; -import type { RequestId, ServerNotification } from "../../../src/app-server/types"; -import type { TurnItem, TurnRecord } from "../../../src/app-server/turn"; +import type { AppServerClient, AppServerClientHandlers, AppServerStartStructuredTurnOptions } from "../../../src/app-server/connection/client"; +import type { AppServerInitialization } from "../../../src/app-server/protocol/initialization"; +import type { RequestId, ServerNotification } from "../../../src/app-server/connection/rpc-messages"; +import type { TurnItem, TurnRecord } from "../../../src/app-server/protocol/turn"; import type { ModelMetadata, ReasoningEffort } from "../../../src/domain/catalog/metadata"; import type { ComposerSendKeyEvent } from "../../../src/shared/ui/keyboard"; import { deferred } from "../../support/async"; diff --git a/tests/features/thread-title/thread-title.test.ts b/tests/features/thread-title/thread-title.test.ts index ff0ad8e1..8e88cb09 100644 --- a/tests/features/thread-title/thread-title.test.ts +++ b/tests/features/thread-title/thread-title.test.ts @@ -1,10 +1,10 @@ import { describe, expect, it } from "vitest"; -import type { AppServerClient, AppServerClientHandlers, AppServerStartStructuredTurnOptions } from "../../../src/app-server/client"; -import { modelMetadataFromCatalogModels, type CatalogModel } from "../../../src/app-server/catalog"; -import type { AppServerInitialization } from "../../../src/app-server/initialization"; -import type { TurnItem, TurnRecord } from "../../../src/app-server/turn"; -import type { RequestId, ServerNotification } from "../../../src/app-server/types"; +import type { AppServerClient, AppServerClientHandlers, AppServerStartStructuredTurnOptions } from "../../../src/app-server/connection/client"; +import { modelMetadataFromCatalogModels, type CatalogModel } from "../../../src/app-server/protocol/catalog"; +import type { AppServerInitialization } from "../../../src/app-server/protocol/initialization"; +import type { TurnItem, TurnRecord } from "../../../src/app-server/protocol/turn"; +import type { RequestId, ServerNotification } from "../../../src/app-server/connection/rpc-messages"; import { generateThreadTitleWithCodex, threadTitleFromGenerationTurn, diff --git a/tests/features/threads-view/view.test.ts b/tests/features/threads-view/view.test.ts index 1b2bf187..64b2a0fa 100644 --- a/tests/features/threads-view/view.test.ts +++ b/tests/features/threads-view/view.test.ts @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import { DEFAULT_SETTINGS } from "../../../src/settings/model"; -import type { TurnRecord } from "../../../src/app-server/turn"; +import type { TurnRecord } from "../../../src/app-server/protocol/turn"; import type * as ThreadTitleGeneratorModule from "../../../src/features/thread-title/generation"; import { deferred, waitForAsyncWork } from "../../support/async"; import { changeInputValue, installObsidianDomShims } from "../../support/dom"; @@ -31,7 +31,7 @@ const namingMock = vi.hoisted(() => ({ generateThreadTitleWithCodex: vi.fn(), })); -vi.mock("../../../src/app-server/connection-manager", () => { +vi.mock("../../../src/app-server/connection/connection-manager", () => { class StaleConnectionError extends Error {} class ConnectionManager { diff --git a/tests/main.test.ts b/tests/main.test.ts index 34ad3ad1..1047993c 100644 --- a/tests/main.test.ts +++ b/tests/main.test.ts @@ -9,8 +9,8 @@ import type CodexPanelPlugin from "../src/main"; import type { CodexChatView } from "../src/features/chat/view"; import type { CodexChatHost } from "../src/features/chat/chat-host"; import type { Thread } from "../src/domain/threads/model"; -import type { SharedAppServerCache } from "../src/app-server/shared-cache"; -import type { SharedAppServerCacheContext } from "../src/app-server/shared-cache-state"; +import type { SharedAppServerCache } from "../src/app-server/services/shared-cache"; +import type { SharedAppServerCacheContext } from "../src/app-server/services/shared-cache-state"; import type { WorkspacePanelCoordinator } from "../src/workspace/panel-coordinator"; import type { ThreadSurfaceCoordinator } from "../src/workspace/thread-surface-coordinator"; import { installObsidianDomShims } from "./support/dom"; diff --git a/tests/runtime/runtime-settings.test.ts b/tests/runtime/runtime-settings.test.ts index 65ee1a2f..acdbbb0c 100644 --- a/tests/runtime/runtime-settings.test.ts +++ b/tests/runtime/runtime-settings.test.ts @@ -4,7 +4,7 @@ import { runtimeConfigSnapshotFromAppServerConfig, type ConfigReadResult, type RuntimeConfigSnapshot, -} from "../../src/app-server/runtime-config"; +} from "../../src/app-server/protocol/runtime-config"; import type { ModelMetadata } from "../../src/domain/catalog/metadata"; import { compactModelLabel, diff --git a/tests/settings/settings-lifecycle.test.ts b/tests/settings/settings-lifecycle.test.ts index 07a08caf..73a4607b 100644 --- a/tests/settings/settings-lifecycle.test.ts +++ b/tests/settings/settings-lifecycle.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from "vitest"; -import type { AppServerClient } from "../../src/app-server/client"; +import type { AppServerClient } from "../../src/app-server/connection/client"; import { loadHookData, loadSettingsData } from "../../src/settings/app-server-data"; import { createSettingsDynamicSectionLifecycle, diff --git a/tests/settings/settings-tab.test.ts b/tests/settings/settings-tab.test.ts index aaa5bc54..be8c2215 100644 --- a/tests/settings/settings-tab.test.ts +++ b/tests/settings/settings-tab.test.ts @@ -2,10 +2,10 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; -import type { CatalogHookMetadata, CatalogModel } from "../../src/app-server/catalog"; -import type { ThreadRecord } from "../../src/app-server/thread"; +import type { CatalogHookMetadata, CatalogModel } from "../../src/app-server/protocol/catalog"; +import type { ThreadRecord } from "../../src/app-server/protocol/thread"; import type { ModelMetadata, ReasoningEffort } from "../../src/domain/catalog/metadata"; -import { modelMetadataFromCatalogModels } from "../../src/app-server/catalog"; +import { modelMetadataFromCatalogModels } from "../../src/app-server/protocol/catalog"; import { CodexPanelSettingTab } from "../../src/settings/tab"; import { archivedThreadDisplayTitle, type Thread } from "../../src/domain/threads/model"; import { notices } from "../mocks/obsidian"; @@ -18,7 +18,7 @@ const { withShortLivedAppServerClientMock } = vi.hoisted(() => ({ withShortLivedAppServerClientMock: vi.fn(), })); -vi.mock("../../src/app-server/short-lived-client", () => ({ +vi.mock("../../src/app-server/connection/short-lived-client", () => ({ withShortLivedAppServerClient: withShortLivedAppServerClientMock, }));