Skip to content

Commit 77848a5

Browse files
Eljo GeorgeCopilot
andcommitted
feat(rust): support model list cache refresh
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent c4bd973 commit 77848a5

5 files changed

Lines changed: 62 additions & 22 deletions

File tree

rust/src/generated/api_types.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8484,7 +8484,7 @@ pub struct ModelSetReasoningEffortResult {
84848484
pub reasoning_effort: String,
84858485
}
84868486

8487-
/// Optional GitHub token and working directory used to resolve available models.
8487+
/// Optional GitHub token, working directory, and cache controls used to resolve available models.
84888488
///
84898489
/// <div class="warning">
84908490
///
@@ -8501,6 +8501,9 @@ pub struct ModelsListRequest {
85018501
/// GitHub token for per-user model listing. When provided, resolves this token to determine the user's Copilot plan and available models instead of using the global auth.
85028502
#[serde(skip_serializing_if = "Option::is_none")]
85038503
pub git_hub_token: Option<String>,
8504+
/// When true, bypasses cached model data and refreshes the available model list.
8505+
#[serde(skip_serializing_if = "Option::is_none")]
8506+
pub skip_cache: Option<bool>,
85048507
}
85058508

85068509
/// Target model identifier and optional reasoning effort, summary, capability overrides, and context tier.

rust/tests/api_types_test.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,23 @@ fn permission_event_exposes_managed_approval_required() {
106106
}
107107

108108
#[test]
109-
fn models_list_request_serializes_repository_cwd() {
109+
fn models_list_request_serializes_repository_options() {
110110
let request = ModelsListRequest {
111111
cwd: Some("/workspace/repository".to_string()),
112112
git_hub_token: None,
113+
skip_cache: Some(true),
113114
};
114115

115116
assert_eq!(
116117
serde_json::to_value(request).unwrap(),
117-
serde_json::json!({ "cwd": "/workspace/repository" })
118+
serde_json::json!({
119+
"cwd": "/workspace/repository",
120+
"skipCache": true
121+
})
122+
);
123+
assert_eq!(
124+
serde_json::to_value(ModelsListRequest::default()).unwrap(),
125+
serde_json::json!({})
118126
);
119127
}
120128

rust/tests/session_test.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4045,7 +4045,7 @@ async fn rpc_namespace_client_models_list_dispatches_correctly() {
40454045
}
40464046

40474047
#[tokio::test]
4048-
async fn rpc_namespace_client_models_list_sends_repository_cwd() {
4048+
async fn rpc_namespace_client_models_list_sends_repository_options() {
40494049
let (session, mut server) = create_session_pair().await;
40504050
let session = Arc::new(session);
40514051

@@ -4057,6 +4057,7 @@ async fn rpc_namespace_client_models_list_sends_repository_cwd() {
40574057
.list_with_params(ModelsListRequest {
40584058
cwd: Some("/workspace/repository".to_string()),
40594059
git_hub_token: None,
4060+
skip_cache: Some(true),
40604061
})
40614062
.await
40624063
});
@@ -4066,7 +4067,8 @@ async fn rpc_namespace_client_models_list_sends_repository_cwd() {
40664067
assert_eq!(
40674068
request["params"],
40684069
serde_json::json!({
4069-
"cwd": "/workspace/repository"
4070+
"cwd": "/workspace/repository",
4071+
"skipCache": true
40704072
})
40714073
);
40724074
server

scripts/codegen/rust.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ import { fileURLToPath } from "url";
1717
import { promisify } from "util";
1818
import type { JSONSchema7, JSONSchema7Definition } from "json-schema";
1919
import {
20-
addCwdToModelsListRequest,
2120
addManagedApprovalRequiredToPermissionRequests,
21+
addModelsListRequestOptions,
2222
type ApiSchema,
2323
type DefinitionCollections,
2424
EXCLUDED_EVENT_TYPES,
@@ -2220,7 +2220,7 @@ async function generate(): Promise<void> {
22202220
);
22212221
const apiSchema = propagateInternalVisibility(
22222222
postProcessSchema(
2223-
stripBooleanLiterals(addCwdToModelsListRequest(apiRaw)) as JSONSchema7,
2223+
stripBooleanLiterals(addModelsListRequestOptions(apiRaw)) as JSONSchema7,
22242224
),
22252225
) as unknown as ApiSchema;
22262226

scripts/codegen/utils.ts

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -497,29 +497,56 @@ export function addManagedApprovalRequiredToPermissionRequests<T extends JSONSch
497497
}
498498

499499
/**
500-
* Add repository scoping to model listing until the pinned CLI schema includes the field.
500+
* Add model listing options until the pinned CLI schema includes the fields.
501501
*/
502-
export function addCwdToModelsListRequest<T extends JSONSchema7>(schema: T): T {
502+
export function addModelsListRequestOptions<T extends JSONSchema7>(schema: T): T {
503503
const cloned = cloneSchemaForCodegen(schema);
504-
const property: JSONSchema7 = {
505-
description:
506-
"Working directory used to apply repository model policy. When omitted, model availability is account-global.",
507-
type: ["string", "null"],
504+
const properties: Record<string, JSONSchema7> = {
505+
cwd: {
506+
description:
507+
"Working directory used to apply repository model policy. When omitted, model availability is account-global.",
508+
type: ["string", "null"],
509+
},
510+
skipCache: {
511+
description:
512+
"When true, bypasses cached model data and refreshes the available model list.",
513+
type: ["boolean", "null"],
514+
},
508515
};
509-
(property as Record<string, unknown>)["x-copilot-sdk-append-last"] = true;
516+
for (const property of Object.values(properties)) {
517+
(property as Record<string, unknown>)["x-copilot-sdk-append-last"] = true;
518+
}
510519

511520
for (const definitions of [cloned.definitions, cloned.$defs]) {
512521
if (!definitions) continue;
513522
const definition = definitions.ModelsListRequest;
514523
if (!definition || typeof definition !== "object") continue;
515-
const objectDefinition = definition as JSONSchema7;
516-
if (objectDefinition.properties?.cwd) continue;
517-
objectDefinition.description =
518-
"Optional GitHub token and working directory used to resolve available models.";
519-
objectDefinition.properties = {
520-
...objectDefinition.properties,
521-
cwd: cloneSchemaForCodegen(property),
522-
};
524+
const requestDefinition = definition as JSONSchema7;
525+
const objectDefinition = [
526+
requestDefinition,
527+
...(requestDefinition.anyOf ?? []),
528+
...(requestDefinition.oneOf ?? []),
529+
].find(
530+
(candidate): candidate is JSONSchema7 =>
531+
typeof candidate === "object" &&
532+
candidate !== null &&
533+
(candidate.type === "object" || candidate.properties !== undefined),
534+
);
535+
if (!objectDefinition) continue;
536+
537+
let patched = false;
538+
for (const [name, property] of Object.entries(properties)) {
539+
if (objectDefinition.properties?.[name]) continue;
540+
objectDefinition.properties = {
541+
...objectDefinition.properties,
542+
[name]: cloneSchemaForCodegen(property),
543+
};
544+
patched = true;
545+
}
546+
if (patched) {
547+
requestDefinition.description =
548+
"Optional GitHub token, working directory, and cache controls used to resolve available models.";
549+
}
523550
}
524551

525552
return cloned;

0 commit comments

Comments
 (0)