1import type { ModelSelection, OrchestrationV2ProviderCapabilities } from "@t3tools/contracts";
2
3export interface ProviderSelectionTransitionInput {
4 readonly current: ModelSelection;
5 readonly target: ModelSelection;
6 readonly sessionCapabilities: OrchestrationV2ProviderCapabilities;
7}
8
9/**
10 * Provider-owned classification of how a complete selection can be applied.
11 * The orchestrator remains responsible for attempts and resource lifecycle.
12 */
13export type ProviderSelectionTransitionPlan =
14 | { readonly type: "apply_on_next_turn" }
15 | { readonly type: "restart_session" }
16 | { readonly type: "create_with_handoff" }
17 | { readonly type: "reject"; readonly reason: string };
18
19export function turnScopedSelectionTransition(): ProviderSelectionTransitionPlan {
20 return { type: "apply_on_next_turn" };
21}
22
23/** ACP models require a negotiated model/config mutation capability. */
24export function acpSelectionTransition(
25 input: ProviderSelectionTransitionInput,
26): ProviderSelectionTransitionPlan {
27 if (
28 input.current.model !== input.target.model &&
29 !input.sessionCapabilities.sessions.supportsModelSwitchInSession
30 ) {
31 return {
32 type: "reject",
33 reason: "The active ACP session does not expose a model-switch capability.",
34 };
35 }
36 return { type: "apply_on_next_turn" };
37}