@tanstack-ai-browser/webgllm 0.2.0 → 0.2.1

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/dist/adapter.d.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  * calls) are TanStack's. This file adds what's webgllm's own: loading the
10
10
  * model before a call, and its reasoning levels and thinking budget.
11
11
  */
12
- import type { AdapterYieldChunk, ModelReasoning, TextOptions } from "@tanstack/ai";
12
+ import type { AdapterYieldChunk, ModelReasoning, TextOptions, TokenUsage } from "@tanstack/ai";
13
13
  import type { StructuredOutputOptions, StructuredOutputResult } from "@tanstack/ai/adapters";
14
14
  import { OpenAIBaseChatCompletionsTextAdapter } from "@tanstack/openai-base";
15
15
  import type { OpenAIClientLike } from "@tanstack/openai-base";
@@ -115,6 +115,16 @@ export declare class WebGllmTextAdapter<TModel extends WebGllmModel> extends Ope
115
115
  structuredOutputStream(options: StructuredOutputOptions<WebGllmTextModelOptions>): AsyncIterable<AdapterYieldChunk>;
116
116
  structuredOutput(options: StructuredOutputOptions<WebGllmTextModelOptions>): Promise<StructuredOutputResult<unknown>>;
117
117
  /** The request, with `modelOptions` as given, the thinking budget and the prompt cache. */
118
+ /**
119
+ * The engine's usage, as TanStack converts it, but with a cached count of 0
120
+ * kept, which TanStack's conversion leaves out: 0 means the whole prompt was
121
+ * read, where no count means the engine didn't say.
122
+ */
123
+ protected chatCompletionsTokenUsage(usage: {
124
+ prompt_tokens_details?: {
125
+ cached_tokens?: number;
126
+ } | null;
127
+ } | null | undefined, source?: unknown): TokenUsage | undefined;
118
128
  protected mapOptionsToRequest(options: TextOptions): CreateParams & {
119
129
  stream: true;
120
130
  };
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
package/dist/adapter.js CHANGED
@@ -124,6 +124,18 @@ export class WebGllmTextAdapter extends OpenAIBaseChatCompletionsTextAdapter {
124
124
  return super.structuredOutput(options);
125
125
  }
126
126
  /** The request, with `modelOptions` as given, the thinking budget and the prompt cache. */
127
+ /**
128
+ * The engine's usage, as TanStack converts it, but with a cached count of 0
129
+ * kept, which TanStack's conversion leaves out: 0 means the whole prompt was
130
+ * read, where no count means the engine didn't say.
131
+ */
132
+ chatCompletionsTokenUsage(usage, source) {
133
+ const result = super.chatCompletionsTokenUsage(usage, source);
134
+ const cachedTokens = usage?.prompt_tokens_details?.cached_tokens;
135
+ if (!result || cachedTokens !== 0)
136
+ return result;
137
+ return { ...result, promptTokensDetails: { ...result.promptTokensDetails, cachedTokens } };
138
+ }
127
139
  mapOptionsToRequest(options) {
128
140
  const request = super.mapOptionsToRequest(options);
129
141
  const resolved = resolveReasoning(options.reasoning, this.modelReasoning(this.model));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack-ai-browser/webgllm",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "TanStack AI adapter for webgllm: LFM3, LFM2.5 and Qwen3.5 in the browser on WebGL 2, for devices without WebGPU",
5
5
  "license": "MIT",
6
6
  "author": "daveycodez",
@@ -43,6 +43,9 @@
43
43
  "dist",
44
44
  "!**/*.tsbuildinfo"
45
45
  ],
46
+ "scripts": {
47
+ "test": "node scripts/test.mjs"
48
+ },
46
49
  "publishConfig": {
47
50
  "access": "public"
48
51
  },
@@ -60,8 +63,5 @@
60
63
  "@huggingface/transformers": "4.3.2",
61
64
  "@tanstack/ai": "1.4.0",
62
65
  "esbuild": "0.28.2"
63
- },
64
- "scripts": {
65
- "test": "node scripts/test.mjs"
66
66
  }
67
- }
67
+ }
package/src/adapter.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  * calls) are TanStack's. This file adds what's webgllm's own: loading the
10
10
  * model before a call, and its reasoning levels and thinking budget.
11
11
  */
12
- import type { AdapterYieldChunk, ModelReasoning, TextOptions } from "@tanstack/ai"
12
+ import type { AdapterYieldChunk, ModelReasoning, TextOptions, TokenUsage } from "@tanstack/ai"
13
13
  import { resolveReasoning } from "@tanstack/ai/adapter-internals"
14
14
  import type { StructuredOutputOptions, StructuredOutputResult } from "@tanstack/ai/adapters"
15
15
  import { OpenAIBaseChatCompletionsTextAdapter } from "@tanstack/openai-base"
@@ -235,6 +235,21 @@ export class WebGllmTextAdapter<TModel extends WebGllmModel> extends OpenAIBaseC
235
235
  }
236
236
 
237
237
  /** The request, with `modelOptions` as given, the thinking budget and the prompt cache. */
238
+ /**
239
+ * The engine's usage, as TanStack converts it, but with a cached count of 0
240
+ * kept, which TanStack's conversion leaves out: 0 means the whole prompt was
241
+ * read, where no count means the engine didn't say.
242
+ */
243
+ protected override chatCompletionsTokenUsage(
244
+ usage: { prompt_tokens_details?: { cached_tokens?: number } | null } | null | undefined,
245
+ source?: unknown
246
+ ): TokenUsage | undefined {
247
+ const result = super.chatCompletionsTokenUsage(usage as never, source)
248
+ const cachedTokens = usage?.prompt_tokens_details?.cached_tokens
249
+ if (!result || cachedTokens !== 0) return result
250
+ return { ...result, promptTokensDetails: { ...result.promptTokensDetails, cachedTokens } }
251
+ }
252
+
238
253
  protected override mapOptionsToRequest(options: TextOptions): CreateParams & { stream: true } {
239
254
  const request = super.mapOptionsToRequest(options)
240
255
  const resolved = resolveReasoning(options.reasoning, this.modelReasoning(this.model))
@@ -134,3 +134,13 @@ test("images: a model with a vision encoder reads them, sent as OpenAI image_url
134
134
  { type: "text", text: "What's this?" }
135
135
  ])
136
136
  })
137
+
138
+ test("usage keeps webgllm's cached count, 0 included (TanStack's conversion leaves a 0 out)", async () => {
139
+ for (const cached of [0, 352]) {
140
+ fake.script = () => [chunk({ role: "assistant", content: "Hi" }), chunk({}, "stop"), usageChunk({ prompt: 371, completion: 2, cached })]
141
+ const events = (await collect(webgllmText(MODEL).chatStream(textOptions()))) as Array<Event>
142
+ const usage = events.find((e) => e.type === "RUN_FINISHED")?.usage as { promptTokens: number; promptTokensDetails?: unknown }
143
+ assert.equal(usage.promptTokens, 371)
144
+ assert.deepEqual(usage.promptTokensDetails, { cachedTokens: cached })
145
+ }
146
+ })