baml-sap-ts 0.1.0
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 +36 -0
- package/LICENSE +21 -0
- package/README.md +355 -0
- package/dist/index.d.ts +180 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +274 -0
- package/dist/index.js.map +1 -0
- package/dist/json-extractor.d.ts +57 -0
- package/dist/json-extractor.d.ts.map +1 -0
- package/dist/json-extractor.js +382 -0
- package/dist/json-extractor.js.map +1 -0
- package/dist/schema-renderer.d.ts +34 -0
- package/dist/schema-renderer.d.ts.map +1 -0
- package/dist/schema-renderer.js +329 -0
- package/dist/schema-renderer.js.map +1 -0
- package/dist/type-coercer.d.ts +59 -0
- package/dist/type-coercer.d.ts.map +1 -0
- package/dist/type-coercer.js +589 -0
- package/dist/type-coercer.js.map +1 -0
- package/package.json +79 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2025-02-14
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release of baml-sap-ts
|
|
12
|
+
- Schema-Aligned Parsing (SAP) algorithm implementation
|
|
13
|
+
- TypeBox integration for schema definition
|
|
14
|
+
- JSON extraction from markdown code blocks
|
|
15
|
+
- Automatic JSON fixing (trailing commas, missing quotes)
|
|
16
|
+
- Chain-of-thought reasoning filtering
|
|
17
|
+
- Type coercion and validation
|
|
18
|
+
- Union type matching
|
|
19
|
+
- Optional field handling with defaults
|
|
20
|
+
- Support for partial/streaming responses
|
|
21
|
+
- Comprehensive test suite (24 tests)
|
|
22
|
+
- Biome linting and formatting
|
|
23
|
+
- Full TypeScript support with type declarations
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
- `parseResponse()` - Main parsing function
|
|
27
|
+
- `createPromptWithSchema()` - Generate prompts with schema instructions
|
|
28
|
+
- `extractJson()` - Low-level JSON extraction
|
|
29
|
+
- `coerceValue()` - Type coercion against schemas
|
|
30
|
+
- `renderSchema()` - Schema to prompt text conversion
|
|
31
|
+
- Support for complex nested schemas
|
|
32
|
+
- Enum and literal type handling
|
|
33
|
+
- Record/map type support
|
|
34
|
+
- Tuple type support
|
|
35
|
+
|
|
36
|
+
[0.1.0]: https://github.com/yourusername/baml-sap-ts/releases/tag/v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 aiamblichus
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# baml-sap-ts
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/baml-sap-ts)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
A TypeScript implementation of BAML's **Schema-Aligned Parsing (SAP)** algorithm using [TypeBox](https://github.com/sinclairzx81/typebox) for schema definition.
|
|
7
|
+
|
|
8
|
+
> **Note:** This is an unofficial community migration of BAML's core SAP algorithm. For the official BAML project, visit [boundaryml.com](https://www.boundaryml.com).
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
This package provides **LLM framework independent** structured output parsing - use it with any LLM client (OpenAI, Anthropic, Ollama, etc.).
|
|
13
|
+
|
|
14
|
+
### What is Schema-Aligned Parsing (SAP)?
|
|
15
|
+
|
|
16
|
+
SAP is BAML's algorithm for reliably extracting structured outputs from LLMs:
|
|
17
|
+
|
|
18
|
+
1. **Prompt Rendering**: Auto-generates schema instructions for the LLM
|
|
19
|
+
2. **Response Parsing**: Handles malformed JSON, markdown extraction, chain-of-thought filtering
|
|
20
|
+
3. **Type Coercion**: Validates and coerces parsed data to the target schema
|
|
21
|
+
|
|
22
|
+
### Key Features
|
|
23
|
+
|
|
24
|
+
- ✅ **Markdown code block extraction** - Extract JSON from ` ```json ` blocks
|
|
25
|
+
- ✅ **JSON fixing** - Auto-fix trailing commas, missing quotes, etc.
|
|
26
|
+
- ✅ **Chain-of-thought filtering** - Remove reasoning text before JSON
|
|
27
|
+
- ✅ **Union type matching** - Automatically select best matching variant
|
|
28
|
+
- ✅ **Optional fields with defaults** - Handle missing fields gracefully
|
|
29
|
+
- ✅ **Type coercion** - Convert strings to numbers, etc.
|
|
30
|
+
- ✅ **Partial/streaming support** - Parse incomplete responses
|
|
31
|
+
- ✅ **Detailed error reporting** - Know exactly what went wrong
|
|
32
|
+
- ✅ **Full TypeScript support** - Type-safe schemas and responses
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install baml-sap-ts @sinclair/typebox
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
````typescript
|
|
43
|
+
import { Type } from "@sinclair/typebox";
|
|
44
|
+
import { createPromptWithSchema, parseResponse } from "baml-sap-ts";
|
|
45
|
+
|
|
46
|
+
// 1. Define your schema
|
|
47
|
+
const UserSchema = Type.Object({
|
|
48
|
+
name: Type.String(),
|
|
49
|
+
age: Type.Number(),
|
|
50
|
+
email: Type.Optional(Type.String()),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// 2. Create a prompt with schema instructions
|
|
54
|
+
const prompt = createPromptWithSchema(
|
|
55
|
+
'Extract user information from: "Alice is 30 years old"',
|
|
56
|
+
UserSchema
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
console.log(prompt);
|
|
60
|
+
// Output:
|
|
61
|
+
// Extract user information from: "Alice is 30 years old"
|
|
62
|
+
//
|
|
63
|
+
// Respond with a JSON object in the following format:
|
|
64
|
+
//
|
|
65
|
+
// ```json
|
|
66
|
+
// {
|
|
67
|
+
// "name": string,
|
|
68
|
+
// "age": number,
|
|
69
|
+
// "email": string (optional)
|
|
70
|
+
// }
|
|
71
|
+
// ```
|
|
72
|
+
|
|
73
|
+
// 3. Send prompt to LLM and parse response
|
|
74
|
+
const response = `Here's the information:
|
|
75
|
+
|
|
76
|
+
\`\`\`json
|
|
77
|
+
{
|
|
78
|
+
"name": "Alice",
|
|
79
|
+
"age": 30
|
|
80
|
+
}
|
|
81
|
+
\`\`\``;
|
|
82
|
+
|
|
83
|
+
const result = parseResponse(response, UserSchema);
|
|
84
|
+
|
|
85
|
+
if (result.success) {
|
|
86
|
+
console.log(result.value); // { name: "Alice", age: 30 }
|
|
87
|
+
} else {
|
|
88
|
+
console.error(result.errors);
|
|
89
|
+
}
|
|
90
|
+
````
|
|
91
|
+
|
|
92
|
+
## API Reference
|
|
93
|
+
|
|
94
|
+
### `createPromptWithSchema(basePrompt, schema, options?)`
|
|
95
|
+
|
|
96
|
+
Appends schema instructions to a base prompt to guide the LLM toward producing correctly structured output.
|
|
97
|
+
|
|
98
|
+
**Parameters:**
|
|
99
|
+
|
|
100
|
+
- `basePrompt: string` - Your prompt text
|
|
101
|
+
- `schema: TSchema` - TypeBox schema
|
|
102
|
+
- `options?: SchemaRenderOptions` - Optional rendering options
|
|
103
|
+
|
|
104
|
+
**Returns:** `string` - Complete prompt with schema instructions
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
### `parseResponse(response, schema, options?)`
|
|
109
|
+
|
|
110
|
+
Parse an LLM response into a typed value. This is the main entry point for the SAP algorithm.
|
|
111
|
+
|
|
112
|
+
**Parameters:**
|
|
113
|
+
|
|
114
|
+
- `response: string` - Raw LLM response text
|
|
115
|
+
- `schema: TSchema` - TypeBox schema to validate against
|
|
116
|
+
- `options?: ParseOptions` - Optional parsing options
|
|
117
|
+
|
|
118
|
+
**Returns:** `ParseResult<T>` - Parsed value with metadata
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
interface ParseResult<T> {
|
|
122
|
+
success: boolean;
|
|
123
|
+
value: T;
|
|
124
|
+
errors: Array<{ path: string; message: string }>;
|
|
125
|
+
isPartial: boolean;
|
|
126
|
+
meta: {
|
|
127
|
+
raw: string;
|
|
128
|
+
fromMarkdown?: boolean;
|
|
129
|
+
chainOfThoughtFiltered?: boolean;
|
|
130
|
+
fixes?: string[];
|
|
131
|
+
coercions?: string[];
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
### `parsePartialResponse(response, schema, options?)`
|
|
139
|
+
|
|
140
|
+
For streaming scenarios - parses partial responses with `allowPartials: true`.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
### `extractJson(text, options?)`
|
|
145
|
+
|
|
146
|
+
Low-level JSON extraction from text. Handles markdown blocks and malformed JSON.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
### `coerceValue(value, schema, options?)`
|
|
151
|
+
|
|
152
|
+
Low-level type coercion and validation against a TypeBox schema.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
### `validateValue(value, schema)`
|
|
157
|
+
|
|
158
|
+
Validates a value against a schema without coercion. Returns validation errors.
|
|
159
|
+
|
|
160
|
+
## Usage Examples
|
|
161
|
+
|
|
162
|
+
### Chain-of-Thought Reasoning
|
|
163
|
+
|
|
164
|
+
Automatically detected and filtered:
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
const response = `Let me think step by step...
|
|
168
|
+
|
|
169
|
+
First, I'll analyze the input. The user mentions they are 25.
|
|
170
|
+
|
|
171
|
+
Therefore the output JSON is:
|
|
172
|
+
\`\`\`json
|
|
173
|
+
{"name": "John", "age": 25}
|
|
174
|
+
\`\`\``;
|
|
175
|
+
|
|
176
|
+
const result = parseResponse(response, schema);
|
|
177
|
+
console.log(result.meta.chainOfThoughtFiltered); // true
|
|
178
|
+
console.log(result.value); // { name: "John", age: 25 }
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Malformed JSON
|
|
182
|
+
|
|
183
|
+
Auto-fixes common issues:
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const response = '{"name": "test", "age": 25,}'; // trailing comma
|
|
187
|
+
const result = parseResponse(response, schema);
|
|
188
|
+
console.log(result.meta.fixes); // ['applied_auto_fixes']
|
|
189
|
+
console.log(result.value); // { name: "test", age: 25 }
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Markdown Code Blocks
|
|
193
|
+
|
|
194
|
+
Extracts JSON from markdown:
|
|
195
|
+
|
|
196
|
+
````typescript
|
|
197
|
+
const response = '```json\n{"key": "value"}\n```';
|
|
198
|
+
const result = parseResponse(response, schema);
|
|
199
|
+
console.log(result.meta.fromMarkdown); // true
|
|
200
|
+
````
|
|
201
|
+
|
|
202
|
+
### Union Types
|
|
203
|
+
|
|
204
|
+
Selects best matching variant:
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
const Schema = Type.Union([
|
|
208
|
+
Type.Object({ type: Type.Literal("user"), name: Type.String() }),
|
|
209
|
+
Type.Object({ type: Type.Literal("bot"), id: Type.Number() }),
|
|
210
|
+
]);
|
|
211
|
+
|
|
212
|
+
const result = parseResponse('{"type": "user", "name": "Alice"}', Schema);
|
|
213
|
+
// Automatically matches the first variant
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Complex Nested Schema
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
const OrderSchema = Type.Object({
|
|
220
|
+
orderId: Type.String(),
|
|
221
|
+
status: Type.Enum({ ORDERED: "ORDERED", SHIPPED: "SHIPPED" }),
|
|
222
|
+
items: Type.Array(
|
|
223
|
+
Type.Object({
|
|
224
|
+
name: Type.String(),
|
|
225
|
+
quantity: Type.Integer({ minimum: 1 }),
|
|
226
|
+
price: Type.Number({ minimum: 0 }),
|
|
227
|
+
})
|
|
228
|
+
),
|
|
229
|
+
total: Type.Number({ minimum: 0 }),
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
const response = await openai.chat.completions.create({
|
|
233
|
+
model: "gpt-4",
|
|
234
|
+
messages: [
|
|
235
|
+
{
|
|
236
|
+
role: "user",
|
|
237
|
+
content: createPromptWithSchema("Extract order info", OrderSchema),
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
const result = parseResponse(response.choices[0].message.content, OrderSchema);
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Options
|
|
246
|
+
|
|
247
|
+
### ParseOptions
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
interface ParseOptions {
|
|
251
|
+
// Extraction options
|
|
252
|
+
allowMarkdownJson?: boolean; // Extract from markdown blocks (default: true)
|
|
253
|
+
allowFixes?: boolean; // Fix malformed JSON (default: true)
|
|
254
|
+
allowAsString?: boolean; // Return string if all fails (default: true)
|
|
255
|
+
findAllJsonObjects?: boolean; // Find multiple JSON objects (default: true)
|
|
256
|
+
maxDepth?: number; // Max parsing depth (default: 100)
|
|
257
|
+
|
|
258
|
+
// Coercion options
|
|
259
|
+
allowPartials?: boolean; // Allow incomplete objects (default: false)
|
|
260
|
+
useDefaults?: boolean; // Use default values (default: true)
|
|
261
|
+
strict?: boolean; // No type coercion (default: false)
|
|
262
|
+
trackCoercions?: boolean; // Track applied coercions (default: false)
|
|
263
|
+
|
|
264
|
+
// Parse options
|
|
265
|
+
filterChainOfThought?: boolean; // Filter reasoning text (default: true)
|
|
266
|
+
returnAllCandidates?: boolean; // Return all candidate parses (default: false)
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Architecture
|
|
271
|
+
|
|
272
|
+
```
|
|
273
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
274
|
+
│ parseResponse │
|
|
275
|
+
├─────────────────────────────────────────────────────────────┤
|
|
276
|
+
│ │
|
|
277
|
+
│ ┌─────────────────────┐ ┌───────────────────────────┐ │
|
|
278
|
+
│ │ 1. Filter CoT Text │───▶│ 2. Extract JSON │ │
|
|
279
|
+
│ │ (if detected) │ │ - Markdown blocks │ │
|
|
280
|
+
│ └─────────────────────┘ │ - Direct JSON │ │
|
|
281
|
+
│ │ - Fix malformed │ │
|
|
282
|
+
│ └───────────────────────────┘ │
|
|
283
|
+
│ │ │
|
|
284
|
+
│ ▼ │
|
|
285
|
+
│ ┌───────────────────────────┐ │
|
|
286
|
+
│ │ 3. Type Coercion │ │
|
|
287
|
+
│ │ - Union matching │ │
|
|
288
|
+
│ │ - Field validation │ │
|
|
289
|
+
│ │ - Default values │ │
|
|
290
|
+
│ └───────────────────────────┘ │
|
|
291
|
+
│ │ │
|
|
292
|
+
│ ▼ │
|
|
293
|
+
│ ┌───────────────────────────┐ │
|
|
294
|
+
│ │ 4. Return ParseResult │ │
|
|
295
|
+
│ │ with metadata │ │
|
|
296
|
+
│ └───────────────────────────┘ │
|
|
297
|
+
│ │
|
|
298
|
+
└─────────────────────────────────────────────────────────────┘
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Comparison with Original BAML
|
|
302
|
+
|
|
303
|
+
| Feature | Original BAML (Rust) | This Migration (TS) |
|
|
304
|
+
| ----------------- | -------------------- | ------------------- |
|
|
305
|
+
| Schema Definition | BAML DSL | TypeBox |
|
|
306
|
+
| Prompt Rendering | `ctx.output_format` | `renderSchema()` |
|
|
307
|
+
| JSON Extraction | jsonish parser | `extractJson()` |
|
|
308
|
+
| Type Coercion | Coercer IR | `coerceValue()` |
|
|
309
|
+
| Streaming | Native | Supported |
|
|
310
|
+
| Partial Results | Native | Supported |
|
|
311
|
+
| Error Reporting | Detailed | Detailed |
|
|
312
|
+
| Performance | Native Rust | JavaScript |
|
|
313
|
+
|
|
314
|
+
## Development
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# Clone the repository
|
|
318
|
+
git clone https://github.com/aiamblichus/baml-sap-ts.git
|
|
319
|
+
cd baml-sap-ts
|
|
320
|
+
|
|
321
|
+
# Install dependencies
|
|
322
|
+
npm install
|
|
323
|
+
|
|
324
|
+
# Build
|
|
325
|
+
npm run build
|
|
326
|
+
|
|
327
|
+
# Run tests
|
|
328
|
+
npm test
|
|
329
|
+
|
|
330
|
+
# Run example
|
|
331
|
+
npm run example
|
|
332
|
+
|
|
333
|
+
# Lint and format
|
|
334
|
+
npm run check
|
|
335
|
+
npm run check:fix
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## Contributing
|
|
339
|
+
|
|
340
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
341
|
+
|
|
342
|
+
1. Fork the repository
|
|
343
|
+
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
|
344
|
+
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
|
345
|
+
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
|
346
|
+
5. Open a Pull Request
|
|
347
|
+
|
|
348
|
+
## License
|
|
349
|
+
|
|
350
|
+
MIT © [Your Name](https://github.com/yourusername)
|
|
351
|
+
|
|
352
|
+
## Acknowledgments
|
|
353
|
+
|
|
354
|
+
- Original BAML project by [BoundaryML](https://www.boundaryml.com)
|
|
355
|
+
- [TypeBox](https://github.com/sinclairzx81/typebox) for the excellent schema validation library
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BAML SAP TypeScript Migration
|
|
3
|
+
*
|
|
4
|
+
* Schema-Aligned Parsing (SAP) for TypeScript using TypeBox
|
|
5
|
+
*
|
|
6
|
+
* This is a TypeScript port of BAML's core algorithm for structured
|
|
7
|
+
* data extraction from LLM responses.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { Type } from '@sinclair/typebox';
|
|
12
|
+
* import { createPromptWithSchema, parseResponse } from 'baml-sap-ts';
|
|
13
|
+
*
|
|
14
|
+
* const schema = Type.Object({
|
|
15
|
+
* name: Type.String(),
|
|
16
|
+
* age: Type.Number(),
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Create a prompt with schema instructions
|
|
20
|
+
* const prompt = createPromptWithSchema(
|
|
21
|
+
* 'Extract user information from: John is 25 years old',
|
|
22
|
+
* schema
|
|
23
|
+
* );
|
|
24
|
+
*
|
|
25
|
+
* // After getting LLM response, parse it
|
|
26
|
+
* const response = `{ "name": "John", "age": 25 }`;
|
|
27
|
+
* const result = parseResponse(response, schema);
|
|
28
|
+
*
|
|
29
|
+
* if (result.success) {
|
|
30
|
+
* console.log(result.value); // { name: "John", age: 25 }
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
import type { Static, TSchema } from "@sinclair/typebox";
|
|
35
|
+
import { type ExtractionOptions, extractJson, filterChainOfThought, hasChainOfThought } from "./json-extractor.js";
|
|
36
|
+
import { createJsonSchemaPrompt, renderSchema, type SchemaRenderOptions } from "./schema-renderer.js";
|
|
37
|
+
import { type CoercionOptions, type CoercionResult, coerceValue, validateValue } from "./type-coercer.js";
|
|
38
|
+
export { extractAllCandidates, extractJson, filterChainOfThought, hasChainOfThought, } from "./json-extractor.js";
|
|
39
|
+
export { createJsonSchemaPrompt, renderSchema } from "./schema-renderer.js";
|
|
40
|
+
export { type CoercionError, type CoercionOptions, type CoercionResult, coerceValue, validateValue, } from "./type-coercer.js";
|
|
41
|
+
export type { SchemaRenderOptions, ExtractionOptions };
|
|
42
|
+
/**
|
|
43
|
+
* Main options for parseResponse
|
|
44
|
+
*/
|
|
45
|
+
export interface ParseOptions extends ExtractionOptions, CoercionOptions {
|
|
46
|
+
/** Filter out chain-of-thought reasoning before parsing */
|
|
47
|
+
filterChainOfThought?: boolean;
|
|
48
|
+
/** Return all candidate parses (useful for debugging) */
|
|
49
|
+
returnAllCandidates?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Result from parsing an LLM response
|
|
53
|
+
*/
|
|
54
|
+
export interface ParseResult<T = unknown> {
|
|
55
|
+
/** Whether parsing was successful */
|
|
56
|
+
success: boolean;
|
|
57
|
+
/** The parsed and validated value */
|
|
58
|
+
value: T;
|
|
59
|
+
/** Errors encountered during parsing */
|
|
60
|
+
errors: Array<{
|
|
61
|
+
path: string;
|
|
62
|
+
message: string;
|
|
63
|
+
}>;
|
|
64
|
+
/** Whether the result is partial (for streaming) */
|
|
65
|
+
isPartial: boolean;
|
|
66
|
+
/** Metadata about the parsing process */
|
|
67
|
+
meta: {
|
|
68
|
+
/** Raw text that was parsed */
|
|
69
|
+
raw: string;
|
|
70
|
+
/** Whether text was extracted from markdown */
|
|
71
|
+
fromMarkdown?: boolean;
|
|
72
|
+
/** Whether chain-of-thought was detected and filtered */
|
|
73
|
+
chainOfThoughtFiltered?: boolean;
|
|
74
|
+
/** Fixes applied during JSON extraction */
|
|
75
|
+
fixes?: string[];
|
|
76
|
+
/** Coercions applied during type validation */
|
|
77
|
+
coercions?: string[];
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parse an LLM response into a typed value
|
|
82
|
+
*
|
|
83
|
+
* This is the main entry point for the SAP algorithm.
|
|
84
|
+
* It handles:
|
|
85
|
+
* 1. Chain-of-thought filtering
|
|
86
|
+
* 2. JSON extraction from markdown/text
|
|
87
|
+
* 3. Type coercion and validation
|
|
88
|
+
*
|
|
89
|
+
* @param response - The raw LLM response text
|
|
90
|
+
* @param schema - TypeBox schema to validate against
|
|
91
|
+
* @param options - Parsing options
|
|
92
|
+
* @returns ParseResult with the typed value or errors
|
|
93
|
+
*/
|
|
94
|
+
export declare function parseResponse<T extends TSchema>(response: string, schema: T, options?: ParseOptions): ParseResult<Static<T>>;
|
|
95
|
+
/**
|
|
96
|
+
* Stream parser for handling partial LLM responses
|
|
97
|
+
*
|
|
98
|
+
* This is useful for streaming scenarios where you want to
|
|
99
|
+
* show partial results as they arrive.
|
|
100
|
+
*
|
|
101
|
+
* @param partialResponse - The partial response text so far
|
|
102
|
+
* @param schema - TypeBox schema to validate against
|
|
103
|
+
* @param options - Parsing options
|
|
104
|
+
* @returns ParseResult with the best-effort typed value
|
|
105
|
+
*/
|
|
106
|
+
export declare function parsePartialResponse<T extends TSchema>(partialResponse: string, schema: T, options?: ParseOptions): ParseResult<Static<T>>;
|
|
107
|
+
/**
|
|
108
|
+
* Create a prompt with schema instructions
|
|
109
|
+
*
|
|
110
|
+
* Appends schema instructions to a base prompt to guide
|
|
111
|
+
* the LLM toward producing correctly structured output.
|
|
112
|
+
*
|
|
113
|
+
* @param basePrompt - The base prompt text
|
|
114
|
+
* @param schema - TypeBox schema describing expected output
|
|
115
|
+
* @param options - Schema rendering options
|
|
116
|
+
* @returns Complete prompt with schema instructions
|
|
117
|
+
*/
|
|
118
|
+
export declare function createPromptWithSchema(basePrompt: string, schema: TSchema, options?: SchemaRenderOptions): string;
|
|
119
|
+
/**
|
|
120
|
+
* Parse multiple candidates from a response
|
|
121
|
+
*
|
|
122
|
+
* Useful when the LLM might have provided multiple JSON objects
|
|
123
|
+
* and you want to try them all.
|
|
124
|
+
*
|
|
125
|
+
* @param response - The raw LLM response text
|
|
126
|
+
* @param schema - TypeBox schema to validate against
|
|
127
|
+
* @param options - Parsing options
|
|
128
|
+
* @returns Array of ParseResults for each candidate
|
|
129
|
+
*/
|
|
130
|
+
export declare function parseAllCandidates<T extends TSchema>(response: string, schema: T, options?: ParseOptions): ParseResult<Static<T>>[];
|
|
131
|
+
/**
|
|
132
|
+
* Get the best candidate from multiple options
|
|
133
|
+
*
|
|
134
|
+
* Returns the candidate with the fewest errors.
|
|
135
|
+
*
|
|
136
|
+
* @param response - The raw LLM response text
|
|
137
|
+
* @param schema - TypeBox schema to validate against
|
|
138
|
+
* @param options - Parsing options
|
|
139
|
+
* @returns The best ParseResult or null if none valid
|
|
140
|
+
*/
|
|
141
|
+
export declare function parseBestCandidate<T extends TSchema>(response: string, schema: T, options?: ParseOptions): ParseResult<Static<T>> | null;
|
|
142
|
+
/**
|
|
143
|
+
* Check if a response is valid against a schema without full parsing
|
|
144
|
+
*
|
|
145
|
+
* @param response - The raw LLM response text
|
|
146
|
+
* @param schema - TypeBox schema to validate against
|
|
147
|
+
* @returns Whether the response is valid
|
|
148
|
+
*/
|
|
149
|
+
export declare function isValidResponse(response: string, schema: TSchema): boolean;
|
|
150
|
+
/**
|
|
151
|
+
* Debug helper to see what the parser is doing
|
|
152
|
+
*
|
|
153
|
+
* @param response - The raw LLM response text
|
|
154
|
+
* @param schema - TypeBox schema to validate against
|
|
155
|
+
* @returns Debug information
|
|
156
|
+
*/
|
|
157
|
+
export declare function debugParse(response: string, schema: TSchema): {
|
|
158
|
+
filteredText: string;
|
|
159
|
+
extractedValue: unknown;
|
|
160
|
+
extractionErrors: string[];
|
|
161
|
+
coercionResult: CoercionResult<unknown>;
|
|
162
|
+
};
|
|
163
|
+
declare const _default: {
|
|
164
|
+
parseResponse: typeof parseResponse;
|
|
165
|
+
parsePartialResponse: typeof parsePartialResponse;
|
|
166
|
+
createPromptWithSchema: typeof createPromptWithSchema;
|
|
167
|
+
parseAllCandidates: typeof parseAllCandidates;
|
|
168
|
+
parseBestCandidate: typeof parseBestCandidate;
|
|
169
|
+
isValidResponse: typeof isValidResponse;
|
|
170
|
+
debugParse: typeof debugParse;
|
|
171
|
+
renderSchema: typeof renderSchema;
|
|
172
|
+
createJsonSchemaPrompt: typeof createJsonSchemaPrompt;
|
|
173
|
+
extractJson: typeof extractJson;
|
|
174
|
+
filterChainOfThought: typeof filterChainOfThought;
|
|
175
|
+
hasChainOfThought: typeof hasChainOfThought;
|
|
176
|
+
coerceValue: typeof coerceValue;
|
|
177
|
+
validateValue: typeof validateValue;
|
|
178
|
+
};
|
|
179
|
+
export default _default;
|
|
180
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EACN,KAAK,iBAAiB,EAEtB,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,sBAAsB,EAEtB,YAAY,EACZ,KAAK,mBAAmB,EACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAE1G,OAAO,EACN,oBAAoB,EACpB,WAAW,EACX,oBAAoB,EACpB,iBAAiB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,WAAW,EACX,aAAa,GACb,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,YAAa,SAAQ,iBAAiB,EAAE,eAAe;IACvE,2DAA2D;IAC3D,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,yDAAyD;IACzD,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAmBD;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACvC,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,KAAK,EAAE,CAAC,CAAC;IACT,wCAAwC;IACxC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,oDAAoD;IACpD,SAAS,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,IAAI,EAAE;QACL,+BAA+B;QAC/B,GAAG,EAAE,MAAM,CAAC;QACZ,+CAA+C;QAC/C,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,yDAAyD;QACzD,sBAAsB,CAAC,EAAE,OAAO,CAAC;QACjC,2CAA2C;QAC3C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,+CAA+C;QAC/C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,OAAO,EAC9C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,CAAC,EACT,OAAO,GAAE,YAAiB,GACxB,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAkDxB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,OAAO,EACrD,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,CAAC,EACT,OAAO,GAAE,YAAiB,GACxB,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CASxB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAEjH;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,OAAO,EACnD,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,CAAC,EACT,OAAO,GAAE,YAAiB,GACxB,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAgB1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,OAAO,EACnD,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,CAAC,EACT,OAAO,GAAE,YAAiB,GACxB,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAW/B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAO1E;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,GACb;IACF,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,cAAc,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;CACxC,CAqBA;;;;;;;;;;;;;;;;;AAGD,wBAeE"}
|