json-from-llm 0.1.2 → 0.1.3

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/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ All notable changes to this project are documented here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres
5
5
  to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.1.3] - 2026-06-05
8
+
9
+ ### Added
10
+
11
+ - Added a public reasoning-output fixture corpus covering `<think>` /
12
+ `<reasoning>` blocks, fenced JSON, prose wrappers, trailing commas, type
13
+ expectations and no-JSON failures.
14
+ - Added tests that read the published fixture corpus and verify `tryExtractJson`
15
+ results.
16
+ - Published the `fixtures/` directory in the npm package for downstream parser
17
+ and agent-loop tests.
18
+
7
19
  ## [0.1.2] - 2026-06-04
8
20
 
9
21
  ### Changed
package/README.md CHANGED
@@ -9,6 +9,9 @@
9
9
 
10
10
  > Extract valid JSON from an LLM response — even when it's wrapped in reasoning/thinking tags, markdown fences or prose. **Zero dependencies.**
11
11
 
12
+ Security posture is tracked in [docs/security-posture.md](./docs/security-posture.md),
13
+ including CodeQL, OpenSSF Scorecard, Dependabot and branch rules.
14
+
12
15
  You asked for JSON. The model gave you:
13
16
 
14
17
  ````text
@@ -36,6 +39,7 @@ const data = extractJson<{ score: number }>(modelOutput);
36
39
  - **Handles the real wrappers.** Markdown fences (`json` and bare ```), conversational prose before/after, and the JSON sitting bare in the text.
37
40
  - **String-aware, never corrupts.** The scanner and the trailing-comma repair both respect string contents — a `}` or `,` inside `"a string value"` is left alone.
38
41
  - **Conservative repair.** Removes trailing commas (the most common malformation); it will never rewrite your data.
42
+ - **Fixture-backed edge cases.** Public fixtures cover reasoning tags, fenced JSON, prose wrappers, trailing commas, top-level type expectations and no-JSON failures.
39
43
  - **Two entry points.** `extractJson` throws on failure; `tryExtractJson` returns `{ found }`.
40
44
  - **Zero dependencies**, ESM + CJS, fully typed.
41
45
 
@@ -79,6 +83,21 @@ extractJson('[1,2] then the answer {"a":1}', { expect: 'object' }); // { a: 1 }
79
83
 
80
84
  The low-level pieces (`stripReasoning`, `fencedBlocks`, `balancedSpans`, `removeTrailingCommas`) are exported too.
81
85
 
86
+ ## Fixture corpus
87
+
88
+ The package includes a small public corpus under [`fixtures/`](./fixtures):
89
+
90
+ - `deepseek-thinking-object.txt`
91
+ - `gemini-reasoning-array.txt`
92
+ - `prose-trailing-commas.txt`
93
+ - `expect-object-skips-array.txt`
94
+ - `no-json.txt`
95
+ - expected `tryExtractJson` outputs under `fixtures/expected/`
96
+
97
+ The tests read these files directly, so parser changes are checked against
98
+ stable, reusable examples. The fixtures are synthetic and safe for public CI:
99
+ they contain no prompts, secrets, user data or live provider responses.
100
+
82
101
  ## Related
83
102
 
84
103
  - [`tool-schema`](https://www.npmjs.com/package/tool-schema) — turn a JSON Schema into a provider tool/function schema (define the shape you then extract).
@@ -0,0 +1,14 @@
1
+ # Reasoning Output Fixture Corpus
2
+
3
+ This corpus contains deterministic model-output examples that commonly break
4
+ plain `JSON.parse`:
5
+
6
+ - reasoning/thinking tags with brace-laden prose
7
+ - fenced JSON blocks inside conversational text
8
+ - trailing commas in otherwise valid JSON
9
+ - competing arrays/objects when callers expect a specific top-level type
10
+ - negative text with no recoverable JSON
11
+
12
+ Each `.txt` file has a matching expected JSON file under `fixtures/expected/`.
13
+ The fixtures are synthetic and safe for public CI: they contain no prompts,
14
+ secrets, user data or live provider responses.
@@ -0,0 +1,13 @@
1
+ <think>
2
+ The user asked for a risk score. I might draft {score: maybe 6}, but that is
3
+ not JSON and should not be selected.
4
+ </think>
5
+
6
+ Final answer:
7
+ ```json
8
+ {
9
+ "score": 8,
10
+ "reason": "clear evidence",
11
+ "tags": ["portable", "safe"]
12
+ }
13
+ ```
@@ -0,0 +1,7 @@
1
+ First, a quick list: ["draft", "ignore"].
2
+
3
+ The object you asked for:
4
+ {
5
+ "city": "Santiago",
6
+ "units": "metric"
7
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "found": true,
3
+ "expect": "object",
4
+ "value": {
5
+ "score": 8,
6
+ "reason": "clear evidence",
7
+ "tags": ["portable", "safe"]
8
+ }
9
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "found": true,
3
+ "expect": "object",
4
+ "value": {
5
+ "city": "Santiago",
6
+ "units": "metric"
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "found": true,
3
+ "expect": "array",
4
+ "value": [
5
+ { "id": "alpha", "score": 0.91 },
6
+ { "id": "beta", "score": 0.72 }
7
+ ]
8
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "found": false,
3
+ "expect": "any"
4
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "found": true,
3
+ "expect": "object",
4
+ "value": {
5
+ "providers": ["openai", "anthropic", "gemini"],
6
+ "ok": true
7
+ }
8
+ }
@@ -0,0 +1,12 @@
1
+ <reasoning>
2
+ Need to rank the candidates. The scratch list [bad, draft] is only prose.
3
+ </reasoning>
4
+
5
+ Here is the JSON:
6
+
7
+ ```json
8
+ [
9
+ { "id": "alpha", "score": 0.91 },
10
+ { "id": "beta", "score": 0.72 }
11
+ ]
12
+ ```
@@ -0,0 +1 @@
1
+ I cannot produce a structured result from the supplied input.
@@ -0,0 +1,8 @@
1
+ Sure — I normalized the provider names below.
2
+
3
+ {
4
+ "providers": ["openai", "anthropic", "gemini",],
5
+ "ok": true,
6
+ }
7
+
8
+ Let me know if you want CSV too.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-from-llm",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Extract valid JSON from an LLM response, even when it is wrapped in reasoning/thinking tags, markdown fences or prose. Zero dependencies.",
5
5
  "keywords": [
6
6
  "llm",
@@ -42,6 +42,7 @@
42
42
  },
43
43
  "files": [
44
44
  "dist",
45
+ "fixtures",
45
46
  "README.md",
46
47
  "LICENSE",
47
48
  "CHANGELOG.md"