| author | |
| committer | |
| log | a7ec0179fb42b12ab7e1fd4c2cabd508c8f8de67 |
| tree | 5d97745b5e18e9b6b39ff6ea2de9fa640dcf5897 |
| parent | c97c6b7836ce888b24a157de8eb4aea761028979 |
| signature | Signed by PGP key B5690EEEBB952194 |
* refactor(contracts): export ProviderStartOptions schema
* feat(contracts): add providerOptions to ThreadTurnStartCommand
* feat(web): send codex binary/home path settings to server
* feat(server): thread providerOptions through to session startup
* fix(contracts): define ProviderStartOptions inline to avoid circular dep
The import from provider.ts caused a ReferenceError at runtime because
of module initialization order in the bundled output.
* fix(server): preserve providerOptions across runtime mode changes and session recovery
Runtime mode toggles and server restarts silently dropped the custom
codex binary/home path, falling back to the default binary. Cache
providerOptions per thread in ProviderCommandReactor and persist it in
the session binding's runtimePayload so recovery can restore it.
Closes #4867 files changed, 79 insertions(+), 9 deletions(-)
apps/server/scripts/cli.ts+2| ... | @@ -132,6 +132,7 @@ const buildCmd = Command.make( | ... | @@ -132,6 +132,7 @@ const buildCmd = Command.make( |
| 132 | cwd: serverDir, | 132 | cwd: serverDir, |
| 133 | stdout: config.verbose ? "inherit" : "ignore", | 133 | stdout: config.verbose ? "inherit" : "ignore", |
| 134 | stderr: "inherit", | 134 | stderr: "inherit", |
| 135 | shell: process.platform === "win32", | ||
| 135 | })`bun tsdown`, | 136 | })`bun tsdown`, |
| 136 | ); | 137 | ); |
| 137 | 138 | ||
| ... | @@ -225,6 +226,7 @@ const publishCmd = Command.make( | ... | @@ -225,6 +226,7 @@ const publishCmd = Command.make( |
| 225 | cwd: serverDir, | 226 | cwd: serverDir, |
| 226 | stdout: config.verbose ? "inherit" : "ignore", | 227 | stdout: config.verbose ? "inherit" : "ignore", |
| 227 | stderr: "inherit", | 228 | stderr: "inherit", |
| 229 | shell: process.platform === "win32", | ||
| 228 | }), | 230 | }), |
| 229 | ); | 231 | ); |
| 230 | }), | 232 | }), |
apps/server/src/orchestration/Layers/ProviderCommandReactor.ts+15-1| ... | @@ -6,6 +6,7 @@ import { | ... | @@ -6,6 +6,7 @@ import { |
| 6 | type ProviderModelOptions, | 6 | type ProviderModelOptions, |
| 7 | type ProviderKind, | 7 | type ProviderKind, |
| 8 | type ProviderServiceTier, | 8 | type ProviderServiceTier, |
| 9 | type ProviderStartOptions, | ||
| 9 | type OrchestrationSession, | 10 | type OrchestrationSession, |
| 10 | ThreadId, | 11 | ThreadId, |
| 11 | type ProviderSession, | 12 | type ProviderSession, |
| ... | @@ -144,6 +145,8 @@ const make = Effect.gen(function* () { | ... | @@ -144,6 +145,8 @@ const make = Effect.gen(function* () { |
| 144 | ), | 145 | ), |
| 145 | ); | 146 | ); |
| 146 | 147 | ||
| 148 | const threadProviderOptions = new Map<string, ProviderStartOptions>(); | ||
| 149 | |||
| 147 | const appendProviderFailureActivity = (input: { | 150 | const appendProviderFailureActivity = (input: { |
| 148 | readonly threadId: ThreadId; | 151 | readonly threadId: ThreadId; |
| 149 | readonly kind: | 152 | readonly kind: |
| ... | @@ -203,6 +206,7 @@ const make = Effect.gen(function* () { | ... | @@ -203,6 +206,7 @@ const make = Effect.gen(function* () { |
| 203 | readonly model?: string; | 206 | readonly model?: string; |
| 204 | readonly modelOptions?: ProviderModelOptions; | 207 | readonly modelOptions?: ProviderModelOptions; |
| 205 | readonly serviceTier?: ProviderServiceTier | null; | 208 | readonly serviceTier?: ProviderServiceTier | null; |
| 209 | readonly providerOptions?: ProviderStartOptions; | ||
| 206 | }, | 210 | }, |
| 207 | ) { | 211 | ) { |
| 208 | const readModel = yield* orchestrationEngine.getReadModel(); | 212 | const readModel = yield* orchestrationEngine.getReadModel(); |
| ... | @@ -239,6 +243,7 @@ const make = Effect.gen(function* () { | ... | @@ -239,6 +243,7 @@ const make = Effect.gen(function* () { |
| 239 | ...(desiredModel ? { model: desiredModel } : {}), | 243 | ...(desiredModel ? { model: desiredModel } : {}), |
| 240 | ...(options?.serviceTier !== undefined ? { serviceTier: options.serviceTier } : {}), | 244 | ...(options?.serviceTier !== undefined ? { serviceTier: options.serviceTier } : {}), |
| 241 | ...(options?.modelOptions !== undefined ? { modelOptions: options.modelOptions } : {}), | 245 | ...(options?.modelOptions !== undefined ? { modelOptions: options.modelOptions } : {}), |
| 246 | ...(options?.providerOptions !== undefined ? { providerOptions: options.providerOptions } : {}), | ||
| 242 | ...(input?.resumeCursor !== undefined ? { resumeCursor: input.resumeCursor } : {}), | 247 | ...(input?.resumeCursor !== undefined ? { resumeCursor: input.resumeCursor } : {}), |
| 243 | runtimeMode: desiredRuntimeMode, | 248 | runtimeMode: desiredRuntimeMode, |
| 244 | }); | 249 | }); |
| ... | @@ -325,6 +330,7 @@ const make = Effect.gen(function* () { | ... | @@ -325,6 +330,7 @@ const make = Effect.gen(function* () { |
| 325 | readonly model?: string; | 330 | readonly model?: string; |
| 326 | readonly serviceTier?: ProviderServiceTier | null; | 331 | readonly serviceTier?: ProviderServiceTier | null; |
| 327 | readonly modelOptions?: ProviderModelOptions; | 332 | readonly modelOptions?: ProviderModelOptions; |
| 333 | readonly providerOptions?: ProviderStartOptions; | ||
| 328 | readonly interactionMode?: "default" | "plan"; | 334 | readonly interactionMode?: "default" | "plan"; |
| 329 | readonly createdAt: string; | 335 | readonly createdAt: string; |
| 330 | }) { | 336 | }) { |
| ... | @@ -332,11 +338,15 @@ const make = Effect.gen(function* () { | ... | @@ -332,11 +338,15 @@ const make = Effect.gen(function* () { |
| 332 | if (!thread) { | 338 | if (!thread) { |
| 333 | return; | 339 | return; |
| 334 | } | 340 | } |
| 341 | if (input.providerOptions !== undefined) { | ||
| 342 | threadProviderOptions.set(input.threadId, input.providerOptions); | ||
| 343 | } | ||
| 335 | yield* ensureSessionForThread(input.threadId, input.createdAt, { | 344 | yield* ensureSessionForThread(input.threadId, input.createdAt, { |
| 336 | ...(input.provider !== undefined ? { provider: input.provider } : {}), | 345 | ...(input.provider !== undefined ? { provider: input.provider } : {}), |
| 337 | ...(input.model !== undefined ? { model: input.model } : {}), | 346 | ...(input.model !== undefined ? { model: input.model } : {}), |
| 338 | ...(input.serviceTier !== undefined ? { serviceTier: input.serviceTier } : {}), | 347 | ...(input.serviceTier !== undefined ? { serviceTier: input.serviceTier } : {}), |
| 339 | ...(input.modelOptions !== undefined ? { modelOptions: input.modelOptions } : {}), | 348 | ...(input.modelOptions !== undefined ? { modelOptions: input.modelOptions } : {}), |
| 349 | ...(input.providerOptions !== undefined ? { providerOptions: input.providerOptions } : {}), | ||
| 340 | }); | 350 | }); |
| 341 | const normalizedInput = toNonEmptyProviderInput(input.messageText); | 351 | const normalizedInput = toNonEmptyProviderInput(input.messageText); |
| 342 | const normalizedAttachments = input.attachments ?? []; | 352 | const normalizedAttachments = input.attachments ?? []; |
| ... | @@ -472,6 +482,7 @@ const make = Effect.gen(function* () { | ... | @@ -472,6 +482,7 @@ const make = Effect.gen(function* () { |
| 472 | ...(event.payload.model !== undefined ? { model: event.payload.model } : {}), | 482 | ...(event.payload.model !== undefined ? { model: event.payload.model } : {}), |
| 473 | ...(event.payload.serviceTier !== undefined ? { serviceTier: event.payload.serviceTier } : {}), | 483 | ...(event.payload.serviceTier !== undefined ? { serviceTier: event.payload.serviceTier } : {}), |
| 474 | ...(event.payload.modelOptions !== undefined ? { modelOptions: event.payload.modelOptions } : {}), | 484 | ...(event.payload.modelOptions !== undefined ? { modelOptions: event.payload.modelOptions } : {}), |
| 485 | ...(event.payload.providerOptions !== undefined ? { providerOptions: event.payload.providerOptions } : {}), | ||
| 475 | interactionMode: event.payload.interactionMode, | 486 | interactionMode: event.payload.interactionMode, |
| 476 | createdAt: event.payload.createdAt, | 487 | createdAt: event.payload.createdAt, |
| 477 | }); | 488 | }); |
| ... | @@ -627,7 +638,10 @@ const make = Effect.gen(function* () { | ... | @@ -627,7 +638,10 @@ const make = Effect.gen(function* () { |
| 627 | if (!thread?.session || thread.session.status === "stopped") { | 638 | if (!thread?.session || thread.session.status === "stopped") { |
| 628 | return; | 639 | return; |
| 629 | } | 640 | } |
| 630 | yield* ensureSessionForThread(event.payload.threadId, event.occurredAt); | 641 | const cachedProviderOptions = threadProviderOptions.get(event.payload.threadId); |
| 642 | yield* ensureSessionForThread(event.payload.threadId, event.occurredAt, { | ||
| 643 | ...(cachedProviderOptions !== undefined ? { providerOptions: cachedProviderOptions } : {}), | ||
| 644 | }); | ||
| 631 | return; | 645 | return; |
| 632 | } | 646 | } |
| 633 | case "thread.turn-start-requested": | 647 | case "thread.turn-start-requested": |
apps/server/src/orchestration/decider.ts+1| ... | @@ -303,6 +303,7 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand" | ... | @@ -303,6 +303,7 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand" |
| 303 | ...(command.model !== undefined ? { model: command.model } : {}), | 303 | ...(command.model !== undefined ? { model: command.model } : {}), |
| 304 | ...(command.serviceTier !== undefined ? { serviceTier: command.serviceTier } : {}), | 304 | ...(command.serviceTier !== undefined ? { serviceTier: command.serviceTier } : {}), |
| 305 | ...(command.modelOptions !== undefined ? { modelOptions: command.modelOptions } : {}), | 305 | ...(command.modelOptions !== undefined ? { modelOptions: command.modelOptions } : {}), |
| 306 | ...(command.providerOptions !== undefined ? { providerOptions: command.providerOptions } : {}), | ||
| 306 | assistantDeliveryMode: command.assistantDeliveryMode ?? DEFAULT_ASSISTANT_DELIVERY_MODE, | 307 | assistantDeliveryMode: command.assistantDeliveryMode ?? DEFAULT_ASSISTANT_DELIVERY_MODE, |
| 307 | runtimeMode: | 308 | runtimeMode: |
| 308 | readModel.threads.find((entry) => entry.id === command.threadId)?.runtimeMode ?? | 309 | readModel.threads.find((entry) => entry.id === command.threadId)?.runtimeMode ?? |
apps/server/src/provider/Layers/ProviderService.ts+23-3| ... | @@ -86,15 +86,30 @@ function toRuntimeStatus(session: ProviderSession): "starting" | "running" | "st | ... | @@ -86,15 +86,30 @@ function toRuntimeStatus(session: ProviderSession): "starting" | "running" | "st |
| 86 | } | 86 | } |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | function toRuntimePayloadFromSession(session: ProviderSession): Record<string, unknown> { | 89 | function toRuntimePayloadFromSession( |
| 90 | session: ProviderSession, | ||
| 91 | extra?: { readonly providerOptions?: unknown }, | ||
| 92 | ): Record<string, unknown> { | ||
| 90 | return { | 93 | return { |
| 91 | cwd: session.cwd ?? null, | 94 | cwd: session.cwd ?? null, |
| 92 | model: session.model ?? null, | 95 | model: session.model ?? null, |
| 93 | activeTurnId: session.activeTurnId ?? null, | 96 | activeTurnId: session.activeTurnId ?? null, |
| 94 | lastError: session.lastError ?? null, | 97 | lastError: session.lastError ?? null, |
| 98 | ...(extra?.providerOptions !== undefined ? { providerOptions: extra.providerOptions } : {}), | ||
| 95 | }; | 99 | }; |
| 96 | } | 100 | } |
| 97 | 101 | ||
| 102 | function readPersistedProviderOptions( | ||
| 103 | runtimePayload: ProviderRuntimeBinding["runtimePayload"], | ||
| 104 | ): Record<string, unknown> | undefined { | ||
| 105 | if (!runtimePayload || typeof runtimePayload !== "object" || Array.isArray(runtimePayload)) { | ||
| 106 | return undefined; | ||
| 107 | } | ||
| 108 | const raw = "providerOptions" in runtimePayload ? runtimePayload.providerOptions : undefined; | ||
| 109 | if (!raw || typeof raw !== "object" || Array.isArray(raw)) return undefined; | ||
| 110 | return raw as Record<string, unknown>; | ||
| 111 | } | ||
| 112 | |||
| 98 | function readPersistedCwd( | 113 | function readPersistedCwd( |
| 99 | runtimePayload: ProviderRuntimeBinding["runtimePayload"], | 114 | runtimePayload: ProviderRuntimeBinding["runtimePayload"], |
| 100 | ): string | undefined { | 115 | ): string | undefined { |
| ... | @@ -137,6 +152,7 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => | ... | @@ -137,6 +152,7 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => |
| 137 | const upsertSessionBinding = ( | 152 | const upsertSessionBinding = ( |
| 138 | session: ProviderSession, | 153 | session: ProviderSession, |
| 139 | threadId: ThreadId, | 154 | threadId: ThreadId, |
| 155 | extra?: { readonly providerOptions?: unknown }, | ||
| 140 | ) => | 156 | ) => |
| 141 | directory.upsert({ | 157 | directory.upsert({ |
| 142 | threadId, | 158 | threadId, |
| ... | @@ -144,7 +160,7 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => | ... | @@ -144,7 +160,7 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => |
| 144 | runtimeMode: session.runtimeMode, | 160 | runtimeMode: session.runtimeMode, |
| 145 | status: toRuntimeStatus(session), | 161 | status: toRuntimeStatus(session), |
| 146 | ...(session.resumeCursor !== undefined ? { resumeCursor: session.resumeCursor } : {}), | 162 | ...(session.resumeCursor !== undefined ? { resumeCursor: session.resumeCursor } : {}), |
| 147 | runtimePayload: toRuntimePayloadFromSession(session), | 163 | runtimePayload: toRuntimePayloadFromSession(session, extra), |
| 148 | }); | 164 | }); |
| 149 | 165 | ||
| 150 | const providers = yield* registry.listProviders(); | 166 | const providers = yield* registry.listProviders(); |
| ... | @@ -197,11 +213,13 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => | ... | @@ -197,11 +213,13 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => |
| 197 | } | 213 | } |
| 198 | 214 | ||
| 199 | const persistedCwd = readPersistedCwd(input.binding.runtimePayload); | 215 | const persistedCwd = readPersistedCwd(input.binding.runtimePayload); |
| 216 | const persistedProviderOptions = readPersistedProviderOptions(input.binding.runtimePayload); | ||
| 200 | 217 | ||
| 201 | const resumed = yield* adapter.startSession({ | 218 | const resumed = yield* adapter.startSession({ |
| 202 | threadId: input.binding.threadId, | 219 | threadId: input.binding.threadId, |
| 203 | provider: input.binding.provider, | 220 | provider: input.binding.provider, |
| 204 | ...(persistedCwd ? { cwd: persistedCwd } : {}), | 221 | ...(persistedCwd ? { cwd: persistedCwd } : {}), |
| 222 | ...(persistedProviderOptions ? { providerOptions: persistedProviderOptions } : {}), | ||
| 205 | ...(hasResumeCursor ? { resumeCursor: input.binding.resumeCursor } : {}), | 223 | ...(hasResumeCursor ? { resumeCursor: input.binding.resumeCursor } : {}), |
| 206 | runtimeMode: input.binding.runtimeMode ?? "full-access", | 224 | runtimeMode: input.binding.runtimeMode ?? "full-access", |
| 207 | }); | 225 | }); |
| ... | @@ -273,7 +291,9 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => | ... | @@ -273,7 +291,9 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => |
| 273 | ); | 291 | ); |
| 274 | } | 292 | } |
| 275 | 293 | ||
| 276 | yield* upsertSessionBinding(session, threadId); | 294 | yield* upsertSessionBinding(session, threadId, { |
| 295 | ...(input.providerOptions !== undefined ? { providerOptions: input.providerOptions } : {}), | ||
| 296 | }); | ||
| 277 | yield* analytics.record("provider.session.started", { | 297 | yield* analytics.record("provider.session.started", { |
| 278 | provider: session.provider, | 298 | provider: session.provider, |
| 279 | runtimeMode: input.runtimeMode, | 299 | runtimeMode: input.runtimeMode, |
apps/web/src/components/ChatView.tsx+26-4| ... | @@ -830,6 +830,17 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -830,6 +830,17 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 830 | }; | 830 | }; |
| 831 | return Object.keys(codexOptions).length > 0 ? { codex: codexOptions } : undefined; | 831 | return Object.keys(codexOptions).length > 0 ? { codex: codexOptions } : undefined; |
| 832 | }, [selectedCodexFastModeEnabled, selectedEffort, selectedProvider, supportsReasoningEffort]); | 832 | }, [selectedCodexFastModeEnabled, selectedEffort, selectedProvider, supportsReasoningEffort]); |
| 833 | const providerOptionsForDispatch = useMemo(() => { | ||
| 834 | if (!settings.codexBinaryPath && !settings.codexHomePath) { | ||
| 835 | return undefined; | ||
| 836 | } | ||
| 837 | return { | ||
| 838 | codex: { | ||
| 839 | ...(settings.codexBinaryPath ? { binaryPath: settings.codexBinaryPath } : {}), | ||
| 840 | ...(settings.codexHomePath ? { homePath: settings.codexHomePath } : {}), | ||
| 841 | }, | ||
| 842 | }; | ||
| 843 | }, [settings.codexBinaryPath, settings.codexHomePath]); | ||
| 833 | const selectedModelForPicker = selectedModel; | 844 | const selectedModelForPicker = selectedModel; |
| 834 | const modelOptionsByProvider = useMemo( | 845 | const modelOptionsByProvider = useMemo( |
| 835 | () => getCustomModelOptionsByProvider(settings), | 846 | () => getCustomModelOptionsByProvider(settings), |
| ... | @@ -2626,6 +2637,9 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -2626,6 +2637,9 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 2626 | ...(selectedModelOptionsForDispatch | 2637 | ...(selectedModelOptionsForDispatch |
| 2627 | ? { modelOptions: selectedModelOptionsForDispatch } | 2638 | ? { modelOptions: selectedModelOptionsForDispatch } |
| 2628 | : {}), | 2639 | : {}), |
| 2640 | ...(providerOptionsForDispatch | ||
| 2641 | ? { providerOptions: providerOptionsForDispatch } | ||
| 2642 | : {}), | ||
| 2629 | provider: selectedProvider, | 2643 | provider: selectedProvider, |
| 2630 | assistantDeliveryMode: settings.enableAssistantStreaming ? "streaming" : "buffered", | 2644 | assistantDeliveryMode: settings.enableAssistantStreaming ? "streaming" : "buffered", |
| 2631 | runtimeMode, | 2645 | runtimeMode, |
| ... | @@ -2903,6 +2917,9 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -2903,6 +2917,9 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 2903 | ...(selectedModelOptionsForDispatch | 2917 | ...(selectedModelOptionsForDispatch |
| 2904 | ? { modelOptions: selectedModelOptionsForDispatch } | 2918 | ? { modelOptions: selectedModelOptionsForDispatch } |
| 2905 | : {}), | 2919 | : {}), |
| 2920 | ...(providerOptionsForDispatch | ||
| 2921 | ? { providerOptions: providerOptionsForDispatch } | ||
| 2922 | : {}), | ||
| 2906 | assistantDeliveryMode: settings.enableAssistantStreaming ? "streaming" : "buffered", | 2923 | assistantDeliveryMode: settings.enableAssistantStreaming ? "streaming" : "buffered", |
| 2907 | runtimeMode, | 2924 | runtimeMode, |
| 2908 | interactionMode: nextInteractionMode, | 2925 | interactionMode: nextInteractionMode, |
| ... | @@ -2933,6 +2950,7 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -2933,6 +2950,7 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 2933 | runtimeMode, | 2950 | runtimeMode, |
| 2934 | selectedModel, | 2951 | selectedModel, |
| 2935 | selectedModelOptionsForDispatch, | 2952 | selectedModelOptionsForDispatch, |
| 2953 | providerOptionsForDispatch, | ||
| 2936 | selectedProvider, | 2954 | selectedProvider, |
| 2937 | setComposerDraftInteractionMode, | 2955 | setComposerDraftInteractionMode, |
| 2938 | setThreadError, | 2956 | setThreadError, |
| ... | @@ -2987,8 +3005,8 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -2987,8 +3005,8 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 2987 | worktreePath: activeThread.worktreePath, | 3005 | worktreePath: activeThread.worktreePath, |
| 2988 | createdAt, | 3006 | createdAt, |
| 2989 | }) | 3007 | }) |
| 2990 | .then(() => | 3008 | .then(() => { |
| 2991 | api.orchestration.dispatchCommand({ | 3009 | return api.orchestration.dispatchCommand({ |
| 2992 | type: "thread.turn.start", | 3010 | type: "thread.turn.start", |
| 2993 | commandId: newCommandId(), | 3011 | commandId: newCommandId(), |
| 2994 | threadId: nextThreadId, | 3012 | threadId: nextThreadId, |
| ... | @@ -3003,12 +3021,15 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -3003,12 +3021,15 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 3003 | ...(selectedModelOptionsForDispatch | 3021 | ...(selectedModelOptionsForDispatch |
| 3004 | ? { modelOptions: selectedModelOptionsForDispatch } | 3022 | ? { modelOptions: selectedModelOptionsForDispatch } |
| 3005 | : {}), | 3023 | : {}), |
| 3024 | ...(providerOptionsForDispatch | ||
| 3025 | ? { providerOptions: providerOptionsForDispatch } | ||
| 3026 | : {}), | ||
| 3006 | assistantDeliveryMode: settings.enableAssistantStreaming ? "streaming" : "buffered", | 3027 | assistantDeliveryMode: settings.enableAssistantStreaming ? "streaming" : "buffered", |
| 3007 | runtimeMode, | 3028 | runtimeMode, |
| 3008 | interactionMode: "default", | 3029 | interactionMode: "default", |
| 3009 | createdAt, | 3030 | createdAt, |
| 3010 | }), | 3031 | }); |
| 3011 | ) | 3032 | }) |
| 3012 | .then(() => api.orchestration.getSnapshot()) | 3033 | .then(() => api.orchestration.getSnapshot()) |
| 3013 | .then((snapshot) => { | 3034 | .then((snapshot) => { |
| 3014 | syncServerReadModel(snapshot); | 3035 | syncServerReadModel(snapshot); |
| ... | @@ -3052,6 +3073,7 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -3052,6 +3073,7 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 3052 | runtimeMode, | 3073 | runtimeMode, |
| 3053 | selectedModel, | 3074 | selectedModel, |
| 3054 | selectedModelOptionsForDispatch, | 3075 | selectedModelOptionsForDispatch, |
| 3076 | providerOptionsForDispatch, | ||
| 3055 | selectedProvider, | 3077 | selectedProvider, |
| 3056 | settings.enableAssistantStreaming, | 3078 | settings.enableAssistantStreaming, |
| 3057 | syncServerReadModel, | 3079 | syncServerReadModel, |
packages/contracts/src/orchestration.ts+10| ... | @@ -45,6 +45,13 @@ export type ProviderSandboxMode = typeof ProviderSandboxMode.Type; | ... | @@ -45,6 +45,13 @@ export type ProviderSandboxMode = typeof ProviderSandboxMode.Type; |
| 45 | export const ProviderServiceTier = Schema.Literals(["fast", "flex"]); | 45 | export const ProviderServiceTier = Schema.Literals(["fast", "flex"]); |
| 46 | export type ProviderServiceTier = typeof ProviderServiceTier.Type; | 46 | export type ProviderServiceTier = typeof ProviderServiceTier.Type; |
| 47 | export const DEFAULT_PROVIDER_KIND: ProviderKind = "codex"; | 47 | export const DEFAULT_PROVIDER_KIND: ProviderKind = "codex"; |
| 48 | const CodexProviderStartOptions = Schema.Struct({ | ||
| 49 | binaryPath: Schema.optional(TrimmedNonEmptyString), | ||
| 50 | homePath: Schema.optional(TrimmedNonEmptyString), | ||
| 51 | }); | ||
| 52 | const ProviderStartOptions = Schema.Struct({ | ||
| 53 | codex: Schema.optional(CodexProviderStartOptions), | ||
| 54 | }); | ||
| 48 | export const RuntimeMode = Schema.Literals(["approval-required", "full-access"]); | 55 | export const RuntimeMode = Schema.Literals(["approval-required", "full-access"]); |
| 49 | export type RuntimeMode = typeof RuntimeMode.Type; | 56 | export type RuntimeMode = typeof RuntimeMode.Type; |
| 50 | export const DEFAULT_RUNTIME_MODE: RuntimeMode = "full-access"; | 57 | export const DEFAULT_RUNTIME_MODE: RuntimeMode = "full-access"; |
| ... | @@ -366,6 +373,7 @@ export const ThreadTurnStartCommand = Schema.Struct({ | ... | @@ -366,6 +373,7 @@ export const ThreadTurnStartCommand = Schema.Struct({ |
| 366 | model: Schema.optional(TrimmedNonEmptyString), | 373 | model: Schema.optional(TrimmedNonEmptyString), |
| 367 | serviceTier: Schema.optional(Schema.NullOr(ProviderServiceTier)), | 374 | serviceTier: Schema.optional(Schema.NullOr(ProviderServiceTier)), |
| 368 | modelOptions: Schema.optional(ProviderModelOptions), | 375 | modelOptions: Schema.optional(ProviderModelOptions), |
| 376 | providerOptions: Schema.optional(ProviderStartOptions), | ||
| 369 | assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), | 377 | assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), |
| 370 | runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(() => DEFAULT_RUNTIME_MODE)), | 378 | runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(() => DEFAULT_RUNTIME_MODE)), |
| 371 | interactionMode: ProviderInteractionMode.pipe( | 379 | interactionMode: ProviderInteractionMode.pipe( |
| ... | @@ -388,6 +396,7 @@ const ClientThreadTurnStartCommand = Schema.Struct({ | ... | @@ -388,6 +396,7 @@ const ClientThreadTurnStartCommand = Schema.Struct({ |
| 388 | model: Schema.optional(TrimmedNonEmptyString), | 396 | model: Schema.optional(TrimmedNonEmptyString), |
| 389 | serviceTier: Schema.optional(Schema.NullOr(ProviderServiceTier)), | 397 | serviceTier: Schema.optional(Schema.NullOr(ProviderServiceTier)), |
| 390 | modelOptions: Schema.optional(ProviderModelOptions), | 398 | modelOptions: Schema.optional(ProviderModelOptions), |
| 399 | providerOptions: Schema.optional(ProviderStartOptions), | ||
| 391 | assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), | 400 | assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), |
| 392 | runtimeMode: RuntimeMode, | 401 | runtimeMode: RuntimeMode, |
| 393 | interactionMode: ProviderInteractionMode, | 402 | interactionMode: ProviderInteractionMode, |
| ... | @@ -668,6 +677,7 @@ export const ThreadTurnStartRequestedPayload = Schema.Struct({ | ... | @@ -668,6 +677,7 @@ export const ThreadTurnStartRequestedPayload = Schema.Struct({ |
| 668 | model: Schema.optional(TrimmedNonEmptyString), | 677 | model: Schema.optional(TrimmedNonEmptyString), |
| 669 | serviceTier: Schema.optional(Schema.NullOr(ProviderServiceTier)), | 678 | serviceTier: Schema.optional(Schema.NullOr(ProviderServiceTier)), |
| 670 | modelOptions: Schema.optional(ProviderModelOptions), | 679 | modelOptions: Schema.optional(ProviderModelOptions), |
| 680 | providerOptions: Schema.optional(ProviderStartOptions), | ||
| 671 | assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), | 681 | assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), |
| 672 | runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(() => DEFAULT_RUNTIME_MODE)), | 682 | runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(() => DEFAULT_RUNTIME_MODE)), |
| 673 | interactionMode: ProviderInteractionMode.pipe( | 683 | interactionMode: ProviderInteractionMode.pipe( |
packages/contracts/src/provider.ts+2-1| ... | @@ -53,9 +53,10 @@ const CodexProviderStartOptions = Schema.Struct({ | ... | @@ -53,9 +53,10 @@ const CodexProviderStartOptions = Schema.Struct({ |
| 53 | homePath: Schema.optional(TrimmedNonEmptyStringSchema), | 53 | homePath: Schema.optional(TrimmedNonEmptyStringSchema), |
| 54 | }); | 54 | }); |
| 55 | 55 | ||
| 56 | const ProviderStartOptions = Schema.Struct({ | 56 | export const ProviderStartOptions = Schema.Struct({ |
| 57 | codex: Schema.optional(CodexProviderStartOptions), | 57 | codex: Schema.optional(CodexProviderStartOptions), |
| 58 | }); | 58 | }); |
| 59 | export type ProviderStartOptions = typeof ProviderStartOptions.Type; | ||
| 59 | 60 | ||
| 60 | export const ProviderSessionStartInput = Schema.Struct({ | 61 | export const ProviderSessionStartInput = Schema.Struct({ |
| 61 | threadId: ThreadId, | 62 | threadId: ThreadId, |