tinyai 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.
Files changed (66) hide show
  1. package/README.md +302 -0
  2. package/dist/core/client.d.ts +48 -0
  3. package/dist/core/client.d.ts.map +1 -0
  4. package/dist/core/client.js +53 -0
  5. package/dist/core/client.js.map +1 -0
  6. package/dist/core/schema.d.ts +26 -0
  7. package/dist/core/schema.d.ts.map +1 -0
  8. package/dist/core/schema.js +112 -0
  9. package/dist/core/schema.js.map +1 -0
  10. package/dist/core/streaming.d.ts +15 -0
  11. package/dist/core/streaming.d.ts.map +1 -0
  12. package/dist/core/streaming.js +33 -0
  13. package/dist/core/streaming.js.map +1 -0
  14. package/dist/index.d.ts +81 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +60 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/primitives/ask.d.ts +23 -0
  19. package/dist/primitives/ask.d.ts.map +1 -0
  20. package/dist/primitives/ask.js +36 -0
  21. package/dist/primitives/ask.js.map +1 -0
  22. package/dist/primitives/classify.d.ts +18 -0
  23. package/dist/primitives/classify.d.ts.map +1 -0
  24. package/dist/primitives/classify.js +44 -0
  25. package/dist/primitives/classify.js.map +1 -0
  26. package/dist/primitives/embed.d.ts +22 -0
  27. package/dist/primitives/embed.d.ts.map +1 -0
  28. package/dist/primitives/embed.js +37 -0
  29. package/dist/primitives/embed.js.map +1 -0
  30. package/dist/primitives/extract.d.ts +25 -0
  31. package/dist/primitives/extract.d.ts.map +1 -0
  32. package/dist/primitives/extract.js +47 -0
  33. package/dist/primitives/extract.js.map +1 -0
  34. package/dist/primitives/generate.d.ts +26 -0
  35. package/dist/primitives/generate.d.ts.map +1 -0
  36. package/dist/primitives/generate.js +40 -0
  37. package/dist/primitives/generate.js.map +1 -0
  38. package/dist/primitives/summarize.d.ts +30 -0
  39. package/dist/primitives/summarize.d.ts.map +1 -0
  40. package/dist/primitives/summarize.js +43 -0
  41. package/dist/primitives/summarize.js.map +1 -0
  42. package/dist/primitives/translate.d.ts +22 -0
  43. package/dist/primitives/translate.d.ts.map +1 -0
  44. package/dist/primitives/translate.js +36 -0
  45. package/dist/primitives/translate.js.map +1 -0
  46. package/dist/providers/groq.d.ts +18 -0
  47. package/dist/providers/groq.d.ts.map +1 -0
  48. package/dist/providers/groq.js +113 -0
  49. package/dist/providers/groq.js.map +1 -0
  50. package/dist/providers/ollama.d.ts +24 -0
  51. package/dist/providers/ollama.d.ts.map +1 -0
  52. package/dist/providers/ollama.js +123 -0
  53. package/dist/providers/ollama.js.map +1 -0
  54. package/dist/providers/openai.d.ts +12 -0
  55. package/dist/providers/openai.d.ts.map +1 -0
  56. package/dist/providers/openai.js +127 -0
  57. package/dist/providers/openai.js.map +1 -0
  58. package/dist/utils/prompts.d.ts +29 -0
  59. package/dist/utils/prompts.d.ts.map +1 -0
  60. package/dist/utils/prompts.js +29 -0
  61. package/dist/utils/prompts.js.map +1 -0
  62. package/dist/utils/retry.d.ts +10 -0
  63. package/dist/utils/retry.d.ts.map +1 -0
  64. package/dist/utils/retry.js +44 -0
  65. package/dist/utils/retry.js.map +1 -0
  66. package/package.json +74 -0
package/README.md ADDED
@@ -0,0 +1,302 @@
1
+ <p align="center">
2
+ <img src="./assets/logo.svg" alt="TinyAI" width="200">
3
+ </p>
4
+
5
+ <h1 align="center">TinyAI</h1>
6
+
7
+ <p align="center">
8
+ <a href="https://www.npmjs.com/package/tinyai"><img src="https://img.shields.io/npm/v/tinyai.svg" alt="npm version"></a>
9
+ <a href="https://bundlephobia.com/package/tinyai"><img src="https://img.shields.io/bundlephobia/minzip/tinyai" alt="bundle size"></a>
10
+ <a href="https://www.npmjs.com/package/tinyai"><img src="https://img.shields.io/badge/dependencies-0-brightgreen" alt="zero dependencies"></a>
11
+ <a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-Ready-blue.svg" alt="TypeScript"></a>
12
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
13
+ </p>
14
+
15
+ <p align="center"><strong>The 5KB AI SDK.</strong> Zero dependencies. Just works.</p>
16
+
17
+ <p align="center"><em>"The missing middle between raw API calls and over-engineered frameworks."</em></p>
18
+
19
+ ---
20
+
21
+ ```bash
22
+ npm install tinyai
23
+ ```
24
+
25
+ ## Why TinyAI?
26
+
27
+ ```typescript
28
+ // Vercel AI SDK - 186KB, lots of setup
29
+ import { openai } from '@ai-sdk/openai';
30
+ import { generateText } from 'ai';
31
+ const { text } = await generateText({
32
+ model: openai('gpt-4o-mini'),
33
+ prompt: 'Summarize this text...',
34
+ });
35
+
36
+ // TinyAI - 5KB, one line
37
+ import { summarize } from 'tinyai';
38
+ const summary = await summarize(text);
39
+ ```
40
+
41
+ ## Quick Start
42
+
43
+ ```typescript
44
+ import { tinyai } from 'tinyai';
45
+
46
+ // Configure once
47
+ const ai = tinyai({
48
+ provider: 'openai',
49
+ apiKey: process.env.OPENAI_API_KEY // or auto-detects from env
50
+ });
51
+
52
+ // Use anywhere
53
+ const summary = await ai.summarize(longArticle);
54
+ const sentiment = await ai.classify(review, ['positive', 'negative', 'neutral']);
55
+ const data = await ai.extract(email, { name: 'string', date: 'date', amount: 'number' });
56
+ const spanish = await ai.translate(text, 'spanish');
57
+ const answer = await ai.ask("What's the capital of France?");
58
+ const embedding = await ai.embed(text);
59
+ ```
60
+
61
+ ## Free Options
62
+
63
+ TinyAI supports **completely free** AI providers:
64
+
65
+ ### Groq (Free Cloud)
66
+
67
+ Fast, free cloud AI with generous limits (14K tokens/min).
68
+
69
+ ```typescript
70
+ import { tinyai } from 'tinyai';
71
+
72
+ // Get free API key: https://console.groq.com/keys
73
+ const ai = tinyai({
74
+ provider: 'groq',
75
+ apiKey: process.env.GROQ_API_KEY
76
+ });
77
+
78
+ const summary = await ai.summarize(text); // Free!
79
+ ```
80
+
81
+ **Models:** Llama 3.3 70B, Llama 3.1 8B, Mixtral, Gemma2
82
+
83
+ ### Ollama (Free Local)
84
+
85
+ Run AI 100% locally on your machine. No API key needed.
86
+
87
+ ```bash
88
+ # 1. Install Ollama: https://ollama.ai
89
+ # 2. Pull a model
90
+ ollama pull llama3.2
91
+ ```
92
+
93
+ ```typescript
94
+ import { tinyai } from 'tinyai';
95
+
96
+ // No API key needed!
97
+ const ai = tinyai({
98
+ provider: 'ollama',
99
+ model: 'llama3.2' // or mistral, codellama, phi, gemma2
100
+ });
101
+
102
+ const summary = await ai.summarize(text); // 100% free, runs locally
103
+ ```
104
+
105
+ ### Provider Comparison
106
+
107
+ | Provider | Cost | Speed | Privacy | Setup |
108
+ |----------|------|-------|---------|-------|
109
+ | **Ollama** | Free | Depends on hardware | 100% local | Install app |
110
+ | **Groq** | Free tier | Very fast | Cloud | Get API key |
111
+ | OpenAI | Paid | Fast | Cloud | Get API key |
112
+
113
+ ## Features
114
+
115
+ ### Type-Safe Extraction (like Zod, but for AI)
116
+
117
+ ```typescript
118
+ const invoice = await ai.extract(pdfText, {
119
+ vendor: 'string',
120
+ total: 'number',
121
+ items: [{ name: 'string', price: 'number' }],
122
+ dueDate: 'date',
123
+ });
124
+
125
+ // TypeScript knows the exact shape:
126
+ // { vendor: string, total: number, items: { name: string, price: number }[], dueDate: Date }
127
+ ```
128
+
129
+ ### Zero-Config Defaults
130
+
131
+ ```typescript
132
+ // Just set OPENAI_API_KEY env var
133
+ import { summarize, classify, extract } from 'tinyai';
134
+
135
+ const summary = await summarize(text); // Works instantly
136
+ ```
137
+
138
+ ### Streaming
139
+
140
+ ```typescript
141
+ for await (const chunk of ai.stream.summarize(text)) {
142
+ process.stdout.write(chunk);
143
+ }
144
+ ```
145
+
146
+ ### Edge-Ready
147
+
148
+ Works everywhere: Node.js, Deno, Bun, Cloudflare Workers, Vercel Edge.
149
+
150
+ ```typescript
151
+ // Cloudflare Worker
152
+ export default {
153
+ async fetch(req: Request) {
154
+ const summary = await summarize(await req.text());
155
+ return new Response(summary);
156
+ }
157
+ };
158
+ ```
159
+
160
+ ## API
161
+
162
+ ### `tinyai(config?)`
163
+
164
+ Creates a TinyAI instance.
165
+
166
+ ```typescript
167
+ const ai = tinyai({
168
+ provider: 'openai', // 'openai' | 'anthropic' | 'groq' | 'ollama'
169
+ apiKey: '...', // Optional, uses env vars by default
170
+ model: 'gpt-4o', // Optional, defaults to gpt-4o-mini
171
+ });
172
+ ```
173
+
174
+ ### `summarize(text, options?)`
175
+
176
+ Summarizes text.
177
+
178
+ ```typescript
179
+ const summary = await ai.summarize(longText);
180
+ const brief = await ai.summarize(text, { maxLength: 50 });
181
+ ```
182
+
183
+ ### `classify(text, categories)`
184
+
185
+ Classifies text into one of the provided categories.
186
+
187
+ ```typescript
188
+ const sentiment = await ai.classify(review, ['positive', 'negative', 'neutral']);
189
+ const category = await ai.classify(email, ['urgent', 'normal', 'spam']);
190
+ ```
191
+
192
+ ### `extract(text, schema)`
193
+
194
+ Extracts structured data with full TypeScript inference.
195
+
196
+ ```typescript
197
+ const person = await ai.extract(bio, {
198
+ name: 'string',
199
+ age: 'number',
200
+ skills: ['string'],
201
+ contact: {
202
+ email: 'string',
203
+ phone: 'string',
204
+ },
205
+ });
206
+ ```
207
+
208
+ **Supported types:** `'string'` | `'number'` | `'boolean'` | `'date'`
209
+
210
+ ### `translate(text, language)`
211
+
212
+ Translates text to another language.
213
+
214
+ ```typescript
215
+ const spanish = await ai.translate('Hello, world!', 'spanish');
216
+ ```
217
+
218
+ ### `ask(question, options?)`
219
+
220
+ Answers questions, optionally with context.
221
+
222
+ ```typescript
223
+ const answer = await ai.ask("What's 2+2?");
224
+ const specific = await ai.ask("What's the total?", { context: invoiceText });
225
+ ```
226
+
227
+ ### `embed(text)`
228
+
229
+ Generates embedding vectors.
230
+
231
+ ```typescript
232
+ const embedding = await ai.embed("Hello, world!");
233
+ // Returns number[] with 1536 dimensions (OpenAI)
234
+ ```
235
+
236
+ ### `generate(prompt, options?)`
237
+
238
+ Low-level text generation.
239
+
240
+ ```typescript
241
+ const poem = await ai.generate("Write a haiku about coding");
242
+ const story = await ai.generate("Once upon a time...", {
243
+ system: "You are a creative storyteller"
244
+ });
245
+ ```
246
+
247
+ ## Comparison
248
+
249
+ | Feature | TinyAI | Vercel AI SDK | LangChain |
250
+ |---------|--------|---------------|-----------|
251
+ | Bundle size | **5KB** | 186KB | 500KB+ |
252
+ | Dependencies | **0** | 12+ | 50+ |
253
+ | TypeScript inference | **Native** | Partial | Plugin |
254
+ | Setup time | **1 min** | 10 min | 30 min |
255
+ | Learning curve | **None** | Medium | Steep |
256
+
257
+ ## Standalone Functions
258
+
259
+ All primitives work standalone without creating an instance:
260
+
261
+ ```typescript
262
+ import { summarize, classify, extract } from 'tinyai';
263
+
264
+ // Just set OPENAI_API_KEY in your environment
265
+ const summary = await summarize(text);
266
+ const sentiment = await classify(text, ['positive', 'negative']);
267
+ const data = await extract(text, { name: 'string' });
268
+ ```
269
+
270
+ ## Streaming Helpers
271
+
272
+ ```typescript
273
+ import { toReadableStream, collectStream } from 'tinyai';
274
+
275
+ // Convert to ReadableStream for HTTP responses
276
+ const stream = toReadableStream(ai.stream.summarize(text));
277
+ return new Response(stream);
278
+
279
+ // Collect stream to string
280
+ const full = await collectStream(ai.stream.summarize(text));
281
+ ```
282
+
283
+ ## Roadmap
284
+
285
+ - [x] Core client with OpenAI provider
286
+ - [x] `summarize()` - text summarization
287
+ - [x] `classify()` - text classification
288
+ - [x] `extract()` - structured data extraction
289
+ - [x] `translate()` - translation
290
+ - [x] `ask()` - Q&A
291
+ - [x] `embed()` - embeddings
292
+ - [x] TypeScript inference
293
+ - [x] Streaming support
294
+ - [x] Provider: Groq (free cloud)
295
+ - [x] Provider: Ollama (free local)
296
+ - [ ] Provider: Anthropic
297
+ - [ ] `pipe()` - composable pipelines
298
+ - [ ] CLI tool
299
+
300
+ ## License
301
+
302
+ MIT
@@ -0,0 +1,48 @@
1
+ /**
2
+ * TinyAI Core Client
3
+ * Provider-agnostic AI client
4
+ */
5
+ export interface ChatMessage {
6
+ role: 'system' | 'user' | 'assistant';
7
+ content: string;
8
+ }
9
+ export interface ChatResponse {
10
+ content: string;
11
+ usage: {
12
+ promptTokens: number;
13
+ completionTokens: number;
14
+ totalTokens: number;
15
+ };
16
+ }
17
+ export interface EmbedResponse {
18
+ embedding: number[];
19
+ usage: {
20
+ totalTokens: number;
21
+ };
22
+ }
23
+ export interface Provider {
24
+ chat(messages: ChatMessage[]): Promise<ChatResponse>;
25
+ chatStream(messages: ChatMessage[]): AsyncGenerator<string, void, unknown>;
26
+ embed(text: string): Promise<EmbedResponse>;
27
+ }
28
+ export interface ProviderConfig {
29
+ apiKey?: string;
30
+ }
31
+ export type ProviderName = 'openai' | 'anthropic' | 'groq' | 'ollama';
32
+ export interface TinyAIConfig {
33
+ provider?: ProviderName;
34
+ apiKey?: string;
35
+ model?: string;
36
+ baseUrl?: string;
37
+ }
38
+ export interface TinyAIClient {
39
+ provider: Provider;
40
+ config: TinyAIConfig;
41
+ }
42
+ /**
43
+ * Creates a TinyAI client
44
+ */
45
+ export declare function createClient(config?: TinyAIConfig): TinyAIClient;
46
+ export declare function getDefaultClient(): TinyAIClient;
47
+ export declare function setDefaultClient(client: TinyAIClient): void;
48
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACrD,UAAU,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3E,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEtE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,GAAE,YAAiB,GAAG,YAAY,CAgCpE;AAKD,wBAAgB,gBAAgB,IAAI,YAAY,CAK/C;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAE3D"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * TinyAI Core Client
3
+ * Provider-agnostic AI client
4
+ */
5
+ import { createOpenAIProvider } from '../providers/openai.js';
6
+ import { createGroqProvider } from '../providers/groq.js';
7
+ import { createOllamaProvider } from '../providers/ollama.js';
8
+ /**
9
+ * Creates a TinyAI client
10
+ */
11
+ export function createClient(config = {}) {
12
+ const providerName = config.provider ?? 'openai';
13
+ let provider;
14
+ switch (providerName) {
15
+ case 'openai':
16
+ provider = createOpenAIProvider({
17
+ apiKey: config.apiKey,
18
+ model: config.model,
19
+ baseUrl: config.baseUrl,
20
+ });
21
+ break;
22
+ case 'groq':
23
+ provider = createGroqProvider({
24
+ apiKey: config.apiKey,
25
+ model: config.model,
26
+ baseUrl: config.baseUrl,
27
+ });
28
+ break;
29
+ case 'ollama':
30
+ provider = createOllamaProvider({
31
+ model: config.model,
32
+ baseUrl: config.baseUrl,
33
+ });
34
+ break;
35
+ case 'anthropic':
36
+ throw new Error('Anthropic provider coming soon. Use "groq" or "ollama" for free.');
37
+ default:
38
+ throw new Error(`Unknown provider: ${providerName}`);
39
+ }
40
+ return { provider, config };
41
+ }
42
+ // Default client (lazy initialized)
43
+ let defaultClient = null;
44
+ export function getDefaultClient() {
45
+ if (!defaultClient) {
46
+ defaultClient = createClient();
47
+ }
48
+ return defaultClient;
49
+ }
50
+ export function setDefaultClient(client) {
51
+ defaultClient = client;
52
+ }
53
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AA+C9D;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,SAAuB,EAAE;IACpD,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC;IACjD,IAAI,QAAkB,CAAC;IAEvB,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,QAAQ;YACX,QAAQ,GAAG,oBAAoB,CAAC;gBAC9B,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,CAAC,CAAC;YACH,MAAM;QACR,KAAK,MAAM;YACT,QAAQ,GAAG,kBAAkB,CAAC;gBAC5B,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,CAAC,CAAC;YACH,MAAM;QACR,KAAK,QAAQ;YACX,QAAQ,GAAG,oBAAoB,CAAC;gBAC9B,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,CAAC,CAAC;YACH,MAAM;QACR,KAAK,WAAW;YACd,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;QACtF;YACE,MAAM,IAAI,KAAK,CAAC,qBAAqB,YAAY,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED,oCAAoC;AACpC,IAAI,aAAa,GAAwB,IAAI,CAAC;AAE9C,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,aAAa,GAAG,YAAY,EAAE,CAAC;IACjC,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAoB;IACnD,aAAa,GAAG,MAAM,CAAC;AACzB,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * TinyAI Schema System
3
+ * Provides Zod-like type inference without dependencies
4
+ */
5
+ export type PrimitiveType = 'string' | 'number' | 'boolean' | 'date';
6
+ export type SchemaValue = PrimitiveType | SchemaObject | readonly [SchemaValue];
7
+ export type SchemaObject = {
8
+ readonly [key: string]: SchemaValue;
9
+ };
10
+ type InferPrimitive<T extends PrimitiveType> = T extends 'string' ? string : T extends 'number' ? number : T extends 'boolean' ? boolean : T extends 'date' ? Date : never;
11
+ type InferSchemaValue<T extends SchemaValue> = T extends PrimitiveType ? InferPrimitive<T> : T extends readonly [infer U extends SchemaValue] ? InferSchemaValue<U>[] : T extends SchemaObject ? {
12
+ [K in keyof T]: InferSchemaValue<T[K]>;
13
+ } : never;
14
+ export type InferSchema<T extends SchemaObject> = {
15
+ [K in keyof T]: InferSchemaValue<T[K]>;
16
+ };
17
+ /**
18
+ * Converts a schema definition to a JSON Schema for the AI prompt
19
+ */
20
+ export declare function schemaToJsonSchema(schema: SchemaObject): object;
21
+ /**
22
+ * Parses AI response and converts types (especially dates)
23
+ */
24
+ export declare function parseResponse<T extends SchemaObject>(data: unknown, schema: T): InferSchema<T>;
25
+ export {};
26
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAGrE,MAAM,MAAM,WAAW,GACnB,aAAa,GACb,YAAY,GACZ,SAAS,CAAC,WAAW,CAAC,CAAC;AAE3B,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;CACrC,CAAC;AAGF,KAAK,cAAc,CAAC,CAAC,SAAS,aAAa,IAAI,CAAC,SAAS,QAAQ,GAC7D,MAAM,GACN,CAAC,SAAS,QAAQ,GAChB,MAAM,GACN,CAAC,SAAS,SAAS,GACjB,OAAO,GACP,CAAC,SAAS,MAAM,GACd,IAAI,GACJ,KAAK,CAAC;AAEhB,KAAK,gBAAgB,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,SAAS,aAAa,GAClE,cAAc,CAAC,CAAC,CAAC,GACjB,CAAC,SAAS,SAAS,CAAC,MAAM,CAAC,SAAS,WAAW,CAAC,GAC9C,gBAAgB,CAAC,CAAC,CAAC,EAAE,GACrB,CAAC,SAAS,YAAY,GACpB;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAC1C,KAAK,CAAC;AAEd,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,YAAY,IAAI;KAC/C,CAAC,IAAI,MAAM,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACvC,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAc/D;AA2CD;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,YAAY,EAClD,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,CAAC,GACR,WAAW,CAAC,CAAC,CAAC,CAMhB"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * TinyAI Schema System
3
+ * Provides Zod-like type inference without dependencies
4
+ */
5
+ /**
6
+ * Converts a schema definition to a JSON Schema for the AI prompt
7
+ */
8
+ export function schemaToJsonSchema(schema) {
9
+ const properties = {};
10
+ const required = [];
11
+ for (const [key, value] of Object.entries(schema)) {
12
+ properties[key] = valueToJsonSchema(value);
13
+ required.push(key);
14
+ }
15
+ return {
16
+ type: 'object',
17
+ properties,
18
+ required,
19
+ };
20
+ }
21
+ function valueToJsonSchema(value) {
22
+ if (typeof value === 'string') {
23
+ return primitiveToJsonSchema(value);
24
+ }
25
+ if (Array.isArray(value)) {
26
+ return {
27
+ type: 'array',
28
+ items: valueToJsonSchema(value[0]),
29
+ };
30
+ }
31
+ // Object
32
+ const properties = {};
33
+ const required = [];
34
+ for (const [key, v] of Object.entries(value)) {
35
+ properties[key] = valueToJsonSchema(v);
36
+ required.push(key);
37
+ }
38
+ return {
39
+ type: 'object',
40
+ properties,
41
+ required,
42
+ };
43
+ }
44
+ function primitiveToJsonSchema(type) {
45
+ switch (type) {
46
+ case 'string':
47
+ return { type: 'string' };
48
+ case 'number':
49
+ return { type: 'number' };
50
+ case 'boolean':
51
+ return { type: 'boolean' };
52
+ case 'date':
53
+ return { type: 'string', format: 'date-time' };
54
+ }
55
+ }
56
+ /**
57
+ * Parses AI response and converts types (especially dates)
58
+ */
59
+ export function parseResponse(data, schema) {
60
+ if (typeof data !== 'object' || data === null) {
61
+ throw new Error('Invalid response: expected object');
62
+ }
63
+ return parseValue(data, schema);
64
+ }
65
+ function parseValue(value, schema) {
66
+ if (typeof schema === 'string') {
67
+ return parsePrimitive(value, schema);
68
+ }
69
+ if (Array.isArray(schema)) {
70
+ if (!Array.isArray(value)) {
71
+ throw new Error('Expected array');
72
+ }
73
+ return value.map((item) => parseValue(item, schema[0]));
74
+ }
75
+ // Object
76
+ if (typeof value !== 'object' || value === null) {
77
+ throw new Error('Expected object');
78
+ }
79
+ const result = {};
80
+ for (const [key, fieldSchema] of Object.entries(schema)) {
81
+ const fieldValue = value[key];
82
+ result[key] = parseValue(fieldValue, fieldSchema);
83
+ }
84
+ return result;
85
+ }
86
+ function parsePrimitive(value, type) {
87
+ switch (type) {
88
+ case 'date':
89
+ if (typeof value === 'string') {
90
+ return new Date(value);
91
+ }
92
+ throw new Error('Expected date string');
93
+ case 'number':
94
+ if (typeof value === 'number')
95
+ return value;
96
+ if (typeof value === 'string') {
97
+ const num = parseFloat(value);
98
+ if (!isNaN(num))
99
+ return num;
100
+ }
101
+ throw new Error('Expected number');
102
+ case 'boolean':
103
+ if (typeof value === 'boolean')
104
+ return value;
105
+ throw new Error('Expected boolean');
106
+ case 'string':
107
+ if (typeof value === 'string')
108
+ return value;
109
+ throw new Error('Expected string');
110
+ }
111
+ }
112
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Streaming utilities
3
+ * Unified streaming interface across providers
4
+ */
5
+ export type StreamCallback = (chunk: string) => void;
6
+ /**
7
+ * Collects a stream into a single string
8
+ */
9
+ export declare function collectStream(stream: AsyncGenerator<string, void, unknown>): Promise<string>;
10
+ /**
11
+ * Creates a ReadableStream from an async generator
12
+ * Useful for HTTP streaming responses
13
+ */
14
+ export declare function toReadableStream(stream: AsyncGenerator<string, void, unknown>): ReadableStream<Uint8Array>;
15
+ //# sourceMappingURL=streaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../src/core/streaming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAErD;;GAEG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,GAC5C,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,GAC5C,cAAc,CAAC,UAAU,CAAC,CAa5B"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Streaming utilities
3
+ * Unified streaming interface across providers
4
+ */
5
+ /**
6
+ * Collects a stream into a single string
7
+ */
8
+ export async function collectStream(stream) {
9
+ let result = '';
10
+ for await (const chunk of stream) {
11
+ result += chunk;
12
+ }
13
+ return result;
14
+ }
15
+ /**
16
+ * Creates a ReadableStream from an async generator
17
+ * Useful for HTTP streaming responses
18
+ */
19
+ export function toReadableStream(stream) {
20
+ const encoder = new TextEncoder();
21
+ return new ReadableStream({
22
+ async pull(controller) {
23
+ const { done, value } = await stream.next();
24
+ if (done) {
25
+ controller.close();
26
+ }
27
+ else {
28
+ controller.enqueue(encoder.encode(value));
29
+ }
30
+ },
31
+ });
32
+ }
33
+ //# sourceMappingURL=streaming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.js","sourceRoot":"","sources":["../../src/core/streaming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAA6C;IAE7C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAA6C;IAE7C,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAElC,OAAO,IAAI,cAAc,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,UAAU;YACnB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,IAAI,EAAE,CAAC;gBACT,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}