opencodekit 0.21.5 → 0.21.6

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/dist/index.js CHANGED
@@ -20,7 +20,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
20
20
 
21
21
  //#endregion
22
22
  //#region package.json
23
- var version = "0.21.5";
23
+ var version = "0.21.6";
24
24
 
25
25
  //#endregion
26
26
  //#region src/utils/license.ts
Binary file
@@ -84,6 +84,21 @@ function normalizeDomain(url: string): string {
84
84
  return url.replace(/^https?:\/\//, "").replace(/\/$/, "");
85
85
  }
86
86
 
87
+ const DEFAULT_COPILOT_API_BASE = "https://api.githubcopilot.com";
88
+
89
+ function toCopilotMessagesBase(url: string | undefined): string {
90
+ const base = (url?.trim() || DEFAULT_COPILOT_API_BASE)
91
+ .replace(/\/+$/, "")
92
+ .replace(/\/v1$/, "");
93
+ return `${base}/v1`;
94
+ }
95
+
96
+ function isClaudeCopilotModel(modelId: string, model: any): boolean {
97
+ return [modelId, model?.id, model?.api?.id]
98
+ .filter((value): value is string => typeof value === "string")
99
+ .some((value) => value.toLowerCase().includes("claude"));
100
+ }
101
+
87
102
  function getUrls(domain: string) {
88
103
  return {
89
104
  DEVICE_CODE_URL: `https://${domain}/login/device/code`,
@@ -565,7 +580,7 @@ export const CopilotAuthPlugin: Plugin = async ({ client: sdk, directory }) => {
565
580
  : undefined;
566
581
 
567
582
  if (provider && provider.models) {
568
- for (const [_modelId, model] of Object.entries(provider.models)) {
583
+ for (const [modelId, model] of Object.entries(provider.models)) {
569
584
  model.cost = {
570
585
  input: 0,
571
586
  output: 0,
@@ -575,9 +590,18 @@ export const CopilotAuthPlugin: Plugin = async ({ client: sdk, directory }) => {
575
590
  },
576
591
  };
577
592
 
578
- // Route all Copilot models through the local file-based SDK.
579
- // OpenCode's built-in github-copilot model loader will automatically
580
- // choose sdk.responses(model) for GPT-5+ and sdk.chat(model) otherwise.
593
+ // OpenCode 1.14.33 routes Copilot Claude models through the
594
+ // Anthropic Messages API when Copilot /models reports /v1/messages.
595
+ // Keep that route: the local OpenAI-compatible SDK calls
596
+ // /chat/completions, which returns 404 for current Claude models.
597
+ if (isClaudeCopilotModel(modelId, model)) {
598
+ model.api.npm = "@ai-sdk/anthropic";
599
+ model.api.url = toCopilotMessagesBase(baseURL ?? model.api.url);
600
+ continue;
601
+ }
602
+
603
+ // Route OpenAI-compatible Copilot models through the local file-based
604
+ // SDK so GPT/Gemini keep the reasoning_opaque and Responses fixes.
581
605
  model.api.npm = localCopilotSdk;
582
606
  }
583
607
  }
@@ -872,45 +896,40 @@ export const CopilotAuthPlugin: Plugin = async ({ client: sdk, directory }) => {
872
896
  const toolSource = modifiedBody || body;
873
897
  if (Array.isArray(toolSource?.tools)) {
874
898
  let toolsChanged = false;
875
- const sanitizedTools = toolSource.tools.map(
876
- (tool: any) => {
877
- if (!tool || typeof tool !== "object") return tool;
878
-
879
- let result = tool;
880
-
881
- // Strip top-level non-standard fields from tool object
882
- if (
883
- "custom" in result ||
884
- "eager_input_streaming" in result
885
- ) {
886
- toolsChanged = true;
887
- const {
888
- custom: _custom,
889
- eager_input_streaming: _eis,
890
- ...clean
891
- } = result;
892
- result = clean;
893
- }
899
+ const sanitizedTools = toolSource.tools.map((tool: any) => {
900
+ if (!tool || typeof tool !== "object") return tool;
901
+
902
+ let result = tool;
903
+
904
+ // Strip top-level non-standard fields from tool object
905
+ if ("custom" in result || "eager_input_streaming" in result) {
906
+ toolsChanged = true;
907
+ const {
908
+ custom: _custom,
909
+ eager_input_streaming: _eis,
910
+ ...clean
911
+ } = result;
912
+ result = clean;
913
+ }
894
914
 
895
- // Also check nested function object (Chat Completions format)
896
- if (
897
- result.function &&
898
- typeof result.function === "object" &&
899
- ("custom" in result.function ||
900
- "eager_input_streaming" in result.function)
901
- ) {
902
- toolsChanged = true;
903
- const {
904
- custom: _c,
905
- eager_input_streaming: _e,
906
- ...cleanFn
907
- } = result.function;
908
- result = { ...result, function: cleanFn };
909
- }
915
+ // Also check nested function object (Chat Completions format)
916
+ if (
917
+ result.function &&
918
+ typeof result.function === "object" &&
919
+ ("custom" in result.function ||
920
+ "eager_input_streaming" in result.function)
921
+ ) {
922
+ toolsChanged = true;
923
+ const {
924
+ custom: _c,
925
+ eager_input_streaming: _e,
926
+ ...cleanFn
927
+ } = result.function;
928
+ result = { ...result, function: cleanFn };
929
+ }
910
930
 
911
- return result;
912
- },
913
- );
931
+ return result;
932
+ });
914
933
 
915
934
  if (toolsChanged) {
916
935
  modifiedBody = {
@@ -1248,6 +1267,12 @@ export const CopilotAuthPlugin: Plugin = async ({ client: sdk, directory }) => {
1248
1267
  "chat.params": async (input: any, output: any) => {
1249
1268
  if (!input.model?.providerID?.includes("github-copilot")) return;
1250
1269
 
1270
+ // Copilot rejects eager tool streaming on Anthropic Messages routing.
1271
+ if (input.model?.api?.npm === "@ai-sdk/anthropic") {
1272
+ output.options ??= {};
1273
+ output.options.toolStreaming = false;
1274
+ }
1275
+
1251
1276
  // GPT models don't support maxOutputTokens through the Copilot proxy
1252
1277
  if (input.model?.api?.id?.includes("gpt")) {
1253
1278
  output.maxOutputTokens = undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencodekit",
3
- "version": "0.21.5",
3
+ "version": "0.21.6",
4
4
  "description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
5
5
  "keywords": [
6
6
  "agents",