Skip to content
Source
Sign inSign up
Open History to see the last commit

CodexChatGptModels.test.ts

115 lines4.2 KB

1import { assert, it } from "@effect/vitest";
2import * as Effect from "effect/Effect";
3import { HttpClient, HttpClientResponse } from "effect/http";
4import { chatGptModels } from "./CodexChatGptModels.ts";
5​
6it.effect(
7 "uses each selected profile's token and the server's visible catalog order and names",
8 () =>
9 Effect.gen(function* () {
10 const requests: string[] = [];
11 const http = HttpClient.make((request) =>
12 Effect.sync(() => {
13 assert.strictEqual(request.url, "https://api.openai.com/v1/models");
14 requests.push(request.headers.authorization!);
15 return HttpClientResponse.fromWeb(
16 request,
17 new Response(
18 JSON.stringify({
19 models:
20 request.headers.authorization === "Bearer account-a"
21 ? [
22 {
23 slug: "second",
24 display_name: "Second from OpenAI",
25 visibility: "list",
26 default_reasoning_level: "low",
27 supported_reasoning_levels: [
28 { effort: "low", description: "Fast" },
29 { effort: "high", description: "Deep" },
30 ],
31 },
32 {
33 slug: "hidden",
34 display_name: "Hidden",
35 visibility: "hidden",
36 default_reasoning_level: null,
37 supported_reasoning_levels: null,
38 },
39 {
40 slug: "first",
41 display_name: "First from OpenAI",
42 visibility: "list",
43 default_reasoning_level: "high",
44 supported_reasoning_levels: [{ effort: "high", description: "Deep" }],
45 },
46 ]
47 : [
48 {
49 slug: "account-b-only",
50 display_name: "B",
51 visibility: "list",
52 default_reasoning_level: null,
53 supported_reasoning_levels: null,
54 },
55 ],
56 }),
57 ),
58 );
59 }),
60 );
61 const native = [
62 {
63 slug: "first",
64 name: "Cached first",
65 isCustom: false,
66 capabilities: { optionDescriptors: [] },
67 },
68 { slug: "not-entitled", name: "Cached other", isCustom: false, capabilities: null },
69 ];
70 const a = yield* chatGptModels("account-a", native).pipe(
71 Effect.provideService(HttpClient.HttpClient, http),
72 );
73 assert.deepEqual(
74 a.map((model) => [model.slug, model.name]),
75 [
76 ["second", "Second from OpenAI"],
77 ["first", "First from OpenAI"],
78 ],
79 );
80 assert.deepEqual(a[1]!.capabilities, native[0]!.capabilities);
81 assert.deepEqual(a[0]!.capabilities?.optionDescriptors, [
82 {
83 id: "reasoningEffort",
84 label: "Reasoning",
85 type: "select",
86 options: [
87 { id: "low", label: "Low", isDefault: true },
88 { id: "high", label: "High" },
89 ],
90 currentValue: "low",
91 },
92 ]);
93 const b = yield* chatGptModels("account-b", native).pipe(
94 Effect.provideService(HttpClient.HttpClient, http),
95 );
96 assert.deepEqual(
97 b.map((model) => model.slug),
98 ["account-b-only"],
99 );
100 assert.isNull(b[0]!.capabilities);
101 assert.deepEqual(requests, ["Bearer account-a", "Bearer account-b"]);
102 }),
103);
104​
105it.effect("does not present a cached catalog as account entitlements when discovery fails", () =>
106 Effect.gen(function* () {
107 const http = HttpClient.make((request) =>
108 Effect.succeed(HttpClientResponse.fromWeb(request, new Response(null, { status: 503 }))),
109 );
110 const error = yield* Effect.flip(
111 chatGptModels("account-a", []).pipe(Effect.provideService(HttpClient.HttpClient, http)),
112 );
113 assert.strictEqual(error._tag, "ChatGptCatalogError");
114 }),
115);