fix(github-copilot): bound usage response (#96607) · openclaw/openclaw@646e54a
Alix-007
·
2026-06-26
·
via Recent Commits to openclaw:main
File tree
extensions/github-copilot
| Original file line number | Diff line number | Diff line change |
|---|
@@ -267,6 +267,47 @@ describe("fetchCopilotUsage", () => {
|
267 | 267 | plan: "free", |
268 | 268 | }); |
269 | 269 | }); |
| 270 | + |
| 271 | +it("bounds the usage read and cancels the stream when the body exceeds the JSON byte cap", async () => { |
| 272 | +// Larger than the shared 16 MiB readProviderJsonResponse cap so the bounded reader cancels the |
| 273 | +// stream mid-flight; if the cap were removed the unbounded res.json() would buffer the whole body. |
| 274 | +const ONE_MIB = 1024 * 1024; |
| 275 | +const TOTAL_CHUNKS = 32; // 32 MiB advertised body, double the cap. |
| 276 | +const chunk = new Uint8Array(ONE_MIB); |
| 277 | + |
| 278 | +let bytesPulled = 0; |
| 279 | +let canceled = false; |
| 280 | +const makeOversizedJsonResponse = (): Response => { |
| 281 | +let pulled = 0; |
| 282 | +const body = new ReadableStream<Uint8Array>({ |
| 283 | +pull(controller) { |
| 284 | +if (pulled >= TOTAL_CHUNKS) { |
| 285 | +controller.close(); |
| 286 | +return; |
| 287 | +} |
| 288 | +pulled += 1; |
| 289 | +bytesPulled += chunk.length; |
| 290 | +controller.enqueue(chunk); |
| 291 | +}, |
| 292 | +cancel() { |
| 293 | +canceled = true; |
| 294 | +}, |
| 295 | +}); |
| 296 | +return new Response(body, { |
| 297 | +status: 200, |
| 298 | +headers: { "Content-Type": "application/json" }, |
| 299 | +}); |
| 300 | +}; |
| 301 | + |
| 302 | +const mockFetch = createProviderUsageFetch(async () => makeOversizedJsonResponse()); |
| 303 | + |
| 304 | +await expect(fetchCopilotUsage("token", 5000, mockFetch)).rejects.toThrow( |
| 305 | +/github-copilot-usage: JSON response exceeds/, |
| 306 | +); |
| 307 | +// The bounded reader cancels the body and never pulls the full advertised 32 MiB stream. |
| 308 | +expect(canceled).toBe(true); |
| 309 | +expect(bytesPulled).toBeLessThan(TOTAL_CHUNKS * ONE_MIB); |
| 310 | +}); |
270 | 311 | }); |
271 | 312 | |
272 | 313 | describe("github-copilot token", () => { |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
1 | 1 | // Github Copilot plugin module implements usage behavior. |
2 | 2 | import { buildCopilotIdeHeaders } from "openclaw/plugin-sdk/provider-auth"; |
| 3 | +import { readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http"; |
3 | 4 | import { |
4 | 5 | buildUsageHttpErrorSnapshot, |
5 | 6 | fetchJson, |
@@ -41,7 +42,10 @@ export async function fetchCopilotUsage(
|
41 | 42 | }); |
42 | 43 | } |
43 | 44 | |
44 | | -const data = (await res.json()) as CopilotUsageResponse; |
| 45 | +const data = await readProviderJsonResponse<CopilotUsageResponse>( |
| 46 | +res, |
| 47 | +"github-copilot-usage", |
| 48 | +); |
45 | 49 | const windows: UsageWindow[] = []; |
46 | 50 | |
47 | 51 | if (data.quota_snapshots?.premium_interactions) { |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。