Skip to content

perf(util): add an incremental partial-JSON stream parser - #681

Merged
sroussey merged 3 commits into
mainfrom
claude/libs-issues-triage-prs-mh6x2o-507
Aug 7, 2026
Merged

perf(util): add an incremental partial-JSON stream parser#681
sroussey merged 3 commits into
mainfrom
claude/libs-issues-triage-prs-mh6x2o-507

Conversation

@sroussey

@sroussey sroussey commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Closes #507

The literal ask was already done; the stated goal was not

A partial-JSON parser already exists — packages/util/src/json-schema/parsePartialJson.ts, tested and in use. So "add a json streaming parser" reads as satisfied.

But the issue's stated goal is "so we don't have to accumulate structured output", and that never happened. parsePartialJson is a repair-and-reparse of a truncated buffer, not a streaming parser: every call runs JSON.parse on the whole buffer, then re-scans the whole buffer character-by-character to repair it, then JSON.parses again. There is no cursor, no container stack, no push()/finish().

Accumulation was therefore never eliminated — it was relocated into every provider run-fn. All eleven *_StructuredGeneration.ts files held a growing accumulatedJson string and called parsePartialJson(accumulatedJson) once per delta. That is O(n²), and run-fns execute inside workers, so it fully blocks a worker thread.

Measured on the built bundle (packages/util/dist), accumulate-and-reparse vs. the new parser:

payload chunk size chunks before after speedup
24 KB 8 chars 3129 3999 ms 12.3 ms 326x
98 KB 40 chars 2502 9512 ms 9.8 ms 971x

4.1x the bytes costs ~2.4x the time before (super-linear); after, it is flat.

What this adds

createPartialJsonStream(options?) in packages/util/src/json-schema/PartialJsonStream.ts — a resumable tokenizer holding a container stack of live JS objects/arrays, the pending key, a scalar buffer bounded by the current token (not the document), and string-escape / \uXXXX state. push(chunk) is O(chunk.length) and never re-scans consumed input.

  • push(chunk) → the live root once a top-level object has opened, else undefined
  • finish() → closes open containers/strings; idempotent
  • snapshot() → detached deep copy
  • complete → whether the root closed on its own
  • skipPreamble option → discards text before the first {/[, for providers that emit prose or a <think> block first

parsePartialJson is exported and unchanged — it remains correct and in use for one-shot repair call sites.

⚠️ Behavioral tradeoff reviewers must consent to: live-root aliasing

push() returns the parser's live root object, which subsequent pushes keep mutating. This is the one intentional behavior change, and it is what makes the parser O(n) — deep-cloning on every delta would reinstate the O(n²) this PR exists to remove.

Why it is safe on the paths we actually use:

  • StreamEventAccumulator.observe and StreamProcessor use replace semantics for non-array object-deltas, so repeatedly storing the same growing object converges to the correct final value.
  • Events are structured-cloned crossing the worker boundary, so out-of-process consumers get independent copies anyway.

Where it bites: an in-process consumer that retains an earlier delta will see that object change under it. The aliasing is documented in the interface JSDoc, snapshot() is the escape hatch for anyone needing a frozen copy, and there is a test asserting each behavior explicitly.

Guard preserved: push() returns undefined for a top-level array root (matching parsePartialJson), so no run-fn can emit an array as an objectDelta — that would hit the accumulators' append-by-id branch and re-append the whole growing array each delta.

Why the parser stays in @workglow/util, not @workglow/ai

The issue says "to the ai package", but that placement would be wrong here. util is the foundation package, and the consumers are provider run-fns that already import worker-safe helpers from @workglow/util/worker@workglow/ai sits above them in the dependency graph. Moving it would break that import path and buy nothing. It is exported from both schema-entry.ts and worker-entry.ts, exactly like parsePartialJson.

Migrated call sites

All 11 *_StructuredGeneration.ts run-fns: anthropic, openai, google-gemini, ollama, xai, deepseek, openrouter, chrome-ai, node-llama-cpp, huggingface-transformers, tf-mediapipe. Each collapses accumulatedJson + per-delta parsePartialJson + the trailing try { JSON.parse } catch { parsePartialJson } into one stream instance ending in emit({ type: "finish", data: { object: json.finish() } }).

Notes:

  • HFT / TFMP additionally did parsePartialJson(fullText.slice(jsonStart)) per delta; both now use skipPreamble and drop the jsonStart bookkeeping and the per-delta .slice(). Their existing behavior of emitting text-delta while no JSON has appeared yet is preserved (detected via push() returning undefined). HFT's now-dead extractJsonFromText/stripThinkingAndSpecialTokens helpers are removed; TFMP's extractJsonFromText is exported and tested, so it stays.
  • chrome-ai emits progressive full-text snapshots rather than deltas; it keeps its snapshot diff and feeds only the newly-appended tail, restarting the parser on the rare replacement case.
  • deepseek's assertNotTruncatedByReasoning only distinguishes "no content" from "some content", so it now gets one retained delta instead of a full second copy of the document. The helper's public signature is untouched.
  • The CLAUDE.md rule that json-mode run-fns MUST populate finish.data.object stays in forcejson.finish() satisfies it, and it remains the validation anchor for StructuredGenerationTask's retry loop. The stale rationale ("avoids requiring a JSON streaming parser in the consumer layer") is replaced with the real reason plus the aliasing note.

Two incidental correctness wins over parsePartialJson, both asserted as tests: a mid-key prefix keeps the object built so far instead of discarding the whole object, and trailing whitespace inside an in-flight string value is preserved instead of being trimmed away. __proto__ is written as an own property via defineProperty, matching JSON.parse and avoiding prototype pollution from untrusted model output.

Deliberately NOT in scope

The *_ToolCalling.ts call sites (anthropic, ollama, llamacpp-server, and the provider-utils shared helper) still use parsePartialJson. Open PR #641 edits those files, so migrating them here would conflict. Follow-up:

  • providers/anthropic/src/ai/common/Anthropic_ToolCalling.ts
  • providers/ollama/src/ai/common/Ollama_ToolCalling.ts
  • providers/llamacpp-server/src/ai/common/LlamaCppServer_ToolCalling.ts
  • packages/ai/src/provider-utils/OpenAIShapedChat.ts

Verification

All run on this branch; every command's real result:

command result
bun run build 84/84 tasks successful
bun run build:types 41/41 tasks successful
bun scripts/test.ts util vitest 47 files passed, 711 passed / 10 skipped
bun scripts/test.ts ai vitest 38 files passed, 247 passed
bun scripts/test.ts provider-api unit vitest 38 files passed, 410 passed
bun scripts/test.ts provider unit vitest 16 passed / 1 skipped, 226 passed / 5 skipped
npx eslint on changed files clean

packages/test/src/test/util/PartialJsonStream.test.ts adds 39 tests:

  1. Chunk-boundary exhaustive — 11 documents (nested objects, arrays, escapes, unicode, numbers, null/true/false, empty containers, pretty-printed whitespace) split at every 1-character boundary, plus fed one character at a time; finish() deep-equals JSON.parse(doc) in every case.
  2. Equivalence with parsePartialJson at every prefix — where it produces a result the stream matches it, and the stream never loses a result it would have produced. Prefixes ending in whitespace are excluded because parsePartialJson trims its input; both intentional divergences are asserted explicitly as their own tests.
  3. Split escapes"a\ + "b", \u00 + 41, \\ at a chunk edge, a surrogate pair, and a \uXXXX document split at every internal boundary.
  4. Split scalars1. + 5e + -3, tr + ue, nul + l, and an exponent terminated by end of stream.
  5. Truncated streamsfinish() closes open containers and drops trailing incomplete tokens, matching the current repair behavior ({"a": tru{}, {"n": 30{n:30}); idempotency asserted.
  6. Preamble skippingHere you go: {"a":1}, a <think>…</think> prefix, a markdown fence, trailing commentary, and recovery when a <think> block itself contains braces.
  7. Perf regression guard — 100 KB in 40-char chunks must finish under 250 ms (measured ~10 ms; the old path takes multiple seconds), so only a genuine algorithmic regression trips it.

packages/test/src/test/ai-provider-api/Ollama_StructuredGenerationStream.test.ts — which specifically asserts the no-closing-brace recovery path — passes unchanged, as does parsePartialJson.test.ts.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PwyJuFrJnibKvrrk8Fa4Fn


Generated by Claude Code

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 64.35% 31731 / 49306
🔵 Statements 64.15% 32830 / 51170
🔵 Functions 65.43% 5975 / 9131
🔵 Branches 53.33% 16345 / 30648
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
providers/huggingface-transformers/src/ai/common/HFT_StructuredGeneration.ts 2.56% 0% 0% 2.63% 24-28, 37-105
Generated in workflow #2891 for commit fb7c7b3 by the Vitest Coverage Report Action

A one-shot partial-JSON repair (`parsePartialJson`) already existed, but it
re-parses and re-scans the whole buffer on every call, so the eleven provider
structured-generation run-fns each kept a growing `accumulatedJson` string and
re-parsed it per delta — O(n^2), on a worker thread.

`createPartialJsonStream()` is a resumable tokenizer: a container stack of live
JS values, a token-bounded scalar buffer, and string-escape / \uXXXX state, so
`push(chunk)` is O(chunk.length) and never re-scans consumed input. Measured on
the built bundle, 98 KB in 40-char chunks goes from 9512 ms to 9.8 ms.

`push()` returns the live root, which is what keeps the cost linear; deep-cloning
per delta would reinstate the quadratic behavior. `StreamEventAccumulator` and
`StreamProcessor` use replace semantics for non-array object-deltas so they still
converge, and events are structured-cloned across the worker hop, but an
in-process consumer retaining an earlier delta will observe it mutate —
`snapshot()` is the escape hatch.

`parsePartialJson` is unchanged and still exported; the `*_ToolCalling.ts` call
sites keep using it.

Claude-Session: https://claude.ai/code/session_01PwyJuFrJnibKvrrk8Fa4Fn
…s verbatim

A bracketed aside in model prose ([1], [2024 figures]) parsed as a valid
array root: a complete one closed the parser and a partial one left a
non-empty root that fail() refuses to discard, so the real JSON payload
behind it was dropped. skipPreamble now only opens a candidate on '{',
matching the parser's object-only contract.

An invalid \uXXXX escape also dropped the hex digits already consumed
(\u00zz came back as \uzz); the raw digits are now replayed.

Claude-Session: https://claude.ai/code/session_01PwyJuFrJnibKvrrk8Fa4Fn
A stray } or ] popped an empty stack and marked the document complete,
discarding the real payload behind it.

Claude-Session: https://claude.ai/code/session_01PwyJuFrJnibKvrrk8Fa4Fn
@sroussey
sroussey force-pushed the claude/libs-issues-triage-prs-mh6x2o-507 branch from 34ad5d9 to fb7c7b3 Compare August 6, 2026 23:58
@sroussey
sroussey merged commit abcddf6 into main Aug 7, 2026
14 checks passed
@sroussey
sroussey deleted the claude/libs-issues-triage-prs-mh6x2o-507 branch August 13, 2026 05:03
sroussey added a commit that referenced this pull request Aug 13, 2026
## @workglow/browser-control

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/task-graph

### Features

- add tests for task usage duration and enhance usage line handling

#### web-example

- show the run's cumulative token total

#### task-graph

- add an opt-in run-usage recorder
- report a cache hit as a stated zero cost
- aggregate token usage per run
- add a task-level usage event
- fold mid-stream usage snapshots without double-counting
- add the mid-stream usage event
- ship InMemoryTaskOutputRepository from ./test

### Bug Fixes

- improve usage tracking
- usage tracking for owned subtasks in Task Graph

#### ai,task-graph

- keep heuristic usage estimates out of accounting

#### task-graph

- count an owned child's late charge once
- scope usage sinks to the run that supplied them
- drop the run_usage columns nothing can populate
- roll usage up by task and by model, not one slice each
- count a nested task's spend once, not once per hop
- break the Task/ConditionalTask module cycle
- detach the run's usage listeners at run end
- reset the usage aggregator per run instead of replacing it
- key usage buckets without string collision
- defer the pipe-function wrapper past the Task cycle

#### task-graph,ai

- route a checkpoint's storage charge into the run total

#### test

- satisfy typecheck:tests across the usage test helpers
- close the gaps the Turbo/projects wiring opened

#### util

- last complete object wins when skipping JSON preamble (#718)

### Refactors

- decompose BaseTabularStorage.ts and Task.ts along functional seams (#682)

#### task-graph

- name run-usage columns like every sibling schema

#### test

- drop the FsFolderTaskOutputRepository shim

### Tests

- run tests through Turbo and per-package vitest projects
- move 174 more unit tests into their owning packages
- discover test files instead of enumerating sections

#### task-graph

- cover the cache-hit usage emit
- cover usage survival on aborted and finish-less streams
- make the StreamUsage type assertion actually enforceable
- relocate the remaining task-graph test infrastructure
- move TestTasks into the package's ./test entry
- extract the streaming task-output repository contract

#### ai

- pin the Usage field contract and assert disjointness

### Chores

- upgrade to catalog for many deps and update the deps themselves

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/javascript

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/ai

### Features

- enhance provisional usage reporting in AI provider streams
- implement CLI duration formatting and enhance task usage tracking

#### ai

- add ModelConfig.effort coarse thinking dial
- add a shared usage and cost formatter
- charge checkpoint cache storage at disposal
- add estimateCost over disjoint usage buckets
- add optional per-model pricing to the model schema
- fold usage snapshots in the accumulator and publish from AiTask
- add a ./test entry and drop _testOnly from the public API

#### providers

- emit cumulative usage snapshots mid-stream

### Bug Fixes

- improve usage tracking
- make the ./test entries survive a real build

#### ai,task-graph

- keep heuristic usage estimates out of accounting

#### task-graph,ai

- route a checkpoint's storage charge into the run total

#### ai

- delete the CheckpointEntry fields nothing reads
- attribute chat spend to the chat model
- charge every checkpoint's storage cost, not just the last link
- count the whole prompt in the usage arrow
- keep checkpoint teardown from stranding registry entries
- require explicit ModelPricing rates and make the type assertion enforceable
- make the OpenAI-shaped usage mappers report disjoint input

#### task-graph

- detach the run's usage listeners at run end

#### test

- close the gaps the Turbo/projects wiring opened

### Tests

- run tests through Turbo and per-package vitest projects
- move 174 more unit tests into their owning packages

#### ai

- verify OpenAI cache counters are portions of input_tokens
- drop the unused binding without gutting the pricing check
- pin the cumulative detail level and the detailed cached counter
- drop the non-falsifiable ModelPricing round-trip

### Chores

- add Lezer dependencies and update Vite configuration

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/knowledge-base

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

### Tests

- run tests through Turbo and per-package vitest projects

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## workglow

### Features

#### ai

- add a ./test entry and drop _testOnly from the public API

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

### Documentation

#### build

- correct the surviving bun-condition count and pin it with a test (#716)

## @workglow/storage

### Features

#### storage

- enhance query operators to support null handling and inequality checks

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

### Refactors

- decompose BaseTabularStorage.ts and Task.ts along functional seams (#682)

### Tests

- run tests through Turbo and per-package vitest projects
- move 174 more unit tests into their owning packages

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/mcp

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

### Tests

- run tests through Turbo and per-package vitest projects
- settle the Bun policy, close a CI gap, and pilot the __tests__ move

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/util

### Features

#### util

- add a ./test entry and drop _testOnly from the public API

### Bug Fixes

- reunite the graph test helper with its dependents
- make the ./test entries survive a real build

#### util

- last complete object wins when skipping JSON preamble (#718)
- resolve repo-root script imports independently of the vitest root
- stop TestingLogger inlining a second ConsoleLogger

#### test

- close the gaps the Turbo/projects wiring opened

### Performance

#### util

- add an incremental partial-JSON stream parser (#681)

### Tests

- run tests through Turbo and per-package vitest projects
- move 174 more unit tests into their owning packages
- settle the Bun policy, close a CI gap, and pilot the __tests__ move
- discover test files instead of enumerating sections

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/test

### Features

- enhance model existence verification in AI provider streams
- enhance provisional usage reporting in AI provider streams
- dd prefill phase emission to HFT streaming

#### models

- update pricing and add new model for DeepSeek

#### anthropic

- honor model.effort for extended/adaptive thinking

#### deepseek

- map model.effort to reasoning_allowance

#### openrouter

- map model.effort into reasoning extras

#### openai

- map model.effort to Responses reasoning

#### hft

- report local token counts as usage, not a phase message

#### gemini

- report checkpoint write tokens and cache lifetime
- add support for reproducible generation with sampling seed

#### providers

- report cache-checkpoint warm-up token cost
- emit cumulative usage snapshots mid-stream

#### storage

- enhance query operators to support null handling and inequality checks

#### task-graph

- ship InMemoryTaskOutputRepository from ./test

#### ai

- add a ./test entry and drop _testOnly from the public API

#### util

- add a ./test entry and drop _testOnly from the public API

### Bug Fixes

- improve usage tracking
- usage tracking for owned subtasks in Task Graph
- reunite the graph test helper with its dependents
- make the ./test entries survive a real build

#### huggingface-inference

- forward provider-stated usage from text run-fns
- encode Hub model ids per path segment

#### anthropic

- keep an in-range top_p under legacy extended thinking
- build a legal request under legacy extended thinking

#### ai,task-graph

- keep heuristic usage estimates out of accounting

#### task-graph

- count an owned child's late charge once
- scope usage sinks to the run that supplied them
- count a nested task's spend once, not once per hop
- break the Task/ConditionalTask module cycle
- key usage buckets without string collision

#### gemini

- remove structured-generation 2048 thinking default
- return cache disposal result through the queued path
- report disjoint input and fold thoughts into output

#### tasks

- handle the SafeFetch body-pipe rejection instead of crashing the process
- keep resolved credentials out of queued job payloads, add credential schemes (#677)

#### task-graph,ai

- route a checkpoint's storage charge into the run total

#### test

- satisfy typecheck:tests across the usage test helpers
- update provider-api usage expectations to the disjoint contract
- guard against getAll() returning undefined in PostgresTabularDateTime test

#### deepseek

- map the stated cache-miss count to disjoint input

#### ai

- make the OpenAI-shaped usage mappers report disjoint input

#### job-queue

- retry promptly when an idle peek finds a ready job

### Refactors

- decompose BaseTabularStorage.ts and Task.ts along functional seams (#682)

#### tests

- streamline model info test function calls (fix type errors)

#### test

- drop the FsFolderTaskOutputRepository shim

#### job-queue

- collapse per-backend queue adapters onto wrapQueueStorage (#684)

### Performance

#### util

- add an incremental partial-JSON stream parser (#681)

### Tests

- fix out of date assertion in test
- run tests through Turbo and per-package vitest projects
- delete the unused Postgres task-output and task-graph repositories
- move 174 more unit tests into their owning packages
- settle the Bun policy, close a CI gap, and pilot the __tests__ move
- discover test files instead of enumerating sections
- add unit tests for OpenAI reasoning and temperature coupling, and Postgres date handling

#### huggingface-inference

- pin the estimate/stated boundary for HFI

#### ai

- verify OpenAI cache counters are portions of input_tokens
- pin the Usage field contract and assert disjointness

#### task-graph

- cover a nested task's spend reaching the run total
- relocate the remaining task-graph test infrastructure
- move TestTasks into the package's ./test entry
- extract the streaming task-output repository contract

#### providers

- drop a plan reference from a test comment
- cover checkpoint warm-up usage wiring

#### storage

- exercise a null criterion against a real index

### Documentation

#### build

- correct the surviving bun-condition count and pin it with a test (#716)

### Chores

- update deps
- add Lezer dependencies and update Vite configuration
- upgrade to catalog for many deps and update the deps themselves
- update deps

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

### Updated Dependencies

- `@aws-sdk/client-sqs`: catalog:
- `@cloudflare/workers-types`: catalog:
- `@types/dom-chromium-ai`: catalog:
- `@types/pg`: catalog:
- `aws-sdk-client-mock`: catalog:
- `fake-indexeddb`: catalog:
- `miniflare`: ^5.20260811.0-alpha
- `vitest`: catalog:

## @workglow/tasks

### Bug Fixes

#### tasks

- handle the SafeFetch body-pipe rejection instead of crashing the process
- keep resolved credentials out of queued job payloads, add credential schemes (#677)

#### test

- close the gaps the Turbo/projects wiring opened

### Chores

- update deps

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

### Updated Dependencies

- `ipaddr.js`: ^2.5.0
- `undici`: ^8.10.0

## @workglow/job-queue

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

#### job-queue

- retry promptly when an idle peek finds a ready job

### Refactors

#### job-queue

- collapse per-backend queue adapters onto wrapQueueStorage (#684)

### Tests

- run tests through Turbo and per-package vitest projects
- move 174 more unit tests into their owning packages

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/indexeddb

### Features

#### storage

- enhance query operators to support null handling and inequality checks

### Bug Fixes

#### indexeddb

- keep a null equality criterion out of IDBKeyRange

#### test

- close the gaps the Turbo/projects wiring opened

### Refactors

#### job-queue

- collapse per-backend queue adapters onto wrapQueueStorage (#684)

### Chores

- upgrade to catalog for many deps and update the deps themselves

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

### Updated Dependencies

- `fake-indexeddb`: catalog:

## @workglow/openai

### Features

- enhance model existence verification in AI provider streams
- enhance provisional usage reporting in AI provider streams

#### openai

- map model.effort to Responses reasoning

#### providers

- report cache-checkpoint warm-up token cost

### Bug Fixes

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

#### util

- last complete object wins when skipping JSON preamble (#718)

### Performance

#### util

- add an incremental partial-JSON stream parser (#681)

### Tests

- add unit tests for OpenAI reasoning and temperature coupling, and Postgres date handling

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/llamacpp-server

### Features

- enhance usage tracking in AI providers

### Bug Fixes

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

## @workglow/electron

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

## @workglow/ollama

### Features

- enhance provisional usage reporting in AI provider streams

### Bug Fixes

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

#### util

- last complete object wins when skipping JSON preamble (#718)

### Performance

#### util

- add an incremental partial-JSON stream parser (#681)

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/node-llama-cpp

### Features

- enhance usage tracking in AI providers

### Bug Fixes

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

#### util

- last complete object wins when skipping JSON preamble (#718)

### Performance

#### util

- add an incremental partial-JSON stream parser (#681)

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/aws

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

### Refactors

#### job-queue

- collapse per-backend queue adapters onto wrapQueueStorage (#684)

### Chores

- upgrade to catalog for many deps and update the deps themselves
- update deps

### Updated Dependencies

- `@aws-sdk/client-sqs`: catalog:
- `aws-sdk-client-mock`: catalog:

## @workglow/anthropic

### Features

- enhance model existence verification in AI provider streams

#### anthropic

- honor model.effort for extended/adaptive thinking

#### providers

- report cache-checkpoint warm-up token cost
- emit cumulative usage snapshots mid-stream

### Bug Fixes

#### anthropic

- keep an in-range top_p under legacy extended thinking
- build a legal request under legacy extended thinking

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

#### util

- last complete object wins when skipping JSON preamble (#718)

### Refactors

#### tests

- streamline model info test function calls (fix type errors)

### Performance

#### util

- add an incremental partial-JSON stream parser (#681)

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/duckdb

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/google-gemini

### Features

- enhance model existence verification in AI provider streams

#### gemini

- map model.effort to thinking_budget
- report checkpoint write tokens and cache lifetime
- add support for reproducible generation with sampling seed

#### ai

- charge checkpoint cache storage at disposal

#### providers

- emit cumulative usage snapshots mid-stream

### Bug Fixes

#### gemini

- remove structured-generation 2048 thinking default
- return cache disposal result through the queued path
- report disjoint input and fold thoughts into output

#### ai

- keep checkpoint teardown from stranding registry entries
- require explicit ModelPricing rates and make the type assertion enforceable

#### util

- last complete object wins when skipping JSON preamble (#718)

### Performance

#### util

- add an incremental partial-JSON stream parser (#681)

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/postgres

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

### Refactors

#### job-queue

- collapse per-backend queue adapters onto wrapQueueStorage (#684)

### Tests

- add unit tests for OpenAI reasoning and temperature coupling, and Postgres date handling

### Chores

- upgrade to catalog for many deps and update the deps themselves
- update deps

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

### Updated Dependencies

- `@types/pg`: catalog:

## @workglow/stable-diffusion-server

### Bug Fixes

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

## @workglow/supabase

### Features

#### storage

- enhance query operators to support null handling and inequality checks

### Bug Fixes

#### supabase

- keep deleteSearch's filter builder off the generic path

#### test

- close the gaps the Turbo/projects wiring opened

### Refactors

#### job-queue

- collapse per-backend queue adapters onto wrapQueueStorage (#684)

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/xai

### Features

- enhance model existence verification in AI provider streams
- enhance provisional usage reporting in AI provider streams

#### models

- update pricing and add new model for DeepSeek

### Bug Fixes

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

#### util

- last complete object wins when skipping JSON preamble (#718)

### Performance

#### util

- add an incremental partial-JSON stream parser (#681)

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/deepseek

### Features

- enhance model existence verification in AI provider streams
- enhance provisional usage reporting in AI provider streams

#### models

- update pricing and add new model for DeepSeek

#### deepseek

- map model.effort to reasoning_allowance

### Bug Fixes

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

#### deepseek

- map the stated cache-miss count to disjoint input

#### util

- last complete object wins when skipping JSON preamble (#718)

### Performance

#### util

- add an incremental partial-JSON stream parser (#681)

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/playwright

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

## @workglow/sqlite

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

### Refactors

#### job-queue

- collapse per-backend queue adapters onto wrapQueueStorage (#684)

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/cloudflare

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

### Refactors

#### job-queue

- collapse per-backend queue adapters onto wrapQueueStorage (#684)

### Chores

- upgrade to catalog for many deps and update the deps themselves
- update deps

### Updated Dependencies

- `@cloudflare/workers-types`: catalog:

## @workglow/huggingface-transformers

### Features

- dd prefill phase emission to HFT streaming

#### hft

- report local token counts as usage, not a phase message

### Bug Fixes

- better error message when HFT has issues importing

#### task-graph

- count a nested task's spend once, not once per hop

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

#### HFT_Device

- remove "webgpu" from device resolution logic

#### util

- last complete object wins when skipping JSON preamble (#718)

### Refactors

- update @huggingface/transformers to peerDependency and add to devDependencies

### Performance

#### util

- add an incremental partial-JSON stream parser (#681)

### Chores

- upgrade to catalog for many deps and update the deps themselves

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/tf-mediapipe

### Bug Fixes

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

#### util

- last complete object wins when skipping JSON preamble (#718)

### Performance

#### util

- add an incremental partial-JSON stream parser (#681)

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/chrome-ai

### Bug Fixes

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

#### util

- last complete object wins when skipping JSON preamble (#718)

### Performance

#### util

- add an incremental partial-JSON stream parser (#681)

### Tests

- discover test files instead of enumerating sections

### Chores

- upgrade to catalog for many deps and update the deps themselves

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

### Updated Dependencies

- `@types/dom-chromium-ai`: catalog:

## @workglow/openrouter

### Features

- enhance model existence verification in AI provider streams

#### openrouter

- map model.effort into reasoning extras

### Bug Fixes

- improve usage tracking

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

#### util

- last complete object wins when skipping JSON preamble (#718)

### Performance

#### util

- add an incremental partial-JSON stream parser (#681)

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/huggingface-inference

### Features

- enhance model existence verification in AI provider streams
- enhance provisional usage reporting in AI provider streams

### Bug Fixes

#### huggingface-inference

- forward provider-stated usage from text run-fns
- encode Hub model ids per path segment

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/cactus

### Bug Fixes

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

### Tests

- discover test files instead of enumerating sections

### Chores

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

## @workglow/bun-webview

### Bug Fixes

#### test

- close the gaps the Turbo/projects wiring opened

## @workglow/eval

### Features

#### models

- update pricing and add new model for DeepSeek

#### eval-example

- record and rank token usage and cost

### Bug Fixes

#### eval

- price the gpt-5.6 family, drop the bogus Anthropic max_tokens

### Tests

- run tests through Turbo and per-package vitest projects

#### eval-example

- cover the token-accounting logic the crux review flagged

### Documentation

#### eval-example

- stop the rate card asserting a provenance it lacks

### Chores

- update CodeMirror dependencies and improve TypeScript configuration
- upgrade to catalog for many deps and update the deps themselves

### Updated Dependencies

- `commander`: catalog:
- `hyparquet`: ^1.28.1

## @workglow/cli

### Features

- add tests for task usage duration and enhance usage line handling
- implement CLI duration formatting and enhance task usage tracking

#### cli-example

- show live input and output token counts

### Bug Fixes

- usage tracking for owned subtasks in Task Graph

#### cli-example

- render token usage on the actual rendered path

#### ai

- require explicit ModelPricing rates and make the type assertion enforceable

### Refactors

#### pricing

- optimize model pricing state management and improve usage line updates

#### cli-example

- hoist the footer's format call and drop a needless cast

### Tests

- run tests through Turbo and per-package vitest projects

#### cli-example

- gate usage emission on a mounted row, not a fixed sleep

### Chores

- update deps
- update CodeMirror dependencies and improve TypeScript configuration
- upgrade to catalog for many deps and update the deps themselves

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

### Updated Dependencies

- `commander`: catalog:
- `react`: catalog:
- `smol-toml`: ^1.8.0
- `@types/react`: catalog:

## @workglow/web

### Features

#### web-example

- show the run's cumulative token total

### Bug Fixes

- improve usage tracking

#### task-graph,ai

- route a checkpoint's storage charge into the run total

#### task-graph

- roll usage up by task and by model, not one slice each

### Chores

- untrack examples/web/tsconfig.norefs.tsbuildinfo
- update deps
- add Lezer dependencies and update Vite configuration
- update CodeMirror dependencies and improve TypeScript configuration
- upgrade to catalog for many deps and update the deps themselves
- update deps

#### eslint

- enforce consistent-type-imports and apply the repo-wide autofix (#683)

### Updated Dependencies

- `@xyflow/react`: ^12.11.3
- `react`: catalog:
- `@types/react`: catalog:
- `vite`: ^8.2.1
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.

add a json streaming parser

1 participant