overhaul provider inventory and agent/model selection (#8652)

Signed-off-by: Bradley Axen <baxen@squareup.com>
This commit is contained in:
Bradley Axen
2026-04-20 15:00:17 -07:00
committed by GitHub
parent 3d582943fd
commit 8eda6fdabc
70 changed files with 5321 additions and 2123 deletions
+25 -8
View File
@@ -31,8 +31,8 @@ import type {
GetExtensionsResponse,
GetProviderDetailsRequest,
GetProviderDetailsResponse,
GetProviderModelsRequest,
GetProviderModelsResponse,
GetProviderInventoryRequest,
GetProviderInventoryResponse,
GetSessionExtensionsRequest,
GetSessionExtensionsResponse,
GetToolsRequest,
@@ -45,6 +45,8 @@ import type {
ReadConfigResponse,
ReadResourceRequest,
ReadResourceResponse,
RefreshProviderInventoryRequest,
RefreshProviderInventoryResponse,
RemoveConfigRequest,
RemoveExtensionRequest,
RemoveSecretRequest,
@@ -62,13 +64,14 @@ import {
zExportSessionResponse,
zGetExtensionsResponse,
zGetProviderDetailsResponse,
zGetProviderModelsResponse,
zGetProviderInventoryResponse,
zGetSessionExtensionsResponse,
zGetToolsResponse,
zImportSessionResponse,
zListProvidersResponse,
zReadConfigResponse,
zReadResourceResponse,
zRefreshProviderInventoryResponse,
} from './zod.gen.js';
export class GooseExtClient {
@@ -132,11 +135,25 @@ export class GooseExtClient {
return zGetProviderDetailsResponse.parse(raw) as GetProviderDetailsResponse;
}
async GooseProvidersModels(
params: GetProviderModelsRequest,
): Promise<GetProviderModelsResponse> {
const raw = await this.conn.extMethod("_goose/providers/models", params);
return zGetProviderModelsResponse.parse(raw) as GetProviderModelsResponse;
async GooseProvidersInventory(
params: GetProviderInventoryRequest,
): Promise<GetProviderInventoryResponse> {
const raw = await this.conn.extMethod("_goose/providers/inventory", params);
return zGetProviderInventoryResponse.parse(
raw,
) as GetProviderInventoryResponse;
}
async GooseProvidersInventoryRefresh(
params: RefreshProviderInventoryRequest,
): Promise<RefreshProviderInventoryResponse> {
const raw = await this.conn.extMethod(
"_goose/providers/inventory/refresh",
params,
);
return zRefreshProviderInventoryResponse.parse(
raw,
) as RefreshProviderInventoryResponse;
}
async GooseConfigRead(
+9 -4
View File
@@ -1,6 +1,6 @@
// This file is auto-generated by @hey-api/openapi-ts
export type { AddExtensionRequest, ArchiveSessionRequest, CheckSecretRequest, CheckSecretResponse, DeleteSessionRequest, DictationConfigRequest, DictationConfigResponse, DictationDownloadProgress, DictationLocalModelStatus, DictationModelCancelRequest, DictationModelDeleteRequest, DictationModelDownloadProgressRequest, DictationModelDownloadProgressResponse, DictationModelDownloadRequest, DictationModelOption, DictationModelSelectRequest, DictationModelsListRequest, DictationModelsListResponse, DictationProviderStatusEntry, DictationTranscribeRequest, DictationTranscribeResponse, EmptyResponse, ExportSessionRequest, ExportSessionResponse, ExtRequest, ExtResponse, GetExtensionsRequest, GetExtensionsResponse, GetProviderDetailsRequest, GetProviderDetailsResponse, GetProviderModelsRequest, GetProviderModelsResponse, GetSessionExtensionsRequest, GetSessionExtensionsResponse, GetToolsRequest, GetToolsResponse, ImportSessionRequest, ImportSessionResponse, ListProvidersRequest, ListProvidersResponse, ModelEntry, ProviderConfigKey, ProviderDetailEntry, ProviderListEntry, ReadConfigRequest, ReadConfigResponse, ReadResourceRequest, ReadResourceResponse, RemoveConfigRequest, RemoveExtensionRequest, RemoveSecretRequest, UnarchiveSessionRequest, UpdateWorkingDirRequest, UpsertConfigRequest, UpsertSecretRequest } from './types.gen.js';
export type { AddExtensionRequest, ArchiveSessionRequest, CheckSecretRequest, CheckSecretResponse, DeleteSessionRequest, DictationConfigRequest, DictationConfigResponse, DictationDownloadProgress, DictationLocalModelStatus, DictationModelCancelRequest, DictationModelDeleteRequest, DictationModelDownloadProgressRequest, DictationModelDownloadProgressResponse, DictationModelDownloadRequest, DictationModelOption, DictationModelSelectRequest, DictationModelsListRequest, DictationModelsListResponse, DictationProviderStatusEntry, DictationTranscribeRequest, DictationTranscribeResponse, EmptyResponse, ExportSessionRequest, ExportSessionResponse, ExtRequest, ExtResponse, GetExtensionsRequest, GetExtensionsResponse, GetProviderDetailsRequest, GetProviderDetailsResponse, GetProviderInventoryRequest, GetProviderInventoryResponse, GetSessionExtensionsRequest, GetSessionExtensionsResponse, GetToolsRequest, GetToolsResponse, ImportSessionRequest, ImportSessionResponse, ListProvidersRequest, ListProvidersResponse, ModelEntry, ProviderConfigKey, ProviderDetailEntry, ProviderInventoryEntryDto, ProviderInventoryModelDto, ProviderListEntry, ReadConfigRequest, ReadConfigResponse, ReadResourceRequest, ReadResourceResponse, RefreshProviderInventoryRequest, RefreshProviderInventoryResponse, RefreshProviderInventorySkipDto, RefreshProviderInventorySkipReasonDto, RemoveConfigRequest, RemoveExtensionRequest, RemoveSecretRequest, UnarchiveSessionRequest, UpdateWorkingDirRequest, UpsertConfigRequest, UpsertSecretRequest } from './types.gen.js';
export const GOOSE_EXT_METHODS = [
{
@@ -54,9 +54,14 @@ export const GOOSE_EXT_METHODS = [
responseType: "GetProviderDetailsResponse",
},
{
method: "_goose/providers/models",
requestType: "GetProviderModelsRequest",
responseType: "GetProviderModelsResponse",
method: "_goose/providers/inventory",
requestType: "GetProviderInventoryRequest",
responseType: "GetProviderInventoryResponse",
},
{
method: "_goose/providers/inventory/refresh",
requestType: "RefreshProviderInventoryRequest",
responseType: "RefreshProviderInventoryResponse",
},
{
method: "_goose/config/read",
+122 -8
View File
@@ -165,19 +165,133 @@ export type ModelEntry = {
};
/**
* Fetch the full list of models available for a specific provider.
* Read per-provider inventory. Always returns immediately from stored state.
*/
export type GetProviderModelsRequest = {
providerName: string;
export type GetProviderInventoryRequest = {
/**
* Only return entries for these providers. Empty means all.
*/
providerIds?: Array<string>;
};
/**
* Provider models response.
* Provider inventory response.
*/
export type GetProviderModelsResponse = {
models: Array<string>;
export type GetProviderInventoryResponse = {
entries: Array<ProviderInventoryEntryDto>;
};
/**
* Provider inventory entry.
*/
export type ProviderInventoryEntryDto = {
/**
* Provider identifier.
*/
providerId: string;
/**
* Human-readable provider name.
*/
providerName: string;
/**
* Whether Goose has enough configuration to use this provider.
*/
configured: boolean;
/**
* Whether this provider supports background inventory refresh.
*/
supportsRefresh: boolean;
/**
* Whether a refresh is currently in flight.
*/
refreshing: boolean;
/**
* The list of available models.
*/
models: Array<ProviderInventoryModelDto>;
/**
* When this entry was last successfully refreshed (ISO 8601).
*/
lastUpdatedAt?: string | null;
/**
* When a refresh was most recently attempted (ISO 8601).
*/
lastRefreshAttemptAt?: string | null;
/**
* The last refresh failure message, if any.
*/
lastRefreshError?: string | null;
/**
* Whether we believe this data may be outdated.
*/
stale: boolean;
/**
* Guidance message shown when this provider manages its own model selection externally.
*/
modelSelectionHint?: string | null;
};
/**
* A single model in provider inventory.
*/
export type ProviderInventoryModelDto = {
/**
* Model identifier as the provider knows it.
*/
id: string;
/**
* Human-readable display name.
*/
name: string;
/**
* Model family for grouping in UI.
*/
family?: string | null;
/**
* Context window size in tokens.
*/
contextLimit?: number | null;
/**
* Whether the model supports reasoning/extended thinking.
*/
reasoning?: boolean | null;
/**
* Whether this model should appear in the compact recommended picker.
*/
recommended?: boolean;
};
/**
* Trigger a background refresh of provider inventories.
*/
export type RefreshProviderInventoryRequest = {
/**
* Which providers to refresh. Empty means all known providers.
*/
providerIds?: Array<string>;
};
/**
* Refresh acknowledgement.
*/
export type RefreshProviderInventoryResponse = {
/**
* Which providers will be refreshed.
*/
started: Array<string>;
/**
* Which providers were skipped and why.
*/
skipped?: Array<RefreshProviderInventorySkipDto>;
};
export type RefreshProviderInventorySkipDto = {
providerId: string;
reason: RefreshProviderInventorySkipReasonDto;
};
export type RefreshProviderInventorySkipReasonDto = 'unknown_provider' | 'not_configured' | 'does_not_support_refresh' | 'already_refreshing';
/**
* Read a single non-secret config value.
*/
@@ -421,14 +535,14 @@ export type DictationModelSelectRequest = {
export type ExtRequest = {
id: string;
method: string;
params?: AddExtensionRequest | RemoveExtensionRequest | GetToolsRequest | ReadResourceRequest | UpdateWorkingDirRequest | DeleteSessionRequest | GetExtensionsRequest | GetSessionExtensionsRequest | ListProvidersRequest | GetProviderDetailsRequest | GetProviderModelsRequest | ReadConfigRequest | UpsertConfigRequest | RemoveConfigRequest | CheckSecretRequest | UpsertSecretRequest | RemoveSecretRequest | ExportSessionRequest | ImportSessionRequest | ArchiveSessionRequest | UnarchiveSessionRequest | DictationTranscribeRequest | DictationConfigRequest | DictationModelsListRequest | DictationModelDownloadRequest | DictationModelDownloadProgressRequest | DictationModelCancelRequest | DictationModelDeleteRequest | DictationModelSelectRequest | {
params?: AddExtensionRequest | RemoveExtensionRequest | GetToolsRequest | ReadResourceRequest | UpdateWorkingDirRequest | DeleteSessionRequest | GetExtensionsRequest | GetSessionExtensionsRequest | ListProvidersRequest | GetProviderDetailsRequest | GetProviderInventoryRequest | RefreshProviderInventoryRequest | ReadConfigRequest | UpsertConfigRequest | RemoveConfigRequest | CheckSecretRequest | UpsertSecretRequest | RemoveSecretRequest | ExportSessionRequest | ImportSessionRequest | ArchiveSessionRequest | UnarchiveSessionRequest | DictationTranscribeRequest | DictationConfigRequest | DictationModelsListRequest | DictationModelDownloadRequest | DictationModelDownloadProgressRequest | DictationModelCancelRequest | DictationModelDeleteRequest | DictationModelSelectRequest | {
[key: string]: unknown;
} | null;
};
export type ExtResponse = {
id: string;
result?: EmptyResponse | GetToolsResponse | ReadResourceResponse | GetExtensionsResponse | GetSessionExtensionsResponse | ListProvidersResponse | GetProviderDetailsResponse | GetProviderModelsResponse | ReadConfigResponse | CheckSecretResponse | ExportSessionResponse | ImportSessionResponse | DictationTranscribeResponse | DictationConfigResponse | DictationModelsListResponse | DictationModelDownloadProgressResponse | unknown;
result?: EmptyResponse | GetToolsResponse | ReadResourceResponse | GetExtensionsResponse | GetSessionExtensionsResponse | ListProvidersResponse | GetProviderDetailsResponse | GetProviderInventoryResponse | RefreshProviderInventoryResponse | ReadConfigResponse | CheckSecretResponse | ExportSessionResponse | ImportSessionResponse | DictationTranscribeResponse | DictationConfigResponse | DictationModelsListResponse | DictationModelDownloadProgressResponse | unknown;
} | {
error: {
code: number;
+87 -8
View File
@@ -149,17 +149,94 @@ export const zGetProviderDetailsResponse = z.object({
});
/**
* Fetch the full list of models available for a specific provider.
* Read per-provider inventory. Always returns immediately from stored state.
*/
export const zGetProviderModelsRequest = z.object({
providerName: z.string()
export const zGetProviderInventoryRequest = z.object({
providerIds: z.array(z.string()).optional().default([])
});
/**
* Provider models response.
* A single model in provider inventory.
*/
export const zGetProviderModelsResponse = z.object({
models: z.array(z.string())
export const zProviderInventoryModelDto = z.object({
id: z.string(),
name: z.string(),
family: z.union([
z.string(),
z.null()
]).optional(),
contextLimit: z.union([
z.number().int().gte(0),
z.null()
]).optional(),
reasoning: z.union([
z.boolean(),
z.null()
]).optional(),
recommended: z.boolean().optional().default(false)
});
/**
* Provider inventory entry.
*/
export const zProviderInventoryEntryDto = z.object({
providerId: z.string(),
providerName: z.string(),
configured: z.boolean(),
supportsRefresh: z.boolean(),
refreshing: z.boolean(),
models: z.array(zProviderInventoryModelDto),
lastUpdatedAt: z.union([
z.string(),
z.null()
]).optional(),
lastRefreshAttemptAt: z.union([
z.string(),
z.null()
]).optional(),
lastRefreshError: z.union([
z.string(),
z.null()
]).optional(),
stale: z.boolean(),
modelSelectionHint: z.union([
z.string(),
z.null()
]).optional()
});
/**
* Provider inventory response.
*/
export const zGetProviderInventoryResponse = z.object({
entries: z.array(zProviderInventoryEntryDto)
});
/**
* Trigger a background refresh of provider inventories.
*/
export const zRefreshProviderInventoryRequest = z.object({
providerIds: z.array(z.string()).optional().default([])
});
export const zRefreshProviderInventorySkipReasonDto = z.enum([
'unknown_provider',
'not_configured',
'does_not_support_refresh',
'already_refreshing'
]);
export const zRefreshProviderInventorySkipDto = z.object({
providerId: z.string(),
reason: zRefreshProviderInventorySkipReasonDto
});
/**
* Refresh acknowledgement.
*/
export const zRefreshProviderInventoryResponse = z.object({
started: z.array(z.string()),
skipped: z.array(zRefreshProviderInventorySkipDto).optional().default([])
});
/**
@@ -426,7 +503,8 @@ export const zExtRequest = z.object({
zGetSessionExtensionsRequest,
zListProvidersRequest,
zGetProviderDetailsRequest,
zGetProviderModelsRequest,
zGetProviderInventoryRequest,
zRefreshProviderInventoryRequest,
zReadConfigRequest,
zUpsertConfigRequest,
zRemoveConfigRequest,
@@ -465,7 +543,8 @@ export const zExtResponse = z.union([
zGetSessionExtensionsResponse,
zListProvidersResponse,
zGetProviderDetailsResponse,
zGetProviderModelsResponse,
zGetProviderInventoryResponse,
zRefreshProviderInventoryResponse,
zReadConfigResponse,
zCheckSecretResponse,
zExportSessionResponse,