@jeffreycao/copilot-api 2.6.24 → 2.6.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/dist/{auth-CiQGjfAS.js → auth-BUdtezdW.js} +6 -4
- package/dist/auth-BUdtezdW.js.map +1 -0
- package/dist/auth-BYKwBiQx.js +2 -0
- package/dist/{config-B_pC8QXv.js → config-B2OaAnpL.js} +24 -370
- package/dist/config-B2OaAnpL.js.map +1 -0
- package/dist/config-store-CARrUljo.js +371 -0
- package/dist/config-store-CARrUljo.js.map +1 -0
- package/dist/{debug-C4rsL806.js → debug-CcfAczV9.js} +3 -2
- package/dist/{debug-C4rsL806.js.map → debug-CcfAczV9.js.map} +1 -1
- package/dist/github-copilot-provider-DlQZgaCT.js +79 -0
- package/dist/github-copilot-provider-DlQZgaCT.js.map +1 -0
- package/dist/main.js +6 -4
- package/dist/main.js.map +1 -1
- package/dist/{models-DG6m2Cfd.js → models-CHdnmX1S.js} +2 -2
- package/dist/{models-DG6m2Cfd.js.map → models-CHdnmX1S.js.map} +1 -1
- package/dist/provider-DktH3jcC.js +36 -0
- package/dist/provider-DktH3jcC.js.map +1 -0
- package/dist/provider-management-z3m7cUkp.js +61 -0
- package/dist/provider-management-z3m7cUkp.js.map +1 -0
- package/dist/{server-D-oBVjPR.js → server-JC3AQpcl.js} +177 -65
- package/dist/server-JC3AQpcl.js.map +1 -0
- package/dist/{start-DqY0wdWh.js → start-bv97pvAG.js} +12 -9
- package/dist/{start-DqY0wdWh.js.map → start-bv97pvAG.js.map} +1 -1
- package/dist/{token-6Ld3Ff3c.js → token-DgVri1k7.js} +16 -63
- package/dist/token-DgVri1k7.js.map +1 -0
- package/package.json +2 -1
- package/dist/auth-CiQGjfAS.js.map +0 -1
- package/dist/auth-D2amX0hm.js +0 -2
- package/dist/config-B_pC8QXv.js.map +0 -1
- package/dist/server-D-oBVjPR.js.map +0 -1
- package/dist/token-6Ld3Ff3c.js.map +0 -1
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { c as getConfig } from "./config-store-CARrUljo.js";
|
|
2
|
+
import consola from "consola";
|
|
3
|
+
//#region src/lib/error.ts
|
|
4
|
+
var HTTPError = class extends Error {
|
|
5
|
+
response;
|
|
6
|
+
constructor(message, response) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.response = response;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
var UpstreamHeadersTimeoutError = class extends Error {
|
|
12
|
+
timeoutMs;
|
|
13
|
+
constructor(timeoutMs) {
|
|
14
|
+
super(`Upstream did not return headers within ${timeoutMs}ms`);
|
|
15
|
+
this.name = "UpstreamHeadersTimeoutError";
|
|
16
|
+
this.timeoutMs = timeoutMs;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
var UpstreamStreamInactivityTimeoutError = class extends Error {
|
|
20
|
+
timeoutMs;
|
|
21
|
+
constructor(timeoutMs) {
|
|
22
|
+
super(`Upstream stream was inactive for ${timeoutMs}ms`);
|
|
23
|
+
this.name = "UpstreamStreamInactivityTimeoutError";
|
|
24
|
+
this.timeoutMs = timeoutMs;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
async function forwardError(c, error) {
|
|
28
|
+
if (error instanceof UpstreamHeadersTimeoutError || error instanceof UpstreamStreamInactivityTimeoutError) {
|
|
29
|
+
consola.error("Error occurred:", error);
|
|
30
|
+
return c.json({ error: {
|
|
31
|
+
message: error.message,
|
|
32
|
+
type: "upstream_timeout"
|
|
33
|
+
} }, 504);
|
|
34
|
+
}
|
|
35
|
+
if (c.req.raw.signal.aborted || isAbortError(error)) return new Response(null, {
|
|
36
|
+
status: 499,
|
|
37
|
+
statusText: "Client Closed Request"
|
|
38
|
+
});
|
|
39
|
+
consola.error("Error occurred:", error);
|
|
40
|
+
if (error instanceof HTTPError) {
|
|
41
|
+
if (error.response.status === 429) for (const [name, value] of error.response.headers) {
|
|
42
|
+
const lowerName = name.toLowerCase();
|
|
43
|
+
if (lowerName === "retry-after" || lowerName.startsWith("x-")) c.header(name, value);
|
|
44
|
+
}
|
|
45
|
+
const errorText = await error.response.text();
|
|
46
|
+
let errorJson;
|
|
47
|
+
try {
|
|
48
|
+
errorJson = JSON.parse(errorText);
|
|
49
|
+
} catch {
|
|
50
|
+
errorJson = errorText;
|
|
51
|
+
}
|
|
52
|
+
consola.error("HTTP error:", errorJson);
|
|
53
|
+
return c.json({ error: {
|
|
54
|
+
message: errorText,
|
|
55
|
+
type: "error"
|
|
56
|
+
} }, error.response.status);
|
|
57
|
+
}
|
|
58
|
+
return c.json({ error: {
|
|
59
|
+
message: error.message,
|
|
60
|
+
type: "error"
|
|
61
|
+
} }, 500);
|
|
62
|
+
}
|
|
63
|
+
const isAbortError = (error) => error instanceof Error && error.name === "AbortError";
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/lib/github-copilot-provider.ts
|
|
66
|
+
const GITHUB_COPILOT_PROVIDER = "github-copilot";
|
|
67
|
+
function isGitHubCopilotEnabled(config = getConfig()) {
|
|
68
|
+
return config.providers?.[GITHUB_COPILOT_PROVIDER]?.enabled !== false;
|
|
69
|
+
}
|
|
70
|
+
function assertGitHubCopilotEnabled() {
|
|
71
|
+
if (!isGitHubCopilotEnabled()) throw new HTTPError("GitHub Copilot provider is disabled", Response.json({ error: {
|
|
72
|
+
message: "GitHub Copilot provider is disabled",
|
|
73
|
+
type: "provider_disabled"
|
|
74
|
+
} }, { status: 403 }));
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
export { UpstreamHeadersTimeoutError as a, HTTPError as i, assertGitHubCopilotEnabled as n, UpstreamStreamInactivityTimeoutError as o, isGitHubCopilotEnabled as r, forwardError as s, GITHUB_COPILOT_PROVIDER as t };
|
|
78
|
+
|
|
79
|
+
//# sourceMappingURL=github-copilot-provider-DlQZgaCT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-copilot-provider-DlQZgaCT.js","names":[],"sources":["../src/lib/error.ts","../src/lib/github-copilot-provider.ts"],"sourcesContent":["import type { Context } from \"hono\"\nimport type { ContentfulStatusCode } from \"hono/utils/http-status\"\n\nimport consola from \"consola\"\n\nexport class HTTPError extends Error {\n response: Response\n\n constructor(message: string, response: Response) {\n super(message)\n this.response = response\n }\n}\n\nexport class UpstreamHeadersTimeoutError extends Error {\n readonly timeoutMs: number\n\n constructor(timeoutMs: number) {\n super(`Upstream did not return headers within ${timeoutMs}ms`)\n this.name = \"UpstreamHeadersTimeoutError\"\n this.timeoutMs = timeoutMs\n }\n}\n\nexport class UpstreamStreamInactivityTimeoutError extends Error {\n readonly timeoutMs: number\n\n constructor(timeoutMs: number) {\n super(`Upstream stream was inactive for ${timeoutMs}ms`)\n this.name = \"UpstreamStreamInactivityTimeoutError\"\n this.timeoutMs = timeoutMs\n }\n}\n\nexport async function forwardError(\n c: Context,\n error: unknown,\n): Promise<Response> {\n if (\n error instanceof UpstreamHeadersTimeoutError\n || error instanceof UpstreamStreamInactivityTimeoutError\n ) {\n consola.error(\"Error occurred:\", error)\n return c.json(\n {\n error: {\n message: error.message,\n type: \"upstream_timeout\",\n },\n },\n 504,\n )\n }\n\n if (c.req.raw.signal.aborted || isAbortError(error)) {\n return new Response(null, {\n status: 499,\n statusText: \"Client Closed Request\",\n })\n }\n\n consola.error(\"Error occurred:\", error)\n\n if (error instanceof HTTPError) {\n if (error.response.status === 429) {\n for (const [name, value] of error.response.headers) {\n const lowerName = name.toLowerCase()\n if (lowerName === \"retry-after\" || lowerName.startsWith(\"x-\")) {\n c.header(name, value)\n }\n }\n }\n\n const errorText = await error.response.text()\n let errorJson: unknown\n try {\n errorJson = JSON.parse(errorText)\n } catch {\n errorJson = errorText\n }\n consola.error(\"HTTP error:\", errorJson)\n return c.json(\n {\n error: {\n message: errorText,\n type: \"error\",\n },\n },\n error.response.status as ContentfulStatusCode,\n )\n }\n\n return c.json(\n {\n error: {\n message: (error as Error).message,\n type: \"error\",\n },\n },\n 500,\n )\n}\n\nconst isAbortError = (error: unknown): boolean =>\n error instanceof Error && error.name === \"AbortError\"\n","import { getConfig, type AppConfig } from \"./config-store\"\nimport { HTTPError } from \"./error\"\n\nexport const GITHUB_COPILOT_PROVIDER = \"github-copilot\"\n\n// Missing configuration preserves the legacy builtin Copilot behavior.\nexport function isGitHubCopilotEnabled(\n config: AppConfig = getConfig(),\n): boolean {\n return config.providers?.[GITHUB_COPILOT_PROVIDER]?.enabled !== false\n}\n\nexport function assertGitHubCopilotEnabled(): void {\n if (!isGitHubCopilotEnabled()) {\n throw new HTTPError(\n \"GitHub Copilot provider is disabled\",\n Response.json(\n {\n error: {\n message: \"GitHub Copilot provider is disabled\",\n type: \"provider_disabled\",\n },\n },\n { status: 403 },\n ),\n )\n }\n}\n"],"mappings":";;;AAKA,IAAa,YAAb,cAA+B,MAAM;CACnC;CAEA,YAAY,SAAiB,UAAoB;EAC/C,MAAM,OAAO;EACb,KAAK,WAAW;CAClB;AACF;AAEA,IAAa,8BAAb,cAAiD,MAAM;CACrD;CAEA,YAAY,WAAmB;EAC7B,MAAM,0CAA0C,UAAU,GAAG;EAC7D,KAAK,OAAO;EACZ,KAAK,YAAY;CACnB;AACF;AAEA,IAAa,uCAAb,cAA0D,MAAM;CAC9D;CAEA,YAAY,WAAmB;EAC7B,MAAM,oCAAoC,UAAU,GAAG;EACvD,KAAK,OAAO;EACZ,KAAK,YAAY;CACnB;AACF;AAEA,eAAsB,aACpB,GACA,OACmB;CACnB,IACE,iBAAiB,+BACd,iBAAiB,sCACpB;EACA,QAAQ,MAAM,mBAAmB,KAAK;EACtC,OAAO,EAAE,KACP,EACE,OAAO;GACL,SAAS,MAAM;GACf,MAAM;EACR,EACF,GACA,GACF;CACF;CAEA,IAAI,EAAE,IAAI,IAAI,OAAO,WAAW,aAAa,KAAK,GAChD,OAAO,IAAI,SAAS,MAAM;EACxB,QAAQ;EACR,YAAY;CACd,CAAC;CAGH,QAAQ,MAAM,mBAAmB,KAAK;CAEtC,IAAI,iBAAiB,WAAW;EAC9B,IAAI,MAAM,SAAS,WAAW,KAC5B,KAAK,MAAM,CAAC,MAAM,UAAU,MAAM,SAAS,SAAS;GAClD,MAAM,YAAY,KAAK,YAAY;GACnC,IAAI,cAAc,iBAAiB,UAAU,WAAW,IAAI,GAC1D,EAAE,OAAO,MAAM,KAAK;EAExB;EAGF,MAAM,YAAY,MAAM,MAAM,SAAS,KAAK;EAC5C,IAAI;EACJ,IAAI;GACF,YAAY,KAAK,MAAM,SAAS;EAClC,QAAQ;GACN,YAAY;EACd;EACA,QAAQ,MAAM,eAAe,SAAS;EACtC,OAAO,EAAE,KACP,EACE,OAAO;GACL,SAAS;GACT,MAAM;EACR,EACF,GACA,MAAM,SAAS,MACjB;CACF;CAEA,OAAO,EAAE,KACP,EACE,OAAO;EACL,SAAU,MAAgB;EAC1B,MAAM;CACR,EACF,GACA,GACF;AACF;AAEA,MAAM,gBAAgB,UACpB,iBAAiB,SAAS,MAAM,SAAS;;;ACrG3C,MAAa,0BAA0B;AAGvC,SAAgB,uBACd,SAAoB,UAAU,GACrB;CACT,OAAO,OAAO,YAAY,wBAAwB,EAAE,YAAY;AAClE;AAEA,SAAgB,6BAAmC;CACjD,IAAI,CAAC,uBAAuB,GAC1B,MAAM,IAAI,UACR,uCACA,SAAS,KACP,EACE,OAAO;EACL,SAAS;EACT,MAAM;CACR,EACF,GACA,EAAE,QAAQ,IAAI,CAChB,CACF;AAEJ"}
|
package/dist/main.js
CHANGED
|
@@ -27,10 +27,11 @@ if (isMcpFastPath(process.argv)) {
|
|
|
27
27
|
if (process.platform === "win32" && process.stdout.isTTY && !process.env.WT_SESSION) process.env.WT_SESSION = "copilot-api";
|
|
28
28
|
const { bindElectronFetch } = await import("./electron-fetch-DsMaRX6v.js");
|
|
29
29
|
bindElectronFetch();
|
|
30
|
-
const { auth } = await import("./auth-
|
|
31
|
-
const { debug } = await import("./debug-
|
|
30
|
+
const { auth } = await import("./auth-BYKwBiQx.js");
|
|
31
|
+
const { debug } = await import("./debug-CcfAczV9.js");
|
|
32
32
|
const { mcp } = await import("./mcp-Byz9h_xz.js");
|
|
33
|
-
const { start } = await import("./start-
|
|
33
|
+
const { start } = await import("./start-bv97pvAG.js");
|
|
34
|
+
const { provider } = await import("./provider-DktH3jcC.js");
|
|
34
35
|
await runMain(defineCommand({
|
|
35
36
|
meta: {
|
|
36
37
|
name: "copilot-api",
|
|
@@ -40,7 +41,8 @@ if (isMcpFastPath(process.argv)) {
|
|
|
40
41
|
auth,
|
|
41
42
|
start,
|
|
42
43
|
debug,
|
|
43
|
-
mcp
|
|
44
|
+
mcp,
|
|
45
|
+
provider
|
|
44
46
|
},
|
|
45
47
|
args: cliArgs
|
|
46
48
|
}));
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","names":[],"sources":["../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { isMcpFastPath } from \"./lib/fast-path\"\n\n// Fast path: `copilot-api mcp` starts the MCP bridge without loading citty\n// or the gateway modules, keeping MCP client startup fast.\nif (isMcpFastPath(process.argv)) {\n const { runMcpServer } = await import(\"./lib/mcp-server\")\n await runMcpServer()\n} else {\n const { defineCommand, runMain, parseArgs } = await import(\"citty\")\n\n const cliArgs = {\n \"api-home\": {\n type: \"string\",\n description: \"Path to the API home directory.\",\n },\n \"oauth-app\": {\n type: \"string\",\n description: \"OAuth app identifier.\",\n },\n \"enterprise-url\": {\n type: \"string\",\n description: \"Enterprise URL for GitHub.\",\n },\n } as const\n\n const args = parseArgs(process.argv, cliArgs)\n\n // Set environment variables before loading other modules\n if (typeof args[\"api-home\"] === \"string\") {\n process.env.COPILOT_API_HOME = args[\"api-home\"]\n }\n if (typeof args[\"oauth-app\"] === \"string\") {\n process.env.COPILOT_API_OAUTH_APP = args[\"oauth-app\"]\n }\n if (typeof args[\"enterprise-url\"] === \"string\") {\n process.env.COPILOT_API_ENTERPRISE_URL = args[\"enterprise-url\"]\n }\n\n // Work around unjs/consola#392 until consola ships the upstream fix.\n if (\n process.platform === \"win32\"\n && process.stdout.isTTY\n && !process.env.WT_SESSION\n ) {\n process.env.WT_SESSION = \"copilot-api\"\n }\n\n const { bindElectronFetch } = await import(\"./lib/electron-fetch\")\n bindElectronFetch()\n\n // Dynamically import other modules to ensure environment variables are set\n const { auth } = await import(\"./auth\")\n const { debug } = await import(\"./debug\")\n const { mcp } = await import(\"./mcp\")\n const { start } = await import(\"./start\")\n\n const main = defineCommand({\n meta: {\n name: \"copilot-api\",\n description:\n \"A wrapper around GitHub Copilot API to make it OpenAI compatible, making it usable for other tools.\",\n },\n subCommands: { auth, start, debug, mcp },\n args: cliArgs,\n })\n\n await runMain(main)\n}\n"],"mappings":";;;AAMA,IAAI,cAAc,QAAQ,IAAI,GAAG;CAC/B,MAAM,EAAE,iBAAiB,MAAM,OAAO;CACtC,MAAM,aAAa;AACrB,OAAO;CACL,MAAM,EAAE,eAAe,SAAS,cAAc,MAAM,OAAO;CAE3D,MAAM,UAAU;EACd,YAAY;GACV,MAAM;GACN,aAAa;EACf;EACA,aAAa;GACX,MAAM;GACN,aAAa;EACf;EACA,kBAAkB;GAChB,MAAM;GACN,aAAa;EACf;CACF;CAEA,MAAM,OAAO,UAAU,QAAQ,MAAM,OAAO;CAG5C,IAAI,OAAO,KAAK,gBAAgB,UAC9B,QAAQ,IAAI,mBAAmB,KAAK;CAEtC,IAAI,OAAO,KAAK,iBAAiB,UAC/B,QAAQ,IAAI,wBAAwB,KAAK;CAE3C,IAAI,OAAO,KAAK,sBAAsB,UACpC,QAAQ,IAAI,6BAA6B,KAAK;CAIhD,IACE,QAAQ,aAAa,WAClB,QAAQ,OAAO,SACf,CAAC,QAAQ,IAAI,YAEhB,QAAQ,IAAI,aAAa;CAG3B,MAAM,EAAE,sBAAsB,MAAM,OAAO;CAC3C,kBAAkB;CAGlB,MAAM,EAAE,SAAS,MAAM,OAAO;CAC9B,MAAM,EAAE,UAAU,MAAM,OAAO;CAC/B,MAAM,EAAE,QAAQ,MAAM,OAAO;CAC7B,MAAM,EAAE,UAAU,MAAM,OAAO;
|
|
1
|
+
{"version":3,"file":"main.js","names":[],"sources":["../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { isMcpFastPath } from \"./lib/fast-path\"\n\n// Fast path: `copilot-api mcp` starts the MCP bridge without loading citty\n// or the gateway modules, keeping MCP client startup fast.\nif (isMcpFastPath(process.argv)) {\n const { runMcpServer } = await import(\"./lib/mcp-server\")\n await runMcpServer()\n} else {\n const { defineCommand, runMain, parseArgs } = await import(\"citty\")\n\n const cliArgs = {\n \"api-home\": {\n type: \"string\",\n description: \"Path to the API home directory.\",\n },\n \"oauth-app\": {\n type: \"string\",\n description: \"OAuth app identifier.\",\n },\n \"enterprise-url\": {\n type: \"string\",\n description: \"Enterprise URL for GitHub.\",\n },\n } as const\n\n const args = parseArgs(process.argv, cliArgs)\n\n // Set environment variables before loading other modules\n if (typeof args[\"api-home\"] === \"string\") {\n process.env.COPILOT_API_HOME = args[\"api-home\"]\n }\n if (typeof args[\"oauth-app\"] === \"string\") {\n process.env.COPILOT_API_OAUTH_APP = args[\"oauth-app\"]\n }\n if (typeof args[\"enterprise-url\"] === \"string\") {\n process.env.COPILOT_API_ENTERPRISE_URL = args[\"enterprise-url\"]\n }\n\n // Work around unjs/consola#392 until consola ships the upstream fix.\n if (\n process.platform === \"win32\"\n && process.stdout.isTTY\n && !process.env.WT_SESSION\n ) {\n process.env.WT_SESSION = \"copilot-api\"\n }\n\n const { bindElectronFetch } = await import(\"./lib/electron-fetch\")\n bindElectronFetch()\n\n // Dynamically import other modules to ensure environment variables are set\n const { auth } = await import(\"./auth\")\n const { debug } = await import(\"./debug\")\n const { mcp } = await import(\"./mcp\")\n const { start } = await import(\"./start\")\n const { provider } = await import(\"./provider\")\n\n const main = defineCommand({\n meta: {\n name: \"copilot-api\",\n description:\n \"A wrapper around GitHub Copilot API to make it OpenAI compatible, making it usable for other tools.\",\n },\n subCommands: { auth, start, debug, mcp, provider },\n args: cliArgs,\n })\n\n await runMain(main)\n}\n"],"mappings":";;;AAMA,IAAI,cAAc,QAAQ,IAAI,GAAG;CAC/B,MAAM,EAAE,iBAAiB,MAAM,OAAO;CACtC,MAAM,aAAa;AACrB,OAAO;CACL,MAAM,EAAE,eAAe,SAAS,cAAc,MAAM,OAAO;CAE3D,MAAM,UAAU;EACd,YAAY;GACV,MAAM;GACN,aAAa;EACf;EACA,aAAa;GACX,MAAM;GACN,aAAa;EACf;EACA,kBAAkB;GAChB,MAAM;GACN,aAAa;EACf;CACF;CAEA,MAAM,OAAO,UAAU,QAAQ,MAAM,OAAO;CAG5C,IAAI,OAAO,KAAK,gBAAgB,UAC9B,QAAQ,IAAI,mBAAmB,KAAK;CAEtC,IAAI,OAAO,KAAK,iBAAiB,UAC/B,QAAQ,IAAI,wBAAwB,KAAK;CAE3C,IAAI,OAAO,KAAK,sBAAsB,UACpC,QAAQ,IAAI,6BAA6B,KAAK;CAIhD,IACE,QAAQ,aAAa,WAClB,QAAQ,OAAO,SACf,CAAC,QAAQ,IAAI,YAEhB,QAAQ,IAAI,aAAa;CAG3B,MAAM,EAAE,sBAAsB,MAAM,OAAO;CAC3C,kBAAkB;CAGlB,MAAM,EAAE,SAAS,MAAM,OAAO;CAC9B,MAAM,EAAE,UAAU,MAAM,OAAO;CAC/B,MAAM,EAAE,QAAQ,MAAM,OAAO;CAC7B,MAAM,EAAE,UAAU,MAAM,OAAO;CAC/B,MAAM,EAAE,aAAa,MAAM,OAAO;CAYlC,MAAM,QAVO,cAAc;EACzB,MAAM;GACJ,MAAM;GACN,aACE;EACJ;EACA,aAAa;GAAE;GAAM;GAAO;GAAO;GAAK;EAAS;EACjD,MAAM;CACR,CAEiB,CAAC;AACpB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Z as state } from "./token-
|
|
1
|
+
import { Z as state } from "./token-DgVri1k7.js";
|
|
2
2
|
//#region src/lib/models.ts
|
|
3
3
|
/**
|
|
4
4
|
* Converts a Copilot upstream model ID to a client-friendly ID that Claude Code
|
|
@@ -87,4 +87,4 @@ const normalizeSdkModelId = (sdkModelId) => {
|
|
|
87
87
|
//#endregion
|
|
88
88
|
export { toClientModelId as i, getLatestModelForFamily as n, normalizeSdkModelId as r, findEndpointModel as t };
|
|
89
89
|
|
|
90
|
-
//# sourceMappingURL=models-
|
|
90
|
+
//# sourceMappingURL=models-CHdnmX1S.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models-
|
|
1
|
+
{"version":3,"file":"models-CHdnmX1S.js","names":[],"sources":["../src/lib/models.ts"],"sourcesContent":["import type { Model } from \"~/lib/types/models\"\n\nimport { state } from \"~/lib/state\"\n\n/**\n * Converts a Copilot upstream model ID to a client-friendly ID that Claude Code\n * and Claude Desktop recognize (dots in version replaced with hyphens).\n * e.g. \"claude-sonnet-4.6\" -> \"claude-sonnet-4-6\"\n * Non-Claude models are returned unchanged.\n */\nexport const toClientModelId = (modelId: string): string => {\n const normalized = normalizeSdkModelId(modelId)\n if (!normalized) return modelId\n const versionHyphenated = normalized.version.replaceAll(\".\", \"-\")\n return `claude-${normalized.family}-${versionHyphenated}`\n}\n\nexport interface NormalizedSdkModelId {\n family: string\n version: string\n}\n\nexport const findEndpointModel = (sdkModelId: string): Model | undefined => {\n const models = state.models?.data ?? []\n const exactMatch = models.find((m) => m.id === sdkModelId)\n if (exactMatch) {\n return exactMatch\n }\n\n const normalized = normalizeSdkModelId(sdkModelId)\n if (!normalized) {\n return undefined\n }\n\n const modelName = `claude-${normalized.family}-${normalized.version}`\n const model = models.find((m) => m.id === modelName)\n if (model) {\n return model\n }\n\n return undefined\n}\n\n/**\n * Finds the latest available model for a given Claude family (e.g. \"opus\",\n * \"sonnet\", \"haiku\") among the models currently cached in `state.models`.\n * \"Latest\" is determined by the highest semantic version parsed from the model\n * ID. Returns `undefined` when no model of that family is available.\n */\nexport const getLatestModelForFamily = (family: string): Model | undefined => {\n const models = state.models?.data ?? []\n\n let best: { model: Model; major: number; minor: number } | undefined\n\n for (const model of models) {\n const normalized = normalizeSdkModelId(model.id)\n if (!normalized || normalized.family !== family) {\n continue\n }\n\n const [majorPart, minorPart = \"0\"] = normalized.version.split(\".\")\n const major = Number.parseInt(majorPart, 10)\n const minor = Number.parseInt(minorPart, 10)\n if (Number.isNaN(major) || Number.isNaN(minor)) {\n continue\n }\n\n if (\n !best\n || major > best.major\n || (major === best.major && minor > best.minor)\n ) {\n best = { model, major, minor }\n }\n }\n\n return best?.model\n}\n\n/**\n * Normalizes an SDK model ID to extract the model family and version.\n * this method from github copilot extension\n * Examples:\n * - \"claude-opus-4-5-20251101\" -> { family: \"opus\", version: \"4.5\" }\n * - \"claude-3-5-sonnet-20241022\" -> { family: \"sonnet\", version: \"3.5\" }\n * - \"claude-sonnet-4-20250514\" -> { family: \"sonnet\", version: \"4\" }\n * - \"claude-haiku-3-5-20250514\" -> { family: \"haiku\", version: \"3.5\" }\n * - \"claude-haiku-4.5\" -> { family: \"haiku\", version: \"4.5\" }\n */\nexport const normalizeSdkModelId = (\n sdkModelId: string,\n): NormalizedSdkModelId | undefined => {\n const lower = sdkModelId.toLowerCase()\n\n // Strip date suffix (8 digits at the end)\n const withoutDate = lower.replace(/-\\d{8}$/, \"\")\n\n // Pattern 1: claude-{family}-{major}.{minor} (e.g., claude-haiku-4.5)\n const pattern1 = withoutDate.match(/^claude-(\\w+)-(\\d+)\\.(\\d+)$/)\n if (pattern1) {\n return { family: pattern1[1], version: `${pattern1[2]}.${pattern1[3]}` }\n }\n\n // Pattern 2: claude-{family}-{major}-{minor} (e.g., claude-opus-4-5, claude-haiku-3-5)\n const pattern2 = withoutDate.match(/^claude-(\\w+)-(\\d+)-(\\d+)$/)\n if (pattern2) {\n return { family: pattern2[1], version: `${pattern2[2]}.${pattern2[3]}` }\n }\n\n // Pattern 3: claude-{major}-{minor}-{family} (e.g., claude-3-5-sonnet)\n const pattern3 = withoutDate.match(/^claude-(\\d+)-(\\d+)-(\\w+)$/)\n if (pattern3) {\n return { family: pattern3[3], version: `${pattern3[1]}.${pattern3[2]}` }\n }\n\n // Pattern 4: claude-{family}-{major} (e.g., claude-sonnet-4)\n const pattern4 = withoutDate.match(/^claude-(\\w+)-(\\d+)$/)\n if (pattern4) {\n return { family: pattern4[1], version: pattern4[2] }\n }\n\n // Pattern 5: claude-{major}-{family} (e.g., claude-3-opus)\n const pattern5 = withoutDate.match(/^claude-(\\d+)-(\\w+)$/)\n if (pattern5) {\n return { family: pattern5[2], version: pattern5[1] }\n }\n\n return undefined\n}\n"],"mappings":";;;;;;;;AAUA,MAAa,mBAAmB,YAA4B;CAC1D,MAAM,aAAa,oBAAoB,OAAO;CAC9C,IAAI,CAAC,YAAY,OAAO;CACxB,MAAM,oBAAoB,WAAW,QAAQ,WAAW,KAAK,GAAG;CAChE,OAAO,UAAU,WAAW,OAAO,GAAG;AACxC;AAOA,MAAa,qBAAqB,eAA0C;CAC1E,MAAM,SAAS,MAAM,QAAQ,QAAQ,CAAC;CACtC,MAAM,aAAa,OAAO,MAAM,MAAM,EAAE,OAAO,UAAU;CACzD,IAAI,YACF,OAAO;CAGT,MAAM,aAAa,oBAAoB,UAAU;CACjD,IAAI,CAAC,YACH;CAGF,MAAM,YAAY,UAAU,WAAW,OAAO,GAAG,WAAW;CAC5D,MAAM,QAAQ,OAAO,MAAM,MAAM,EAAE,OAAO,SAAS;CACnD,IAAI,OACF,OAAO;AAIX;;;;;;;AAQA,MAAa,2BAA2B,WAAsC;CAC5E,MAAM,SAAS,MAAM,QAAQ,QAAQ,CAAC;CAEtC,IAAI;CAEJ,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,aAAa,oBAAoB,MAAM,EAAE;EAC/C,IAAI,CAAC,cAAc,WAAW,WAAW,QACvC;EAGF,MAAM,CAAC,WAAW,YAAY,OAAO,WAAW,QAAQ,MAAM,GAAG;EACjE,MAAM,QAAQ,OAAO,SAAS,WAAW,EAAE;EAC3C,MAAM,QAAQ,OAAO,SAAS,WAAW,EAAE;EAC3C,IAAI,OAAO,MAAM,KAAK,KAAK,OAAO,MAAM,KAAK,GAC3C;EAGF,IACE,CAAC,QACE,QAAQ,KAAK,SACZ,UAAU,KAAK,SAAS,QAAQ,KAAK,OAEzC,OAAO;GAAE;GAAO;GAAO;EAAM;CAEjC;CAEA,OAAO,MAAM;AACf;;;;;;;;;;;AAYA,MAAa,uBACX,eACqC;CAIrC,MAAM,cAHQ,WAAW,YAGD,CAAC,CAAC,QAAQ,WAAW,EAAE;CAG/C,MAAM,WAAW,YAAY,MAAM,6BAA6B;CAChE,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,GAAG,SAAS,GAAG,GAAG,SAAS;CAAK;CAIzE,MAAM,WAAW,YAAY,MAAM,4BAA4B;CAC/D,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,GAAG,SAAS,GAAG,GAAG,SAAS;CAAK;CAIzE,MAAM,WAAW,YAAY,MAAM,4BAA4B;CAC/D,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,GAAG,SAAS,GAAG,GAAG,SAAS;CAAK;CAIzE,MAAM,WAAW,YAAY,MAAM,sBAAsB;CACzD,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,SAAS;CAAG;CAIrD,MAAM,WAAW,YAAY,MAAM,sBAAsB;CACzD,IAAI,UACF,OAAO;EAAE,QAAQ,SAAS;EAAI,SAAS,SAAS;CAAG;AAIvD"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { r as saveProviderManagementConfig } from "./provider-management-z3m7cUkp.js";
|
|
2
|
+
import { defineCommand } from "citty";
|
|
3
|
+
//#region src/provider.ts
|
|
4
|
+
function providerStateCommand(enabled) {
|
|
5
|
+
return defineCommand({
|
|
6
|
+
meta: { description: `${enabled ? "Enable" : "Disable"} a configured provider` },
|
|
7
|
+
args: { name: {
|
|
8
|
+
type: "positional",
|
|
9
|
+
required: true,
|
|
10
|
+
description: "Provider name"
|
|
11
|
+
} },
|
|
12
|
+
run({ args }) {
|
|
13
|
+
try {
|
|
14
|
+
saveProviderManagementConfig({ providers: { [args.name]: { enabled } } });
|
|
15
|
+
process.stdout.write(`Provider '${args.name}' ${enabled ? "enabled" : "disabled"}. Restart the running server to apply the change.\n`);
|
|
16
|
+
} catch (error) {
|
|
17
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
18
|
+
process.exitCode = 1;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
const provider = defineCommand({
|
|
24
|
+
meta: {
|
|
25
|
+
name: "provider",
|
|
26
|
+
description: "Manage configured providers"
|
|
27
|
+
},
|
|
28
|
+
subCommands: {
|
|
29
|
+
enable: providerStateCommand(true),
|
|
30
|
+
disable: providerStateCommand(false)
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
//#endregion
|
|
34
|
+
export { provider };
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=provider-DktH3jcC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-DktH3jcC.js","names":[],"sources":["../src/provider.ts"],"sourcesContent":["import { defineCommand } from \"citty\"\n\nimport { saveProviderManagementConfig } from \"./lib/provider-management\"\n\nfunction providerStateCommand(enabled: boolean) {\n return defineCommand({\n meta: {\n description: `${enabled ? \"Enable\" : \"Disable\"} a configured provider`,\n },\n args: {\n name: {\n type: \"positional\",\n required: true,\n description: \"Provider name\",\n },\n },\n run({ args }) {\n try {\n saveProviderManagementConfig({\n providers: { [args.name]: { enabled } },\n })\n process.stdout.write(\n `Provider '${args.name}' ${enabled ? \"enabled\" : \"disabled\"}. Restart the running server to apply the change.\\n`,\n )\n } catch (error) {\n process.stderr.write(\n `${error instanceof Error ? error.message : String(error)}\\n`,\n )\n process.exitCode = 1\n }\n },\n })\n}\n\nexport const provider = defineCommand({\n meta: { name: \"provider\", description: \"Manage configured providers\" },\n subCommands: {\n enable: providerStateCommand(true),\n disable: providerStateCommand(false),\n },\n})\n"],"mappings":";;;AAIA,SAAS,qBAAqB,SAAkB;CAC9C,OAAO,cAAc;EACnB,MAAM,EACJ,aAAa,GAAG,UAAU,WAAW,UAAU,wBACjD;EACA,MAAM,EACJ,MAAM;GACJ,MAAM;GACN,UAAU;GACV,aAAa;EACf,EACF;EACA,IAAI,EAAE,QAAQ;GACZ,IAAI;IACF,6BAA6B,EAC3B,WAAW,GAAG,KAAK,OAAO,EAAE,QAAQ,EAAE,EACxC,CAAC;IACD,QAAQ,OAAO,MACb,aAAa,KAAK,KAAK,IAAI,UAAU,YAAY,WAAW,oDAC9D;GACF,SAAS,OAAO;IACd,QAAQ,OAAO,MACb,GAAG,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GAC5D;IACA,QAAQ,WAAW;GACrB;EACF;CACF,CAAC;AACH;AAEA,MAAa,WAAW,cAAc;CACpC,MAAM;EAAE,MAAM;EAAY,aAAa;CAA8B;CACrE,aAAa;EACX,QAAQ,qBAAqB,IAAI;EACjC,SAAS,qBAAqB,KAAK;CACrC;AACF,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { _ as readEditableConfigFromDisk, b as writeConfigToDisk, d as invalidateConfigCache, x as PATHS } from "./config-store-CARrUljo.js";
|
|
2
|
+
import { t as GITHUB_COPILOT_PROVIDER } from "./github-copilot-provider-DlQZgaCT.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
//#region src/lib/provider-management.ts
|
|
5
|
+
const updateSchema = z.object({ providers: z.record(z.string(), z.object({
|
|
6
|
+
enabled: z.boolean().optional(),
|
|
7
|
+
codexModels: z.array(z.string().trim().min(1)).nullable().optional()
|
|
8
|
+
}).strict()).optional() }).strict();
|
|
9
|
+
function getProviderCodexModels(provider) {
|
|
10
|
+
const models = provider?.codexModels;
|
|
11
|
+
if (!Array.isArray(models) || !models.every((id) => typeof id === "string")) return;
|
|
12
|
+
return [...new Set(models.map((id) => id.trim()).filter(Boolean))];
|
|
13
|
+
}
|
|
14
|
+
function isProviderCodexModelVisible(provider, modelId) {
|
|
15
|
+
if (provider?.enabled === false) return false;
|
|
16
|
+
const models = getProviderCodexModels(provider);
|
|
17
|
+
return models === void 0 || models.includes(modelId);
|
|
18
|
+
}
|
|
19
|
+
function getProviderManagementConfig(config = readEditableConfigFromDisk()) {
|
|
20
|
+
const providers = {
|
|
21
|
+
[GITHUB_COPILOT_PROVIDER]: {},
|
|
22
|
+
...config.providers
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
configPath: PATHS.CONFIG_PATH,
|
|
26
|
+
providers: Object.entries(providers).filter(([name]) => name !== "copilot").map(([name, provider]) => ({
|
|
27
|
+
name,
|
|
28
|
+
type: name === "github-copilot" ? "github-copilot" : provider.type ?? "anthropic",
|
|
29
|
+
enabled: provider.enabled !== false,
|
|
30
|
+
codexModels: getProviderCodexModels(provider)
|
|
31
|
+
}))
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function applyProviderManagementUpdate(config, input) {
|
|
35
|
+
const parsed = updateSchema.safeParse(input);
|
|
36
|
+
if (!parsed.success) throw new Error(parsed.error.issues[0]?.message ?? "Invalid provider update");
|
|
37
|
+
const { providers: updates } = parsed.data;
|
|
38
|
+
const providers = { ...config.providers };
|
|
39
|
+
for (const [name, update] of Object.entries(updates ?? {})) {
|
|
40
|
+
if (name === "copilot" || name !== "github-copilot" && !Object.hasOwn(providers, name)) throw new Error(`Provider '${name}' is not configured`);
|
|
41
|
+
const provider = { ...providers[name] };
|
|
42
|
+
if (update.enabled !== void 0) provider.enabled = update.enabled;
|
|
43
|
+
if (update.codexModels === null) delete provider.codexModels;
|
|
44
|
+
else if (update.codexModels !== void 0) provider.codexModels = [...new Set(update.codexModels)];
|
|
45
|
+
providers[name] = provider;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
...config,
|
|
49
|
+
...updates !== void 0 ? { providers } : {}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function saveProviderManagementConfig(input) {
|
|
53
|
+
const updated = applyProviderManagementUpdate(readEditableConfigFromDisk(), input);
|
|
54
|
+
writeConfigToDisk(updated);
|
|
55
|
+
invalidateConfigCache();
|
|
56
|
+
return getProviderManagementConfig(updated);
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { isProviderCodexModelVisible as n, saveProviderManagementConfig as r, getProviderCodexModels as t };
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=provider-management-z3m7cUkp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-management-z3m7cUkp.js","names":[],"sources":["../src/lib/provider-management.ts"],"sourcesContent":["import { z } from \"zod\"\n\nimport { GITHUB_COPILOT_PROVIDER } from \"./github-copilot-provider\"\n\nimport {\n invalidateConfigCache,\n readEditableConfigFromDisk,\n writeConfigToDisk,\n type AppConfig,\n type ProviderConfig,\n} from \"./config-store\"\nimport { PATHS } from \"./paths\"\nimport type { ProviderManagementConfig } from \"./types/provider-management\"\nexport type {\n ProviderManagementConfig,\n ProviderManagementUpdate,\n} from \"./types/provider-management\"\n\nconst updateSchema = z\n .object({\n providers: z\n .record(\n z.string(),\n z\n .object({\n enabled: z.boolean().optional(),\n codexModels: z\n .array(z.string().trim().min(1))\n .nullable()\n .optional(),\n })\n .strict(),\n )\n .optional(),\n })\n .strict()\n\nexport function getProviderCodexModels(\n provider: ProviderConfig | null | undefined,\n): Array<string> | undefined {\n const models = provider?.codexModels\n if (!Array.isArray(models) || !models.every((id) => typeof id === \"string\")) {\n return undefined\n }\n return [...new Set(models.map((id) => id.trim()).filter(Boolean))]\n}\n\nexport function isProviderCodexModelVisible(\n provider: ProviderConfig | null | undefined,\n modelId: string,\n): boolean {\n if (provider?.enabled === false) return false\n const models = getProviderCodexModels(provider)\n return models === undefined || models.includes(modelId)\n}\n\nexport function getProviderManagementConfig(\n config: AppConfig = readEditableConfigFromDisk(),\n): ProviderManagementConfig {\n const providers: NonNullable<AppConfig[\"providers\"]> = {\n [GITHUB_COPILOT_PROVIDER]: {},\n ...config.providers,\n }\n return {\n configPath: PATHS.CONFIG_PATH,\n providers: Object.entries(providers)\n .filter(([name]) => name !== \"copilot\")\n .map(([name, provider]) => ({\n name,\n type:\n name === GITHUB_COPILOT_PROVIDER ? \"github-copilot\" : (\n (provider.type ?? \"anthropic\")\n ),\n enabled: provider.enabled !== false,\n codexModels: getProviderCodexModels(provider),\n })),\n }\n}\n\nexport function applyProviderManagementUpdate(\n config: AppConfig,\n input: unknown,\n): AppConfig {\n const parsed = updateSchema.safeParse(input)\n if (!parsed.success) {\n throw new Error(\n parsed.error.issues[0]?.message ?? \"Invalid provider update\",\n )\n }\n const { providers: updates } = parsed.data\n const providers = { ...config.providers }\n for (const [name, update] of Object.entries(updates ?? {})) {\n if (\n name === \"copilot\"\n || (name !== GITHUB_COPILOT_PROVIDER && !Object.hasOwn(providers, name))\n ) {\n throw new Error(`Provider '${name}' is not configured`)\n }\n const provider = { ...providers[name] }\n if (update.enabled !== undefined) provider.enabled = update.enabled\n if (update.codexModels === null) {\n delete provider.codexModels\n } else if (update.codexModels !== undefined) {\n provider.codexModels = [...new Set(update.codexModels)]\n }\n providers[name] = provider\n }\n return {\n ...config,\n ...(updates !== undefined ? { providers } : {}),\n }\n}\n\nexport function saveProviderManagementConfig(\n input: unknown,\n): ProviderManagementConfig {\n const updated = applyProviderManagementUpdate(\n readEditableConfigFromDisk(),\n input,\n )\n writeConfigToDisk(updated)\n invalidateConfigCache()\n return getProviderManagementConfig(updated)\n}\n"],"mappings":";;;;AAkBA,MAAM,eAAe,EAClB,OAAO,EACN,WAAW,EACR,OACC,EAAE,OAAO,GACT,EACG,OAAO;CACN,SAAS,EAAE,QAAQ,CAAC,CAAC,SAAS;CAC9B,aAAa,EACV,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAC/B,SAAS,CAAC,CACV,SAAS;AACd,CAAC,CAAC,CACD,OAAO,CACZ,CAAC,CACA,SAAS,EACd,CAAC,CAAC,CACD,OAAO;AAEV,SAAgB,uBACd,UAC2B;CAC3B,MAAM,SAAS,UAAU;CACzB,IAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,QAAQ,GACxE;CAEF,OAAO,CAAC,GAAG,IAAI,IAAI,OAAO,KAAK,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC;AACnE;AAEA,SAAgB,4BACd,UACA,SACS;CACT,IAAI,UAAU,YAAY,OAAO,OAAO;CACxC,MAAM,SAAS,uBAAuB,QAAQ;CAC9C,OAAO,WAAW,KAAA,KAAa,OAAO,SAAS,OAAO;AACxD;AAEA,SAAgB,4BACd,SAAoB,2BAA2B,GACrB;CAC1B,MAAM,YAAiD;GACpD,0BAA0B,CAAC;EAC5B,GAAG,OAAO;CACZ;CACA,OAAO;EACL,YAAY,MAAM;EAClB,WAAW,OAAO,QAAQ,SAAS,CAAC,CACjC,QAAQ,CAAC,UAAU,SAAS,SAAS,CAAC,CACtC,KAAK,CAAC,MAAM,eAAe;GAC1B;GACA,MACE,SAAA,mBAAmC,mBAChC,SAAS,QAAQ;GAEtB,SAAS,SAAS,YAAY;GAC9B,aAAa,uBAAuB,QAAQ;EAC9C,EAAE;CACN;AACF;AAEA,SAAgB,8BACd,QACA,OACW;CACX,MAAM,SAAS,aAAa,UAAU,KAAK;CAC3C,IAAI,CAAC,OAAO,SACV,MAAM,IAAI,MACR,OAAO,MAAM,OAAO,EAAE,EAAE,WAAW,yBACrC;CAEF,MAAM,EAAE,WAAW,YAAY,OAAO;CACtC,MAAM,YAAY,EAAE,GAAG,OAAO,UAAU;CACxC,KAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,WAAW,CAAC,CAAC,GAAG;EAC1D,IACE,SAAS,aACL,SAAA,oBAAoC,CAAC,OAAO,OAAO,WAAW,IAAI,GAEtE,MAAM,IAAI,MAAM,aAAa,KAAK,oBAAoB;EAExD,MAAM,WAAW,EAAE,GAAG,UAAU,MAAM;EACtC,IAAI,OAAO,YAAY,KAAA,GAAW,SAAS,UAAU,OAAO;EAC5D,IAAI,OAAO,gBAAgB,MACzB,OAAO,SAAS;OACX,IAAI,OAAO,gBAAgB,KAAA,GAChC,SAAS,cAAc,CAAC,GAAG,IAAI,IAAI,OAAO,WAAW,CAAC;EAExD,UAAU,QAAQ;CACpB;CACA,OAAO;EACL,GAAG;EACH,GAAI,YAAY,KAAA,IAAY,EAAE,UAAU,IAAI,CAAC;CAC/C;AACF;AAEA,SAAgB,6BACd,OAC0B;CAC1B,MAAM,UAAU,8BACd,2BAA2B,GAC3B,KACF;CACA,kBAAkB,OAAO;CACzB,sBAAsB;CACtB,OAAO,4BAA4B,OAAO;AAC5C"}
|