@vincemakes/kiso-provider-openai 0.45.0 → 0.45.2

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
@@ -5,6 +5,12 @@ DeepSeek, OpenRouter via base_url): reasoning dialects digested into
5
5
  thinking, real streaming usage, exhaustive finish-reason mapping,
6
6
  connection/timeout/5xx classification.
7
7
 
8
+ One request yields exactly one `usage` event, before its `stop`. A
9
+ channel may report usage several times in one stream (twice after the
10
+ finish, or cumulatively on every chunk); the adapter keeps the last
11
+ report and emits it once, so a host that adds usage events up bills each
12
+ request once.
13
+
8
14
  Requires Node >= 22. See the repository README for the framework
9
15
  overview.
10
16
 
package/dist/index.js CHANGED
@@ -93,6 +93,13 @@ export function createOpenAICompatAdapter(client, adapterOpts = {}) {
93
93
  const pending = new Map();
94
94
  let finishReason = null;
95
95
  let usageSent = false;
96
+ // One request, one usage event. A compat channel may report usage
97
+ // more than once in one stream (two identical chunks after the
98
+ // finish, or the cumulative figure on every chunk); usage here is
99
+ // cumulative, so the LAST report is the request's. It is held and
100
+ // yielded once, after the stream ends and before the stop — a host
101
+ // adding usage events up bills the request exactly once.
102
+ let lastUsage = null;
96
103
  let stopReason = "end_turn";
97
104
  // P1-10: the FIRST finish reason is FINAL — later content and
98
105
  // finish reasons are ignored (a provider that emits text after a
@@ -121,7 +128,7 @@ export function createOpenAICompatAdapter(client, adapterOpts = {}) {
121
128
  const u = chunk.usage;
122
129
  const details = u.prompt_tokens_details;
123
130
  const reasoning = u.completion_tokens_details?.reasoning_tokens;
124
- yield {
131
+ lastUsage = {
125
132
  seq: 0,
126
133
  type: "usage",
127
134
  inputTokens: chunk.usage.prompt_tokens ?? null,
@@ -238,7 +245,7 @@ export function createOpenAICompatAdapter(client, adapterOpts = {}) {
238
245
  // comment saying no provider reports a split — true when
239
246
  // written, false since this vendor shipped one.
240
247
  const reasoning = u.completion_tokens_details?.reasoning_tokens;
241
- yield {
248
+ lastUsage = {
242
249
  seq: 0,
243
250
  type: "usage",
244
251
  inputTokens: chunk.usage.prompt_tokens ?? null,
@@ -287,6 +294,12 @@ export function createOpenAICompatAdapter(client, adapterOpts = {}) {
287
294
  // provider answered, we just do not know the word, and it still
288
295
  // stops.
289
296
  if (finishReason === null && !options.signal?.aborted) {
297
+ // The pending CALLS are withheld (above); a usage the stream
298
+ // already reported is not a call — a gateway that puts the
299
+ // cumulative usage on every chunk has billed this attempt, and
300
+ // that bill is known. It goes out once, before the failure.
301
+ if (lastUsage !== null)
302
+ yield lastUsage;
290
303
  throw streamFailure(`[${vendorOf(options.model)}] request failed: the stream ended with no finish reason`);
291
304
  }
292
305
  // Close out any streamed tool calls.
@@ -309,6 +322,8 @@ export function createOpenAICompatAdapter(client, adapterOpts = {}) {
309
322
  input,
310
323
  };
311
324
  }
325
+ if (lastUsage !== null)
326
+ yield lastUsage;
312
327
  if (!usageSent) {
313
328
  // Area 6: no usage reported is expressed as UNKNOWN — nulls
314
329
  // and known:false — never faked as a zero-cost turn.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-provider-openai",
3
- "version": "0.45.0",
3
+ "version": "0.45.2",
4
4
  "description": "kiso OpenAI-compatible adapter \u2014 OpenAI + the compat family (GLM, Kimi, DeepSeek, OpenRouter) via base_url swap, reasoning dialects digested.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -21,7 +21,7 @@
21
21
  "test": "vitest run"
22
22
  },
23
23
  "dependencies": {
24
- "@vincemakes/kiso-core": "0.45.0",
24
+ "@vincemakes/kiso-core": "0.45.2",
25
25
  "openai": "^7.3.0"
26
26
  },
27
27
  "devDependencies": {