diff --git a/README.md b/README.md index 9b963e1a..beb58f3d 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ Codex Panel acts as a local Obsidian client for Codex App Server: | Key | Version | Policy | | ------------------------ | --------- | ---------------------------------------------------------- | | `obsidian.minAppVersion` | `1.12.0` | Track the latest patch for this Obsidian minor. | -| `codex.testedCliVersion` | `0.134.0` | Track app-server compatibility by Codex CLI minor version. | +| `codex.testedCliVersion` | `0.135.0` | Track app-server compatibility by Codex CLI minor version. | Codex Panel depends on the experimental `codex app-server` API. diff --git a/src/features/chat/chat-app-server-controller.ts b/src/features/chat/chat-app-server-controller.ts index 567bb6af..1bf89e95 100644 --- a/src/features/chat/chat-app-server-controller.ts +++ b/src/features/chat/chat-app-server-controller.ts @@ -229,7 +229,7 @@ export class ChatAppServerController { ), this.probeCapability( "mcpServerStatus/list", - () => client.listMcpServerStatus(), + () => client.listMcpServerStatus(mcpServerStatusParams(this.state.activeThreadId)), (response) => { this.recordMcpServerStatus(response.data); const issueCount = response.data.filter((server) => server.authStatus === "notLoggedIn").length; @@ -270,7 +270,7 @@ export class ChatAppServerController { if (!client) return ["MCP servers", "Codex app-server is not connected."]; try { - const response = await client.listMcpServerStatus(); + const response = await client.listMcpServerStatus(mcpServerStatusParams(this.state.activeThreadId)); return buildMcpStatusLines(response.data, this.state.appServerDiagnostics.mcpServers); } catch (error) { const message = error instanceof Error ? error.message : String(error); @@ -329,3 +329,11 @@ function cloneAppServerDiagnostics(diagnostics: AppServerDiagnostics): AppServer mcpServers: diagnostics.mcpServers.map((server) => ({ ...server })), }; } + +function mcpServerStatusParams(threadId: string | null): Parameters[0] { + return { + detail: "toolsAndAuthOnly", + limit: 100, + ...(threadId ? { threadId } : {}), + }; +} diff --git a/src/generated/app-server/ImageDetail.ts b/src/generated/app-server/ImageDetail.ts index 5a62cc32..a48f07c0 100644 --- a/src/generated/app-server/ImageDetail.ts +++ b/src/generated/app-server/ImageDetail.ts @@ -2,4 +2,4 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type ImageDetail = "high" | "original"; +export type ImageDetail = "auto" | "low" | "high" | "original"; diff --git a/src/generated/app-server/v2/AdditionalContextEntry.ts b/src/generated/app-server/v2/AdditionalContextEntry.ts new file mode 100644 index 00000000..8d959269 --- /dev/null +++ b/src/generated/app-server/v2/AdditionalContextEntry.ts @@ -0,0 +1,6 @@ +// GENERATED CODE! DO NOT MODIFY BY HAND! + +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { AdditionalContextKind } from "./AdditionalContextKind"; + +export type AdditionalContextEntry = { value: string, kind: AdditionalContextKind, }; diff --git a/src/generated/app-server/v2/AdditionalContextKind.ts b/src/generated/app-server/v2/AdditionalContextKind.ts new file mode 100644 index 00000000..cd60bd7a --- /dev/null +++ b/src/generated/app-server/v2/AdditionalContextKind.ts @@ -0,0 +1,5 @@ +// GENERATED CODE! DO NOT MODIFY BY HAND! + +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type AdditionalContextKind = "untrusted" | "application"; diff --git a/src/generated/app-server/v2/ListMcpServerStatusParams.ts b/src/generated/app-server/v2/ListMcpServerStatusParams.ts index fa00b8ea..2296c736 100644 --- a/src/generated/app-server/v2/ListMcpServerStatusParams.ts +++ b/src/generated/app-server/v2/ListMcpServerStatusParams.ts @@ -16,4 +16,4 @@ limit?: number | null, * Controls how much MCP inventory data to fetch for each server. * Defaults to `Full` when omitted. */ -detail?: McpServerStatusDetail | null, }; +detail?: McpServerStatusDetail | null, threadId?: string | null, }; diff --git a/src/generated/app-server/v2/TurnStartParams.ts b/src/generated/app-server/v2/TurnStartParams.ts index 17c92b5d..1955bd8c 100644 --- a/src/generated/app-server/v2/TurnStartParams.ts +++ b/src/generated/app-server/v2/TurnStartParams.ts @@ -7,6 +7,7 @@ import type { Personality } from "../Personality"; import type { ReasoningEffort } from "../ReasoningEffort"; import type { ReasoningSummary } from "../ReasoningSummary"; import type { JsonValue } from "../serde_json/JsonValue"; +import type { AdditionalContextEntry } from "./AdditionalContextEntry"; import type { ApprovalsReviewer } from "./ApprovalsReviewer"; import type { AskForApproval } from "./AskForApproval"; import type { SandboxPolicy } from "./SandboxPolicy"; @@ -18,6 +19,10 @@ export type TurnStartParams = { threadId: string, input: Array, * Optional turn-scoped Responses API client metadata. */ responsesapiClientMetadata?: { [key in string]?: string } | null, +/** + * Optional client-provided context fragments keyed by an opaque source identifier. + */ +additionalContext?: { [key in string]?: AdditionalContextEntry } | null, /** * Optional turn-scoped environments. * diff --git a/src/generated/app-server/v2/TurnSteerParams.ts b/src/generated/app-server/v2/TurnSteerParams.ts index 0361b5c3..c5ffae74 100644 --- a/src/generated/app-server/v2/TurnSteerParams.ts +++ b/src/generated/app-server/v2/TurnSteerParams.ts @@ -1,6 +1,7 @@ // GENERATED CODE! DO NOT MODIFY BY HAND! // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { AdditionalContextEntry } from "./AdditionalContextEntry"; import type { UserInput } from "./UserInput"; export type TurnSteerParams = { threadId: string, input: Array, @@ -8,6 +9,10 @@ export type TurnSteerParams = { threadId: string, input: Array, * Optional turn-scoped Responses API client metadata. */ responsesapiClientMetadata?: { [key in string]?: string } | null, +/** + * Optional client-provided context fragments keyed by an opaque source identifier. + */ +additionalContext?: { [key in string]?: AdditionalContextEntry } | null, /** * Required active turn id precondition. The request fails when it does not * match the currently active turn. diff --git a/src/generated/app-server/v2/index.ts b/src/generated/app-server/v2/index.ts index 962c4306..68f4bf08 100644 --- a/src/generated/app-server/v2/index.ts +++ b/src/generated/app-server/v2/index.ts @@ -7,6 +7,8 @@ export type { AccountUpdatedNotification } from "./AccountUpdatedNotification"; export type { ActivePermissionProfile } from "./ActivePermissionProfile"; export type { AddCreditsNudgeCreditType } from "./AddCreditsNudgeCreditType"; export type { AddCreditsNudgeEmailStatus } from "./AddCreditsNudgeEmailStatus"; +export type { AdditionalContextEntry } from "./AdditionalContextEntry"; +export type { AdditionalContextKind } from "./AdditionalContextKind"; export type { AdditionalFileSystemPermissions } from "./AdditionalFileSystemPermissions"; export type { AdditionalNetworkPermissions } from "./AdditionalNetworkPermissions"; export type { AdditionalPermissionProfile } from "./AdditionalPermissionProfile"; diff --git a/tests/features/chat/chat-app-server-controller.test.ts b/tests/features/chat/chat-app-server-controller.test.ts index efab44d8..3bdb56c8 100644 --- a/tests/features/chat/chat-app-server-controller.test.ts +++ b/tests/features/chat/chat-app-server-controller.test.ts @@ -63,9 +63,12 @@ describe("ChatAppServerController", () => { }); it("loads MCP status lines with cached startup diagnostics", async () => { - const stateStore = createChatStateStore(createChatState()); + const state = createChatState(); + state.activeThreadId = "thread-1"; + const stateStore = createChatStateStore(state); + const listMcpServerStatus = vi.fn().mockResolvedValue({ data: [mcpServerStatus()] }); const client = { - listMcpServerStatus: vi.fn().mockResolvedValue({ data: [mcpServerStatus()] }), + listMcpServerStatus, } as unknown as AppServerClient; const controller = new ChatAppServerController({ stateStore, @@ -79,6 +82,11 @@ describe("ChatAppServerController", () => { controller.recordMcpStartupStatus("github", "ready", null); await expect(controller.mcpStatusLines()).resolves.toEqual(["MCP servers", "github: ready, auth oAuth, 1 tool, 0 resources"]); + expect(listMcpServerStatus).toHaveBeenCalledWith({ + detail: "toolsAndAuthOnly", + limit: 100, + threadId: "thread-1", + }); }); });