@aviasole/shapecraft 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/LICENSE ADDED
@@ -0,0 +1,17 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Copyright 2024 Aviasole Technologies
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # @aviasole/shapecraft
2
+
3
+ Structured output generation for LLMs in Node.js. Token-level constraints for local models, native JSON modes for cloud APIs — one unified Zod API.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @aviasole/shapecraft zod
9
+ ```
10
+
11
+ Install backend SDK as needed:
12
+
13
+ ```bash
14
+ npm install openai # OpenAI
15
+ npm install groq-sdk # Groq
16
+ npm install @anthropic-ai/sdk # Anthropic
17
+ # Ollama: no extra SDK, uses fetch
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ```typescript
23
+ import { z } from "zod";
24
+ import { generate, openai, ollama, anthropic, groq } from "@aviasole/shapecraft";
25
+
26
+ const PersonSchema = z.object({
27
+ name: z.string(),
28
+ age: z.number(),
29
+ email: z.string().email(),
30
+ });
31
+
32
+ // OpenAI — native constrained (server-side)
33
+ const model = openai({ model: "gpt-4o-mini" });
34
+
35
+ const result = await generate(model, PersonSchema, "Extract person info: John Doe, 32, john@example.com");
36
+
37
+ console.log(result.data); // { name: "John Doe", age: 32, email: "john@example.com" }
38
+ console.log(result.guaranteeLevel); // "native"
39
+ console.log(result.attempts); // 1
40
+ ```
41
+
42
+ ## Backends & Guarantee Levels
43
+
44
+ | Backend | Guarantee | Notes |
45
+ |---|---|---|
46
+ | `ollama()` | `constrained` | Token-level via GBNF grammar |
47
+ | `openai()` | `native` | Server-side strict JSON schema |
48
+ | `groq()` | `native` | JSON mode |
49
+ | `anthropic()` | `best-effort` | Prompt + parse + retry |
50
+
51
+ ```typescript
52
+ // Ollama — true token-level constraint (local model)
53
+ const local = ollama({ model: "llama3.2" });
54
+
55
+ // Anthropic — best-effort with auto-retry
56
+ const claude = anthropic({ model: "claude-sonnet-4-6", maxRetries: 3 });
57
+
58
+ // Groq — fast native JSON mode
59
+ const fast = groq({ model: "llama-3.3-70b-versatile" });
60
+ ```
61
+
62
+ ## Error Handling
63
+
64
+ ```typescript
65
+ import { SchemaViolationError, MaxRetriesExceededError } from "@aviasole/shapecraft";
66
+
67
+ try {
68
+ const result = await generate(model, schema, prompt, { maxRetries: 3 });
69
+ } catch (err) {
70
+ if (err instanceof MaxRetriesExceededError) {
71
+ console.error(`Failed after ${err.attempts} attempts`);
72
+ }
73
+ if (err instanceof SchemaViolationError) {
74
+ console.error("Raw output:", err.raw);
75
+ }
76
+ }
77
+ ```
78
+
79
+ ## License
80
+
81
+ Apache-2.0 © Aviasole Technologies
@@ -0,0 +1,7 @@
1
+ import type { ShapecraftModel } from "../types.js";
2
+ export interface AnthropicBackendOptions {
3
+ model?: string;
4
+ apiKey?: string;
5
+ }
6
+ export declare function anthropic(options?: AnthropicBackendOptions): ShapecraftModel;
7
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/backends/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,eAAe,EAAE,MAAM,aAAa,CAAC;AAIhE,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,SAAS,CAAC,OAAO,GAAE,uBAA4B,GAAG,eAAe,CAiChF"}
@@ -0,0 +1,7 @@
1
+ import type { ShapecraftModel } from "../types.js";
2
+ export interface GroqBackendOptions {
3
+ model?: string;
4
+ apiKey?: string;
5
+ }
6
+ export declare function groq(options?: GroqBackendOptions): ShapecraftModel;
7
+ //# sourceMappingURL=groq.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groq.d.ts","sourceRoot":"","sources":["../../src/backends/groq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,eAAe,EAAE,MAAM,aAAa,CAAC;AAIhE,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,IAAI,CAAC,OAAO,GAAE,kBAAuB,GAAG,eAAe,CAkCtE"}
@@ -0,0 +1,5 @@
1
+ export { openai } from "./openai.js";
2
+ export { ollama } from "./ollama.js";
3
+ export { anthropic } from "./anthropic.js";
4
+ export { groq } from "./groq.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backends/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ShapecraftModel } from "../types.js";
2
+ export interface OllamaBackendOptions {
3
+ model: string;
4
+ host?: string;
5
+ }
6
+ export declare function ollama(options: OllamaBackendOptions): ShapecraftModel;
7
+ //# sourceMappingURL=ollama.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../src/backends/ollama.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,eAAe,EAAE,MAAM,aAAa,CAAC;AAKhE,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,oBAAoB,GAAG,eAAe,CA0CrE"}
@@ -0,0 +1,8 @@
1
+ import type { ShapecraftModel } from "../types.js";
2
+ export interface OpenAIBackendOptions {
3
+ model?: string;
4
+ apiKey?: string;
5
+ baseURL?: string;
6
+ }
7
+ export declare function openai(options?: OpenAIBackendOptions): ShapecraftModel;
8
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/backends/openai.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,eAAe,EAAE,MAAM,aAAa,CAAC;AAKhE,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,MAAM,CAAC,OAAO,GAAE,oBAAyB,GAAG,eAAe,CAgD1E"}
@@ -0,0 +1,3 @@
1
+ import type { GenerateOptions, GenerateResult, SchemaInput, ShapecraftModel } from "../types.js";
2
+ export declare function generate<T>(model: ShapecraftModel, schema: SchemaInput<T>, prompt: string, options?: GenerateOptions): Promise<GenerateResult<T>>;
3
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/core/generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAIjG,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EACtB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAoB5B"}
@@ -0,0 +1,5 @@
1
+ import type { SchemaInput } from "../types.js";
2
+ export declare function parseAndValidate<T>(raw: string, schema: SchemaInput<T>, opts?: {
3
+ extractJson?: boolean;
4
+ }): T;
5
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/core/parse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EACtB,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACnC,CAAC,CAsBH"}
@@ -0,0 +1,8 @@
1
+ import { z } from "zod";
2
+ import type { SchemaInput } from "../types.js";
3
+ export declare function toJsonSchema(schema: z.ZodType<any>): Record<string, unknown>;
4
+ export declare function buildStructuredPrompt(prompt: string, schema: SchemaInput, systemPrompt?: string): {
5
+ system: string;
6
+ user: string;
7
+ };
8
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,wBAAgB,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAG5E;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,EACnB,YAAY,CAAC,EAAE,MAAM,GACpB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAkBlC"}
@@ -0,0 +1,5 @@
1
+ import { z } from "zod";
2
+ import type { SchemaInput } from "../types.js";
3
+ export declare function isZodSchema(schema: SchemaInput): schema is z.ZodType<any>;
4
+ export declare function validateOutput<T>(output: unknown, schema: SchemaInput<T>): T;
5
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/core/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAEzE;AAkDD,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAgC5E"}
package/dist/index.cjs ADDED
@@ -0,0 +1,297 @@
1
+ 'use strict';
2
+
3
+ var zod = require('zod');
4
+ var zodToJsonSchema = require('zod-to-json-schema');
5
+
6
+ // src/types.ts
7
+ var SchemaViolationError = class extends Error {
8
+ constructor(raw, validationErrors) {
9
+ super("Model output failed schema validation");
10
+ this.raw = raw;
11
+ this.validationErrors = validationErrors;
12
+ this.name = "SchemaViolationError";
13
+ }
14
+ };
15
+ var MaxRetriesExceededError = class extends Error {
16
+ constructor(attempts) {
17
+ super(`Schema validation failed after ${attempts} attempts`);
18
+ this.attempts = attempts;
19
+ this.name = "MaxRetriesExceededError";
20
+ }
21
+ };
22
+ function isZodSchema(schema) {
23
+ return schema instanceof zod.z.ZodType;
24
+ }
25
+ function nullToUndefined(value) {
26
+ if (value === null) return void 0;
27
+ if (Array.isArray(value)) return value.map(nullToUndefined);
28
+ if (typeof value === "object" && value !== null) {
29
+ return Object.fromEntries(
30
+ Object.entries(value).map(([k, v]) => [k, nullToUndefined(v)])
31
+ );
32
+ }
33
+ return value;
34
+ }
35
+ function checkJsonSchema(value, schema) {
36
+ const type = schema.type;
37
+ if (type) {
38
+ const actual = Array.isArray(value) ? "array" : value === null ? "null" : typeof value;
39
+ if (actual !== type) {
40
+ throw new Error(`Expected type "${type}", got "${actual}"`);
41
+ }
42
+ }
43
+ if (schema.enum) {
44
+ if (!schema.enum.includes(value)) {
45
+ throw new Error(`Value not in enum: ${JSON.stringify(value)}`);
46
+ }
47
+ }
48
+ if (typeof value === "object" && value !== null && !Array.isArray(value) && schema.properties) {
49
+ const obj = value;
50
+ const required = schema.required ?? [];
51
+ const properties = schema.properties;
52
+ for (const key of required) {
53
+ if (!(key in obj)) throw new Error(`Missing required property: "${key}"`);
54
+ }
55
+ for (const [key, propSchema] of Object.entries(properties)) {
56
+ if (key in obj) checkJsonSchema(obj[key], propSchema);
57
+ }
58
+ }
59
+ if (Array.isArray(value) && schema.items) {
60
+ for (const item of value) {
61
+ checkJsonSchema(item, schema.items);
62
+ }
63
+ }
64
+ }
65
+ function validateOutput(output, schema) {
66
+ if (isZodSchema(schema)) {
67
+ const result = schema.safeParse(nullToUndefined(output));
68
+ if (!result.success) throw new SchemaViolationError(JSON.stringify(output), result.error);
69
+ return result.data;
70
+ }
71
+ if ("jsonSchema" in schema) {
72
+ try {
73
+ checkJsonSchema(output, schema.jsonSchema);
74
+ } catch (err) {
75
+ throw new SchemaViolationError(JSON.stringify(output), err);
76
+ }
77
+ return output;
78
+ }
79
+ if ("pattern" in schema) {
80
+ const str = typeof output === "string" ? output : JSON.stringify(output);
81
+ if (!schema.pattern.test(str)) {
82
+ throw new SchemaViolationError(str, `Output does not match pattern ${schema.pattern}`);
83
+ }
84
+ return output;
85
+ }
86
+ if ("validate" in schema) {
87
+ if (!schema.validate(output)) {
88
+ throw new SchemaViolationError(JSON.stringify(output), "Custom validator returned false");
89
+ }
90
+ return output;
91
+ }
92
+ throw new Error("Unknown schema type");
93
+ }
94
+
95
+ // src/core/generate.ts
96
+ async function generate(model, schema, prompt, options = {}) {
97
+ const maxRetries = options.maxRetries ?? 3;
98
+ const { systemPrompt } = options;
99
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
100
+ try {
101
+ const raw = await model.generate(prompt, schema, systemPrompt);
102
+ const data = validateOutput(raw, schema);
103
+ return {
104
+ data,
105
+ guaranteeLevel: model.guaranteeLevel,
106
+ attempts: attempt
107
+ };
108
+ } catch (err) {
109
+ if (!(err instanceof SchemaViolationError)) throw err;
110
+ if (attempt === maxRetries) break;
111
+ }
112
+ }
113
+ throw new MaxRetriesExceededError(maxRetries);
114
+ }
115
+ function toJsonSchema(schema) {
116
+ return zodToJsonSchema.zodToJsonSchema(schema, { target: "openApi3" });
117
+ }
118
+ function buildStructuredPrompt(prompt, schema, systemPrompt) {
119
+ let schemaInfo;
120
+ if (schema instanceof zod.z.ZodType) {
121
+ schemaInfo = `Respond with valid JSON matching this schema exactly:
122
+
123
+ ${JSON.stringify(toJsonSchema(schema), null, 2)}`;
124
+ } else if ("jsonSchema" in schema) {
125
+ schemaInfo = `Respond with valid JSON matching this schema exactly:
126
+
127
+ ${JSON.stringify(schema.jsonSchema, null, 2)}`;
128
+ } else if ("pattern" in schema) {
129
+ schemaInfo = `Respond with a plain string matching this pattern: ${schema.pattern}`;
130
+ } else {
131
+ schemaInfo = "Respond with valid output as required.";
132
+ }
133
+ const system = systemPrompt ? `${systemPrompt}
134
+
135
+ ${schemaInfo} No extra text, no markdown, no explanation.` : `You are a precise assistant. ${schemaInfo} No extra text, no markdown, no explanation.`;
136
+ return { system, user: prompt };
137
+ }
138
+
139
+ // src/core/parse.ts
140
+ function parseAndValidate(raw, schema, opts = {}) {
141
+ if ("pattern" in schema) return raw;
142
+ try {
143
+ const text = opts.extractJson ? raw.match(/\{[\s\S]*\}|\[[\s\S]*\]/)?.[0] ?? raw : raw;
144
+ const parsed = JSON.parse(text);
145
+ if (isZodSchema(schema)) {
146
+ const result = schema.safeParse(parsed);
147
+ if (!result.success) throw new SchemaViolationError(raw, result.error);
148
+ return result.data;
149
+ }
150
+ return parsed;
151
+ } catch (err) {
152
+ if (err instanceof SchemaViolationError) throw err;
153
+ throw new SchemaViolationError(raw, err);
154
+ }
155
+ }
156
+
157
+ // src/backends/openai.ts
158
+ function openai(options = {}) {
159
+ const modelId = options.model ?? "gpt-4o-mini";
160
+ return {
161
+ id: `openai:${modelId}`,
162
+ guaranteeLevel: "native",
163
+ async generate(prompt, schema, systemPrompt) {
164
+ const mod = await import('openai').catch(() => {
165
+ throw new Error("Install openai: npm install openai");
166
+ });
167
+ const OpenAI = mod.default ?? mod;
168
+ const client = new OpenAI({
169
+ apiKey: options.apiKey ?? process.env.OPENAI_API_KEY,
170
+ baseURL: options.baseURL
171
+ });
172
+ const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);
173
+ const responseFormat = isZodSchema(schema) ? {
174
+ type: "json_schema",
175
+ json_schema: { name: "output", strict: true, schema: toJsonSchema(schema) }
176
+ } : "jsonSchema" in schema ? {
177
+ type: "json_schema",
178
+ json_schema: { name: "output", strict: false, schema: schema.jsonSchema }
179
+ } : { type: "json_object" };
180
+ const response = await client.chat.completions.create({
181
+ model: modelId,
182
+ messages: [
183
+ { role: "system", content: system },
184
+ { role: "user", content: user }
185
+ ],
186
+ response_format: responseFormat
187
+ });
188
+ const raw = response.choices[0]?.message?.content ?? "";
189
+ return parseAndValidate(raw, schema);
190
+ }
191
+ };
192
+ }
193
+
194
+ // src/backends/ollama.ts
195
+ function ollama(options) {
196
+ const host = options.host ?? "http://localhost:11434";
197
+ return {
198
+ id: `ollama:${options.model}`,
199
+ guaranteeLevel: "constrained",
200
+ async generate(prompt, schema, systemPrompt) {
201
+ const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);
202
+ let format = void 0;
203
+ if (isZodSchema(schema)) {
204
+ format = toJsonSchema(schema);
205
+ } else if ("jsonSchema" in schema) {
206
+ format = schema.jsonSchema;
207
+ }
208
+ const response = await fetch(`${host}/api/chat`, {
209
+ method: "POST",
210
+ headers: { "Content-Type": "application/json" },
211
+ body: JSON.stringify({
212
+ model: options.model,
213
+ messages: [
214
+ { role: "system", content: system },
215
+ { role: "user", content: user }
216
+ ],
217
+ ...format ? { format } : {},
218
+ stream: false
219
+ })
220
+ });
221
+ if (!response.ok) {
222
+ throw new Error(`Ollama error: ${response.status} ${response.statusText}`);
223
+ }
224
+ const json = await response.json();
225
+ const raw = json.message?.content ?? "";
226
+ return parseAndValidate(raw, schema);
227
+ }
228
+ };
229
+ }
230
+
231
+ // src/backends/anthropic.ts
232
+ function anthropic(options = {}) {
233
+ const modelId = options.model ?? "claude-sonnet-4-6";
234
+ return {
235
+ id: `anthropic:${modelId}`,
236
+ guaranteeLevel: "best-effort",
237
+ async generate(prompt, schema, systemPrompt) {
238
+ const mod = await import('@anthropic-ai/sdk').catch(() => {
239
+ throw new Error("Install sdk: npm install @anthropic-ai/sdk");
240
+ });
241
+ const AnthropicClass = mod.default ?? mod;
242
+ const client = new AnthropicClass({
243
+ apiKey: options.apiKey ?? process.env.ANTHROPIC_API_KEY
244
+ });
245
+ const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);
246
+ const response = await client.messages.create({
247
+ model: modelId,
248
+ max_tokens: 4096,
249
+ system,
250
+ messages: [{ role: "user", content: user }]
251
+ });
252
+ const raw = response.content[0]?.type === "text" ? response.content[0].text : "";
253
+ return parseAndValidate(raw, schema, { extractJson: true });
254
+ }
255
+ };
256
+ }
257
+
258
+ // src/backends/groq.ts
259
+ function groq(options = {}) {
260
+ const modelId = options.model ?? "llama-3.3-70b-versatile";
261
+ return {
262
+ id: `groq:${modelId}`,
263
+ guaranteeLevel: "native",
264
+ async generate(prompt, schema, systemPrompt) {
265
+ const mod = await import('groq-sdk').catch(() => {
266
+ throw new Error("Install groq: npm install groq-sdk");
267
+ });
268
+ const Groq = mod.default ?? mod;
269
+ const client = new Groq({
270
+ apiKey: options.apiKey ?? process.env.GROQ_API_KEY
271
+ });
272
+ const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);
273
+ const response = await client.chat.completions.create({
274
+ model: modelId,
275
+ messages: [
276
+ { role: "system", content: system },
277
+ { role: "user", content: user }
278
+ ],
279
+ response_format: { type: "json_object" }
280
+ });
281
+ const raw = response.choices[0]?.message?.content ?? "";
282
+ return parseAndValidate(raw, schema);
283
+ }
284
+ };
285
+ }
286
+
287
+ exports.MaxRetriesExceededError = MaxRetriesExceededError;
288
+ exports.SchemaViolationError = SchemaViolationError;
289
+ exports.anthropic = anthropic;
290
+ exports.buildStructuredPrompt = buildStructuredPrompt;
291
+ exports.generate = generate;
292
+ exports.groq = groq;
293
+ exports.ollama = ollama;
294
+ exports.openai = openai;
295
+ exports.toJsonSchema = toJsonSchema;
296
+ //# sourceMappingURL=index.cjs.map
297
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts","../src/core/validate.ts","../src/core/generate.ts","../src/core/schema.ts","../src/core/parse.ts","../src/backends/openai.ts","../src/backends/ollama.ts","../src/backends/anthropic.ts","../src/backends/groq.ts"],"names":["z","zodToJsonSchema"],"mappings":"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","file":"index.cjs","sourcesContent":["import { z } from \"zod\";\n\nexport type GuaranteeLevel = \"constrained\" | \"native\" | \"best-effort\";\n\nexport type JsonSchemaInput = { jsonSchema: Record<string, unknown> };\nexport type PatternInput = { pattern: RegExp };\nexport type ValidatorInput = { validate: (output: unknown) => boolean };\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type SchemaInput<T = unknown> = z.ZodType<T> | JsonSchemaInput | PatternInput | ValidatorInput;\n\nexport interface ShapecraftModel {\n id: string;\n guaranteeLevel: GuaranteeLevel;\n generate<T>(prompt: string, schema: SchemaInput<T>, systemPrompt?: string): Promise<T>;\n}\n\nexport interface GenerateOptions {\n maxRetries?: number;\n systemPrompt?: string;\n temperature?: number;\n}\n\nexport interface GenerateResult<T> {\n data: T;\n guaranteeLevel: GuaranteeLevel;\n attempts: number;\n}\n\nexport class SchemaViolationError extends Error {\n constructor(\n public readonly raw: string,\n public readonly validationErrors: unknown\n ) {\n super(\"Model output failed schema validation\");\n this.name = \"SchemaViolationError\";\n }\n}\n\nexport class MaxRetriesExceededError extends Error {\n constructor(public readonly attempts: number) {\n super(`Schema validation failed after ${attempts} attempts`);\n this.name = \"MaxRetriesExceededError\";\n }\n}\n","import { z } from \"zod\";\nimport type { SchemaInput } from \"../types.js\";\nimport { SchemaViolationError } from \"../types.js\";\n\nexport function isZodSchema(schema: SchemaInput): schema is z.ZodType<any> {\n return schema instanceof z.ZodType;\n}\n\nfunction nullToUndefined(value: unknown): unknown {\n if (value === null) return undefined;\n if (Array.isArray(value)) return value.map(nullToUndefined);\n if (typeof value === \"object\" && value !== null) {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([k, v]) => [k, nullToUndefined(v)])\n );\n }\n return value;\n}\n\nfunction checkJsonSchema(value: unknown, schema: Record<string, unknown>): void {\n const type = schema.type as string | undefined;\n\n if (type) {\n const actual = Array.isArray(value) ? \"array\" : value === null ? \"null\" : typeof value;\n if (actual !== type) {\n throw new Error(`Expected type \"${type}\", got \"${actual}\"`);\n }\n }\n\n if (schema.enum) {\n if (!(schema.enum as unknown[]).includes(value)) {\n throw new Error(`Value not in enum: ${JSON.stringify(value)}`);\n }\n }\n\n if (typeof value === \"object\" && value !== null && !Array.isArray(value) && schema.properties) {\n const obj = value as Record<string, unknown>;\n const required = (schema.required as string[]) ?? [];\n const properties = schema.properties as Record<string, Record<string, unknown>>;\n\n for (const key of required) {\n if (!(key in obj)) throw new Error(`Missing required property: \"${key}\"`);\n }\n\n for (const [key, propSchema] of Object.entries(properties)) {\n if (key in obj) checkJsonSchema(obj[key], propSchema);\n }\n }\n\n if (Array.isArray(value) && schema.items) {\n for (const item of value) {\n checkJsonSchema(item, schema.items as Record<string, unknown>);\n }\n }\n}\n\nexport function validateOutput<T>(output: unknown, schema: SchemaInput<T>): T {\n if (isZodSchema(schema)) {\n const result = schema.safeParse(nullToUndefined(output));\n if (!result.success) throw new SchemaViolationError(JSON.stringify(output), result.error);\n return result.data;\n }\n\n if (\"jsonSchema\" in schema) {\n try {\n checkJsonSchema(output, schema.jsonSchema);\n } catch (err) {\n throw new SchemaViolationError(JSON.stringify(output), err);\n }\n return output as T;\n }\n\n if (\"pattern\" in schema) {\n const str = typeof output === \"string\" ? output : JSON.stringify(output);\n if (!schema.pattern.test(str)) {\n throw new SchemaViolationError(str, `Output does not match pattern ${schema.pattern}`);\n }\n return output as T;\n }\n\n if (\"validate\" in schema) {\n if (!schema.validate(output)) {\n throw new SchemaViolationError(JSON.stringify(output), \"Custom validator returned false\");\n }\n return output as T;\n }\n\n throw new Error(\"Unknown schema type\");\n}\n","import type { GenerateOptions, GenerateResult, SchemaInput, ShapecraftModel } from \"../types.js\";\nimport { MaxRetriesExceededError, SchemaViolationError } from \"../types.js\";\nimport { validateOutput } from \"./validate.js\";\n\nexport async function generate<T>(\n model: ShapecraftModel,\n schema: SchemaInput<T>,\n prompt: string,\n options: GenerateOptions = {}\n): Promise<GenerateResult<T>> {\n const maxRetries = options.maxRetries ?? 3;\n const { systemPrompt } = options;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n const raw = await model.generate<T>(prompt, schema, systemPrompt);\n const data = validateOutput<T>(raw, schema);\n return {\n data,\n guaranteeLevel: model.guaranteeLevel,\n attempts: attempt,\n };\n } catch (err) {\n if (!(err instanceof SchemaViolationError)) throw err;\n if (attempt === maxRetries) break;\n }\n }\n\n throw new MaxRetriesExceededError(maxRetries);\n}\n","import { z } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport type { SchemaInput } from \"../types.js\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function toJsonSchema(schema: z.ZodType<any>): Record<string, unknown> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return zodToJsonSchema(schema as any, { target: \"openApi3\" }) as Record<string, unknown>;\n}\n\nexport function buildStructuredPrompt(\n prompt: string,\n schema: SchemaInput,\n systemPrompt?: string\n): { system: string; user: string } {\n let schemaInfo: string;\n\n if (schema instanceof z.ZodType) {\n schemaInfo = `Respond with valid JSON matching this schema exactly:\\n\\n${JSON.stringify(toJsonSchema(schema), null, 2)}`;\n } else if (\"jsonSchema\" in schema) {\n schemaInfo = `Respond with valid JSON matching this schema exactly:\\n\\n${JSON.stringify(schema.jsonSchema, null, 2)}`;\n } else if (\"pattern\" in schema) {\n schemaInfo = `Respond with a plain string matching this pattern: ${schema.pattern}`;\n } else {\n schemaInfo = \"Respond with valid output as required.\";\n }\n\n const system = systemPrompt\n ? `${systemPrompt}\\n\\n${schemaInfo} No extra text, no markdown, no explanation.`\n : `You are a precise assistant. ${schemaInfo} No extra text, no markdown, no explanation.`;\n\n return { system, user: prompt };\n}\n","import type { SchemaInput } from \"../types.js\";\nimport { SchemaViolationError } from \"../types.js\";\nimport { isZodSchema } from \"./validate.js\";\n\nexport function parseAndValidate<T>(\n raw: string,\n schema: SchemaInput<T>,\n opts: { extractJson?: boolean } = {}\n): T {\n // Pattern schemas return the raw string directly — no JSON parsing\n if (\"pattern\" in (schema as object)) return raw as T;\n\n try {\n const text = opts.extractJson\n ? (raw.match(/\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\]/)?.[0] ?? raw)\n : raw;\n const parsed = JSON.parse(text);\n\n if (isZodSchema(schema)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const result = (schema as any).safeParse(parsed);\n if (!result.success) throw new SchemaViolationError(raw, result.error);\n return result.data as T;\n }\n\n return parsed as T;\n } catch (err) {\n if (err instanceof SchemaViolationError) throw err;\n throw new SchemaViolationError(raw, err);\n }\n}\n","import { z } from \"zod\";\nimport type { SchemaInput, ShapecraftModel } from \"../types.js\";\nimport { toJsonSchema, buildStructuredPrompt } from \"../core/schema.js\";\nimport { isZodSchema } from \"../core/validate.js\";\nimport { parseAndValidate } from \"../core/parse.js\";\n\nexport interface OpenAIBackendOptions {\n model?: string;\n apiKey?: string;\n baseURL?: string;\n}\n\nexport function openai(options: OpenAIBackendOptions = {}): ShapecraftModel {\n const modelId = options.model ?? \"gpt-4o-mini\";\n\n return {\n id: `openai:${modelId}`,\n guaranteeLevel: \"native\",\n\n async generate<T>(prompt: string, schema: SchemaInput<T>, systemPrompt?: string): Promise<T> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod: any = await import(\"openai\").catch(() => {\n throw new Error(\"Install openai: npm install openai\");\n });\n\n const OpenAI = mod.default ?? mod;\n const client = new OpenAI({\n apiKey: options.apiKey ?? process.env.OPENAI_API_KEY,\n baseURL: options.baseURL,\n });\n\n const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);\n\n // Use strict json_schema mode for Zod, non-strict for raw jsonSchema, json_object otherwise\n const responseFormat = isZodSchema(schema)\n ? {\n type: \"json_schema\" as const,\n json_schema: { name: \"output\", strict: true, schema: toJsonSchema(schema as z.ZodType<any>) },\n }\n : \"jsonSchema\" in (schema as object)\n ? {\n type: \"json_schema\" as const,\n json_schema: { name: \"output\", strict: false, schema: (schema as { jsonSchema: Record<string, unknown> }).jsonSchema },\n }\n : { type: \"json_object\" as const };\n\n const response = await client.chat.completions.create({\n model: modelId,\n messages: [\n { role: \"system\", content: system },\n { role: \"user\", content: user },\n ],\n response_format: responseFormat,\n });\n\n const raw: string = response.choices[0]?.message?.content ?? \"\";\n\n return parseAndValidate<T>(raw, schema);\n },\n };\n}\n","import { z } from \"zod\";\nimport type { SchemaInput, ShapecraftModel } from \"../types.js\";\nimport { toJsonSchema, buildStructuredPrompt } from \"../core/schema.js\";\nimport { isZodSchema } from \"../core/validate.js\";\nimport { parseAndValidate } from \"../core/parse.js\";\n\nexport interface OllamaBackendOptions {\n model: string;\n host?: string;\n}\n\nexport function ollama(options: OllamaBackendOptions): ShapecraftModel {\n const host = options.host ?? \"http://localhost:11434\";\n\n return {\n id: `ollama:${options.model}`,\n guaranteeLevel: \"constrained\",\n\n async generate<T>(prompt: string, schema: SchemaInput<T>, systemPrompt?: string): Promise<T> {\n const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);\n\n // Pass JSON schema to Ollama's format param for constrained decoding when possible\n let format: unknown = undefined;\n if (isZodSchema(schema)) {\n format = toJsonSchema(schema as z.ZodType<any>);\n } else if (\"jsonSchema\" in (schema as object)) {\n format = (schema as { jsonSchema: Record<string, unknown> }).jsonSchema;\n }\n\n const response = await fetch(`${host}/api/chat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n model: options.model,\n messages: [\n { role: \"system\", content: system },\n { role: \"user\", content: user },\n ],\n ...(format ? { format } : {}),\n stream: false,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Ollama error: ${response.status} ${response.statusText}`);\n }\n\n const json = await response.json() as { message?: { content?: string } };\n const raw = json.message?.content ?? \"\";\n\n return parseAndValidate<T>(raw, schema);\n },\n };\n}\n","import type { SchemaInput, ShapecraftModel } from \"../types.js\";\nimport { buildStructuredPrompt } from \"../core/schema.js\";\nimport { parseAndValidate } from \"../core/parse.js\";\n\nexport interface AnthropicBackendOptions {\n model?: string;\n apiKey?: string;\n}\n\nexport function anthropic(options: AnthropicBackendOptions = {}): ShapecraftModel {\n const modelId = options.model ?? \"claude-sonnet-4-6\";\n\n return {\n id: `anthropic:${modelId}`,\n guaranteeLevel: \"best-effort\",\n\n async generate<T>(prompt: string, schema: SchemaInput<T>, systemPrompt?: string): Promise<T> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod: any = await import(\"@anthropic-ai/sdk\").catch(() => {\n throw new Error(\"Install sdk: npm install @anthropic-ai/sdk\");\n });\n\n const AnthropicClass = mod.default ?? mod;\n const client = new AnthropicClass({\n apiKey: options.apiKey ?? process.env.ANTHROPIC_API_KEY,\n });\n\n const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);\n\n const response = await client.messages.create({\n model: modelId,\n max_tokens: 4096,\n system,\n messages: [{ role: \"user\", content: user }],\n });\n\n const raw: string =\n response.content[0]?.type === \"text\" ? response.content[0].text : \"\";\n\n return parseAndValidate<T>(raw, schema, { extractJson: true });\n },\n };\n}\n","import type { SchemaInput, ShapecraftModel } from \"../types.js\";\nimport { buildStructuredPrompt } from \"../core/schema.js\";\nimport { parseAndValidate } from \"../core/parse.js\";\n\nexport interface GroqBackendOptions {\n model?: string;\n apiKey?: string;\n}\n\nexport function groq(options: GroqBackendOptions = {}): ShapecraftModel {\n const modelId = options.model ?? \"llama-3.3-70b-versatile\";\n\n return {\n id: `groq:${modelId}`,\n guaranteeLevel: \"native\",\n\n async generate<T>(prompt: string, schema: SchemaInput<T>, systemPrompt?: string): Promise<T> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod: any = await import(\"groq-sdk\").catch(() => {\n throw new Error(\"Install groq: npm install groq-sdk\");\n });\n\n const Groq = mod.default ?? mod;\n const client = new Groq({\n apiKey: options.apiKey ?? process.env.GROQ_API_KEY,\n });\n\n const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);\n\n const response = await client.chat.completions.create({\n model: modelId,\n messages: [\n { role: \"system\", content: system },\n { role: \"user\", content: user },\n ],\n response_format: { type: \"json_object\" },\n });\n\n const raw: string = response.choices[0]?.message?.content ?? \"\";\n\n return parseAndValidate<T>(raw, schema);\n },\n };\n}\n"]}
@@ -0,0 +1,6 @@
1
+ export { generate } from "./core/generate.js";
2
+ export { toJsonSchema, buildStructuredPrompt } from "./core/schema.js";
3
+ export * from "./backends/index.js";
4
+ export type { ShapecraftModel, SchemaInput, GenerateOptions, GenerateResult, GuaranteeLevel, } from "./types.js";
5
+ export { SchemaViolationError, MaxRetriesExceededError } from "./types.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEvE,cAAc,qBAAqB,CAAC;AAEpC,YAAY,EACV,eAAe,EACf,WAAW,EACX,eAAe,EACf,cAAc,EACd,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,287 @@
1
+ import { z } from 'zod';
2
+ import { zodToJsonSchema } from 'zod-to-json-schema';
3
+
4
+ // src/types.ts
5
+ var SchemaViolationError = class extends Error {
6
+ constructor(raw, validationErrors) {
7
+ super("Model output failed schema validation");
8
+ this.raw = raw;
9
+ this.validationErrors = validationErrors;
10
+ this.name = "SchemaViolationError";
11
+ }
12
+ };
13
+ var MaxRetriesExceededError = class extends Error {
14
+ constructor(attempts) {
15
+ super(`Schema validation failed after ${attempts} attempts`);
16
+ this.attempts = attempts;
17
+ this.name = "MaxRetriesExceededError";
18
+ }
19
+ };
20
+ function isZodSchema(schema) {
21
+ return schema instanceof z.ZodType;
22
+ }
23
+ function nullToUndefined(value) {
24
+ if (value === null) return void 0;
25
+ if (Array.isArray(value)) return value.map(nullToUndefined);
26
+ if (typeof value === "object" && value !== null) {
27
+ return Object.fromEntries(
28
+ Object.entries(value).map(([k, v]) => [k, nullToUndefined(v)])
29
+ );
30
+ }
31
+ return value;
32
+ }
33
+ function checkJsonSchema(value, schema) {
34
+ const type = schema.type;
35
+ if (type) {
36
+ const actual = Array.isArray(value) ? "array" : value === null ? "null" : typeof value;
37
+ if (actual !== type) {
38
+ throw new Error(`Expected type "${type}", got "${actual}"`);
39
+ }
40
+ }
41
+ if (schema.enum) {
42
+ if (!schema.enum.includes(value)) {
43
+ throw new Error(`Value not in enum: ${JSON.stringify(value)}`);
44
+ }
45
+ }
46
+ if (typeof value === "object" && value !== null && !Array.isArray(value) && schema.properties) {
47
+ const obj = value;
48
+ const required = schema.required ?? [];
49
+ const properties = schema.properties;
50
+ for (const key of required) {
51
+ if (!(key in obj)) throw new Error(`Missing required property: "${key}"`);
52
+ }
53
+ for (const [key, propSchema] of Object.entries(properties)) {
54
+ if (key in obj) checkJsonSchema(obj[key], propSchema);
55
+ }
56
+ }
57
+ if (Array.isArray(value) && schema.items) {
58
+ for (const item of value) {
59
+ checkJsonSchema(item, schema.items);
60
+ }
61
+ }
62
+ }
63
+ function validateOutput(output, schema) {
64
+ if (isZodSchema(schema)) {
65
+ const result = schema.safeParse(nullToUndefined(output));
66
+ if (!result.success) throw new SchemaViolationError(JSON.stringify(output), result.error);
67
+ return result.data;
68
+ }
69
+ if ("jsonSchema" in schema) {
70
+ try {
71
+ checkJsonSchema(output, schema.jsonSchema);
72
+ } catch (err) {
73
+ throw new SchemaViolationError(JSON.stringify(output), err);
74
+ }
75
+ return output;
76
+ }
77
+ if ("pattern" in schema) {
78
+ const str = typeof output === "string" ? output : JSON.stringify(output);
79
+ if (!schema.pattern.test(str)) {
80
+ throw new SchemaViolationError(str, `Output does not match pattern ${schema.pattern}`);
81
+ }
82
+ return output;
83
+ }
84
+ if ("validate" in schema) {
85
+ if (!schema.validate(output)) {
86
+ throw new SchemaViolationError(JSON.stringify(output), "Custom validator returned false");
87
+ }
88
+ return output;
89
+ }
90
+ throw new Error("Unknown schema type");
91
+ }
92
+
93
+ // src/core/generate.ts
94
+ async function generate(model, schema, prompt, options = {}) {
95
+ const maxRetries = options.maxRetries ?? 3;
96
+ const { systemPrompt } = options;
97
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
98
+ try {
99
+ const raw = await model.generate(prompt, schema, systemPrompt);
100
+ const data = validateOutput(raw, schema);
101
+ return {
102
+ data,
103
+ guaranteeLevel: model.guaranteeLevel,
104
+ attempts: attempt
105
+ };
106
+ } catch (err) {
107
+ if (!(err instanceof SchemaViolationError)) throw err;
108
+ if (attempt === maxRetries) break;
109
+ }
110
+ }
111
+ throw new MaxRetriesExceededError(maxRetries);
112
+ }
113
+ function toJsonSchema(schema) {
114
+ return zodToJsonSchema(schema, { target: "openApi3" });
115
+ }
116
+ function buildStructuredPrompt(prompt, schema, systemPrompt) {
117
+ let schemaInfo;
118
+ if (schema instanceof z.ZodType) {
119
+ schemaInfo = `Respond with valid JSON matching this schema exactly:
120
+
121
+ ${JSON.stringify(toJsonSchema(schema), null, 2)}`;
122
+ } else if ("jsonSchema" in schema) {
123
+ schemaInfo = `Respond with valid JSON matching this schema exactly:
124
+
125
+ ${JSON.stringify(schema.jsonSchema, null, 2)}`;
126
+ } else if ("pattern" in schema) {
127
+ schemaInfo = `Respond with a plain string matching this pattern: ${schema.pattern}`;
128
+ } else {
129
+ schemaInfo = "Respond with valid output as required.";
130
+ }
131
+ const system = systemPrompt ? `${systemPrompt}
132
+
133
+ ${schemaInfo} No extra text, no markdown, no explanation.` : `You are a precise assistant. ${schemaInfo} No extra text, no markdown, no explanation.`;
134
+ return { system, user: prompt };
135
+ }
136
+
137
+ // src/core/parse.ts
138
+ function parseAndValidate(raw, schema, opts = {}) {
139
+ if ("pattern" in schema) return raw;
140
+ try {
141
+ const text = opts.extractJson ? raw.match(/\{[\s\S]*\}|\[[\s\S]*\]/)?.[0] ?? raw : raw;
142
+ const parsed = JSON.parse(text);
143
+ if (isZodSchema(schema)) {
144
+ const result = schema.safeParse(parsed);
145
+ if (!result.success) throw new SchemaViolationError(raw, result.error);
146
+ return result.data;
147
+ }
148
+ return parsed;
149
+ } catch (err) {
150
+ if (err instanceof SchemaViolationError) throw err;
151
+ throw new SchemaViolationError(raw, err);
152
+ }
153
+ }
154
+
155
+ // src/backends/openai.ts
156
+ function openai(options = {}) {
157
+ const modelId = options.model ?? "gpt-4o-mini";
158
+ return {
159
+ id: `openai:${modelId}`,
160
+ guaranteeLevel: "native",
161
+ async generate(prompt, schema, systemPrompt) {
162
+ const mod = await import('openai').catch(() => {
163
+ throw new Error("Install openai: npm install openai");
164
+ });
165
+ const OpenAI = mod.default ?? mod;
166
+ const client = new OpenAI({
167
+ apiKey: options.apiKey ?? process.env.OPENAI_API_KEY,
168
+ baseURL: options.baseURL
169
+ });
170
+ const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);
171
+ const responseFormat = isZodSchema(schema) ? {
172
+ type: "json_schema",
173
+ json_schema: { name: "output", strict: true, schema: toJsonSchema(schema) }
174
+ } : "jsonSchema" in schema ? {
175
+ type: "json_schema",
176
+ json_schema: { name: "output", strict: false, schema: schema.jsonSchema }
177
+ } : { type: "json_object" };
178
+ const response = await client.chat.completions.create({
179
+ model: modelId,
180
+ messages: [
181
+ { role: "system", content: system },
182
+ { role: "user", content: user }
183
+ ],
184
+ response_format: responseFormat
185
+ });
186
+ const raw = response.choices[0]?.message?.content ?? "";
187
+ return parseAndValidate(raw, schema);
188
+ }
189
+ };
190
+ }
191
+
192
+ // src/backends/ollama.ts
193
+ function ollama(options) {
194
+ const host = options.host ?? "http://localhost:11434";
195
+ return {
196
+ id: `ollama:${options.model}`,
197
+ guaranteeLevel: "constrained",
198
+ async generate(prompt, schema, systemPrompt) {
199
+ const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);
200
+ let format = void 0;
201
+ if (isZodSchema(schema)) {
202
+ format = toJsonSchema(schema);
203
+ } else if ("jsonSchema" in schema) {
204
+ format = schema.jsonSchema;
205
+ }
206
+ const response = await fetch(`${host}/api/chat`, {
207
+ method: "POST",
208
+ headers: { "Content-Type": "application/json" },
209
+ body: JSON.stringify({
210
+ model: options.model,
211
+ messages: [
212
+ { role: "system", content: system },
213
+ { role: "user", content: user }
214
+ ],
215
+ ...format ? { format } : {},
216
+ stream: false
217
+ })
218
+ });
219
+ if (!response.ok) {
220
+ throw new Error(`Ollama error: ${response.status} ${response.statusText}`);
221
+ }
222
+ const json = await response.json();
223
+ const raw = json.message?.content ?? "";
224
+ return parseAndValidate(raw, schema);
225
+ }
226
+ };
227
+ }
228
+
229
+ // src/backends/anthropic.ts
230
+ function anthropic(options = {}) {
231
+ const modelId = options.model ?? "claude-sonnet-4-6";
232
+ return {
233
+ id: `anthropic:${modelId}`,
234
+ guaranteeLevel: "best-effort",
235
+ async generate(prompt, schema, systemPrompt) {
236
+ const mod = await import('@anthropic-ai/sdk').catch(() => {
237
+ throw new Error("Install sdk: npm install @anthropic-ai/sdk");
238
+ });
239
+ const AnthropicClass = mod.default ?? mod;
240
+ const client = new AnthropicClass({
241
+ apiKey: options.apiKey ?? process.env.ANTHROPIC_API_KEY
242
+ });
243
+ const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);
244
+ const response = await client.messages.create({
245
+ model: modelId,
246
+ max_tokens: 4096,
247
+ system,
248
+ messages: [{ role: "user", content: user }]
249
+ });
250
+ const raw = response.content[0]?.type === "text" ? response.content[0].text : "";
251
+ return parseAndValidate(raw, schema, { extractJson: true });
252
+ }
253
+ };
254
+ }
255
+
256
+ // src/backends/groq.ts
257
+ function groq(options = {}) {
258
+ const modelId = options.model ?? "llama-3.3-70b-versatile";
259
+ return {
260
+ id: `groq:${modelId}`,
261
+ guaranteeLevel: "native",
262
+ async generate(prompt, schema, systemPrompt) {
263
+ const mod = await import('groq-sdk').catch(() => {
264
+ throw new Error("Install groq: npm install groq-sdk");
265
+ });
266
+ const Groq = mod.default ?? mod;
267
+ const client = new Groq({
268
+ apiKey: options.apiKey ?? process.env.GROQ_API_KEY
269
+ });
270
+ const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);
271
+ const response = await client.chat.completions.create({
272
+ model: modelId,
273
+ messages: [
274
+ { role: "system", content: system },
275
+ { role: "user", content: user }
276
+ ],
277
+ response_format: { type: "json_object" }
278
+ });
279
+ const raw = response.choices[0]?.message?.content ?? "";
280
+ return parseAndValidate(raw, schema);
281
+ }
282
+ };
283
+ }
284
+
285
+ export { MaxRetriesExceededError, SchemaViolationError, anthropic, buildStructuredPrompt, generate, groq, ollama, openai, toJsonSchema };
286
+ //# sourceMappingURL=index.js.map
287
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts","../src/core/validate.ts","../src/core/generate.ts","../src/core/schema.ts","../src/core/parse.ts","../src/backends/openai.ts","../src/backends/ollama.ts","../src/backends/anthropic.ts","../src/backends/groq.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from \"zod\";\n\nexport type GuaranteeLevel = \"constrained\" | \"native\" | \"best-effort\";\n\nexport type JsonSchemaInput = { jsonSchema: Record<string, unknown> };\nexport type PatternInput = { pattern: RegExp };\nexport type ValidatorInput = { validate: (output: unknown) => boolean };\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type SchemaInput<T = unknown> = z.ZodType<T> | JsonSchemaInput | PatternInput | ValidatorInput;\n\nexport interface ShapecraftModel {\n id: string;\n guaranteeLevel: GuaranteeLevel;\n generate<T>(prompt: string, schema: SchemaInput<T>, systemPrompt?: string): Promise<T>;\n}\n\nexport interface GenerateOptions {\n maxRetries?: number;\n systemPrompt?: string;\n temperature?: number;\n}\n\nexport interface GenerateResult<T> {\n data: T;\n guaranteeLevel: GuaranteeLevel;\n attempts: number;\n}\n\nexport class SchemaViolationError extends Error {\n constructor(\n public readonly raw: string,\n public readonly validationErrors: unknown\n ) {\n super(\"Model output failed schema validation\");\n this.name = \"SchemaViolationError\";\n }\n}\n\nexport class MaxRetriesExceededError extends Error {\n constructor(public readonly attempts: number) {\n super(`Schema validation failed after ${attempts} attempts`);\n this.name = \"MaxRetriesExceededError\";\n }\n}\n","import { z } from \"zod\";\nimport type { SchemaInput } from \"../types.js\";\nimport { SchemaViolationError } from \"../types.js\";\n\nexport function isZodSchema(schema: SchemaInput): schema is z.ZodType<any> {\n return schema instanceof z.ZodType;\n}\n\nfunction nullToUndefined(value: unknown): unknown {\n if (value === null) return undefined;\n if (Array.isArray(value)) return value.map(nullToUndefined);\n if (typeof value === \"object\" && value !== null) {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([k, v]) => [k, nullToUndefined(v)])\n );\n }\n return value;\n}\n\nfunction checkJsonSchema(value: unknown, schema: Record<string, unknown>): void {\n const type = schema.type as string | undefined;\n\n if (type) {\n const actual = Array.isArray(value) ? \"array\" : value === null ? \"null\" : typeof value;\n if (actual !== type) {\n throw new Error(`Expected type \"${type}\", got \"${actual}\"`);\n }\n }\n\n if (schema.enum) {\n if (!(schema.enum as unknown[]).includes(value)) {\n throw new Error(`Value not in enum: ${JSON.stringify(value)}`);\n }\n }\n\n if (typeof value === \"object\" && value !== null && !Array.isArray(value) && schema.properties) {\n const obj = value as Record<string, unknown>;\n const required = (schema.required as string[]) ?? [];\n const properties = schema.properties as Record<string, Record<string, unknown>>;\n\n for (const key of required) {\n if (!(key in obj)) throw new Error(`Missing required property: \"${key}\"`);\n }\n\n for (const [key, propSchema] of Object.entries(properties)) {\n if (key in obj) checkJsonSchema(obj[key], propSchema);\n }\n }\n\n if (Array.isArray(value) && schema.items) {\n for (const item of value) {\n checkJsonSchema(item, schema.items as Record<string, unknown>);\n }\n }\n}\n\nexport function validateOutput<T>(output: unknown, schema: SchemaInput<T>): T {\n if (isZodSchema(schema)) {\n const result = schema.safeParse(nullToUndefined(output));\n if (!result.success) throw new SchemaViolationError(JSON.stringify(output), result.error);\n return result.data;\n }\n\n if (\"jsonSchema\" in schema) {\n try {\n checkJsonSchema(output, schema.jsonSchema);\n } catch (err) {\n throw new SchemaViolationError(JSON.stringify(output), err);\n }\n return output as T;\n }\n\n if (\"pattern\" in schema) {\n const str = typeof output === \"string\" ? output : JSON.stringify(output);\n if (!schema.pattern.test(str)) {\n throw new SchemaViolationError(str, `Output does not match pattern ${schema.pattern}`);\n }\n return output as T;\n }\n\n if (\"validate\" in schema) {\n if (!schema.validate(output)) {\n throw new SchemaViolationError(JSON.stringify(output), \"Custom validator returned false\");\n }\n return output as T;\n }\n\n throw new Error(\"Unknown schema type\");\n}\n","import type { GenerateOptions, GenerateResult, SchemaInput, ShapecraftModel } from \"../types.js\";\nimport { MaxRetriesExceededError, SchemaViolationError } from \"../types.js\";\nimport { validateOutput } from \"./validate.js\";\n\nexport async function generate<T>(\n model: ShapecraftModel,\n schema: SchemaInput<T>,\n prompt: string,\n options: GenerateOptions = {}\n): Promise<GenerateResult<T>> {\n const maxRetries = options.maxRetries ?? 3;\n const { systemPrompt } = options;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n const raw = await model.generate<T>(prompt, schema, systemPrompt);\n const data = validateOutput<T>(raw, schema);\n return {\n data,\n guaranteeLevel: model.guaranteeLevel,\n attempts: attempt,\n };\n } catch (err) {\n if (!(err instanceof SchemaViolationError)) throw err;\n if (attempt === maxRetries) break;\n }\n }\n\n throw new MaxRetriesExceededError(maxRetries);\n}\n","import { z } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport type { SchemaInput } from \"../types.js\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function toJsonSchema(schema: z.ZodType<any>): Record<string, unknown> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return zodToJsonSchema(schema as any, { target: \"openApi3\" }) as Record<string, unknown>;\n}\n\nexport function buildStructuredPrompt(\n prompt: string,\n schema: SchemaInput,\n systemPrompt?: string\n): { system: string; user: string } {\n let schemaInfo: string;\n\n if (schema instanceof z.ZodType) {\n schemaInfo = `Respond with valid JSON matching this schema exactly:\\n\\n${JSON.stringify(toJsonSchema(schema), null, 2)}`;\n } else if (\"jsonSchema\" in schema) {\n schemaInfo = `Respond with valid JSON matching this schema exactly:\\n\\n${JSON.stringify(schema.jsonSchema, null, 2)}`;\n } else if (\"pattern\" in schema) {\n schemaInfo = `Respond with a plain string matching this pattern: ${schema.pattern}`;\n } else {\n schemaInfo = \"Respond with valid output as required.\";\n }\n\n const system = systemPrompt\n ? `${systemPrompt}\\n\\n${schemaInfo} No extra text, no markdown, no explanation.`\n : `You are a precise assistant. ${schemaInfo} No extra text, no markdown, no explanation.`;\n\n return { system, user: prompt };\n}\n","import type { SchemaInput } from \"../types.js\";\nimport { SchemaViolationError } from \"../types.js\";\nimport { isZodSchema } from \"./validate.js\";\n\nexport function parseAndValidate<T>(\n raw: string,\n schema: SchemaInput<T>,\n opts: { extractJson?: boolean } = {}\n): T {\n // Pattern schemas return the raw string directly — no JSON parsing\n if (\"pattern\" in (schema as object)) return raw as T;\n\n try {\n const text = opts.extractJson\n ? (raw.match(/\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\]/)?.[0] ?? raw)\n : raw;\n const parsed = JSON.parse(text);\n\n if (isZodSchema(schema)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const result = (schema as any).safeParse(parsed);\n if (!result.success) throw new SchemaViolationError(raw, result.error);\n return result.data as T;\n }\n\n return parsed as T;\n } catch (err) {\n if (err instanceof SchemaViolationError) throw err;\n throw new SchemaViolationError(raw, err);\n }\n}\n","import { z } from \"zod\";\nimport type { SchemaInput, ShapecraftModel } from \"../types.js\";\nimport { toJsonSchema, buildStructuredPrompt } from \"../core/schema.js\";\nimport { isZodSchema } from \"../core/validate.js\";\nimport { parseAndValidate } from \"../core/parse.js\";\n\nexport interface OpenAIBackendOptions {\n model?: string;\n apiKey?: string;\n baseURL?: string;\n}\n\nexport function openai(options: OpenAIBackendOptions = {}): ShapecraftModel {\n const modelId = options.model ?? \"gpt-4o-mini\";\n\n return {\n id: `openai:${modelId}`,\n guaranteeLevel: \"native\",\n\n async generate<T>(prompt: string, schema: SchemaInput<T>, systemPrompt?: string): Promise<T> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod: any = await import(\"openai\").catch(() => {\n throw new Error(\"Install openai: npm install openai\");\n });\n\n const OpenAI = mod.default ?? mod;\n const client = new OpenAI({\n apiKey: options.apiKey ?? process.env.OPENAI_API_KEY,\n baseURL: options.baseURL,\n });\n\n const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);\n\n // Use strict json_schema mode for Zod, non-strict for raw jsonSchema, json_object otherwise\n const responseFormat = isZodSchema(schema)\n ? {\n type: \"json_schema\" as const,\n json_schema: { name: \"output\", strict: true, schema: toJsonSchema(schema as z.ZodType<any>) },\n }\n : \"jsonSchema\" in (schema as object)\n ? {\n type: \"json_schema\" as const,\n json_schema: { name: \"output\", strict: false, schema: (schema as { jsonSchema: Record<string, unknown> }).jsonSchema },\n }\n : { type: \"json_object\" as const };\n\n const response = await client.chat.completions.create({\n model: modelId,\n messages: [\n { role: \"system\", content: system },\n { role: \"user\", content: user },\n ],\n response_format: responseFormat,\n });\n\n const raw: string = response.choices[0]?.message?.content ?? \"\";\n\n return parseAndValidate<T>(raw, schema);\n },\n };\n}\n","import { z } from \"zod\";\nimport type { SchemaInput, ShapecraftModel } from \"../types.js\";\nimport { toJsonSchema, buildStructuredPrompt } from \"../core/schema.js\";\nimport { isZodSchema } from \"../core/validate.js\";\nimport { parseAndValidate } from \"../core/parse.js\";\n\nexport interface OllamaBackendOptions {\n model: string;\n host?: string;\n}\n\nexport function ollama(options: OllamaBackendOptions): ShapecraftModel {\n const host = options.host ?? \"http://localhost:11434\";\n\n return {\n id: `ollama:${options.model}`,\n guaranteeLevel: \"constrained\",\n\n async generate<T>(prompt: string, schema: SchemaInput<T>, systemPrompt?: string): Promise<T> {\n const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);\n\n // Pass JSON schema to Ollama's format param for constrained decoding when possible\n let format: unknown = undefined;\n if (isZodSchema(schema)) {\n format = toJsonSchema(schema as z.ZodType<any>);\n } else if (\"jsonSchema\" in (schema as object)) {\n format = (schema as { jsonSchema: Record<string, unknown> }).jsonSchema;\n }\n\n const response = await fetch(`${host}/api/chat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n model: options.model,\n messages: [\n { role: \"system\", content: system },\n { role: \"user\", content: user },\n ],\n ...(format ? { format } : {}),\n stream: false,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Ollama error: ${response.status} ${response.statusText}`);\n }\n\n const json = await response.json() as { message?: { content?: string } };\n const raw = json.message?.content ?? \"\";\n\n return parseAndValidate<T>(raw, schema);\n },\n };\n}\n","import type { SchemaInput, ShapecraftModel } from \"../types.js\";\nimport { buildStructuredPrompt } from \"../core/schema.js\";\nimport { parseAndValidate } from \"../core/parse.js\";\n\nexport interface AnthropicBackendOptions {\n model?: string;\n apiKey?: string;\n}\n\nexport function anthropic(options: AnthropicBackendOptions = {}): ShapecraftModel {\n const modelId = options.model ?? \"claude-sonnet-4-6\";\n\n return {\n id: `anthropic:${modelId}`,\n guaranteeLevel: \"best-effort\",\n\n async generate<T>(prompt: string, schema: SchemaInput<T>, systemPrompt?: string): Promise<T> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod: any = await import(\"@anthropic-ai/sdk\").catch(() => {\n throw new Error(\"Install sdk: npm install @anthropic-ai/sdk\");\n });\n\n const AnthropicClass = mod.default ?? mod;\n const client = new AnthropicClass({\n apiKey: options.apiKey ?? process.env.ANTHROPIC_API_KEY,\n });\n\n const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);\n\n const response = await client.messages.create({\n model: modelId,\n max_tokens: 4096,\n system,\n messages: [{ role: \"user\", content: user }],\n });\n\n const raw: string =\n response.content[0]?.type === \"text\" ? response.content[0].text : \"\";\n\n return parseAndValidate<T>(raw, schema, { extractJson: true });\n },\n };\n}\n","import type { SchemaInput, ShapecraftModel } from \"../types.js\";\nimport { buildStructuredPrompt } from \"../core/schema.js\";\nimport { parseAndValidate } from \"../core/parse.js\";\n\nexport interface GroqBackendOptions {\n model?: string;\n apiKey?: string;\n}\n\nexport function groq(options: GroqBackendOptions = {}): ShapecraftModel {\n const modelId = options.model ?? \"llama-3.3-70b-versatile\";\n\n return {\n id: `groq:${modelId}`,\n guaranteeLevel: \"native\",\n\n async generate<T>(prompt: string, schema: SchemaInput<T>, systemPrompt?: string): Promise<T> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod: any = await import(\"groq-sdk\").catch(() => {\n throw new Error(\"Install groq: npm install groq-sdk\");\n });\n\n const Groq = mod.default ?? mod;\n const client = new Groq({\n apiKey: options.apiKey ?? process.env.GROQ_API_KEY,\n });\n\n const { system, user } = buildStructuredPrompt(prompt, schema, systemPrompt);\n\n const response = await client.chat.completions.create({\n model: modelId,\n messages: [\n { role: \"system\", content: system },\n { role: \"user\", content: user },\n ],\n response_format: { type: \"json_object\" },\n });\n\n const raw: string = response.choices[0]?.message?.content ?? \"\";\n\n return parseAndValidate<T>(raw, schema);\n },\n };\n}\n"]}
@@ -0,0 +1,37 @@
1
+ import { z } from "zod";
2
+ export type GuaranteeLevel = "constrained" | "native" | "best-effort";
3
+ export type JsonSchemaInput = {
4
+ jsonSchema: Record<string, unknown>;
5
+ };
6
+ export type PatternInput = {
7
+ pattern: RegExp;
8
+ };
9
+ export type ValidatorInput = {
10
+ validate: (output: unknown) => boolean;
11
+ };
12
+ export type SchemaInput<T = unknown> = z.ZodType<T> | JsonSchemaInput | PatternInput | ValidatorInput;
13
+ export interface ShapecraftModel {
14
+ id: string;
15
+ guaranteeLevel: GuaranteeLevel;
16
+ generate<T>(prompt: string, schema: SchemaInput<T>, systemPrompt?: string): Promise<T>;
17
+ }
18
+ export interface GenerateOptions {
19
+ maxRetries?: number;
20
+ systemPrompt?: string;
21
+ temperature?: number;
22
+ }
23
+ export interface GenerateResult<T> {
24
+ data: T;
25
+ guaranteeLevel: GuaranteeLevel;
26
+ attempts: number;
27
+ }
28
+ export declare class SchemaViolationError extends Error {
29
+ readonly raw: string;
30
+ readonly validationErrors: unknown;
31
+ constructor(raw: string, validationErrors: unknown);
32
+ }
33
+ export declare class MaxRetriesExceededError extends Error {
34
+ readonly attempts: number;
35
+ constructor(attempts: number);
36
+ }
37
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,QAAQ,GAAG,aAAa,CAAC;AAEtE,MAAM,MAAM,eAAe,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AACtE,MAAM,MAAM,YAAY,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/C,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAA;CAAE,CAAC;AAExE,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,eAAe,GAAG,YAAY,GAAG,cAAc,CAAC;AAEtG,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACxF;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,IAAI,EAAE,CAAC,CAAC;IACR,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,oBAAqB,SAAQ,KAAK;aAE3B,GAAG,EAAE,MAAM;aACX,gBAAgB,EAAE,OAAO;gBADzB,GAAG,EAAE,MAAM,EACX,gBAAgB,EAAE,OAAO;CAK5C;AAED,qBAAa,uBAAwB,SAAQ,KAAK;aACpB,QAAQ,EAAE,MAAM;gBAAhB,QAAQ,EAAE,MAAM;CAI7C"}
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@aviasole/shapecraft",
3
+ "version": "0.1.0",
4
+ "description": "Structured output generation for LLMs in Node.js — token-level constraints for local models, native JSON modes for cloud APIs",
5
+ "author": "Aviasole Technologies",
6
+ "license": "Apache-2.0",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/aviasoletechnologies/shapecraft.git"
10
+ },
11
+ "homepage": "https://github.com/aviasoletechnologies/shapecraft#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/aviasoletechnologies/shapecraft/issues"
14
+ },
15
+ "keywords": [
16
+ "llm",
17
+ "structured-output",
18
+ "constrained-generation",
19
+ "json-schema",
20
+ "zod",
21
+ "openai",
22
+ "ollama",
23
+ "llama",
24
+ "ai"
25
+ ],
26
+ "type": "module",
27
+ "main": "./dist/index.cjs",
28
+ "module": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "import": "./dist/index.js",
34
+ "require": "./dist/index.cjs"
35
+ }
36
+ },
37
+ "files": [
38
+ "dist"
39
+ ],
40
+ "scripts": {
41
+ "build": "tsup && tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist",
42
+ "dev": "tsup --watch",
43
+ "test": "vitest run",
44
+ "test:watch": "vitest",
45
+ "lint": "eslint src --ext .ts",
46
+ "typecheck": "tsc --noEmit",
47
+ "prepublishOnly": "npm run build && npm run typecheck && npm run test"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^20.0.0",
51
+ "tsup": "^8.0.0",
52
+ "typescript": "^5.4.0",
53
+ "vitest": "^1.6.0"
54
+ },
55
+ "peerDependencies": {
56
+ "node-llama-cpp": ">=3.0.0",
57
+ "openai": ">=4.0.0",
58
+ "ollama": ">=0.5.0",
59
+ "zod": ">=3.0.0"
60
+ },
61
+ "peerDependenciesMeta": {
62
+ "node-llama-cpp": { "optional": true },
63
+ "openai": { "optional": true },
64
+ "ollama": { "optional": true }
65
+ },
66
+ "dependencies": {
67
+ "zod-to-json-schema": "^3.23.0"
68
+ }
69
+ }