fix: respect max_completion_tokens and guard missing model capabilities by laizhengbao · Pull Request #275 · ericc-ch/copilot-api · GitHub
Skip to content

fix: respect max_completion_tokens and guard missing model capabilities - #275

Open
laizhengbao wants to merge 7 commits into
ericc-ch:masterfrom
laizhengbao:master
Open

laizhengbao wants to merge 7 commits into
ericc-ch:masterfrom
laizhengbao:master

Conversation

@laizhengbao

Copy link
Copy Markdown

fix: respect max_completion_tokens and guard missing model capabilities

Summary

Two independent bugs in the chat completions handler, both hit by
real-world clients (observed behind Cherry Studio / gpt-load):

  1. Upstream 400 when clients use max_completion_tokens.
    Modern OpenAI clients send the newer max_completion_tokens field
    instead of legacy max_tokens. handleCompletion unconditionally
    injects max_tokens from the model's advertised limits whenever
    max_tokens is unset, so upstream receives BOTH parameters and
    rejects the request:
    max_tokens and max_completion_tokens cannot both be set.

  2. 500 for models without capabilities.
    GitHub's /models endpoint lists some entries with NO
    capabilities object (observed: gpt-41-copilot,
    trajectory-compaction). Requesting one crashes the proxy:
    undefined is not an object (evaluating 'selectedModel?.capabilities.limits.max_output_tokens').

Changes

File Change
src/routes/chat-completions/handler.ts skip max_tokens injection when max_completion_tokens is present; optional-chain the capabilities lookup
src/services/copilot/create-chat-completions.ts add max_completion_tokens?: number | null to ChatCompletionsPayload
src/services/copilot/get-models.ts Model.capabilities made optional, matching the real API
src/lib/tokenizer.ts guard capabilities?.tokenizer lookup
tests/chat-completions.test.ts regression tests for both fixes

Relation to #220: that PR solves the same max_completion_tokens
interop by normalizing the parameter into max_tokens; this PR takes
the passthrough approach (the Copilot API accepts
max_completion_tokens natively, so forwarding it preserves client
intent). Happy to drop that half if #220 lands first — the
capabilities fix is orthogonal and not covered by any open PR.

Test plan

  • bun run typecheck / bun run lint / bun test all green
  • New regression tests:
    • payload carrying only max_completion_tokens is forwarded without
      an injected max_tokens
    • requesting a capability-less model no longer throws
  • Live-tested against a Copilot individual-plan endpoint:
    • max_completion_tokens-only request -> 200 (previously 500)
    • gpt-41-copilot without max_tokens -> clean upstream 4xx, no crash
    • plain gpt-4.1 without either parameter -> max_tokens: 16384
      still injected (existing behavior preserved)
    • streaming requests unaffected

Two fixes in the chat completions handler:

1. Clients that send the newer `max_completion_tokens` parameter
	 (instead of legacy `max_tokens`) receive a 400 from the Copilot API:
	 `max_tokens and max_completion_tokens cannot both be set`.
	 The handler injects its own `max_tokens` whenever the legacy field is
	 unset, and upstream rejects requests carrying both parameters.
	 Injection is now skipped when either parameter is present, and the
	 payload type gains an optional `max_completion_tokens` field so the
	 value is forwarded upstream as intended.

	 Related: ericc-ch#220 addresses the same interop by normalizing
	 `max_completion_tokens` into `max_tokens` instead; this commit takes
	 the passthrough approach. Happy to drop this half if ericc-ch#220 lands first.

2. GitHub's /models endpoint lists some entries WITHOUT a
	 `capabilities` object (observed: `gpt-41-copilot`,
	 `trajectory-compaction`). Requesting one crashed the proxy with a
	 500: `undefined is not an object (evaluating
	 'selectedModel?.capabilities.limits.max_output_tokens')`.
	 `Model.capabilities` is now optional to mirror the real API, and both
	 the handler and the tokenizer lookup guard against its absence.

Tested against a live Copilot endpoint (individual plan):
- `max_completion_tokens`-only request -> 200 (previously 500)
- capability-less model without max_tokens -> clean upstream error, no crash
- plain request without either parameter -> `max_tokens` still injected
- streaming requests unaffected
@coderabbitai

coderabbitai Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The change adds model-session support and adapters for Responses and legacy Completions. It adds POST routes for both protocols and registers standard and /v1 endpoints. Responses-only models can use the Responses API through chat completion creation. The change also updates token-limit handling, tokenizer fallback behavior, and Copilot and API version values.

Priority: ⚪ Not assessed

Merge Risk: 🟡 Moderate · up to 64a30

Some Responses clients may treat token-truncated output as complete; malformed null-body requests return 500, and multi-choice proxy requests return merged choices. These are bounded API failures, but the streaming contract issue should be corrected before merge.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 64a30

The new endpoints expand what callers can do through the server’s shared upstream credentials. Existing request safeguards are applied, but access depends on how the server is exposed, and a translated stream can give clients an inconsistent completion signal.

Retained concerns

  • Medium · security · inferred: New Responses and Completions endpoints extend the operations reachable with the server’s shared Copilot credential without adding caller authentication at the server router. The actual exposure depends on listener and external access controls; existing Chat Completions and Embeddings routes establish that this is an expansion of an existing trust pattern, not a newly removed control.
  • Medium · reliability · observed: For a Chat Completions stream terminated by its length limit, the Responses adapter emits a response.completed event whose response status is incomplete. A consumer relying on the terminal event to contain or recover from truncated output receives a contradictory signal.
Security review details

Security Blast Radius

  • inferred — Any caller able to reach the newly mounted endpoints can request additional operations against Copilot using this process’s credential. The maximum independently attackable scope is the reachable server instance and its configured upstream account; external exposure and caller identity controls remain unverified.

Security Findings and Attack Paths

  • inferred — A reachable caller can select a model and supply a request to either new protocol; its route then invokes a credentialed upstream service. Rate limiting and conditional approval precede dispatch, and comparable credentialed routes existed before this PR. No verified authentication bypass or cross-origin credential leak is established.

Trust Boundaries and Controls

  • observed — The new routes apply the shared rate limit and optional operator approval. Responses input markers can influence the upstream X-Initiator value, but Chat Completions already derives that value from caller-supplied message roles; whether it conveys privileged authority rather than protocol metadata is not established.

Resilience and Maintainability Implications

  • inferred — Wait-mode callers are not serialized by the shared timestamp, limiting how strongly that control can contain concurrent demand on the newly reachable operations. This behavior is inherited from the existing helper, rather than introduced in its implementation by this PR.

Hardening Proposals

  • proposed — If the listener can be reached by callers outside the intended trusted boundary, enforce caller authorization before credentialed dispatch; define whether the shared rate limit is intended to serialize concurrent requests. Bind cached model sessions to the upstream identity if credentials can rotate while the process runs.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 21 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes both primary fixes: preserving max_completion_tokens and safely handling missing model capabilities.
Description check ✅ Passed The description directly explains the two fixes, affected files, regression tests, and reported validation results.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@laizhengbao
laizhengbao marked this pull request as ready for review September 27, 2026 09:33
Copilot AI lite review requested due to automatic review settings September 27, 2026 09:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

A moderate issue remains when max_completion_tokens is explicitly null, potentially forwarding both token-limit parameters.

Review effort: Lite
Findings: None

What changed in this PR

Updates chat completion handling for modern token limits and models with incomplete capability metadata.

Changes:

  • Supports max_completion_tokens without conflicting injection.
  • Makes capability and tokenizer lookups safe.
  • Adds regression tests.
File Summary
tests/​chat-completions.test.ts Adds regression coverage.
src/​services/​copilot/​get-models.ts Makes model capabilities optional.
src/​services/​copilot/​create-chat-completions.ts Adds max_completion_tokens support.
src/​routes/​chat-completions/​handler.ts Adjusts token-limit injection and capability access.
src/​lib/​tokenizer.ts Adds tokenizer fallback handling.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: c588bb46-3afe-46bc-89e9-85f7d04be650

📥 Commits

Reviewing files that changed from the base of the PR and between 6e3b966 and c2c2cdb.

📒 Files selected for processing (17)
  • src/lib/api-config.ts
  • src/lib/state.ts
  • src/routes/completions/route.ts
  • src/routes/responses/route.ts
  • src/server.ts
  • src/services/copilot/completions-adapter.ts
  • src/services/copilot/create-chat-completions.ts
  • src/services/copilot/create-model-session.ts
  • src/services/copilot/create-proxy-completions.ts
  • src/services/copilot/create-responses.ts
  • src/services/copilot/get-models.ts
  • src/services/copilot/responses-adapter.ts
  • src/services/github/get-copilot-usage.ts
  • tests/chat-completions.test.ts
  • tests/create-chat-completions.test.ts
  • tests/model-session.test.ts
  • tests/responses-adapter.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📜 Review details
🔇 Additional comments (13)
tests/chat-completions.test.ts (1)

72-77: LGTM!

src/lib/api-config.ts (1)

14-14: 🎯 Functional Correctness

Do not flag 2026-01-09 based on the public REST version list.

githubHeaders is used only for GitHub's internal Copilot endpoints: /copilot_internal/v2/token and /copilot_internal/user. The public REST version documentation does not establish the version contract for these endpoints, and the supplied evidence does not show that they reject 2026-01-09. No version change is supported by this finding.

src/services/copilot/get-models.ts (1)

49-49: LGTM!

src/lib/state.ts (1)

1-1: LGTM!

Also applies to: 10-11

src/services/github/get-copilot-usage.ts (1)

41-41: LGTM!

src/services/copilot/create-model-session.ts (1)

82-88: LGTM!

tests/model-session.test.ts (1)

1-116: LGTM!

tests/create-chat-completions.test.ts (1)

12-18: LGTM!

src/services/copilot/create-chat-completions.ts (1)

7-15: LGTM!

Also applies to: 53-55, 61-61

tests/responses-adapter.test.ts (1)

1-202: LGTM!

src/routes/responses/route.ts (1)

1-68: LGTM!

src/routes/completions/route.ts (1)

1-66: LGTM!

src/server.ts (1)

6-6: LGTM!

Also applies to: 10-10, 22-22, 25-25, 31-31, 34-34

Comment thread src/services/copilot/completions-adapter.ts Outdated
Comment thread src/services/copilot/completions-adapter.ts
Comment thread src/services/copilot/completions-adapter.ts Outdated
Comment thread src/services/copilot/create-model-session.ts
Comment thread src/services/copilot/create-proxy-completions.ts
Comment thread src/services/copilot/responses-adapter.ts
Comment thread src/services/copilot/responses-adapter.ts Outdated
Comment thread src/services/copilot/responses-adapter.ts
Comment thread src/services/copilot/responses-adapter.ts
Comment thread src/services/copilot/responses-adapter.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

🟠 Major · Propagate Responses stream failures instead of emitting… · responses-adapter.ts:386-389

src/services/copilot/responses-adapter.ts:386-389
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Propagate Responses stream failures instead of emitting content_filter.

A response.failed or error SSE event can pass through the Responses-only Chat Completions path after an initially successful HTTP response. The adapter currently emits a terminal finish_reason: "content_filter" chunk. The Chat Completions handler writes that chunk as a successful SSE response, so clients can treat an upstream failure as a completed request.

Suggested fix
-  if (parsed.type === "response.failed" || parsed.type === "error") {
-    return {
-      chunks: [makeChunk(meta, { delta: {}, finish_reason: "content_filter" })],
-      done: true,
-      emittedRole,
-    }
-  }
+  if (parsed.type === "response.failed" || parsed.type === "error") {
+    throw new Error("Responses stream failed")
+  }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 9ec121b0-336c-49e6-b0f2-604ec67527e1

📥 Commits

Reviewing files that changed from the base of the PR and between c2c2cdb and 2e64394.

📒 Files selected for processing (12)
  • src/routes/chat-completions/handler.ts
  • src/routes/completions/route.ts
  • src/routes/responses/route.ts
  • src/services/copilot/completions-adapter.ts
  • src/services/copilot/create-chat-completions.ts
  • src/services/copilot/create-model-session.ts
  • src/services/copilot/create-proxy-completions.ts
  • src/services/copilot/create-responses.ts
  • src/services/copilot/responses-adapter.ts
  • tests/chat-completions.test.ts
  • tests/completions-adapter.test.ts
  • tests/responses-adapter.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📜 Review details
🔇 Additional comments (13)
src/routes/chat-completions/handler.ts (1)

42-54: LGTM!

tests/chat-completions.test.ts (1)

114-125: LGTM!

src/services/copilot/completions-adapter.ts (1)

22-27: LGTM!

Also applies to: 40-40, 47-66, 84-89

src/routes/completions/route.ts (1)

43-53: LGTM!

tests/completions-adapter.test.ts (1)

1-66: LGTM!

src/services/copilot/responses-adapter.ts (2)

732-732: Guard call.index against non-array-index values.

call.index < toolCalls.length is true for a negative index. toolCalls[-1] is then undefined, so the code falls through. The while loop is skipped, and a new call is pushed. This case is unlikely from a well-behaved upstream. The behavior is safe but wrong for that input. No fix is required.


46-77: LGTM!

Also applies to: 102-108, 245-246, 261-261, 429-430, 548-559, 571-584, 630-647, 729-750

src/services/copilot/create-model-session.ts (1)

21-27: LGTM!

Also applies to: 54-59, 68-68, 73-73, 92-92

src/services/copilot/create-responses.ts (1)

14-24: LGTM!

Also applies to: 32-33

src/services/copilot/create-proxy-completions.ts (1)

26-26: LGTM!

Also applies to: 127-131

src/services/copilot/create-chat-completions.ts (1)

41-41: LGTM!

tests/responses-adapter.test.ts (1)

15-15: LGTM!

Also applies to: 204-302

src/routes/responses/route.ts (1)

13-13: LGTM!

Also applies to: 27-30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Multiple critical and moderate unresolved issues affect new public routes, controls, streaming, and protocol semantics.

Review effort: Lite
Findings: 3 High severity · 2 Medium severity

Open (5)

Comment thread src/routes/completions/route.ts
Comment thread src/routes/responses/route.ts
Comment thread src/services/copilot/responses-adapter.ts
Comment thread src/services/copilot/responses-adapter.ts Outdated
Comment thread src/services/copilot/responses-adapter.ts Outdated
@laizhengbao
laizhengbao requested a balanced review from Copilot September 29, 2026 08:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 3a988130-f9be-4080-a478-c7ba810f878f

📥 Commits

Reviewing files that changed from the base of the PR and between 2e64394 and 23778b3.

📒 Files selected for processing (4)
  • src/routes/completions/route.ts
  • src/routes/responses/route.ts
  • src/services/copilot/responses-adapter.ts
  • tests/responses-adapter.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.

Comment thread src/services/copilot/responses-adapter.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Unresolved compatibility issues and broad API additions require further fixes and human review.

Review effort: Lite
Findings: None

Resolved since last review (5)
Previously missed (3)

In code that hasn't changed since last review

Medium severity Multiple completions are merged into one choice

src/​services/​copilot/​create-proxy-completions.ts:58

When the upstream emits multiple choices for n > 1, this loop appends every choice's text into one string and the returned object always exposes only one choice at index 0. Because n is accepted and forwarded by CompletionsPayload, non-streaming legacy requests lose independent completions; accumulate by choice.index and return one result per choice.

Medium severity Response stream omits the OpenAI DONE sentinel

src/​services/​copilot/​responses-adapter.ts:499

The response-only chat stream never emits the OpenAI [DONE] sentinel: after response.completed this return exits after the JSON chunks, and the EOF fallback below also emits only a final JSON chunk. handleCompletion writes these events directly, so clients that wait for [DONE] can hang or fail to mark the completion finished. Emit the sentinel on both the normal-completion and fallback paths, and update the stream regression test to ignore it.

This issue also appears on line 713 of the same file.

Low severity PR scope omits substantial API and adapter changes

src/​server.ts:10

This change adds two public API routes plus the Responses/completions adapters, proxy integration, model-session flow, and protocol translations, while the PR description scopes the work to two chat-completion fixes and lists only five changed files. Please split this unrelated feature work or update the PR scope and test/compatibility documentation before approval; otherwise the stated review scope does not cover these new behaviors.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Unresolved protocol adapter, validation, streaming, and session-path issues remain.

Review effort: Lite
Findings: None

Previously missed (3)

In code that hasn't changed since last review

Medium severity Preserve response_format in Responses translation

src/​services/​copilot/​responses-adapter.ts:94

The chat payload's response_format is silently dropped on this translation path. A client requesting response_format: { type: "json_object" } for a Responses-only model will therefore receive no JSON-mode constraint, unlike the normal chat path. Map it to the Responses API's text.format (or reject it explicitly) instead of forwarding a request that changes the client's requested behavior.

Medium severity Emit streamed function-call events

src/​services/​copilot/​responses-adapter.ts:800

Tool calls are collected in state.toolCalls, but the streamed Responses event sequence never emits them: this only closes the message item and then puts function calls inside response.completed. Responses clients consume function calls through response.output_item.added and response.function_call_arguments.* events, so a streamed tool-use request can finish without any tool call being delivered incrementally. Emit the corresponding function-call item/argument events (and its output_item.done) before response.completed.

Low severity Split unrelated API feature work or expand PR scope

src/​server.ts:25

The PR is described as two targeted fixes and lists only the handler/model/tokenizer changes, but this hunk also introduces public /completions and /responses APIs, protocol adapters, proxy-engine routing, model-session state, and an upstream API-version change. Please split this unrelated feature work or update the PR scope and validation plan before approval; otherwise the stated review/test scope does not cover the behavior being shipped.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

🟡 Minor · Preserve each indexed choice when aggregating proxy… · create-proxy-completions.ts:41-71

src/services/copilot/create-proxy-completions.ts:41-71
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Preserve each indexed choice when aggregating proxy completions.

When a non-streaming request for a -copilot model sets n greater than one, the route forwards n to the proxy and aggregates the streaming response. The aggregator appends text from every indexed choice to one string, then returns only choice index: 0. Clients receive concatenated completions instead of the separate choices required by the legacy Completions response.

Suggested fix
-  let text = ""
-  let finishReason: string | null = null
+  const choices = new Map<
+    number,
+    { text: string; finishReason: string | null }
+  >()

   for await (const event of events(response)) {
     if (!event.data) continue
     if (event.data === "[DONE]") break
     const chunk = JSON.parse(event.data) as LegacyCompletionChunk
     if (chunk.id) id = chunk.id
     for (const choice of chunk.choices ?? []) {
-      if (typeof choice.text === "string") text += choice.text
-      if (choice.finish_reason) finishReason = choice.finish_reason
+      const aggregate = choices.get(choice.index) ?? {
+        text: "",
+        finishReason: null,
+      }
+      if (typeof choice.text === "string") aggregate.text += choice.text
+      if (choice.finish_reason) aggregate.finishReason = choice.finish_reason
+      choices.set(choice.index, aggregate)
     }
   }

   return {
@@
-    choices: [
-      { text, index: 0, finish_reason: finishReason ?? "stop", logprobs: null },
-    ],
+    choices:
+      choices.size > 0 ?
+        [...choices.entries()]
+          .sort(([left], [right]) => left - right)
+          .map(([index, choice]) => ({
+            text: choice.text,
+            index,
+            finish_reason: choice.finishReason ?? "stop",
+            logprobs: null,
+          }))
+      : [{ text: "", index: 0, finish_reason: "stop", logprobs: null }],
   }
 }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 33fda2ba-6c5a-4e7f-b6a2-451121024460

📥 Commits

Reviewing files that changed from the base of the PR and between 23778b3 and 64a302c.

📒 Files selected for processing (5)
  • src/routes/completions/route.ts
  • src/routes/embeddings/route.ts
  • src/routes/responses/route.ts
  • src/services/copilot/responses-adapter.ts
  • tests/responses-adapter.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📜 Review details
🔇 Additional comments (3)
src/services/copilot/responses-adapter.ts (1)

244-247: LGTM!

tests/responses-adapter.test.ts (1)

396-410: LGTM!

src/routes/embeddings/route.ts (1)

18-19: LGTM!

Comment thread src/routes/completions/route.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Unresolved moderate issues affect token forwarding and Responses API correctness.

Review effort: Lite
Findings: None

Previously missed (2)

In code that hasn't changed since last review

Medium severity Preserve response.incomplete as a length finish reason

src/​services/​copilot/​responses-adapter.ts:420

response.incomplete is the Responses API terminal event for max-output truncation, but only response.completed is converted here. When a Responses-only model hits its output limit, this event is ignored and the fallback at the end emits finish_reason: "stop", so Chat Completions clients see a successful completion instead of length. Handle response.incomplete with the same conversion path so the status is preserved.

Low severity Align PR scope with added APIs and protocol changes

src/​server.ts:34

The description presents this as two targeted chat-completions fixes and lists only five affected files, but this diff also adds and registers full /completions and /responses APIs, model-session handling, and protocol/header changes. That is a materially broader behavioral and operational change than the stated scope; please either update the PR description and test/rollout plan or split the unrelated additions into a separate PR.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants