societyai 0.0.1

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 (114) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/LICENSE +21 -0
  3. package/README.md +879 -0
  4. package/dist/builder.d.ts +181 -0
  5. package/dist/builder.d.ts.map +1 -0
  6. package/dist/builder.js +667 -0
  7. package/dist/builder.js.map +1 -0
  8. package/dist/config.d.ts +43 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +11 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/context.d.ts +107 -0
  13. package/dist/context.d.ts.map +1 -0
  14. package/dist/context.js +319 -0
  15. package/dist/context.js.map +1 -0
  16. package/dist/errors.d.ts +31 -0
  17. package/dist/errors.d.ts.map +1 -0
  18. package/dist/errors.js +85 -0
  19. package/dist/errors.js.map +1 -0
  20. package/dist/events.d.ts +219 -0
  21. package/dist/events.d.ts.map +1 -0
  22. package/dist/events.js +395 -0
  23. package/dist/events.js.map +1 -0
  24. package/dist/graph.d.ts +104 -0
  25. package/dist/graph.d.ts.map +1 -0
  26. package/dist/graph.js +366 -0
  27. package/dist/graph.js.map +1 -0
  28. package/dist/index.d.ts +28 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +113 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/logger.d.ts +13 -0
  33. package/dist/logger.d.ts.map +1 -0
  34. package/dist/logger.js +78 -0
  35. package/dist/logger.js.map +1 -0
  36. package/dist/memory.d.ts +146 -0
  37. package/dist/memory.d.ts.map +1 -0
  38. package/dist/memory.js +353 -0
  39. package/dist/memory.js.map +1 -0
  40. package/dist/metrics.d.ts +143 -0
  41. package/dist/metrics.d.ts.map +1 -0
  42. package/dist/metrics.js +271 -0
  43. package/dist/metrics.js.map +1 -0
  44. package/dist/middleware.d.ts +147 -0
  45. package/dist/middleware.d.ts.map +1 -0
  46. package/dist/middleware.js +484 -0
  47. package/dist/middleware.js.map +1 -0
  48. package/dist/models.d.ts +32 -0
  49. package/dist/models.d.ts.map +1 -0
  50. package/dist/models.js +211 -0
  51. package/dist/models.js.map +1 -0
  52. package/dist/patterns.d.ts +6 -0
  53. package/dist/patterns.d.ts.map +1 -0
  54. package/dist/patterns.js +68 -0
  55. package/dist/patterns.js.map +1 -0
  56. package/dist/pipeline.d.ts +84 -0
  57. package/dist/pipeline.d.ts.map +1 -0
  58. package/dist/pipeline.js +569 -0
  59. package/dist/pipeline.js.map +1 -0
  60. package/dist/retry.d.ts +5 -0
  61. package/dist/retry.d.ts.map +1 -0
  62. package/dist/retry.js +70 -0
  63. package/dist/retry.js.map +1 -0
  64. package/dist/society.d.ts +94 -0
  65. package/dist/society.d.ts.map +1 -0
  66. package/dist/society.js +721 -0
  67. package/dist/society.js.map +1 -0
  68. package/dist/strategies.d.ts +55 -0
  69. package/dist/strategies.d.ts.map +1 -0
  70. package/dist/strategies.js +678 -0
  71. package/dist/strategies.js.map +1 -0
  72. package/dist/tools.d.ts +88 -0
  73. package/dist/tools.d.ts.map +1 -0
  74. package/dist/tools.js +366 -0
  75. package/dist/tools.js.map +1 -0
  76. package/dist/types.d.ts +213 -0
  77. package/dist/types.d.ts.map +1 -0
  78. package/dist/types.js +19 -0
  79. package/dist/types.js.map +1 -0
  80. package/dist/validation.d.ts +64 -0
  81. package/dist/validation.d.ts.map +1 -0
  82. package/dist/validation.js +334 -0
  83. package/dist/validation.js.map +1 -0
  84. package/dist/worker-pool.d.ts +17 -0
  85. package/dist/worker-pool.d.ts.map +1 -0
  86. package/dist/worker-pool.js +80 -0
  87. package/dist/worker-pool.js.map +1 -0
  88. package/docs/README.md +468 -0
  89. package/docs/advanced.md +616 -0
  90. package/docs/aggregation-strategies.md +926 -0
  91. package/docs/api-reference.md +771 -0
  92. package/docs/architecture.md +648 -0
  93. package/docs/context-system.md +642 -0
  94. package/docs/event-system.md +1047 -0
  95. package/docs/examples.md +576 -0
  96. package/docs/getting-started.md +564 -0
  97. package/docs/graph-execution.md +389 -0
  98. package/docs/memory-system.md +497 -0
  99. package/docs/metrics-observability.md +560 -0
  100. package/docs/middleware-system.md +1038 -0
  101. package/docs/migration.md +296 -0
  102. package/docs/pipeline-patterns.md +761 -0
  103. package/docs/structured-output.md +612 -0
  104. package/docs/tool-calling.md +491 -0
  105. package/docs/workflows.md +740 -0
  106. package/examples/README.md +234 -0
  107. package/examples/advanced-patterns.ts +115 -0
  108. package/examples/complete-integration.ts +327 -0
  109. package/examples/graph-workflow.ts +161 -0
  110. package/examples/memory-system.ts +155 -0
  111. package/examples/metrics-tracking.ts +243 -0
  112. package/examples/structured-output.ts +231 -0
  113. package/examples/tool-calling.ts +163 -0
  114. package/package.json +94 -0
@@ -0,0 +1,612 @@
1
+ # Structured Output Validation
2
+
3
+ The Structured Output Validation system ensures AI-generated outputs conform to expected JSON schemas with automatic validation, retry logic, and error feedback.
4
+
5
+ ## Overview
6
+
7
+ The Structured Output Validation provides:
8
+
9
+ - **JSON Schema Validation**: Industry-standard schema validation
10
+ - **Automatic Retry**: Re-prompt agent with error feedback
11
+ - **Error Extraction**: Detailed validation error messages
12
+ - **Complex Schemas**: Support for nested objects, arrays, patterns, enums
13
+ - **Markdown Extraction**: Extract JSON from markdown code blocks
14
+ - **Type Constraints**: Validate types, ranges, lengths, patterns
15
+ - **Helper Functions**: Quick schema creation and validation
16
+
17
+ ## Core Components
18
+
19
+ ### StructuredOutputValidator
20
+
21
+ Main validation class:
22
+
23
+ ```typescript
24
+ import { StructuredOutputValidator } from 'societyai';
25
+
26
+ const schema = {
27
+ type: 'object',
28
+ properties: {
29
+ name: { type: 'string' },
30
+ age: { type: 'number', minimum: 0, maximum: 150 },
31
+ email: { type: 'string', format: 'email' },
32
+ },
33
+ required: ['name', 'age'],
34
+ };
35
+
36
+ const validator = new StructuredOutputValidator(schema);
37
+
38
+ // Validate JSON string
39
+ const result = validator.validate('{"name": "Alice", "age": 30}');
40
+
41
+ if (result.valid) {
42
+ console.log('Valid data:', result.data);
43
+ } else {
44
+ console.error('Validation errors:', result.errors);
45
+ }
46
+ ```
47
+
48
+ ### ValidationResult
49
+
50
+ Result of validation:
51
+
52
+ ```typescript
53
+ interface ValidationResult {
54
+ valid: boolean; // Is valid?
55
+ data?: unknown; // Parsed data if valid
56
+ errors?: ValidationError[]; // Errors if invalid
57
+ errorMessage?: string; // Formatted error message
58
+ }
59
+
60
+ interface ValidationError {
61
+ path: string; // JSON path to error
62
+ message: string; // Error description
63
+ expected?: string; // Expected value/type
64
+ actual?: unknown; // Actual value
65
+ }
66
+ ```
67
+
68
+ ## JSON Schema Support
69
+
70
+ ### Basic Types
71
+
72
+ ```typescript
73
+ const schema = {
74
+ type: 'object',
75
+ properties: {
76
+ // String
77
+ name: { type: 'string' },
78
+
79
+ // Number
80
+ age: { type: 'number' },
81
+
82
+ // Integer
83
+ count: { type: 'integer' },
84
+
85
+ // Boolean
86
+ active: { type: 'boolean' },
87
+
88
+ // Null
89
+ deleted: { type: 'null' },
90
+ },
91
+ };
92
+ ```
93
+
94
+ ### Required Fields
95
+
96
+ ```typescript
97
+ const schema = {
98
+ type: 'object',
99
+ properties: {
100
+ username: { type: 'string' },
101
+ email: { type: 'string' },
102
+ },
103
+ required: ['username', 'email'], // Both required
104
+ };
105
+
106
+ // This will fail
107
+ validator.validate('{"username": "alice"}');
108
+ // Error: Missing required property 'email'
109
+ ```
110
+
111
+ ### String Constraints
112
+
113
+ ```typescript
114
+ const schema = {
115
+ type: 'object',
116
+ properties: {
117
+ username: {
118
+ type: 'string',
119
+ minLength: 3,
120
+ maxLength: 20,
121
+ pattern: '^[a-zA-Z0-9_]+$', // Alphanumeric + underscore
122
+ },
123
+ email: {
124
+ type: 'string',
125
+ format: 'email',
126
+ },
127
+ status: {
128
+ type: 'string',
129
+ enum: ['active', 'inactive', 'pending'],
130
+ },
131
+ },
132
+ };
133
+ ```
134
+
135
+ ### Number Constraints
136
+
137
+ ```typescript
138
+ const schema = {
139
+ type: 'object',
140
+ properties: {
141
+ age: {
142
+ type: 'number',
143
+ minimum: 0,
144
+ maximum: 150,
145
+ },
146
+ rating: {
147
+ type: 'number',
148
+ minimum: 1,
149
+ maximum: 5,
150
+ multipleOf: 0.5, // 1, 1.5, 2, 2.5, ...
151
+ },
152
+ price: {
153
+ type: 'number',
154
+ exclusiveMinimum: 0, // Greater than 0, not equal
155
+ },
156
+ },
157
+ };
158
+ ```
159
+
160
+ ### Arrays
161
+
162
+ ```typescript
163
+ const schema = {
164
+ type: 'object',
165
+ properties: {
166
+ tags: {
167
+ type: 'array',
168
+ items: { type: 'string' },
169
+ minItems: 1,
170
+ maxItems: 10,
171
+ uniqueItems: true,
172
+ },
173
+ coordinates: {
174
+ type: 'array',
175
+ items: { type: 'number' },
176
+ minItems: 2,
177
+ maxItems: 2, // Exactly 2 items
178
+ },
179
+ },
180
+ };
181
+
182
+ // Valid
183
+ validator.validate('{"tags": ["ai", "ml"], "coordinates": [10.5, 20.3]}');
184
+ ```
185
+
186
+ ### Nested Objects
187
+
188
+ ```typescript
189
+ const schema = {
190
+ type: 'object',
191
+ properties: {
192
+ user: {
193
+ type: 'object',
194
+ properties: {
195
+ name: { type: 'string' },
196
+ address: {
197
+ type: 'object',
198
+ properties: {
199
+ street: { type: 'string' },
200
+ city: { type: 'string' },
201
+ zip: { type: 'string', pattern: '^\\d{5}$' },
202
+ },
203
+ required: ['city'],
204
+ },
205
+ },
206
+ required: ['name'],
207
+ },
208
+ },
209
+ };
210
+ ```
211
+
212
+ ### Enums
213
+
214
+ ```typescript
215
+ const schema = {
216
+ type: 'object',
217
+ properties: {
218
+ status: {
219
+ type: 'string',
220
+ enum: ['draft', 'published', 'archived'],
221
+ },
222
+ priority: {
223
+ type: 'number',
224
+ enum: [1, 2, 3],
225
+ },
226
+ },
227
+ };
228
+ ```
229
+
230
+ ## Automatic Retry with Error Feedback
231
+
232
+ The `validateAndRetry` method automatically re-prompts the agent when validation fails:
233
+
234
+ ```typescript
235
+ import { StructuredOutputValidator, StandardModelBase } from 'societyai';
236
+
237
+ const schema = {
238
+ type: 'object',
239
+ properties: {
240
+ name: { type: 'string' },
241
+ age: { type: 'number' },
242
+ },
243
+ required: ['name', 'age'],
244
+ };
245
+
246
+ const validator = new StructuredOutputValidator(schema);
247
+
248
+ class JSONGeneratorModel extends StandardModelBase {
249
+ constructor() {
250
+ super({ name: 'json-gen' }, async (prompt: unknown) => {
251
+ // AI generates JSON (might be invalid initially)
252
+ return '{"name": "Alice", "age": "30"}'; // age is string, should be number
253
+ });
254
+ }
255
+ }
256
+
257
+ const model = new JSONGeneratorModel();
258
+
259
+ // Validates and retries up to 3 times
260
+ const result = await validator.validateAndRetry(
261
+ async (previousError?: string) => {
262
+ const prompt = previousError
263
+ ? `Previous attempt had errors: ${previousError}\n\nPlease fix and try again.`
264
+ : 'Generate user JSON';
265
+
266
+ return await model.process(prompt);
267
+ },
268
+ 3 // Max attempts
269
+ );
270
+
271
+ if (result.valid) {
272
+ console.log('Valid data:', result.data);
273
+ } else {
274
+ console.error('Failed after 3 attempts:', result.errorMessage);
275
+ }
276
+ ```
277
+
278
+ ## Markdown Code Block Extraction
279
+
280
+ Automatically extract JSON from markdown:
281
+
282
+ ```typescript
283
+ const validator = new StructuredOutputValidator(schema);
284
+
285
+ const markdown = `
286
+ Here's the user data:
287
+
288
+ \`\`\`json
289
+ {
290
+ "name": "Alice",
291
+ "age": 30
292
+ }
293
+ \`\`\`
294
+ `;
295
+
296
+ const result = validator.validate(markdown);
297
+ // Automatically extracts JSON from code block
298
+ console.log(result.data); // { name: "Alice", age: 30 }
299
+ ```
300
+
301
+ ## Helper Functions
302
+
303
+ ### createSchema
304
+
305
+ Quick schema creation:
306
+
307
+ ```typescript
308
+ import { createSchema } from 'societyai';
309
+
310
+ const schema = createSchema({
311
+ type: 'object',
312
+ properties: {
313
+ title: { type: 'string' },
314
+ count: { type: 'number' },
315
+ },
316
+ required: ['title'],
317
+ });
318
+ ```
319
+
320
+ ### validateJSON
321
+
322
+ Direct validation without creating a validator:
323
+
324
+ ```typescript
325
+ import { validateJSON } from 'societyai';
326
+
327
+ const result = validateJSON('{"name": "Alice"}', {
328
+ type: 'object',
329
+ properties: {
330
+ name: { type: 'string' },
331
+ },
332
+ required: ['name'],
333
+ });
334
+ ```
335
+
336
+ ## Complete Example
337
+
338
+ ```typescript
339
+ import {
340
+ StructuredOutputValidator,
341
+ StructuredOutputBuilder,
342
+ StandardModelBase,
343
+ } from 'societyai';
344
+
345
+ // Define user schema
346
+ const userSchema = {
347
+ type: 'object',
348
+ properties: {
349
+ username: {
350
+ type: 'string',
351
+ minLength: 3,
352
+ maxLength: 20,
353
+ pattern: '^[a-zA-Z0-9_]+$',
354
+ },
355
+ email: {
356
+ type: 'string',
357
+ format: 'email',
358
+ },
359
+ age: {
360
+ type: 'number',
361
+ minimum: 13,
362
+ maximum: 120,
363
+ },
364
+ interests: {
365
+ type: 'array',
366
+ items: { type: 'string' },
367
+ minItems: 1,
368
+ maxItems: 10,
369
+ },
370
+ },
371
+ required: ['username', 'email'],
372
+ };
373
+
374
+ // Create validator with builder
375
+ const validator = StructuredOutputBuilder.create()
376
+ .withSchema(userSchema)
377
+ .withMaxRetries(3)
378
+ .withStrictMode(true)
379
+ .build();
380
+
381
+ // AI model
382
+ class UserGenerator extends StandardModelBase {
383
+ private attempts = 0;
384
+
385
+ constructor() {
386
+ super({ name: 'user-gen' }, async (prompt: unknown) => {
387
+ this.attempts++;
388
+
389
+ if (this.attempts === 1) {
390
+ // First attempt: invalid (age is string)
391
+ return '{"username": "alice_123", "email": "alice@example.com", "age": "25"}';
392
+ } else {
393
+ // Second attempt: valid (after feedback)
394
+ return '{"username": "alice_123", "email": "alice@example.com", "age": 25, "interests": ["AI", "coding"]}';
395
+ }
396
+ });
397
+ }
398
+ }
399
+
400
+ const model = new UserGenerator();
401
+
402
+ // Validate with automatic retry
403
+ const result = await validator.validateAndRetry(async (previousError?: string) => {
404
+ const prompt = previousError
405
+ ? `Previous JSON was invalid:\n${previousError}\n\nPlease fix it.`
406
+ : 'Generate a user JSON object';
407
+
408
+ return await model.process(prompt);
409
+ }, 3);
410
+
411
+ if (result.valid) {
412
+ console.log('Valid user:', result.data);
413
+ // { username: "alice_123", email: "alice@example.com", age: 25, interests: ["AI", "coding"] }
414
+ } else {
415
+ console.error('Validation failed:', result.errorMessage);
416
+ }
417
+ ```
418
+
419
+ ## Error Messages
420
+
421
+ Detailed error messages help debug validation failures:
422
+
423
+ ```typescript
424
+ const result = validator.validate('{"name": "A", "age": -5}');
425
+
426
+ if (!result.valid) {
427
+ result.errors?.forEach((error) => {
428
+ console.log(`Path: ${error.path}`);
429
+ console.log(`Message: ${error.message}`);
430
+ console.log(`Expected: ${error.expected}`);
431
+ console.log(`Actual: ${error.actual}`);
432
+ });
433
+ }
434
+
435
+ // Output:
436
+ // Path: /name
437
+ // Message: String is too short (minimum length: 3)
438
+ // Expected: minLength: 3
439
+ // Actual: "A"
440
+ //
441
+ // Path: /age
442
+ // Message: Number is below minimum
443
+ // Expected: minimum: 0
444
+ // Actual: -5
445
+ ```
446
+
447
+ ## Integration with Agents
448
+
449
+ Create agents that always return valid JSON:
450
+
451
+ ```typescript
452
+ class ValidatedAgent extends StandardModelBase {
453
+ constructor(
454
+ private validator: StructuredOutputValidator,
455
+ name: string
456
+ ) {
457
+ super({ name }, async (prompt: unknown) => {
458
+ // AI generates JSON
459
+ return this.generateJSON(prompt);
460
+ });
461
+ }
462
+
463
+ async process(prompt: unknown): Promise<string> {
464
+ // Validate and retry
465
+ const result = await this.validator.validateAndRetry(async (previousError?: string) => {
466
+ const enhancedPrompt = previousError
467
+ ? `${prompt}\n\nPrevious attempt had errors: ${previousError}`
468
+ : prompt;
469
+
470
+ return await super.process(enhancedPrompt);
471
+ }, 3);
472
+
473
+ if (!result.valid) {
474
+ throw new Error(`Failed to generate valid JSON: ${result.errorMessage}`);
475
+ }
476
+
477
+ return JSON.stringify(result.data);
478
+ }
479
+
480
+ private generateJSON(prompt: unknown): string {
481
+ // Implementation
482
+ return '{}';
483
+ }
484
+ }
485
+ ```
486
+
487
+ ## Best Practices
488
+
489
+ 1. **Clear Schemas**: Define precise schemas with all constraints
490
+ 2. **Required Fields**: Always specify which fields are required
491
+ 3. **Provide Examples**: Include example outputs in prompts
492
+ 4. **Limit Retries**: Set reasonable max retries (2-3)
493
+ 5. **Detailed Errors**: Use error feedback to help AI self-correct
494
+ 6. **Test Schemas**: Validate your schemas with known good/bad data
495
+ 7. **Version Schemas**: Track schema changes for compatibility
496
+ 8. **Document Formats**: Provide format examples for complex types
497
+
498
+ ## Common Patterns
499
+
500
+ ### API Response Validation
501
+
502
+ ```typescript
503
+ const apiResponseSchema = {
504
+ type: 'object',
505
+ properties: {
506
+ status: {
507
+ type: 'string',
508
+ enum: ['success', 'error'],
509
+ },
510
+ data: {
511
+ type: 'object',
512
+ },
513
+ message: {
514
+ type: 'string',
515
+ },
516
+ timestamp: {
517
+ type: 'string',
518
+ format: 'date-time',
519
+ },
520
+ },
521
+ required: ['status'],
522
+ };
523
+ ```
524
+
525
+ ### Form Validation
526
+
527
+ ```typescript
528
+ const formSchema = {
529
+ type: 'object',
530
+ properties: {
531
+ firstName: {
532
+ type: 'string',
533
+ minLength: 1,
534
+ },
535
+ lastName: {
536
+ type: 'string',
537
+ minLength: 1,
538
+ },
539
+ email: {
540
+ type: 'string',
541
+ format: 'email',
542
+ },
543
+ phone: {
544
+ type: 'string',
545
+ pattern: '^\\+?[0-9]{10,15}$',
546
+ },
547
+ acceptTerms: {
548
+ type: 'boolean',
549
+ const: true,
550
+ },
551
+ },
552
+ required: ['firstName', 'lastName', 'email', 'acceptTerms'],
553
+ };
554
+ ```
555
+
556
+ ### Analysis Results
557
+
558
+ ```typescript
559
+ const analysisSchema = {
560
+ type: 'object',
561
+ properties: {
562
+ summary: {
563
+ type: 'string',
564
+ minLength: 50,
565
+ },
566
+ sentiment: {
567
+ type: 'string',
568
+ enum: ['positive', 'negative', 'neutral'],
569
+ },
570
+ confidence: {
571
+ type: 'number',
572
+ minimum: 0,
573
+ maximum: 1,
574
+ },
575
+ keywords: {
576
+ type: 'array',
577
+ items: { type: 'string' },
578
+ minItems: 1,
579
+ },
580
+ },
581
+ required: ['summary', 'sentiment', 'confidence'],
582
+ };
583
+ ```
584
+
585
+ ## Integration with Graph
586
+
587
+ Use validated outputs in workflows:
588
+
589
+ ```typescript
590
+ const validator = new StructuredOutputValidator(schema);
591
+
592
+ const agent = AgentBuilder.create()
593
+ .withId('json-agent')
594
+ .withRole(role)
595
+ .withModel(new ValidatedModel(validator))
596
+ .build();
597
+
598
+ const graph = GraphBuilder.create()
599
+ .addNode('start', NodeType.START)
600
+ .addNode('generate', NodeType.AGENT, { agentId: 'json-agent' })
601
+ .addNode('end', NodeType.END)
602
+ .addEdge('start', 'generate')
603
+ .addEdge('generate', 'end')
604
+ .build();
605
+ ```
606
+
607
+ ## Next Steps
608
+
609
+ - See [Memory System](./memory-system.md) for context management
610
+ - See [Tool Calling](./tool-calling.md) for external interactions
611
+ - See [Metrics](./metrics-observability.md) for tracking performance
612
+ - See [Examples](./examples.md) for complete implementations