generate_image takes reference images: files the run reaches as [file:ID] refs, or the user's uploads by media id, up to four, each checked like a picture source and limited to raster images. Calls with references go to a new Image editing harness (no automatic picks). While it has no model or is off, image generation takes them; with its fallback on, image generation steps in after its pick fails. Only models that take image input are tried with references, so none drops them unseen. OpenRouter gets them on /images as input_references; other providers as a multipart upload to /images/edits. The Models pages show image editing's unset state as "Same as image generation", and the models cache version is bumped so it shows at once. Co-Authored-By: Claude Opus 5.5 <[email protected]>
56 lines
1.5 KiB
TypeScript
56 lines
1.5 KiB
TypeScript
import SearchSelect from "@moduletrace/twui/form/SearchSelect";
|
|
import type { HarnessModelOption } from "@/src/types";
|
|
import harnessModelSelectOptions, {
|
|
AutoModelValue,
|
|
} from "../(utils)/harness-model-select-options";
|
|
|
|
type Props = {
|
|
id: string;
|
|
/**
|
|
* Already narrowed to the picked provider.
|
|
*/
|
|
models: HarnessModelOption[];
|
|
model_id: number | null;
|
|
provider_name?: string;
|
|
automatic: boolean;
|
|
falls_back_title?: string;
|
|
onChange: (model_id: number | null) => void;
|
|
};
|
|
|
|
/**
|
|
* Searchable model picker: automatic (or not available, for a harness
|
|
* without automatic picks), or any model that can do the job.
|
|
*/
|
|
export default function HarnessModelSelect({
|
|
id,
|
|
models,
|
|
model_id,
|
|
provider_name,
|
|
automatic,
|
|
falls_back_title,
|
|
onChange,
|
|
}: Props) {
|
|
return (
|
|
<SearchSelect
|
|
id={id}
|
|
title="Model"
|
|
label="Model"
|
|
showLabel
|
|
placeholder="Search models"
|
|
options={harnessModelSelectOptions({
|
|
models,
|
|
model_id,
|
|
provider_name,
|
|
automatic,
|
|
falls_back_title,
|
|
})}
|
|
defaultValues={[model_id ? String(model_id) : AutoModelValue]}
|
|
changeHandler={(value) => {
|
|
const picked = Array.isArray(value) ? value[0] : value;
|
|
|
|
onChange(!picked || picked == AutoModelValue ? null : Number(picked));
|
|
}}
|
|
/>
|
|
);
|
|
}
|