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 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
+ [![npm version](https://badge.fury.io/js/baml-sap-ts.svg)](https://www.npmjs.com/package/baml-sap-ts)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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
@@ -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":"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"}