@codeworksh/aikit 0.8.0 → 0.9.0-dev.20260922184333
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 +10 -1
- package/cli.mjs +75 -83
- package/cli.mjs.map +1 -1
- package/{codex-MtP1574D.mjs → codex-CLDBTrFm.mjs} +132 -134
- package/codex-CLDBTrFm.mjs.map +1 -0
- package/copilot-CcD3g6H8.mjs +425 -0
- package/copilot-CcD3g6H8.mjs.map +1 -0
- package/copilot-headers-DceqXlpj.mjs +104 -0
- package/copilot-headers-DceqXlpj.mjs.map +1 -0
- package/github-copilot-BJIrxOzT.mjs +3 -0
- package/github-copilot-SIUCJz1G.mjs +126 -0
- package/github-copilot-SIUCJz1G.mjs.map +1 -0
- package/index.d.mts +980 -932
- package/index.mjs +63 -11
- package/index.mjs.map +1 -1
- package/interactive-eoNnscGB.mjs +57 -0
- package/interactive-eoNnscGB.mjs.map +1 -0
- package/{model-CpX11Oob.d.mts → model-CrVLp622.d.mts} +159 -130
- package/{model-CBnredXj.mjs → model-gCDbmGqT.mjs} +31 -2
- package/model-gCDbmGqT.mjs.map +1 -0
- package/{modelgen-BjSsusLQ.mjs → modelgen-DvorXOjJ.mjs} +148 -29
- package/modelgen-DvorXOjJ.mjs.map +1 -0
- package/modelgen.d.mts +2 -3
- package/modelgen.mjs +1 -1
- package/oauth/github/copilot.d.mts +169 -0
- package/oauth/github/copilot.mjs +2 -0
- package/oauth/interactive.d.mts +21 -0
- package/oauth/interactive.mjs +2 -0
- package/oauth/openai/codex.d.mts +46 -28
- package/oauth/openai/codex.mjs +2 -2
- package/oauth/summary.d.mts +67 -0
- package/oauth/summary.mjs +2 -0
- package/{openai-codex-t4B7g-gv.mjs → openai-codex-Bqzti6Mc.mjs} +3 -3
- package/{openai-codex-t4B7g-gv.mjs.map → openai-codex-Bqzti6Mc.mjs.map} +1 -1
- package/openai-codex-DA1Q7mLN.mjs +2 -0
- package/package.json +34 -22
- package/{registry-DYdYTwFt.mjs → registry-ZxwIW0gX.mjs} +5 -3
- package/registry-ZxwIW0gX.mjs.map +1 -0
- package/storage-v6qjTQ0v.mjs +178 -0
- package/storage-v6qjTQ0v.mjs.map +1 -0
- package/summary-C_QyCVWa.mjs +68 -0
- package/summary-C_QyCVWa.mjs.map +1 -0
- package/codex-MtP1574D.mjs.map +0 -1
- package/model-CBnredXj.mjs.map +0 -1
- package/modelgen-BjSsusLQ.mjs.map +0 -1
- package/openai-codex-BRH4Qa7l.mjs +0 -2
- package/registry-DYdYTwFt.mjs.map +0 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { p as isAnthropicAdaptiveThinkingModel } from "./model-gCDbmGqT.mjs";
|
|
2
|
+
//#region src/providers/github-copilot/copilot-headers.ts
|
|
3
|
+
/**
|
|
4
|
+
* Copilot request identity.
|
|
5
|
+
*
|
|
6
|
+
* Every inference request must look like it came from the Copilot Chat client:
|
|
7
|
+
* the static headers identify that client, while `x-initiator` and
|
|
8
|
+
* `Copilot-Vision-Request` describe the serialized body.
|
|
9
|
+
*/
|
|
10
|
+
const GITHUB_COPILOT_API_VERSION = "2026-08-01";
|
|
11
|
+
const GITHUB_COPILOT_STATIC_HEADERS = {
|
|
12
|
+
"User-Agent": "GitHubCopilotChat/0.35.0",
|
|
13
|
+
"Editor-Version": "vscode/1.107.0",
|
|
14
|
+
"Editor-Plugin-Version": "copilot-chat/0.35.0",
|
|
15
|
+
"Copilot-Integration-Id": "vscode-chat"
|
|
16
|
+
};
|
|
17
|
+
const ADAPTIVE_UNSUPPORTED_BETAS = /* @__PURE__ */ new Set(["interleaved-thinking-2025-05-14", "fine-grained-tool-streaming-2025-05-14"]);
|
|
18
|
+
function isRecord(value) {
|
|
19
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20
|
+
}
|
|
21
|
+
function responsesMetadata(input) {
|
|
22
|
+
const list = Array.isArray(input) ? input : [];
|
|
23
|
+
const last = list[list.length - 1];
|
|
24
|
+
let vision = false;
|
|
25
|
+
for (const item of list) {
|
|
26
|
+
if (!isRecord(item) || !Array.isArray(item.content)) continue;
|
|
27
|
+
if (item.content.some((part) => isRecord(part) && part.type === "input_image")) vision = true;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
agent: isRecord(last) && last.role !== "user",
|
|
31
|
+
vision
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function completionsMetadata(messages) {
|
|
35
|
+
const list = Array.isArray(messages) ? messages : [];
|
|
36
|
+
const last = list[list.length - 1];
|
|
37
|
+
let vision = false;
|
|
38
|
+
for (const message of list) {
|
|
39
|
+
if (!isRecord(message) || !Array.isArray(message.content)) continue;
|
|
40
|
+
if (message.content.some((part) => isRecord(part) && part.type === "image_url")) vision = true;
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
agent: isRecord(last) && last.role !== "user",
|
|
44
|
+
vision
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function messagesMetadata(messages) {
|
|
48
|
+
const list = Array.isArray(messages) ? messages : [];
|
|
49
|
+
const last = list[list.length - 1];
|
|
50
|
+
let vision = false;
|
|
51
|
+
for (const message of list) {
|
|
52
|
+
if (!isRecord(message) || !Array.isArray(message.content)) continue;
|
|
53
|
+
for (const part of message.content) {
|
|
54
|
+
if (!isRecord(part)) continue;
|
|
55
|
+
if (part.type === "image") vision = true;
|
|
56
|
+
if (part.type === "tool_result" && Array.isArray(part.content) && part.content.some((inner) => isRecord(inner) && inner.type === "image")) vision = true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const content = isRecord(last) && Array.isArray(last.content) ? last.content : [];
|
|
60
|
+
return {
|
|
61
|
+
agent: !isRecord(last) || last.role !== "user" || !content.some((part) => isRecord(part) && part.type !== "tool_result"),
|
|
62
|
+
vision
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** Derive `x-initiator` and `Copilot-Vision-Request` inputs from the serialized body. */
|
|
66
|
+
function copilotRequestMetadata(url, body) {
|
|
67
|
+
if (!isRecord(body)) return {
|
|
68
|
+
agent: false,
|
|
69
|
+
vision: false
|
|
70
|
+
};
|
|
71
|
+
if (url.includes("/responses")) return responsesMetadata(body.input);
|
|
72
|
+
if (Array.isArray(body.messages)) return url.includes("/completions") ? completionsMetadata(body.messages) : messagesMetadata(body.messages);
|
|
73
|
+
return {
|
|
74
|
+
agent: false,
|
|
75
|
+
vision: false
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function applyCopilotHeaders(headers, options) {
|
|
79
|
+
headers.delete("authorization");
|
|
80
|
+
headers.delete("x-api-key");
|
|
81
|
+
headers.set("Authorization", `Bearer ${options.token}`);
|
|
82
|
+
for (const [key, value] of Object.entries(GITHUB_COPILOT_STATIC_HEADERS)) headers.set(key, value);
|
|
83
|
+
headers.set("Openai-Intent", "conversation-edits");
|
|
84
|
+
headers.set("X-GitHub-Api-Version", GITHUB_COPILOT_API_VERSION);
|
|
85
|
+
const interactionType = `conversation-${options.interactionType ?? "agent"}`;
|
|
86
|
+
headers.set("X-Interaction-Type", interactionType);
|
|
87
|
+
if (options.sessionId) headers.set("X-Interaction-Id", options.sessionId);
|
|
88
|
+
if (interactionType !== "conversation-agent") headers.set("x-initiator", "agent");
|
|
89
|
+
const metadata = copilotRequestMetadata(options.url, options.body);
|
|
90
|
+
if (metadata.agent) headers.set("x-initiator", "agent");
|
|
91
|
+
else if (!headers.has("x-initiator")) headers.set("x-initiator", "user");
|
|
92
|
+
if (metadata.vision) headers.set("Copilot-Vision-Request", "true");
|
|
93
|
+
const model = isRecord(options.body) && typeof options.body.model === "string" ? options.body.model : void 0;
|
|
94
|
+
const beta = headers.get("anthropic-beta");
|
|
95
|
+
if (model && beta && isAnthropicAdaptiveThinkingModel(model)) {
|
|
96
|
+
const kept = beta.split(",").map((entry) => entry.trim()).filter((entry) => entry && !ADAPTIVE_UNSUPPORTED_BETAS.has(entry));
|
|
97
|
+
if (kept.length > 0) headers.set("anthropic-beta", kept.join(","));
|
|
98
|
+
else headers.delete("anthropic-beta");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//#endregion
|
|
102
|
+
export { copilotRequestMetadata as i, GITHUB_COPILOT_STATIC_HEADERS as n, applyCopilotHeaders as r, GITHUB_COPILOT_API_VERSION as t };
|
|
103
|
+
|
|
104
|
+
//# sourceMappingURL=copilot-headers-DceqXlpj.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-headers-DceqXlpj.mjs","names":[],"sources":["../../src/providers/github-copilot/copilot-headers.ts"],"sourcesContent":["/**\n * Copilot request identity.\n *\n * Every inference request must look like it came from the Copilot Chat client:\n * the static headers identify that client, while `x-initiator` and\n * `Copilot-Vision-Request` describe the serialized body.\n */\n\nimport { isAnthropicAdaptiveThinkingModel } from \"../../model/model.ts\";\n\nexport const GITHUB_COPILOT_API_VERSION = \"2026-08-01\";\n\nexport const GITHUB_COPILOT_STATIC_HEADERS = {\n\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\"Editor-Version\": \"vscode/1.107.0\",\n\t\"Editor-Plugin-Version\": \"copilot-chat/0.35.0\",\n\t\"Copilot-Integration-Id\": \"vscode-chat\",\n} as const;\n\n/** `X-Interaction-Type` is `conversation-{type}`; only `agent` is wired today. */\nexport type GitHubCopilotInteractionType = \"agent\" | \"subagent\" | \"background\" | \"compaction\";\n\n// Copilot rejects these betas on adaptive-thinking Claude models.\nconst ADAPTIVE_UNSUPPORTED_BETAS = new Set([\n\t\"interleaved-thinking-2025-05-14\",\n\t\"fine-grained-tool-streaming-2025-05-14\",\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\ntype RequestMetadata = { agent: boolean; vision: boolean };\n\nfunction responsesMetadata(input: unknown): RequestMetadata {\n\tconst list = Array.isArray(input) ? input : [];\n\tconst last = list[list.length - 1];\n\tlet vision = false;\n\tfor (const item of list) {\n\t\tif (!isRecord(item) || !Array.isArray(item.content)) continue;\n\t\tif (item.content.some((part) => isRecord(part) && part.type === \"input_image\")) vision = true;\n\t}\n\treturn { agent: isRecord(last) && last.role !== \"user\", vision };\n}\n\nfunction completionsMetadata(messages: unknown): RequestMetadata {\n\tconst list = Array.isArray(messages) ? messages : [];\n\tconst last = list[list.length - 1];\n\tlet vision = false;\n\tfor (const message of list) {\n\t\tif (!isRecord(message) || !Array.isArray(message.content)) continue;\n\t\tif (message.content.some((part) => isRecord(part) && part.type === \"image_url\")) vision = true;\n\t}\n\treturn { agent: isRecord(last) && last.role !== \"user\", vision };\n}\n\nfunction messagesMetadata(messages: unknown): RequestMetadata {\n\tconst list = Array.isArray(messages) ? messages : [];\n\tconst last = list[list.length - 1];\n\tlet vision = false;\n\tfor (const message of list) {\n\t\tif (!isRecord(message) || !Array.isArray(message.content)) continue;\n\t\tfor (const part of message.content) {\n\t\t\tif (!isRecord(part)) continue;\n\t\t\tif (part.type === \"image\") vision = true;\n\t\t\tif (\n\t\t\t\tpart.type === \"tool_result\" &&\n\t\t\t\tArray.isArray(part.content) &&\n\t\t\t\tpart.content.some((inner) => isRecord(inner) && inner.type === \"image\")\n\t\t\t) {\n\t\t\t\tvision = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst content = isRecord(last) && Array.isArray(last.content) ? last.content : [];\n\t// A trailing user turn that only carries tool_result parts is still an agent\n\t// step — it answers a tool call, not a human prompt.\n\tconst agent =\n\t\t!isRecord(last) || last.role !== \"user\" || !content.some((part) => isRecord(part) && part.type !== \"tool_result\");\n\treturn { agent, vision };\n}\n\n/** Derive `x-initiator` and `Copilot-Vision-Request` inputs from the serialized body. */\nexport function copilotRequestMetadata(url: string, body: unknown): RequestMetadata {\n\tif (!isRecord(body)) return { agent: false, vision: false };\n\tif (url.includes(\"/responses\")) return responsesMetadata(body.input);\n\tif (Array.isArray(body.messages)) {\n\t\treturn url.includes(\"/completions\") ? completionsMetadata(body.messages) : messagesMetadata(body.messages);\n\t}\n\treturn { agent: false, vision: false };\n}\n\nexport function applyCopilotHeaders(\n\theaders: Headers,\n\toptions: {\n\t\ttoken: string;\n\t\turl: string;\n\t\tbody: unknown;\n\t\tsessionId?: string;\n\t\tinteractionType?: GitHubCopilotInteractionType;\n\t},\n): void {\n\t// Whatever the adapters configured (API key, x-api-key) is replaced by the\n\t// resolved Copilot token; OAuth `ghu_`/`gho_` tokens are Bearer credentials.\n\theaders.delete(\"authorization\");\n\theaders.delete(\"x-api-key\");\n\theaders.set(\"Authorization\", `Bearer ${options.token}`);\n\n\tfor (const [key, value] of Object.entries(GITHUB_COPILOT_STATIC_HEADERS)) {\n\t\theaders.set(key, value);\n\t}\n\theaders.set(\"Openai-Intent\", \"conversation-edits\");\n\theaders.set(\"X-GitHub-Api-Version\", GITHUB_COPILOT_API_VERSION);\n\n\tconst interactionType = `conversation-${options.interactionType ?? \"agent\"}`;\n\theaders.set(\"X-Interaction-Type\", interactionType);\n\tif (options.sessionId) headers.set(\"X-Interaction-Id\", options.sessionId);\n\n\t// `x-initiator` can only escalate to `agent`, never back to `user` — a\n\t// non-agent interaction or an agent-shaped body overrides a declared `user`.\n\tif (interactionType !== \"conversation-agent\") {\n\t\theaders.set(\"x-initiator\", \"agent\");\n\t}\n\tconst metadata = copilotRequestMetadata(options.url, options.body);\n\tif (metadata.agent) {\n\t\theaders.set(\"x-initiator\", \"agent\");\n\t} else if (!headers.has(\"x-initiator\")) {\n\t\theaders.set(\"x-initiator\", \"user\");\n\t}\n\tif (metadata.vision) {\n\t\theaders.set(\"Copilot-Vision-Request\", \"true\");\n\t}\n\n\tconst model = isRecord(options.body) && typeof options.body.model === \"string\" ? options.body.model : undefined;\n\tconst beta = headers.get(\"anthropic-beta\");\n\tif (model && beta && isAnthropicAdaptiveThinkingModel(model)) {\n\t\tconst kept = beta\n\t\t\t.split(\",\")\n\t\t\t.map((entry) => entry.trim())\n\t\t\t.filter((entry) => entry && !ADAPTIVE_UNSUPPORTED_BETAS.has(entry));\n\t\tif (kept.length > 0) {\n\t\t\theaders.set(\"anthropic-beta\", kept.join(\",\"));\n\t\t} else {\n\t\t\theaders.delete(\"anthropic-beta\");\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { r as applyCopilotHeaders } from "./copilot-headers-DceqXlpj.mjs";
|
|
2
|
+
import { LoadAPIKeyError, NoSuchModelError } from "@ai-sdk/provider";
|
|
3
|
+
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
4
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
5
|
+
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
|
|
6
|
+
//#region src/providers/github-copilot/copilot-fetch.ts
|
|
7
|
+
const API_KEY_ENV = "COPILOT_GITHUB_TOKEN";
|
|
8
|
+
async function resolveToken(apiKey) {
|
|
9
|
+
const resolved = typeof apiKey === "function" ? await apiKey() : apiKey;
|
|
10
|
+
if (resolved) return resolved;
|
|
11
|
+
const fromEnv = typeof process === "undefined" ? void 0 : process.env[API_KEY_ENV];
|
|
12
|
+
if (fromEnv) return fromEnv;
|
|
13
|
+
throw new LoadAPIKeyError({ message: `GitHub Copilot API key is missing. Set ${API_KEY_ENV}, pass an apiKey, or authenticate with \`aikit auth --github-copilot\`.` });
|
|
14
|
+
}
|
|
15
|
+
function parseJson(text) {
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(text);
|
|
18
|
+
} catch {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Wrap an upstream fetch with Copilot auth and request metadata. The wrapped
|
|
24
|
+
* call replaces adapter-set auth headers, injects the Copilot identity
|
|
25
|
+
* headers, and derives `x-initiator` / `Copilot-Vision-Request` from the
|
|
26
|
+
* serialized JSON body without consuming it.
|
|
27
|
+
*/
|
|
28
|
+
function createCopilotFetch(options = {}) {
|
|
29
|
+
const upstream = options.fetch ?? globalThis.fetch;
|
|
30
|
+
return async (input, init) => {
|
|
31
|
+
const token = await resolveToken(options.apiKey);
|
|
32
|
+
const headers = new Headers(init?.headers);
|
|
33
|
+
const url = input instanceof URL ? input.href : typeof input === "string" ? input : input.url;
|
|
34
|
+
const body = typeof init?.body === "string" ? parseJson(init.body) : void 0;
|
|
35
|
+
applyCopilotHeaders(headers, {
|
|
36
|
+
token,
|
|
37
|
+
url,
|
|
38
|
+
body,
|
|
39
|
+
...options.sessionId !== void 0 && { sessionId: options.sessionId },
|
|
40
|
+
...options.interactionType !== void 0 && { interactionType: options.interactionType }
|
|
41
|
+
});
|
|
42
|
+
return upstream(input, {
|
|
43
|
+
...init,
|
|
44
|
+
headers
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/providers/github-copilot/copilot-provider.ts
|
|
50
|
+
/**
|
|
51
|
+
* GitHub Copilot provider.
|
|
52
|
+
*
|
|
53
|
+
* Copilot exposes three inference protocols on one host — OpenAI Chat
|
|
54
|
+
* Completions (`/chat/completions`), OpenAI Responses (`/responses`), and
|
|
55
|
+
* Anthropic Messages (`/v1/messages`) — so this provider composes the official
|
|
56
|
+
* AI SDK adapters behind one `ProviderV4` and routes each model through
|
|
57
|
+
* `api.method`. Auth and Copilot request headers are applied inside the shared
|
|
58
|
+
* fetch wrapper, which is why the adapters receive a placeholder key: their
|
|
59
|
+
* headers never reach the wire.
|
|
60
|
+
*/
|
|
61
|
+
const GITHUB_COPILOT_DEFAULT_BASE_URL = "https://api.githubcopilot.com";
|
|
62
|
+
const GITHUB_COPILOT_PROVIDER_NAME = "github-copilot";
|
|
63
|
+
const PLACEHOLDER_API_KEY = "github-copilot";
|
|
64
|
+
function createGitHubCopilot(options = {}) {
|
|
65
|
+
const baseURL = (options.baseURL ?? "https://api.githubcopilot.com").replace(/\/+$/, "");
|
|
66
|
+
const fetch = createCopilotFetch({
|
|
67
|
+
...options.apiKey !== void 0 && { apiKey: options.apiKey },
|
|
68
|
+
...options.fetch !== void 0 && { fetch: options.fetch },
|
|
69
|
+
...options.sessionId !== void 0 && { sessionId: options.sessionId },
|
|
70
|
+
...options.interactionType !== void 0 && { interactionType: options.interactionType }
|
|
71
|
+
});
|
|
72
|
+
const headers = options.headers !== void 0 ? { headers: options.headers } : {};
|
|
73
|
+
const chat = createOpenAICompatible({
|
|
74
|
+
name: GITHUB_COPILOT_PROVIDER_NAME,
|
|
75
|
+
baseURL,
|
|
76
|
+
apiKey: PLACEHOLDER_API_KEY,
|
|
77
|
+
...headers,
|
|
78
|
+
fetch,
|
|
79
|
+
includeUsage: true,
|
|
80
|
+
...options.transformRequestBody !== void 0 && { transformRequestBody: options.transformRequestBody }
|
|
81
|
+
});
|
|
82
|
+
const responses = createOpenAI({
|
|
83
|
+
name: GITHUB_COPILOT_PROVIDER_NAME,
|
|
84
|
+
baseURL,
|
|
85
|
+
apiKey: PLACEHOLDER_API_KEY,
|
|
86
|
+
...headers,
|
|
87
|
+
fetch
|
|
88
|
+
});
|
|
89
|
+
const messages = createAnthropic({
|
|
90
|
+
name: GITHUB_COPILOT_PROVIDER_NAME,
|
|
91
|
+
baseURL: `${baseURL}/v1`,
|
|
92
|
+
authToken: PLACEHOLDER_API_KEY,
|
|
93
|
+
...headers,
|
|
94
|
+
fetch
|
|
95
|
+
});
|
|
96
|
+
const provider = function(modelId) {
|
|
97
|
+
if (new.target) throw new Error("github copilot model function cannot be called with the new keyword.");
|
|
98
|
+
return chat.chatModel(modelId);
|
|
99
|
+
};
|
|
100
|
+
provider.specificationVersion = "v4";
|
|
101
|
+
provider.languageModel = (modelId) => chat.chatModel(modelId);
|
|
102
|
+
provider.chat = (modelId) => chat.chatModel(modelId);
|
|
103
|
+
provider.responses = (modelId) => responses.responses(modelId);
|
|
104
|
+
provider.messages = (modelId) => messages.messages(modelId);
|
|
105
|
+
provider.embeddingModel = (modelId) => {
|
|
106
|
+
throw new NoSuchModelError({
|
|
107
|
+
modelId,
|
|
108
|
+
modelType: "embeddingModel",
|
|
109
|
+
message: "github copilot does not expose embedding models"
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
provider.textEmbeddingModel = provider.embeddingModel;
|
|
113
|
+
provider.imageModel = (modelId) => {
|
|
114
|
+
throw new NoSuchModelError({
|
|
115
|
+
modelId,
|
|
116
|
+
modelType: "imageModel",
|
|
117
|
+
message: "github copilot does not expose image models"
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
return provider;
|
|
121
|
+
}
|
|
122
|
+
const githubCopilot = createGitHubCopilot();
|
|
123
|
+
//#endregion
|
|
124
|
+
export { createCopilotFetch as a, githubCopilot as i, GITHUB_COPILOT_PROVIDER_NAME as n, createGitHubCopilot as r, GITHUB_COPILOT_DEFAULT_BASE_URL as t };
|
|
125
|
+
|
|
126
|
+
//# sourceMappingURL=github-copilot-SIUCJz1G.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-copilot-SIUCJz1G.mjs","names":[],"sources":["../../src/providers/github-copilot/copilot-fetch.ts","../../src/providers/github-copilot/copilot-provider.ts"],"sourcesContent":["import { LoadAPIKeyError } from \"@ai-sdk/provider\";\nimport { applyCopilotHeaders, type GitHubCopilotInteractionType } from \"./copilot-headers.ts\";\n\nexport type GitHubCopilotApiKey = string | (() => string | PromiseLike<string | undefined> | undefined);\n\nexport type CopilotFetchOptions = {\n\t/** Static token or async resolver — e.g. `() => getGitHubCopilotApiKey()`. */\n\tapiKey?: GitHubCopilotApiKey;\n\t/** Upstream fetch implementation; defaults to `globalThis.fetch`. */\n\tfetch?: typeof globalThis.fetch;\n\t/** Sent as `X-Interaction-Id` so Copilot can group requests by session. */\n\tsessionId?: string;\n\tinteractionType?: GitHubCopilotInteractionType;\n};\n\n// Only the Copilot-specific variable: GITHUB_TOKEN and GH_TOKEN are usually set\n// for git or `gh` and have no Copilot access.\nconst API_KEY_ENV = \"COPILOT_GITHUB_TOKEN\";\n\nasync function resolveToken(apiKey: GitHubCopilotApiKey | undefined): Promise<string> {\n\tconst resolved = typeof apiKey === \"function\" ? await apiKey() : apiKey;\n\tif (resolved) return resolved;\n\tconst fromEnv = typeof process === \"undefined\" ? undefined : process.env[API_KEY_ENV];\n\tif (fromEnv) return fromEnv;\n\tthrow new LoadAPIKeyError({\n\t\tmessage: `GitHub Copilot API key is missing. Set ${API_KEY_ENV}, pass an apiKey, or authenticate with \\`aikit auth --github-copilot\\`.`,\n\t});\n}\n\nfunction parseJson(text: string): unknown {\n\ttry {\n\t\treturn JSON.parse(text) as unknown;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Wrap an upstream fetch with Copilot auth and request metadata. The wrapped\n * call replaces adapter-set auth headers, injects the Copilot identity\n * headers, and derives `x-initiator` / `Copilot-Vision-Request` from the\n * serialized JSON body without consuming it.\n */\nexport function createCopilotFetch(options: CopilotFetchOptions = {}): typeof globalThis.fetch {\n\tconst upstream = options.fetch ?? globalThis.fetch;\n\treturn async (input, init) => {\n\t\tconst token = await resolveToken(options.apiKey);\n\t\tconst headers = new Headers(init?.headers);\n\t\tconst url = input instanceof URL ? input.href : typeof input === \"string\" ? input : input.url;\n\t\tconst body = typeof init?.body === \"string\" ? parseJson(init.body) : undefined;\n\t\tapplyCopilotHeaders(headers, {\n\t\t\ttoken,\n\t\t\turl,\n\t\t\tbody,\n\t\t\t...(options.sessionId !== undefined && { sessionId: options.sessionId }),\n\t\t\t...(options.interactionType !== undefined && { interactionType: options.interactionType }),\n\t\t});\n\t\treturn upstream(input, { ...init, headers });\n\t};\n}\n","/**\n * GitHub Copilot provider.\n *\n * Copilot exposes three inference protocols on one host — OpenAI Chat\n * Completions (`/chat/completions`), OpenAI Responses (`/responses`), and\n * Anthropic Messages (`/v1/messages`) — so this provider composes the official\n * AI SDK adapters behind one `ProviderV4` and routes each model through\n * `api.method`. Auth and Copilot request headers are applied inside the shared\n * fetch wrapper, which is why the adapters receive a placeholder key: their\n * headers never reach the wire.\n */\n\nimport { createAnthropic } from \"@ai-sdk/anthropic\";\nimport { createOpenAI } from \"@ai-sdk/openai\";\nimport { createOpenAICompatible } from \"@ai-sdk/openai-compatible\";\nimport { NoSuchModelError, type LanguageModelV4, type ProviderV4 } from \"@ai-sdk/provider\";\nimport { createCopilotFetch, type GitHubCopilotApiKey } from \"./copilot-fetch.ts\";\nimport type { GitHubCopilotInteractionType } from \"./copilot-headers.ts\";\n\nexport const GITHUB_COPILOT_DEFAULT_BASE_URL = \"https://api.githubcopilot.com\";\nexport const GITHUB_COPILOT_PROVIDER_NAME = \"github-copilot\";\n\nconst PLACEHOLDER_API_KEY = \"github-copilot\";\n\nexport interface GitHubCopilotProvider extends ProviderV4 {\n\t/** Chat Completions — the generic fallback for third-party models. */\n\t(modelId: string): LanguageModelV4;\n\tlanguageModel(modelId: string): LanguageModelV4;\n\t/** `POST /chat/completions` — Gemini, Kimi, and other third-party models. */\n\tchat(modelId: string): LanguageModelV4;\n\t/** `POST /responses` — GPT, Grok, OSWE, and MAI models. */\n\tresponses(modelId: string): LanguageModelV4;\n\t/** `POST /v1/messages` — Claude models. */\n\tmessages(modelId: string): LanguageModelV4;\n}\n\nexport interface GitHubCopilotProviderSettings {\n\t/**\n\t * Copilot API host. Defaults to `https://api.githubcopilot.com`; OAuth\n\t * credentials can carry a plan-specific `apiEndpoint` that overrides this.\n\t */\n\tbaseURL?: string;\n\t/**\n\t * GitHub OAuth token (`ghu_`/`gho_`) or an async resolver, e.g.\n\t * `() => getGitHubCopilotApiKey()`. Falls back to `COPILOT_GITHUB_TOKEN`.\n\t */\n\tapiKey?: GitHubCopilotApiKey;\n\t/** Extra headers merged into every request. */\n\theaders?: Record<string, string>;\n\t/** Custom fetch implementation, applied underneath the Copilot wrapper. */\n\tfetch?: typeof globalThis.fetch;\n\t/** Sent as `X-Interaction-Id` so Copilot can group requests by session. */\n\tsessionId?: string;\n\tinteractionType?: GitHubCopilotInteractionType;\n\t/** Forwarded to the Chat Completions adapter only. */\n\ttransformRequestBody?: (body: Record<string, unknown>) => Record<string, unknown>;\n}\n\nexport function createGitHubCopilot(options: GitHubCopilotProviderSettings = {}): GitHubCopilotProvider {\n\tconst baseURL = (options.baseURL ?? GITHUB_COPILOT_DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n\tconst fetch = createCopilotFetch({\n\t\t...(options.apiKey !== undefined && { apiKey: options.apiKey }),\n\t\t...(options.fetch !== undefined && { fetch: options.fetch }),\n\t\t...(options.sessionId !== undefined && { sessionId: options.sessionId }),\n\t\t...(options.interactionType !== undefined && { interactionType: options.interactionType }),\n\t});\n\tconst headers = options.headers !== undefined ? { headers: options.headers } : {};\n\n\tconst chat = createOpenAICompatible({\n\t\tname: GITHUB_COPILOT_PROVIDER_NAME,\n\t\tbaseURL,\n\t\tapiKey: PLACEHOLDER_API_KEY,\n\t\t...headers,\n\t\tfetch,\n\t\tincludeUsage: true,\n\t\t...(options.transformRequestBody !== undefined && { transformRequestBody: options.transformRequestBody }),\n\t});\n\tconst responses = createOpenAI({\n\t\tname: GITHUB_COPILOT_PROVIDER_NAME,\n\t\tbaseURL,\n\t\tapiKey: PLACEHOLDER_API_KEY,\n\t\t...headers,\n\t\tfetch,\n\t});\n\tconst messages = createAnthropic({\n\t\tname: GITHUB_COPILOT_PROVIDER_NAME,\n\t\t// The Anthropic adapter appends /messages to its baseURL.\n\t\tbaseURL: `${baseURL}/v1`,\n\t\tauthToken: PLACEHOLDER_API_KEY,\n\t\t...headers,\n\t\tfetch,\n\t});\n\n\tconst provider = function (modelId: string): LanguageModelV4 {\n\t\tif (new.target) {\n\t\t\tthrow new Error(\"github copilot model function cannot be called with the new keyword.\");\n\t\t}\n\t\treturn chat.chatModel(modelId);\n\t};\n\tprovider.specificationVersion = \"v4\" as const;\n\tprovider.languageModel = (modelId: string) => chat.chatModel(modelId);\n\tprovider.chat = (modelId: string) => chat.chatModel(modelId);\n\tprovider.responses = (modelId: string) => responses.responses(modelId);\n\tprovider.messages = (modelId: string) => messages.messages(modelId);\n\tprovider.embeddingModel = (modelId: string) => {\n\t\tthrow new NoSuchModelError({\n\t\t\tmodelId,\n\t\t\tmodelType: \"embeddingModel\",\n\t\t\tmessage: \"github copilot does not expose embedding models\",\n\t\t});\n\t};\n\tprovider.textEmbeddingModel = provider.embeddingModel;\n\tprovider.imageModel = (modelId: string) => {\n\t\tthrow new NoSuchModelError({\n\t\t\tmodelId,\n\t\t\tmodelType: \"imageModel\",\n\t\t\tmessage: \"github copilot does not expose image models\",\n\t\t});\n\t};\n\n\treturn provider;\n}\n\nexport const githubCopilot = createGitHubCopilot();\n"],"mappings":"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"}
|