feat(ai): exposed catalog metadata in auth gateway model list
- Added context length, max tokens, input modalities, and tool support flags to GET /v1/models response in auth gateway server. - Updated auth gateway model list tests to verify catalog metadata fields in output rows.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
### Added
|
||||
|
||||
- Added model metadata fields (`context_length`, `max_output_tokens`, `input_modalities`, etc.) to auth gateway model listing responses
|
||||
- Added `Tool.coerceArguments` (default `true`): setting it `false` opts a tool out of every LLM-quirk argument repair pass (JSON-string parsing, object→string stringification, unrecognized-key dropping, singleton array wrapping) so validation runs verbatim. Tools whose arguments are the deliverable payload — like the subagent `yield` tool — use it to keep lossy repairs from silently corrupting data their own validate-and-retry loop is designed to correct.
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -730,19 +730,45 @@ async function handleCredentialsCheck(storage: AuthStorage, signal: AbortSignal)
|
||||
return json(200, { generatedAt: Date.now(), credentials });
|
||||
}
|
||||
|
||||
/**
|
||||
* Row shape for `GET /v1/models`. Beyond the OpenAI-standard `id`/`object`/
|
||||
* `owned_by`, rows advertise the catalog metadata OpenAI-compatible clients
|
||||
* (omp's own proxy discovery, Zed's openai_compatible provider, ...) read to
|
||||
* size and capability-gate discovered models: `context_length`,
|
||||
* `max_output_tokens`, `input_modalities`, and `supports_tools` (only emitted
|
||||
* when the catalog explicitly reports `false`; absent means usable).
|
||||
*/
|
||||
interface ModelListRow {
|
||||
id: string;
|
||||
object: "model";
|
||||
owned_by: string;
|
||||
api: Api;
|
||||
display_name: string;
|
||||
context_length?: number;
|
||||
max_output_tokens?: number;
|
||||
input_modalities: ("text" | "image")[];
|
||||
supports_tools?: boolean;
|
||||
}
|
||||
|
||||
function handleModelsList(opts: AuthGatewayBootOptions): Response {
|
||||
const seen = new Set<string>();
|
||||
const data: Array<{ id: string; object: "model"; owned_by: string; api: Api }> = [];
|
||||
const data: ModelListRow[] = [];
|
||||
for (const model of opts.listModels?.() ?? []) {
|
||||
const id = `${model.provider}/${model.id}`;
|
||||
if (seen.has(id)) continue;
|
||||
seen.add(id);
|
||||
data.push({
|
||||
const row: ModelListRow = {
|
||||
id,
|
||||
object: "model",
|
||||
owned_by: model.provider,
|
||||
api: model.api,
|
||||
});
|
||||
display_name: model.name,
|
||||
input_modalities: model.input,
|
||||
};
|
||||
if (model.contextWindow != null) row.context_length = model.contextWindow;
|
||||
if (model.maxTokens != null) row.max_output_tokens = model.maxTokens;
|
||||
if (model.supportsTools === false) row.supports_tools = false;
|
||||
data.push(row);
|
||||
}
|
||||
return json(200, { object: "list", data });
|
||||
}
|
||||
|
||||
@@ -26,8 +26,26 @@ test("model listing exposes one provider-qualified route per upstream model", as
|
||||
expect(await response.json()).toEqual({
|
||||
object: "list",
|
||||
data: [
|
||||
{ id: "anthropic/shared-model", object: "model", owned_by: "anthropic", api: "mock" },
|
||||
{ id: "devin/shared-model", object: "model", owned_by: "devin", api: "mock" },
|
||||
{
|
||||
id: "anthropic/shared-model",
|
||||
object: "model",
|
||||
owned_by: "anthropic",
|
||||
api: "mock",
|
||||
display_name: "shared-model",
|
||||
context_length: 200_000,
|
||||
max_output_tokens: 32_768,
|
||||
input_modalities: ["text"],
|
||||
},
|
||||
{
|
||||
id: "devin/shared-model",
|
||||
object: "model",
|
||||
owned_by: "devin",
|
||||
api: "mock",
|
||||
display_name: "shared-model",
|
||||
context_length: 200_000,
|
||||
max_output_tokens: 32_768,
|
||||
input_modalities: ["text"],
|
||||
},
|
||||
],
|
||||
});
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user