@jeffreycao/copilot-api 2.1.9 → 2.1.10

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 CHANGED
@@ -417,6 +417,10 @@ enabled = false
417
417
 
418
418
  When a Codex client (`User-Agent` starts with `codex`) requests the top-level `GET /v1/models`, the gateway merges native Codex models with models available through the Messages adapter. The latter advertise `use_responses_lite: true`: `/v1/responses` uses **Responses → Messages** for Anthropic providers, while OpenAI-compatible providers and Chat-only Copilot models reuse the existing Messages route for **Responses → Messages → Chat Completions**, then translate streaming or JSON results back to Responses.
419
419
 
420
+ The merged catalog is what Codex shows in its model picker, including the models exposed by your configured providers:
421
+
422
+ <img src="./docs/screenshots/codex-models.png" alt="Codex model picker showing models provided by the gateway" width="900" />
423
+
420
424
  For Codex clients, only `gpt-*` Copilot models use the native Responses API; non-GPT Copilot models always go through the adapter, even when they advertise native `/responses` support. The same Codex rule applies on provider `/v1/responses` routes (top-level `provider/model` aliases and `/:provider/v1/responses`): for `openai-responses` providers, non-`gpt-*` models fall back to the Messages adapter, while `gpt-*` models keep native Responses forwarding.
421
425
 
422
426
  Responses Lite tool definitions are read from `input.additional_tools`, without relying on top-level `tools`. Function, `namespace`, and custom tools are supported; clients must declare `apply_patch` as `type: "custom"`, and it is not handled as a standalone special tool type. Returned calls recover their original `name` and `namespace`. Tools are collected before old history is trimmed, so compaction requests retain them. The Messages fallback does not support Responses `tool_search` mode. Anthropic `output_config.effort` keeps the project's existing valid levels; Responses `minimal` maps to `low`, while `none` omits Anthropic effort.
package/README.zh-CN.md CHANGED
@@ -445,6 +445,10 @@ enabled = false
445
445
 
446
446
  Codex 客户端(`User-Agent` 以 `codex` 开头)请求顶层 `GET /v1/models` 时,网关会把原生 Codex 模型与可通过 Messages 适配的模型合并返回。后者会声明 `use_responses_lite: true`:调用 `/v1/responses` 后,Anthropic provider 走 **Responses → Messages**,OpenAI 兼容 provider 以及只支持 Chat 的 Copilot 模型则复用现有 Messages 路由继续走 **Responses → Messages → Chat Completions**,最终统一翻译回 Responses(包括流式事件)。
447
447
 
448
+ 合并后的模型列表会直接展示在 Codex 的模型选择界面中,包含各 provider 暴露的模型:
449
+
450
+ <img src="./docs/screenshots/codex-models.png" alt="Codex 模型选择界面展示网关提供的模型列表" width="900" />
451
+
448
452
  对 Codex 客户端而言,只有 `gpt-*` Copilot 模型走原生 Responses API;非 GPT Copilot 模型一律走适配路径,即使声明支持原生 `/responses` 也不例外。provider 的 `/v1/responses` 路由(顶层 `provider/model` 别名和 `/:provider/v1/responses`)对 Codex 客户端遵循同一规则:对 `openai-responses` provider,非 `gpt-*` 模型回退到 Messages 适配路径,`gpt-*` 模型保持原生 Responses 转发。
449
453
 
450
454
  Responses Lite 的工具定义从 `input` 中的 `additional_tools` 读取,而不是依赖顶层 `tools`。该适配支持 function、`namespace` 和 custom tool;`apply_patch` 需要由客户端声明为 `type: "custom"`,不会作为独立工具类型特殊处理。工具调用返回时会恢复原始 `name` 与 `namespace`;压缩请求在裁剪旧历史前先保存工具定义,因此压缩期间也不会丢失工具。Messages 回退路径不支持 Responses `tool_search` 模式。Anthropic 的 `output_config.effort` 仍只使用项目既有的合法档位;Responses 的 `minimal` 会降级为 `low`,`none` 则不向 Anthropic 发送 effort。
package/dist/main.js CHANGED
@@ -24,7 +24,7 @@ const { bindElectronFetch } = await import("./electron-fetch-DPhDE6JE.js");
24
24
  bindElectronFetch();
25
25
  const { auth } = await import("./auth-PIo0IPSc.js");
26
26
  const { debug } = await import("./debug-ChC85ySp.js");
27
- const { mcp } = await import("./mcp-BG6fpi6q.js");
27
+ const { mcp } = await import("./mcp-DOp7erlH.js");
28
28
  const { start } = await import("./start-Bnk7SH7n.js");
29
29
  await runMain(defineCommand({
30
30
  meta: {
@@ -6,7 +6,7 @@ import { z } from "zod";
6
6
  //#region src/mcp.ts
7
7
  const SERVER_NAME = "tool_search";
8
8
  const SERVER_VERSION = "1.0.0";
9
- const runMcpServer = async () => {
9
+ const createMcpToolSearchServer = () => {
10
10
  const server = new McpServer({
11
11
  name: SERVER_NAME,
12
12
  version: SERVER_VERSION
@@ -15,12 +15,16 @@ const runMcpServer = async () => {
15
15
  title: "Tool Search Bridge",
16
16
  description: "Load deferred tools by exact name through the Copilot API tool_search bridge.",
17
17
  inputSchema: { names: z.string().describe("Comma-separated exact deferred tool names to load, for example \"TaskList,TaskGet,mcp__fetch__fetch\".") },
18
+ annotations: { readOnlyHint: true },
18
19
  _meta: { "anthropic/alwaysLoad": true }
19
20
  }, ({ names }) => ({ content: [{
20
21
  type: "text",
21
22
  text: createMcpToolSearchSentinel(names)
22
23
  }] }));
23
- await server.connect(new StdioServerTransport());
24
+ return server;
25
+ };
26
+ const runMcpServer = async () => {
27
+ await createMcpToolSearchServer().connect(new StdioServerTransport());
24
28
  };
25
29
  const mcp = defineCommand({
26
30
  meta: {
@@ -34,4 +38,4 @@ const mcp = defineCommand({
34
38
  //#endregion
35
39
  export { mcp };
36
40
 
37
- //# sourceMappingURL=mcp-BG6fpi6q.js.map
41
+ //# sourceMappingURL=mcp-DOp7erlH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-DOp7erlH.js","names":[],"sources":["../src/mcp.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\"\nimport { defineCommand } from \"citty\"\nimport { z } from \"zod\"\n\nimport { createMcpToolSearchSentinel } from \"./lib/tool-search\"\n\nconst SERVER_NAME = \"tool_search\"\nconst SERVER_VERSION = \"1.0.0\"\n\nexport const createMcpToolSearchServer = (): McpServer => {\n const server = new McpServer({\n name: SERVER_NAME,\n version: SERVER_VERSION,\n })\n\n server.registerTool(\n \"search\",\n {\n title: \"Tool Search Bridge\",\n description:\n \"Load deferred tools by exact name through the Copilot API tool_search bridge.\",\n inputSchema: {\n names: z\n .string()\n .describe(\n 'Comma-separated exact deferred tool names to load, for example \"TaskList,TaskGet,mcp__fetch__fetch\".',\n ),\n },\n annotations: {\n readOnlyHint: true,\n },\n _meta: {\n \"anthropic/alwaysLoad\": true,\n },\n },\n ({ names }) => ({\n content: [\n {\n type: \"text\",\n text: createMcpToolSearchSentinel(names),\n },\n ],\n }),\n )\n\n return server\n}\n\nexport const runMcpServer = async (): Promise<void> => {\n await createMcpToolSearchServer().connect(new StdioServerTransport())\n}\n\nexport const mcp = defineCommand({\n meta: {\n name: \"mcp\",\n description: \"Start the Copilot API MCP tool_search bridge over stdio\",\n },\n run() {\n return runMcpServer()\n },\n})\n"],"mappings":";;;;;;AASA,MAAM,cAAc;AACpB,MAAM,iBAAiB;AAEvB,MAAa,kCAA6C;CACxD,MAAM,SAAS,IAAI,UAAU;EAC3B,MAAM;EACN,SAAS;EACV,CAAC;CAEF,OAAO,aACL,UACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EACX,OAAO,EACJ,QAAQ,CACR,SACC,yGACD,EACJ;EACD,aAAa,EACX,cAAc,MACf;EACD,OAAO,EACL,wBAAwB,MACzB;EACF,GACA,EAAE,aAAa,EACd,SAAS,CACP;EACE,MAAM;EACN,MAAM,4BAA4B,MAAM;EACzC,CACF,EACF,EACF;CAED,OAAO;;AAGT,MAAa,eAAe,YAA2B;CACrD,MAAM,2BAA2B,CAAC,QAAQ,IAAI,sBAAsB,CAAC;;AAGvE,MAAa,MAAM,cAAc;CAC/B,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM;EACJ,OAAO,cAAc;;CAExB,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@jeffreycao/copilot-api",
4
- "version": "2.1.9",
4
+ "version": "2.1.10",
5
5
  "description": "GitHub Copilot, OpenAI Codex, OpenCode Go, and third-party AI provider gateway with OpenAI and Anthropic API compatibility.",
6
6
  "keywords": [
7
7
  "github-copilot",
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcp-BG6fpi6q.js","names":[],"sources":["../src/mcp.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\"\nimport { defineCommand } from \"citty\"\nimport { z } from \"zod\"\n\nimport { createMcpToolSearchSentinel } from \"./lib/tool-search\"\n\nconst SERVER_NAME = \"tool_search\"\nconst SERVER_VERSION = \"1.0.0\"\n\nexport const runMcpServer = async (): Promise<void> => {\n const server = new McpServer({\n name: SERVER_NAME,\n version: SERVER_VERSION,\n })\n\n server.registerTool(\n \"search\",\n {\n title: \"Tool Search Bridge\",\n description:\n \"Load deferred tools by exact name through the Copilot API tool_search bridge.\",\n inputSchema: {\n names: z\n .string()\n .describe(\n 'Comma-separated exact deferred tool names to load, for example \"TaskList,TaskGet,mcp__fetch__fetch\".',\n ),\n },\n _meta: {\n \"anthropic/alwaysLoad\": true,\n },\n },\n ({ names }) => ({\n content: [\n {\n type: \"text\",\n text: createMcpToolSearchSentinel(names),\n },\n ],\n }),\n )\n\n await server.connect(new StdioServerTransport())\n}\n\nexport const mcp = defineCommand({\n meta: {\n name: \"mcp\",\n description: \"Start the Copilot API MCP tool_search bridge over stdio\",\n },\n run() {\n return runMcpServer()\n },\n})\n"],"mappings":";;;;;;AASA,MAAM,cAAc;AACpB,MAAM,iBAAiB;AAEvB,MAAa,eAAe,YAA2B;CACrD,MAAM,SAAS,IAAI,UAAU;EAC3B,MAAM;EACN,SAAS;EACV,CAAC;CAEF,OAAO,aACL,UACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EACX,OAAO,EACJ,QAAQ,CACR,SACC,yGACD,EACJ;EACD,OAAO,EACL,wBAAwB,MACzB;EACF,GACA,EAAE,aAAa,EACd,SAAS,CACP;EACE,MAAM;EACN,MAAM,4BAA4B,MAAM;EACzC,CACF,EACF,EACF;CAED,MAAM,OAAO,QAAQ,IAAI,sBAAsB,CAAC;;AAGlD,MAAa,MAAM,cAAc;CAC/B,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM;EACJ,OAAO,cAAc;;CAExB,CAAC"}