@@ -6,6 +6,7 @@ import type { JsonSchemaType } from "@modelcontextprotocol/sdk/validation";
66import {
77 DEFAULT_SERVER_SETTINGS ,
88 ChatImageAttachment ,
9+ CommandId ,
910 EnvironmentId ,
1011 ProviderInstanceId ,
1112 RunId ,
@@ -19,8 +20,13 @@ import { McpAttachmentInput } from "./attachment/input.ts";
1920import { McpSchema , McpServer , Tool } from "effect/ai" ;
2021import { FetchHttpClient } from "effect/http" ;
2122
23+ import {
24+ OrchestratorCommandRejectedError ,
25+ OrchestratorDispatchError ,
26+ OrchestratorProjectionError ,
27+ } from "../../orchestration-v2/Orchestrator.ts" ;
28+
2229import * as ServerConfig from "../../config.ts" ;
23- import { OrchestratorProjectionError } from "../../orchestration-v2/Orchestrator.ts" ;
2430import * as ProviderAdapterRegistry from "../../orchestration-v2/ProviderAdapterRegistry.ts" ;
2531import * as ThreadManagement from "../../orchestration-v2/ThreadManagementService.ts" ;
2632import * as PreviewBrowser from "../../preview/PreviewBrowser.ts" ;
@@ -30,6 +36,7 @@ import * as SecretRequests from "../../secrets/SecretRequests.ts";
3036import * as ScheduledTaskService from "../../scheduledTasks/ScheduledTaskService.ts" ;
3137import * as McpHttpServer from "../McpHttpServer.ts" ;
3238import * as McpInvocationContext from "../McpInvocationContext.ts" ;
39+ import { dispatchFailure } from "../threadAccess.ts" ;
3340import { OrchestratorToolkit } from "./orchestrator/tools.ts" ;
3441import { PreviewToolkit } from "./preview/tools.ts" ;
3542import { PreviewControlsToolkit } from "./previewControls/tools.ts" ;
@@ -202,6 +209,42 @@ it.effect("returns a bounded public failure without serializing storage causes",
202209 ) ,
203210) ;
204211
212+ it ( "bounds public command rejections and redacts internal dispatch causes" , ( ) => {
213+ const command = { commandId : CommandId . make ( "mcp-core-command" ) , commandType : "thread.settle" } ;
214+ expect (
215+ dispatchFailure ( new OrchestratorDispatchError ( { ...command , cause : "🙂" . repeat ( 1001 ) } ) )
216+ . message ,
217+ ) . toBe ( "🙂" . repeat ( 1000 ) ) ;
218+ expect (
219+ dispatchFailure (
220+ new OrchestratorCommandRejectedError ( { ...command , cause : "Run is not queued." } ) ,
221+ ) . message ,
222+ ) . toBe ( "Run is not queued." ) ;
223+ for ( const cause of [
224+ undefined ,
225+ "" ,
226+ new Error ( "private-storage-path" ) ,
227+ { message : "private-storage-path" } ,
228+ ] ) {
229+ expect ( dispatchFailure ( new OrchestratorDispatchError ( { ...command , cause } ) ) ) . toMatchObject ( {
230+ code : "orchestration_error" ,
231+ message : "The operation could not be completed." ,
232+ } ) ;
233+ expect (
234+ dispatchFailure ( new OrchestratorCommandRejectedError ( { ...command , cause } ) ) ,
235+ ) . toMatchObject ( {
236+ code : "orchestration_error" ,
237+ message : "The operation could not be completed." ,
238+ } ) ;
239+ }
240+ expect (
241+ dispatchFailure ( new OrchestratorProjectionError ( { threadId, cause : "private-storage-path" } ) ) ,
242+ ) . toMatchObject ( {
243+ code : "orchestration_error" ,
244+ message : "The operation could not be completed." ,
245+ } ) ;
246+ } ) ;
247+
205248it . effect ( "returns an HTML render reference that Codex and Claude tool rows both carry" , ( ) =>
206249 Effect . gen ( function * ( ) {
207250 const server = yield * McpServer . McpServer ;
0 commit comments