


























@@ -395,6 +395,77 @@ describe("openai transport stream", () => {
395395});
396396});
397397398+it("records usage from OpenAI-compatible streaming usage chunks", async () => {
399+const model = {
400+id: "glm-5",
401+name: "GLM-5",
402+api: "openai-completions",
403+provider: "vllm",
404+baseUrl: "http://localhost:8000/v1",
405+reasoning: false,
406+input: ["text"],
407+cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
408+contextWindow: 128000,
409+maxTokens: 4096,
410+} satisfies Model<"openai-completions">;
411+const output = {
412+role: "assistant" as const,
413+content: [],
414+api: model.api,
415+provider: model.provider,
416+model: model.id,
417+usage: {
418+input: 0,
419+output: 0,
420+cacheRead: 0,
421+cacheWrite: 0,
422+totalTokens: 0,
423+cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
424+},
425+stopReason: "stop",
426+timestamp: Date.now(),
427+};
428+const stream: { push(event: unknown): void } = { push() {} };
429+430+async function* mockStream() {
431+yield {
432+id: "chatcmpl-vllm",
433+object: "chat.completion.chunk" as const,
434+created: 1775425651,
435+model: "glm-5",
436+choices: [
437+{
438+index: 0,
439+delta: { role: "assistant" as const, content: "ok" },
440+logprobs: null,
441+finish_reason: "stop" as const,
442+},
443+],
444+};
445+yield {
446+id: "chatcmpl-vllm",
447+object: "chat.completion.chunk" as const,
448+created: 1775425651,
449+model: "glm-5",
450+choices: [],
451+usage: {
452+prompt_tokens: 8,
453+completion_tokens: 10,
454+total_tokens: 18,
455+},
456+};
457+}
458+459+await __testing.processOpenAICompletionsStream(mockStream(), output, model, stream);
460+461+expect(output.usage).toMatchObject({
462+input: 8,
463+output: 10,
464+cacheRead: 0,
465+totalTokens: 18,
466+});
467+});
468+398469it("keeps OpenRouter thinking format for declared OpenRouter providers on custom proxy URLs", async () => {
399470const streamFn = buildTransportAwareSimpleStreamFn(
400471attachModelProviderRequestTransport(
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。