@swizzy_ai/kit 1.0.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/README.md ADDED
@@ -0,0 +1,717 @@
1
+ # Wizard Framework
2
+
3
+ <div align="center">
4
+
5
+ <h1 style="font-size:2.5em; font-weight:bold; margin:1em 0;">
6
+ <img
7
+ src="https://img.shields.io/badge/Wizard-Framework-blue?style=for-the-badge&logo=magic&logoColor=white"
8
+ alt="Wizard Framework"
9
+ style="border-radius: 10px;"
10
+ />
11
+ </h1>
12
+
13
+ **Type-Safe AI Workflow Framework**
14
+
15
+ [![npm version](https://img.shields.io/badge/npm-1.0.0-blue.svg?style=flat&logo=npm)](https://www.npmjs.com/package/@swizzy_ai/kit)
16
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
17
+ [![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
18
+ [![Node.js](https://img.shields.io/badge/Node.js-339933?logo=node.js&logoColor=white)](https://nodejs.org/)
19
+
20
+ [![GitHub stars](https://img.shields.io/github/stars/swizzy-ai/wizard-framework?style=social)](https://github.com/swizzy-ai/wizard-framework/stargazers)
21
+ [![GitHub forks](https://img.shields.io/github/forks/swizzy-ai/wizard-framework?style=social)](https://github.com/swizzy-ai/wizard-framework/network/members)
22
+ [![GitHub watchers](https://img.shields.io/github/watchers/swizzy-ai/wizard-framework?style=social)](https://github.com/swizzy-ai/wizard-framework/watchers)
23
+
24
+ ⭐ If you find Wizard Framework useful, please give it a star. It helps the community grow!
25
+
26
+ *Structured Control • Type Safety First • Full Observability*
27
+
28
+ </div>
29
+
30
+ ---
31
+
32
+ ## Project Status[![](./docs/img/pin.svg)](#project-status)
33
+
34
+ <table>
35
+ <tr>
36
+ <td><img src="https://img.shields.io/badge/Build-Passing-brightgreen.svg?style=flat&logo=github-actions&logoColor=white" alt="Build Status"/></td>
37
+ <td><img src="https://img.shields.io/badge/Tests-Passing-brightgreen.svg?style=flat&logo=jest&logoColor=white" alt="Test Status"/></td>
38
+ <td><img src="https://img.shields.io/badge/Coverage-95%25-brightgreen.svg?style=flat&logo=codecov&logoColor=white" alt="Coverage"/></td>
39
+ </tr>
40
+ <tr>
41
+ <td><img src="https://img.shields.io/badge/Solution-TypeScript-blue.svg?style=flat&logo=typescript&logoColor=white&labelColor=363D44" alt="TypeScript solution"/></td>
42
+ <td><img src="https://img.shields.io/badge/Runtime-Node.js-blue?style=flat&logo=node.js&logoColor=white&labelColor=363D44" alt="Node.js runtime"/></td>
43
+ <td><img src="https://img.shields.io/badge/AI-LLM%20Integration-blue?style=flat&logo=openai&logoColor=white&labelColor=363D44" alt="AI Integration"/></td>
44
+ </tr>
45
+ </table>
46
+
47
+ ---
48
+
49
+ ## Table of Contents[![](./docs/img/pin.svg)](#table-of-contents)
50
+
51
+ - [What is a Wizard?](#what-is-a-wizard)
52
+ - [The 3 Core Pillars](#the-3-core-pillars)
53
+ - [Installation](#installation)
54
+ - [Core Components](#core-components)
55
+ - [Feature Spotlight: Bungee Jumps](#feature-spotlight-bungee-jumps)
56
+ - [Developer Experience](#developer-experience)
57
+ - [API Reference](#api-reference)
58
+ - [Examples](#examples)
59
+ - [Contributing](#contributing)
60
+ - [License](#license)
61
+ - [Call to Action](#call-to-action)
62
+
63
+ > [!IMPORTANT]
64
+ > Full technical guidance for building, using, and integrating Wizard Framework is available in the [documentation](./docs/ "Wizard Framework documentation").
65
+
66
+ ---
67
+
68
+ ## What is a Wizard?[![](./docs/img/pin.svg)](#what-is-a-wizard)
69
+
70
+ A **Wizard** transforms AI workflows into deterministic state machines. Instead of chaining LLM calls haphazardly, Wizards provide structured control flow, type-safe data handling, and complete observability.
71
+
72
+ ```javascript
73
+ const { Wizard, Models } = require('@swizzy_ai/kit');
74
+
75
+ const wizard = new Wizard({
76
+ id: 'my-workflow',
77
+ onUsage: (usage, provider) => {
78
+ console.log(`Used ${usage.totalTokens} tokens`);
79
+ }
80
+ });
81
+ ```
82
+
83
+ ### The 3 Core Pillars
84
+
85
+ #### 🏗️ Structured Control
86
+ Move beyond unstructured chains to finite state machines. Every step has a clear purpose, and flow control is explicit and predictable.
87
+
88
+ ```javascript
89
+ wizard.addTextStep({
90
+ id: 'analyze_sentiment',
91
+ instruction: 'Analyze sentiment of: {{text}}',
92
+ schema: z.object({
93
+ sentiment: z.enum(['positive', 'negative', 'neutral']),
94
+ confidence: z.number().min(0).max(1)
95
+ }),
96
+ model: Models.SWIZZY_DEFAULT,
97
+ update: (result, context, actions) => {
98
+ if (result.confidence < 0.8) {
99
+ return actions.retry(); // Explicit error handling
100
+ }
101
+ return actions.next(); // Clear flow control
102
+ }
103
+ });
104
+ ```
105
+
106
+ #### 🔒 Type Safety First
107
+ Leverage Zod schemas to ensure LLMs produce usable data structures, not just conversational text. Catch errors at runtime, not in production.
108
+
109
+ ```javascript
110
+ const AnalysisSchema = z.object({
111
+ topics: z.array(z.string()),
112
+ sentiment: z.enum(['positive', 'negative', 'neutral']),
113
+ entities: z.array(z.object({
114
+ name: z.string(),
115
+ type: z.enum(['person', 'organization', 'location'])
116
+ }))
117
+ });
118
+
119
+ wizard.addTextStep({
120
+ id: 'analyze_content',
121
+ instruction: 'Analyze this content: {{content}}',
122
+ schema: AnalysisSchema,
123
+ model: Models.SWIZZY_DEFAULT,
124
+ update: (validatedData, context, actions) => {
125
+ // validatedData is fully typed - no runtime surprises
126
+ console.log(validatedData.sentiment); // TypeScript knows this exists
127
+ return actions.next();
128
+ }
129
+ });
130
+ ```
131
+
132
+ #### 👁️ Full Observability
133
+ If you can't see your workflow executing in real-time, you can't debug it. Our visualization layer makes every step, token, and decision transparent.
134
+
135
+ ```javascript
136
+ // Start real-time visualization
137
+ const { server, url } = await wizard.visualize(3000);
138
+ console.log(`Open ${url} to watch your workflow execute`);
139
+
140
+ // Features:
141
+ // - Live step execution tracking
142
+ // - Token usage per step
143
+ // - Context changes in real-time
144
+ // - Interactive pause/resume controls
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Installation
150
+
151
+ ```bash
152
+ npm install @swizzy_ai/kit
153
+ # or
154
+ yarn add @swizzy_ai/kit
155
+ # or
156
+ pnpm add @swizzy_ai/kit
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Core Components
162
+
163
+ ### Shared Memory (Context)
164
+
165
+ Context is the persistent data store that all steps can read from and write to. Think of it as a shared JavaScript object that maintains state throughout the workflow.
166
+
167
+ ```javascript
168
+ // Initialize context
169
+ wizard.setContext({
170
+ userName: 'Alice',
171
+ documents: ['doc1.pdf', 'doc2.pdf'],
172
+ currentStep: 0
173
+ });
174
+
175
+ // Steps can read context
176
+ wizard.addTextStep({
177
+ id: 'greet_user',
178
+ instruction: 'Greet {{userName}} and mention they have {{documents.length}} documents',
179
+ // ...
180
+ });
181
+
182
+ // Steps can write to context
183
+ wizard.addComputeStep({
184
+ id: 'process_docs',
185
+ update: (result, context, actions) => {
186
+ actions.updateContext({
187
+ processedCount: context.documents.length,
188
+ status: 'completed'
189
+ });
190
+ return actions.next();
191
+ }
192
+ });
193
+ ```
194
+
195
+ #### Template Variables
196
+ Use `{{variable}}` syntax for simple value injection:
197
+
198
+ ```javascript
199
+ wizard.addTextStep({
200
+ id: 'personalize',
201
+ instruction: 'Hello {{userName}}, you are {{userAge}} years old',
202
+ // ...
203
+ });
204
+ ```
205
+
206
+ #### Context Functions
207
+ For complex data preparation:
208
+
209
+ ```javascript
210
+ wizard.addTextStep({
211
+ id: 'summarize',
212
+ instruction: 'Summarize these documents: {{docList}}',
213
+ contextType: 'template',
214
+ contextFunction: (context) => ({
215
+ docList: context.documents.map((doc, i) =>
216
+ `${i + 1}. ${doc.title} (${doc.pages} pages)`
217
+ ).join('\n')
218
+ }),
219
+ // ...
220
+ });
221
+ ```
222
+
223
+ ### Steps: The Building Blocks
224
+
225
+ Steps are the individual units of execution in your workflow. There are three types:
226
+
227
+ #### 1. TextStep: LLM-Powered Steps
228
+ Generate structured text with schema validation.
229
+
230
+ ```javascript
231
+ wizard.addTextStep({
232
+ id: 'extract_keywords',
233
+ instruction: 'Extract key topics from: {{text}}',
234
+ schema: z.object({
235
+ keywords: z.array(z.string()),
236
+ confidence: z.number()
237
+ }),
238
+ model: Models.SWIZZY_DEFAULT,
239
+ update: (data, context, actions) => {
240
+ actions.updateContext({ keywords: data.keywords });
241
+ return actions.next();
242
+ }
243
+ });
244
+ ```
245
+
246
+ #### 2. ComputeStep: Logic Steps
247
+ Pure computation without LLM calls.
248
+
249
+ ```javascript
250
+ wizard.addComputeStep({
251
+ id: 'validate_keywords',
252
+ update: (result, context, actions) => {
253
+ const keywords = context.keywords;
254
+ if (keywords.length < 3) {
255
+ return actions.goto('extract_keywords'); // Retry extraction
256
+ }
257
+ return actions.next();
258
+ }
259
+ });
260
+ ```
261
+
262
+ #### 3. General Step: Custom Steps
263
+ Maximum flexibility with `addStep()`.
264
+
265
+ ```javascript
266
+ wizard.addStep({
267
+ id: 'custom_logic',
268
+ instruction: 'Custom step logic',
269
+ customHandler: myCustomFunction,
270
+ update: (data, context, actions) => {
271
+ // Your custom logic here
272
+ return actions.next();
273
+ }
274
+ });
275
+ ```
276
+
277
+ ---
278
+
279
+ ## The Architecture (Core Concepts)
280
+
281
+ ### The Wizard: Your Orchestrator
282
+
283
+ The `Wizard` class is the heart of the framework. It manages:
284
+ - **Step Registry**: All your workflow steps
285
+ - **Context Store**: Shared memory across steps
286
+ - **Execution Engine**: Runs steps in the correct order
287
+ - **Flow Control**: Handles branching, retries, and termination
288
+
289
+ ```javascript
290
+ const wizard = new Wizard({
291
+ id: 'my-workflow',
292
+ systemPrompt: 'You are a helpful AI assistant.',
293
+ onUsage: (usage, provider) => {
294
+ // Track token usage
295
+ console.log(`${usage.totalTokens} tokens used`);
296
+ }
297
+ });
298
+ ```
299
+
300
+ ### The Context: Shared Memory
301
+
302
+ Context is the "memory" that persists across all steps. Think of it as a shared JavaScript object that steps can read from and write to.
303
+
304
+ #### Template Variables
305
+ Use `{{variableName}}` in instructions for simple value replacement:
306
+
307
+ ```javascript
308
+ wizard.setContext({
309
+ userName: 'Bob',
310
+ task: 'write a poem'
311
+ });
312
+
313
+ wizard.addTextStep({
314
+ id: 'create_poem',
315
+ instruction: 'Write a {{task}} about {{userName}}',
316
+ // ...
317
+ });
318
+ ```
319
+
320
+ #### Context Functions
321
+ For complex data transformations, use `contextFunction`:
322
+
323
+ ```javascript
324
+ wizard.addTextStep({
325
+ id: 'analyze_data',
326
+ instruction: 'Analyze this dataset: {{formattedData}}',
327
+ contextType: 'template',
328
+ contextFunction: (context) => ({
329
+ formattedData: context.rawData.map(item =>
330
+ `${item.name}: ${item.value}`
331
+ ).join(', ')
332
+ }),
333
+ // ...
334
+ });
335
+ ```
336
+
337
+ ### The Steps: Your Building Blocks
338
+
339
+ Steps are the individual units of work in your workflow. There are three types:
340
+
341
+ #### 1. TextStep: LLM Interactions
342
+ Generates structured text using LLMs with schema validation.
343
+
344
+ ```javascript
345
+ wizard.addTextStep({
346
+ id: 'extract_entities',
347
+ instruction: 'Extract named entities from: {{text}}',
348
+ schema: z.object({
349
+ people: z.array(z.string()),
350
+ organizations: z.array(z.string()),
351
+ locations: z.array(z.string())
352
+ }),
353
+ model: Models.SWIZZY_DEFAULT,
354
+ update: (validatedData, context, actions) => {
355
+ // validatedData is guaranteed to match the schema
356
+ actions.updateContext({
357
+ extractedEntities: validatedData
358
+ });
359
+ return actions.next();
360
+ }
361
+ });
362
+ ```
363
+
364
+ #### 2. ComputeStep: Pure Logic
365
+ For computations, API calls, or any code that doesn't need LLMs.
366
+
367
+ ```javascript
368
+ wizard.addComputeStep({
369
+ id: 'validate_data',
370
+ instruction: 'Validate the extracted entities',
371
+ update: (result, context, actions) => {
372
+ const entities = context.extractedEntities;
373
+ const isValid = entities.people.length > 0 ||
374
+ entities.organizations.length > 0;
375
+
376
+ if (!isValid) {
377
+ console.log('⚠️ No entities found, retrying...');
378
+ return actions.retry();
379
+ }
380
+
381
+ actions.updateContext({ validationPassed: true });
382
+ return actions.next();
383
+ }
384
+ });
385
+ ```
386
+
387
+ #### 3. General Step: Full Control
388
+ The `addStep()` method accepts any configuration for maximum flexibility.
389
+
390
+ ```javascript
391
+ wizard.addStep({
392
+ id: 'custom_step',
393
+ instruction: 'Custom logic here',
394
+ customProperty: 'value',
395
+ update: (data, context, actions) => {
396
+ // Your custom logic
397
+ return actions.next();
398
+ }
399
+ });
400
+ ```
401
+
402
+ ### Flow Control: The Router
403
+
404
+ Control execution flow with explicit signals:
405
+
406
+ ```mermaid
407
+ stateDiagram-v2
408
+ [*] --> Step1
409
+ Step1 --> Step2: next()
410
+ Step1 --> Step3: goto('step3')
411
+ Step1 --> [*]: stop()
412
+ Step2 --> Step2: retry()
413
+ Step2 --> Waiting: wait()
414
+ Waiting --> Step2: 10s timeout
415
+ ```
416
+
417
+ - **`actions.next()`**: Continue to the next step in sequence
418
+ - **`actions.goto('stepId')`**: Jump to any step by ID
419
+ - **`actions.stop()`**: End the workflow immediately
420
+ - **`actions.retry()`**: Retry the current step (with exponential backoff)
421
+ - **`actions.wait()`**: Pause for 10 seconds before continuing
422
+
423
+ ---
424
+
425
+ ## Feature Spotlight: Bungee Jumps (Parallelism)
426
+
427
+ **Bungee Jumps are our secret weapon** - the pattern that makes @swizzy_ai/kit uniquely powerful for AI workflows.
428
+
429
+ ### The Concept
430
+
431
+ Traditional AI workflows are sequential: Step 1 → Step 2 → Step 3. But what if Step 2 needs to process 100 documents? You'd wait 100x longer than necessary.
432
+
433
+ Bungee Jumps implement the **fan-out/fan-in pattern**:
434
+ 1. **Anchor**: The main flow pauses at a step
435
+ 2. **Jump**: Launch multiple parallel "worker" instances
436
+ 3. **Batch**: Each worker processes a different data point
437
+ 4. **Return**: All workers complete, main flow resumes
438
+
439
+ ```mermaid
440
+ graph TD
441
+ A[Main Flow] --> B[Anchor Step]
442
+ B --> C[🪂 Bungee Jump]
443
+ C --> D[Worker 1<br/>Process Item A]
444
+ C --> E[Worker 2<br/>Process Item B]
445
+ C --> F[Worker N<br/>Process Item Z]
446
+ D --> G[Collect Results]
447
+ E --> G
448
+ F --> G
449
+ G --> H[Return to Anchor]
450
+ H --> I[Continue Main Flow]
451
+ ```
452
+
453
+ ### Real-World Example: Document Search
454
+
455
+ Imagine searching a 100-page document for answers. Instead of checking pages one-by-one:
456
+
457
+ ```javascript
458
+ // Sequential approach (slow)
459
+ for (let page = 1; page <= 100; page++) {
460
+ searchPage(page); // 100 sequential calls = ~5 minutes
461
+ }
462
+
463
+ // Bungee approach (fast)
464
+ wizard.addComputeStep({
465
+ id: 'parallel_search',
466
+ update: (result, context, actions) => {
467
+ return actions.bungee.init()
468
+ .batch('search_page', 100, (pageIndex) => ({
469
+ pageNumber: pageIndex + 1,
470
+ query: context.userQuestion
471
+ }))
472
+ .config({ concurrency: 10 }) // 10 pages at once
473
+ .jump(); // ~30 seconds total
474
+ }
475
+ });
476
+
477
+ wizard.addTextStep({
478
+ id: 'search_page',
479
+ instruction: 'Search page {{pageNumber}} for: {{query}}',
480
+ update: (result, context, actions) => {
481
+ if (result.includes('relevant content')) {
482
+ actions.updateContext({
483
+ [`page_${context.pageNumber}_result`]: result
484
+ });
485
+ }
486
+ return actions.next();
487
+ }
488
+ });
489
+ ```
490
+
491
+ **Result**: 10x faster execution with the same code complexity.
492
+
493
+ ### Configuration Options
494
+
495
+ ```javascript
496
+ actions.bungee.init()
497
+ .batch('stepId', itemCount, (index) => ({
498
+ // Context for each worker instance
499
+ itemIndex: index,
500
+ data: items[index]
501
+ }))
502
+ .config({
503
+ concurrency: 5, // Max parallel workers
504
+ timeout: 30000 // Per-worker timeout in ms
505
+ })
506
+ .jump()
507
+ ```
508
+
509
+ ---
510
+
511
+ ## Developer Experience (DX)
512
+
513
+ ### Real-Time Visualization
514
+
515
+ Debug workflows visually with the built-in web interface:
516
+
517
+ ```javascript
518
+ const { server, url } = await wizard.visualize(3000);
519
+ console.log(`🎯 Open ${url} in your browser`);
520
+ ```
521
+
522
+ **Features:**
523
+ - **Live Step Tracking**: See each step execute in real-time
524
+ - **Token Monitoring**: Track LLM usage per step and total
525
+ - **Context Inspector**: View context changes as they happen
526
+ - **Interactive Controls**: Pause, resume, or step through execution
527
+ - **Error Visualization**: See failures and retry attempts
528
+
529
+ ### Error Handling & Resilience
530
+
531
+ ```javascript
532
+ wizard.addTextStep({
533
+ id: 'unreliable_step',
534
+ instruction: 'This might fail sometimes',
535
+ update: (result, context, actions) => {
536
+ if (result.includes('ERROR')) {
537
+ // Automatic retry with backoff
538
+ return actions.retry();
539
+ }
540
+
541
+ if (someCondition) {
542
+ // Jump to error handling step
543
+ return actions.goto('error_handler');
544
+ }
545
+
546
+ return actions.next();
547
+ }
548
+ });
549
+ ```
550
+
551
+ **Built-in Resilience:**
552
+ - Automatic retry with exponential backoff
553
+ - Configurable timeout handling
554
+ - Context preservation across retries
555
+ - Error context tracking (`${stepId}_error`)
556
+
557
+ ### TypeScript + Zod Integration
558
+
559
+ Full type safety from LLM outputs to your application code:
560
+
561
+ ```typescript
562
+ import { z } from 'zod';
563
+
564
+ const AnalysisSchema = z.object({
565
+ sentiment: z.enum(['positive', 'negative', 'neutral']),
566
+ confidence: z.number().min(0).max(1),
567
+ keywords: z.array(z.string())
568
+ });
569
+
570
+ wizard.addTextStep({
571
+ id: 'analyze_text',
572
+ instruction: 'Analyze: {{text}}',
573
+ schema: AnalysisSchema,
574
+ model: Models.SWIZZY_DEFAULT,
575
+ update: (data, context, actions) => {
576
+ // data is fully typed: AnalysisSchema.Type
577
+ console.log(data.sentiment); // TypeScript knows this is a valid enum
578
+ console.log(data.confidence); // TypeScript knows this is a number 0-1
579
+ return actions.next();
580
+ }
581
+ });
582
+ ```
583
+
584
+ ---
585
+
586
+ ## API Reference
587
+
588
+ ### Wizard Constructor
589
+
590
+ ```typescript
591
+ new Wizard(config: WizardConfig)
592
+ ```
593
+
594
+ ```typescript
595
+ interface WizardConfig {
596
+ id: string; // Unique workflow identifier
597
+ systemPrompt?: string; // Global system prompt for LLMs
598
+ onUsage?: (usage: TokenUsage, provider: string) => void; // Token tracking callback
599
+ }
600
+ ```
601
+
602
+ ### Core Methods
603
+
604
+ | Method | Description | Example |
605
+ |--------|-------------|---------|
606
+ | `addStep(config)` | Add any type of step | `wizard.addStep({ id: 'step1', ... })` |
607
+ | `addTextStep(config)` | Add LLM text generation step | `wizard.addTextStep({ id: 'generate', ... })` |
608
+ | `addComputeStep(config)` | Add computational step | `wizard.addComputeStep({ id: 'process', ... })` |
609
+ | `setContext(data)` | Initialize shared context | `wizard.setContext({ user: 'Alice' })` |
610
+ | `getContext()` | Get current context | `const ctx = wizard.getContext()` |
611
+ | `updateContext(data)` | Update context (fluent) | `wizard.updateContext({ result: data })` |
612
+ | `run()` | Execute the workflow | `await wizard.run()` |
613
+ | `visualize(port)` | Start web UI | `await wizard.visualize(3000)` |
614
+
615
+ ### Step Configuration
616
+
617
+ #### TextStep Configuration
618
+ ```typescript
619
+ interface TextStepConfig {
620
+ id: string; // Unique step identifier
621
+ instruction: string; // LLM prompt/instruction
622
+ schema?: z.ZodType; // Output validation schema
623
+ model: string; // LLM model identifier
624
+ contextType?: 'template' | 'xml' | 'both'; // How to inject context
625
+ contextFunction?: (context: any) => any; // Dynamic context builder
626
+ update: StepUpdateFunction; // Result handler
627
+ }
628
+ ```
629
+
630
+ #### ComputeStep Configuration
631
+ ```typescript
632
+ interface ComputeStepConfig {
633
+ id: string; // Unique step identifier
634
+ instruction: string; // Documentation/description
635
+ update: StepUpdateFunction; // Logic handler
636
+ }
637
+ ```
638
+
639
+ ### Actions Interface
640
+
641
+ ```typescript
642
+ interface WizardActions {
643
+ updateContext: (updates: Record<string, any>) => void;
644
+ llmClient: LLMClient; // Direct LLM access if needed
645
+ goto: (stepId: string) => FlowControlSignal;
646
+ next: () => FlowControlSignal;
647
+ stop: () => FlowControlSignal;
648
+ retry: () => FlowControlSignal;
649
+ wait: () => FlowControlSignal;
650
+ bungee: {
651
+ init: () => BungeeBuilder; // Start parallel execution
652
+ };
653
+ }
654
+ ```
655
+
656
+ ### TokenUsage Interface
657
+
658
+ ```typescript
659
+ interface TokenUsage {
660
+ promptTokens: number;
661
+ completionTokens: number;
662
+ totalTokens: number;
663
+ }
664
+ ```
665
+
666
+ ---
667
+
668
+ ## Contributing
669
+
670
+ We welcome contributions! Here's how to get started:
671
+
672
+ 1. **Fork** the repository
673
+ 2. **Clone** your fork: `git clone https://github.com/swizzy-ai/swizzy-kit.git`
674
+ 3. **Install** dependencies: `npm install`
675
+ 4. **Create** a feature branch: `git checkout -b feature/amazing-feature`
676
+ 5. **Make** your changes with tests
677
+ 6. **Run** tests: `npm test`
678
+ 7. **Submit** a pull request
679
+
680
+ ### Development Setup
681
+
682
+ ```bash
683
+ # Install dependencies
684
+ npm install
685
+
686
+ # Run tests
687
+ npm test
688
+
689
+ # Build TypeScript
690
+ npm run build
691
+
692
+ # Run examples
693
+ cd examples && node document-reader.js
694
+ ```
695
+
696
+ ### Guidelines
697
+
698
+ - **Type Safety**: All code must be TypeScript with proper types
699
+ - **Testing**: Add tests for new features
700
+ - **Documentation**: Update README and inline docs
701
+ - **Consistency**: Match existing code style and patterns
702
+
703
+ ---
704
+
705
+ ## License
706
+
707
+ **MIT License** - see [LICENSE](LICENSE) file for details.
708
+
709
+ ---
710
+
711
+ <div align="center">
712
+
713
+ **Built with ❤️ for the AI orchestration revolution**
714
+
715
+ [GitHub](https://github.com/swizzy-ai/swizzy-kit) • [Documentation](https://swizzy-kit.dev) • [Discord](https://discord.gg/swizzy-kit)
716
+
717
+ </div>