Skip to content

Commit acb5004

Browse files
authored
Add new Copilot model aliases and upgrade SDK (#36)
* Add new Copilot model aliases and catalog entries * Upgrade Copilot SDK and fix runtime model ordering
1 parent f22fc29 commit acb5004

5 files changed

Lines changed: 70 additions & 28 deletions

File tree

apps/server/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
"dependencies": {
2525
"@effect/platform-node": "catalog:",
2626
"@effect/sql-sqlite-bun": "catalog:",
27-
"@github/copilot": "1.0.2",
28-
"@github/copilot-sdk": "0.1.31-unstable.0",
27+
"@github/copilot": "1.0.7",
28+
"@github/copilot-sdk": "0.1.32",
2929
"@pierre/diffs": "^1.1.0-beta.16",
3030
"effect": "catalog:",
3131
"node-pty": "^1.1.0",

apps/web/src/components/ChatView.logic.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { EventId, TurnId, type OrchestrationThreadActivity } from "@t3tools/cont
22
import { describe, expect, it } from "vitest";
33
import {
44
deriveVisibleThreadWorkLogEntries,
5+
orderCopilotBuiltInModelOptions,
56
resolveProviderHealthBannerProvider,
67
} from "./ChatView.logic";
78

@@ -47,6 +48,29 @@ describe("resolveProviderHealthBannerProvider", () => {
4748
});
4849
});
4950

51+
describe("orderCopilotBuiltInModelOptions", () => {
52+
it("reorders runtime copilot models to match the preferred built-in picker order", () => {
53+
expect(
54+
orderCopilotBuiltInModelOptions([
55+
{ slug: "gpt-5.4", name: "GPT-5.4" },
56+
{ slug: "gpt-5.3-codex", name: "GPT-5.3 Codex" },
57+
{ slug: "gpt-5.4-mini", name: "GPT-5.4 mini" },
58+
{ slug: "gpt-5.2", name: "GPT-5.2" },
59+
]).map((option) => option.slug),
60+
).toEqual(["gpt-5.4", "gpt-5.4-mini", "gpt-5.3-codex", "gpt-5.2"]);
61+
});
62+
63+
it("keeps unknown runtime-only models after the preferred built-in models", () => {
64+
expect(
65+
orderCopilotBuiltInModelOptions([
66+
{ slug: "gpt-5.4", name: "GPT-5.4" },
67+
{ slug: "future-runtime-model", name: "Future Runtime Model" },
68+
{ slug: "gpt-5.4-mini", name: "GPT-5.4 mini" },
69+
]).map((option) => option.slug),
70+
).toEqual(["gpt-5.4", "gpt-5.4-mini", "future-runtime-model"]);
71+
});
72+
});
73+
5074
describe("deriveVisibleThreadWorkLogEntries", () => {
5175
it("keeps completed tool calls from previous turns visible in the thread timeline", () => {
5276
const activities: OrchestrationThreadActivity[] = [

apps/web/src/components/ChatView.logic.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import {
44
type ProviderKind,
55
type ThreadId,
66
} from "@t3tools/contracts";
7+
import { getModelOptions } from "@t3tools/shared/model";
78
import { type ChatMessage, type Thread } from "../types";
89
import { randomUUID } from "~/lib/utils";
9-
import { getAppModelOptions } from "../appSettings";
10+
import { getAppModelOptions, type BuiltInAppModelOption } from "../appSettings";
1011
import { type ComposerImageAttachment, type DraftThreadState } from "../composerDraftStore";
1112
import { Schema } from "effect";
1213
import { deriveWorkLogEntries, type WorkLogEntry } from "../session-logic";
@@ -132,6 +133,34 @@ export function getCustomModelOptionsByProvider(settings: {
132133
};
133134
}
134135

136+
export function orderCopilotBuiltInModelOptions(
137+
runtimeOptions: ReadonlyArray<BuiltInAppModelOption>,
138+
preferredOptions: ReadonlyArray<BuiltInAppModelOption> = getModelOptions("copilot"),
139+
): ReadonlyArray<BuiltInAppModelOption> {
140+
const preferredIndexBySlug = new Map(
141+
preferredOptions.map((option, index) => [option.slug, index] as const),
142+
);
143+
144+
return runtimeOptions
145+
.map((option, runtimeIndex) => ({ option, runtimeIndex }))
146+
.toSorted((left, right) => {
147+
const leftPreferredIndex = preferredIndexBySlug.get(left.option.slug);
148+
const rightPreferredIndex = preferredIndexBySlug.get(right.option.slug);
149+
150+
if (leftPreferredIndex !== undefined && rightPreferredIndex !== undefined) {
151+
return leftPreferredIndex - rightPreferredIndex;
152+
}
153+
if (leftPreferredIndex !== undefined) {
154+
return -1;
155+
}
156+
if (rightPreferredIndex !== undefined) {
157+
return 1;
158+
}
159+
return left.runtimeIndex - right.runtimeIndex;
160+
})
161+
.map(({ option }) => option);
162+
}
163+
135164
export function resolveProviderHealthBannerProvider(input: {
136165
sessionProvider: ProviderKind | null;
137166
selectedProvider: ProviderKind;

apps/web/src/components/ChatView.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ import {
250250
} from "./chat/MessagesTimeline.logic";
251251
import {
252252
deriveVisibleThreadWorkLogEntries,
253+
orderCopilotBuiltInModelOptions,
253254
resolveProviderHealthBannerProvider,
254255
} from "./ChatView.logic";
255256

@@ -1401,7 +1402,9 @@ export default function ChatView({ threadId }: ChatViewProps) {
14011402
codex: getModelOptions("codex"),
14021403
copilot:
14031404
copilotProviderModels.length > 0
1404-
? copilotProviderModels.map((model) => ({ slug: model.id, name: model.name }))
1405+
? orderCopilotBuiltInModelOptions(
1406+
copilotProviderModels.map((model) => ({ slug: model.id, name: model.name })),
1407+
)
14051408
: getModelOptions("copilot"),
14061409
}),
14071410
[copilotProviderModels],

bun.lock

Lines changed: 10 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)