feat(coding-agent): add model catalog refresh flag
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
- Added neutral auth-flow information/link events and provider-owned Amazon Bedrock and Google Vertex AI credential selection flows.
|
||||
- Added `ModelsStore` with an in-memory default for restoring and persisting dynamic provider catalogs.
|
||||
- Added the dynamic Radius `pi-messages` gateway provider with OAuth and credential-specific catalog refresh.
|
||||
- Added `Models.refresh({ force: true })` to let providers bypass freshness checks for explicit refreshes.
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -1047,7 +1047,7 @@ if (result.aborted) console.log('refresh cancelled');
|
||||
for (const [provider, error] of result.errors) console.error(provider, error);
|
||||
```
|
||||
|
||||
Use `models.refresh({ allowNetwork: false })` to restore persisted catalogs without network access. Model reads stay synchronous and return the last restored or refreshed list.
|
||||
Use `models.refresh({ allowNetwork: false })` to restore persisted catalogs without network access, or `models.refresh({ force: true })` to bypass provider freshness checks. Model reads stay synchronous and return the last restored or refreshed list.
|
||||
|
||||
Custom models can carry `headers` (e.g. proxies behind bot detection) and `compat` flags. `Models.getAuth(model)` includes those model headers, and stream methods merge them before explicit request headers and `transformHeaders`. See [OpenAI Compatibility Settings](#openai-compatibility-settings).
|
||||
|
||||
|
||||
@@ -38,11 +38,15 @@ export interface RefreshModelsContext {
|
||||
store: ProviderModelsStore;
|
||||
/** False during offline/cache-only initialization. */
|
||||
allowNetwork: boolean;
|
||||
/** Bypass provider freshness checks and fetch immediately when network access is allowed. */
|
||||
force?: boolean;
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
|
||||
export interface ModelsRefreshOptions {
|
||||
allowNetwork?: boolean;
|
||||
/** Bypass provider freshness checks and fetch immediately when network access is allowed. */
|
||||
force?: boolean;
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
|
||||
@@ -290,7 +294,13 @@ class ModelsImpl implements MutableModels {
|
||||
stored = await this.readCredential(provider.id);
|
||||
const credential = await this.resolveRefreshCredential(provider, stored, allowNetwork, options.signal);
|
||||
if (!credential) return;
|
||||
await provider.refreshModels({ credential, store, allowNetwork, signal: options.signal });
|
||||
await provider.refreshModels({
|
||||
credential,
|
||||
store,
|
||||
allowNetwork,
|
||||
force: options.force,
|
||||
signal: options.signal,
|
||||
});
|
||||
} catch (error) {
|
||||
if (!options.signal?.aborted) {
|
||||
errors.set(
|
||||
|
||||
@@ -283,8 +283,9 @@ describe("Models runtime", () => {
|
||||
expect(offline.getModel("dynamic", "fetched")).toBeDefined();
|
||||
});
|
||||
|
||||
it("passes effective API-key credentials and skips unconfigured providers", async () => {
|
||||
it("passes effective API-key credentials and refresh options while skipping unconfigured providers", async () => {
|
||||
let effectiveCredential: unknown;
|
||||
let forceRefresh: boolean | undefined;
|
||||
let unconfiguredRefreshes = 0;
|
||||
const models = createModels();
|
||||
models.setProvider(
|
||||
@@ -293,6 +294,7 @@ describe("Models runtime", () => {
|
||||
auth: { apiKey: envKeyAuth("ambient-key") },
|
||||
refreshModels: async (context) => {
|
||||
effectiveCredential = context.credential;
|
||||
forceRefresh = context.force;
|
||||
},
|
||||
}),
|
||||
);
|
||||
@@ -306,8 +308,9 @@ describe("Models runtime", () => {
|
||||
}),
|
||||
);
|
||||
|
||||
await models.refresh();
|
||||
await models.refresh({ force: true });
|
||||
expect(effectiveCredential).toEqual({ type: "api_key", key: "ambient-key", env: undefined });
|
||||
expect(forceRefresh).toBe(true);
|
||||
expect(unconfiguredRefreshes).toBe(0);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user