-
Notifications
You must be signed in to change notification settings - Fork 0
SDK supports model selection #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c694930
13ba8b0
7a64a2f
8726da3
3f0265e
e72426b
7147ce3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -485,6 +485,97 @@ export interface JobDetails { | |
| commit_login: string; | ||
| commit_email: string; | ||
| mcp_proxy_url?: string; | ||
| /** Model selected by the platform for this run. Present when model selection is enabled. */ | ||
| selected_model?: string; | ||
| /** Default model for the selected engine. Present when model selection is enabled. */ | ||
| default_model?: string; | ||
| /** Models the engine can choose from. Present when model selection is enabled. */ | ||
| available_models?: string[]; | ||
| /** Model vendors for filtering (e.g. ["Anthropic", "OpenAI"]). Present when model selection is enabled. */ | ||
| model_vendors?: string[]; | ||
| /** Feature flags enabled for this job. */ | ||
| features?: { | ||
| /** Whether the platform has enabled model selection for this job. */ | ||
| model_selection?: boolean; | ||
| }; | ||
| } | ||
|
|
||
| /** | ||
| * Check whether the platform has enabled model selection for this job. | ||
| * | ||
| * When this returns `false`, engines should use their own hardcoded model. | ||
| */ | ||
| export function isModelSelectionEnabled(job: Pick<JobDetails, "features">): boolean { | ||
| return job.features?.model_selection === true; | ||
| } | ||
|
|
||
| /** | ||
| * Resolve which model an engine should use for a job. | ||
| * | ||
| * Returns `undefined` when model selection is not enabled for the job | ||
| * (i.e. `features.model_selection` is not `true`), allowing engines that | ||
| * do not support model selection to ignore it entirely. | ||
|
Comment on lines
+515
to
+517
|
||
| * | ||
| * When enabled, the selection order is: | ||
| * 1) caller preferred model | ||
| * 2) model selected by platform (`selected_model`) | ||
| * 3) platform-provided engine default (`default_model`) | ||
| * 4) caller fallback model | ||
| * | ||
| * If `available_models` is present the resolved model must appear in that | ||
| * list. When no candidate matches, the first available model is returned | ||
| * and a warning is logged if `selected_model` was set but missing from the | ||
| * list (indicates a platform misconfiguration). | ||
| */ | ||
| /** Options for {@link resolveSelectedModel}. */ | ||
| export interface ResolveSelectedModelOptions { | ||
| /** Model the engine prefers to use, checked first. */ | ||
| preferredModel?: string; | ||
| /** Model to fall back to when no platform-provided candidate matches. */ | ||
| fallbackModel?: string; | ||
| } | ||
|
|
||
| export function resolveSelectedModel( | ||
| job: Pick<JobDetails, "selected_model" | "default_model" | "available_models" | "features">, | ||
| options?: ResolveSelectedModelOptions, | ||
| ): string | undefined { | ||
| // Model selection must be explicitly enabled via feature flag | ||
| if (job.features?.model_selection !== true) { | ||
| return undefined; | ||
| } | ||
|
|
||
| const availableModels = job.available_models | ||
| ?.map((model) => model.trim()) | ||
| .filter((model) => model.length > 0) ?? []; | ||
|
|
||
| const candidates = [ | ||
| options?.preferredModel, | ||
| job.selected_model, | ||
| job.default_model, | ||
| options?.fallbackModel, | ||
| ].map((model) => model?.trim()) | ||
| .filter((model): model is string => Boolean(model && model.length > 0)); | ||
|
|
||
| if (availableModels.length === 0) { | ||
| return candidates[0]; | ||
| } | ||
|
|
||
| for (const candidate of candidates) { | ||
| if (availableModels.includes(candidate)) { | ||
| return candidate; | ||
| } | ||
| } | ||
|
|
||
| // Warn when the platform-selected model is not in the available list | ||
| const trimmedSelectedModel = job.selected_model?.trim(); | ||
| if (trimmedSelectedModel && !availableModels.includes(trimmedSelectedModel)) { | ||
| console.warn( | ||
| `resolveSelectedModel: selected_model "${trimmedSelectedModel}" is not in available_models [${availableModels.join(", ")}]. ` + | ||
| `Falling back to "${availableModels[0]}".` | ||
| ); | ||
| } | ||
|
|
||
| return availableModels[0]; | ||
| } | ||
|
|
||
| /** | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With
--enable-model-selection, the mock job response will setfeatures.model_selection=trueeven if none of--selected-model,--default-model, or--available-modelare provided, resulting in a job payload with the feature enabled but no model information. Consider validating the flag combination and returning an error (or auto-populating a default) to avoid confusing local engine testing.