digital-workers 2.1.1 → 2.3.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 (197) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +136 -180
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +34 -21
  5. package/dist/actions.js.map +1 -1
  6. package/dist/agent-comms.d.ts +438 -0
  7. package/dist/agent-comms.d.ts.map +1 -0
  8. package/dist/agent-comms.js +677 -0
  9. package/dist/agent-comms.js.map +1 -0
  10. package/dist/approve.d.ts +40 -8
  11. package/dist/approve.d.ts.map +1 -1
  12. package/dist/approve.js +86 -20
  13. package/dist/approve.js.map +1 -1
  14. package/dist/ask.d.ts +38 -7
  15. package/dist/ask.d.ts.map +1 -1
  16. package/dist/ask.js +85 -25
  17. package/dist/ask.js.map +1 -1
  18. package/dist/browse.d.ts +223 -0
  19. package/dist/browse.d.ts.map +1 -0
  20. package/dist/browse.js +392 -0
  21. package/dist/browse.js.map +1 -0
  22. package/dist/capability-tiers.d.ts +230 -0
  23. package/dist/capability-tiers.d.ts.map +1 -0
  24. package/dist/capability-tiers.js +388 -0
  25. package/dist/capability-tiers.js.map +1 -0
  26. package/dist/cascade-context.d.ts +523 -0
  27. package/dist/cascade-context.d.ts.map +1 -0
  28. package/dist/cascade-context.js +494 -0
  29. package/dist/cascade-context.js.map +1 -0
  30. package/dist/client.d.ts +162 -0
  31. package/dist/client.d.ts.map +1 -0
  32. package/dist/client.js +64 -0
  33. package/dist/client.js.map +1 -0
  34. package/dist/decide.d.ts +42 -6
  35. package/dist/decide.d.ts.map +1 -1
  36. package/dist/decide.js +54 -11
  37. package/dist/decide.js.map +1 -1
  38. package/dist/do.d.ts +36 -7
  39. package/dist/do.d.ts.map +1 -1
  40. package/dist/do.js +82 -39
  41. package/dist/do.js.map +1 -1
  42. package/dist/error-escalation.d.ts +416 -0
  43. package/dist/error-escalation.d.ts.map +1 -0
  44. package/dist/error-escalation.js +656 -0
  45. package/dist/error-escalation.js.map +1 -0
  46. package/dist/generate.d.ts +48 -7
  47. package/dist/generate.d.ts.map +1 -1
  48. package/dist/generate.js +49 -8
  49. package/dist/generate.js.map +1 -1
  50. package/dist/goals.d.ts +10 -9
  51. package/dist/goals.d.ts.map +1 -1
  52. package/dist/goals.js +30 -24
  53. package/dist/goals.js.map +1 -1
  54. package/dist/image.d.ts +189 -0
  55. package/dist/image.d.ts.map +1 -0
  56. package/dist/image.js +528 -0
  57. package/dist/image.js.map +1 -0
  58. package/dist/index.d.ts +59 -2
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +92 -2
  61. package/dist/index.js.map +1 -1
  62. package/dist/is.d.ts +45 -10
  63. package/dist/is.d.ts.map +1 -1
  64. package/dist/is.js +56 -21
  65. package/dist/is.js.map +1 -1
  66. package/dist/kpis.d.ts +24 -15
  67. package/dist/kpis.d.ts.map +1 -1
  68. package/dist/kpis.js +16 -14
  69. package/dist/kpis.js.map +1 -1
  70. package/dist/load-balancing.d.ts +395 -0
  71. package/dist/load-balancing.d.ts.map +1 -0
  72. package/dist/load-balancing.js +991 -0
  73. package/dist/load-balancing.js.map +1 -0
  74. package/dist/logger.d.ts +76 -0
  75. package/dist/logger.d.ts.map +1 -0
  76. package/dist/logger.js +39 -0
  77. package/dist/logger.js.map +1 -0
  78. package/dist/notify.d.ts +38 -9
  79. package/dist/notify.d.ts.map +1 -1
  80. package/dist/notify.js +72 -17
  81. package/dist/notify.js.map +1 -1
  82. package/dist/role.d.ts +5 -4
  83. package/dist/role.d.ts.map +1 -1
  84. package/dist/role.js +13 -10
  85. package/dist/role.js.map +1 -1
  86. package/dist/runtime.d.ts +310 -0
  87. package/dist/runtime.d.ts.map +1 -0
  88. package/dist/runtime.js +510 -0
  89. package/dist/runtime.js.map +1 -0
  90. package/dist/team.d.ts +11 -6
  91. package/dist/team.d.ts.map +1 -1
  92. package/dist/team.js +22 -15
  93. package/dist/team.js.map +1 -1
  94. package/dist/transports/email.d.ts +318 -0
  95. package/dist/transports/email.d.ts.map +1 -0
  96. package/dist/transports/email.js +779 -0
  97. package/dist/transports/email.js.map +1 -0
  98. package/dist/transports/slack.d.ts +515 -0
  99. package/dist/transports/slack.d.ts.map +1 -0
  100. package/dist/transports/slack.js +844 -0
  101. package/dist/transports/slack.js.map +1 -0
  102. package/dist/transports.d.ts.map +1 -1
  103. package/dist/transports.js +44 -25
  104. package/dist/transports.js.map +1 -1
  105. package/dist/types.d.ts +149 -19
  106. package/dist/types.d.ts.map +1 -1
  107. package/dist/types.js +6 -0
  108. package/dist/types.js.map +1 -1
  109. package/dist/utils/id.d.ts +19 -0
  110. package/dist/utils/id.d.ts.map +1 -0
  111. package/dist/utils/id.js +21 -0
  112. package/dist/utils/id.js.map +1 -0
  113. package/dist/video.d.ts +203 -0
  114. package/dist/video.d.ts.map +1 -0
  115. package/dist/video.js +528 -0
  116. package/dist/video.js.map +1 -0
  117. package/dist/worker.d.ts +343 -0
  118. package/dist/worker.d.ts.map +1 -0
  119. package/dist/worker.js +698 -0
  120. package/dist/worker.js.map +1 -0
  121. package/package.json +24 -5
  122. package/src/actions.ts +48 -38
  123. package/src/agent-comms.ts +1200 -0
  124. package/src/approve.ts +91 -20
  125. package/src/ask.ts +99 -25
  126. package/src/browse.ts +627 -0
  127. package/src/capability-tiers.ts +545 -0
  128. package/src/cascade-context.ts +648 -0
  129. package/src/client.ts +221 -0
  130. package/src/decide.ts +81 -35
  131. package/src/do.ts +98 -52
  132. package/src/error-escalation.ts +1123 -0
  133. package/src/generate.ts +52 -18
  134. package/src/goals.ts +36 -27
  135. package/src/image.ts +816 -0
  136. package/src/index.ts +410 -2
  137. package/src/is.ts +59 -25
  138. package/src/kpis.ts +41 -36
  139. package/src/load-balancing.ts +1467 -0
  140. package/src/logger.ts +93 -0
  141. package/src/notify.ts +78 -17
  142. package/src/role.ts +30 -20
  143. package/src/runtime.ts +796 -0
  144. package/src/team.ts +24 -19
  145. package/src/transports/email.ts +1160 -0
  146. package/src/transports/slack.ts +1320 -0
  147. package/src/transports.ts +58 -43
  148. package/src/types.ts +182 -46
  149. package/src/utils/id.ts +21 -0
  150. package/src/video.ts +906 -0
  151. package/src/worker.ts +1007 -0
  152. package/test/agent-comms.test.ts +1397 -0
  153. package/test/approve.test.ts +305 -0
  154. package/test/ask.test.ts +274 -0
  155. package/test/browse.test.ts +361 -0
  156. package/test/capability-tiers.test.ts +631 -0
  157. package/test/cascade-context.test.ts +692 -0
  158. package/test/decide.test.ts +252 -0
  159. package/test/do.test.ts +144 -0
  160. package/test/error-escalation.test.ts +1205 -0
  161. package/test/error-logging.test.ts +357 -0
  162. package/test/generate.test.ts +319 -0
  163. package/test/image.test.ts +398 -0
  164. package/test/is.test.ts +287 -0
  165. package/test/load-balancing-safety.test.ts +404 -0
  166. package/test/load-balancing-thread-safety.test.ts +464 -0
  167. package/test/load-balancing.test.ts +1145 -0
  168. package/test/notify.test.ts +434 -0
  169. package/test/primitives.test.ts +320 -0
  170. package/test/runtime-integration.test.ts +892 -0
  171. package/test/transports/crypto.test.ts +230 -0
  172. package/test/transports/email.test.ts +866 -0
  173. package/test/transports/id-generation.test.ts +91 -0
  174. package/test/transports/slack.test.ts +760 -0
  175. package/test/type-safety.test.ts +834 -0
  176. package/test/types.test.ts +95 -2
  177. package/test/video.test.ts +530 -0
  178. package/test/worker.test.ts +1433 -0
  179. package/tsconfig.json +4 -1
  180. package/vitest.config.ts +42 -0
  181. package/wrangler.jsonc +36 -0
  182. package/.turbo/turbo-build.log +0 -5
  183. package/src/actions.js +0 -436
  184. package/src/approve.js +0 -234
  185. package/src/ask.js +0 -226
  186. package/src/decide.js +0 -244
  187. package/src/do.js +0 -227
  188. package/src/generate.js +0 -298
  189. package/src/goals.js +0 -205
  190. package/src/index.js +0 -68
  191. package/src/is.js +0 -317
  192. package/src/kpis.js +0 -270
  193. package/src/notify.js +0 -219
  194. package/src/role.js +0 -110
  195. package/src/team.js +0 -130
  196. package/src/transports.js +0 -357
  197. package/src/types.js +0 -71
package/src/index.ts CHANGED
@@ -6,7 +6,29 @@
6
6
  * defines a unified Worker interface that enables workflows to be designed
7
7
  * once and executed by any combination of AI and human workers.
8
8
  *
9
- * Package relationships:
9
+ * ## Worker Routing vs ai-functions Primitives
10
+ *
11
+ * **IMPORTANT:** This package exports functions that overlap in name with
12
+ * `ai-functions` primitives (do, ask, decide, approve, generate, is) but
13
+ * serve fundamentally different purposes:
14
+ *
15
+ * | Function | digital-workers | ai-functions |
16
+ * |----------|----------------|--------------|
17
+ * | `do` | Routes tasks to Workers | Direct LLM task description |
18
+ * | `ask` | Routes questions via Slack/email | LLM content for human UI |
19
+ * | `decide` | Multi-criteria decision framework | LLM-as-judge comparison |
20
+ * | `approve` | Real approval workflow via channels | LLM-generated approval content |
21
+ * | `generate` | Content generation with metadata | Core LLM generation primitive |
22
+ * | `is` | Type/schema validation with errors | Boolean assertion via LLM |
23
+ * | `notify` | Real channel delivery | (no equivalent) |
24
+ *
25
+ * **digital-workers functions are worker coordination primitives** that route
26
+ * work to AI Agents or Humans via real communication channels.
27
+ *
28
+ * **ai-functions primitives are direct LLM operations** for text generation,
29
+ * decision-making, and content creation.
30
+ *
31
+ * ## Package relationships:
10
32
  * - `autonomous-agents` - Implements Worker for AI agents
11
33
  * - `human-in-the-loop` - Implements Worker for humans
12
34
  * - `ai-workflows` - Uses digital-workers to orchestrate execution
@@ -32,12 +54,13 @@
32
54
  * const worker$ = withWorkers($)
33
55
  *
34
56
  * $.on.Expense.submitted(async (expense) => {
57
+ * // These route to REAL workers via REAL channels
35
58
  * await worker$.notify(finance, `New expense: ${expense.amount}`)
36
59
  *
37
60
  * const approval = await worker$.approve(
38
61
  * `Expense: $${expense.amount}`,
39
62
  * manager,
40
- * { via: 'slack' }
63
+ * { via: 'slack' } // Actually sends to Slack!
41
64
  * )
42
65
  *
43
66
  * if (approval.approved) {
@@ -72,18 +95,103 @@ export {
72
95
  export { Role } from './role.js'
73
96
  export { Team } from './team.js'
74
97
  export { Goals } from './goals.js'
98
+
99
+ /**
100
+ * Worker Routing Functions
101
+ *
102
+ * These functions route work to Workers (AI Agents or Humans) via real
103
+ * communication channels. They are NOT direct LLM primitives.
104
+ *
105
+ * For direct LLM primitives, use the identically-named functions from
106
+ * `ai-functions` instead. See module documentation for comparison table.
107
+ */
75
108
  export { approve } from './approve.js'
76
109
  export { ask } from './ask.js'
110
+ export { browse } from './browse.js'
77
111
  export { do } from './do.js'
78
112
  export { decide } from './decide.js'
79
113
  export { generate } from './generate.js'
114
+ export { image } from './image.js'
80
115
  export { is } from './is.js'
81
116
  export { notify } from './notify.js'
117
+ export { video } from './video.js'
118
+
82
119
  export { kpis, okrs } from './kpis.js'
83
120
 
84
121
  // Export verb definitions
85
122
  export { WorkerVerbs } from './types.js'
86
123
 
124
+ // Export capability tiers
125
+ export {
126
+ CAPABILITY_TIERS,
127
+ TIER_ORDER,
128
+ compareTiers,
129
+ isHigherTier,
130
+ isLowerTier,
131
+ getNextTier,
132
+ getPreviousTier,
133
+ getTierConfig,
134
+ getToolsForTier,
135
+ matchTierToComplexity,
136
+ canExecuteAtTier,
137
+ validateTierEscalation,
138
+ createCapabilityProfile,
139
+ TierRegistry,
140
+ } from './capability-tiers.js'
141
+
142
+ export type {
143
+ CapabilityTier,
144
+ CapabilityProfile,
145
+ TierConfig,
146
+ TierToolset,
147
+ TaskComplexity,
148
+ TierMatchResult,
149
+ TierEscalation,
150
+ EscalationValidationResult,
151
+ ProfileConstraints,
152
+ } from './capability-tiers.js'
153
+
154
+ // Export browser automation types
155
+ export type {
156
+ BrowseOptions,
157
+ BrowseResult,
158
+ BrowseAction,
159
+ BrowseActionType,
160
+ Viewport,
161
+ ClickOptions,
162
+ TypeOptions,
163
+ ScrollOptions,
164
+ ScreenshotOptions,
165
+ ExtractOptions,
166
+ } from './browse.js'
167
+
168
+ // Export image generation types
169
+ export type {
170
+ ImageStyle,
171
+ ImageSize,
172
+ ImageFormat,
173
+ ImageOptions,
174
+ ImageResult,
175
+ VariationOptions,
176
+ EditOptions,
177
+ UpscaleOptions,
178
+ UpscaleResult,
179
+ } from './image.js'
180
+
181
+ // Export video generation types
182
+ export type {
183
+ VideoOptions,
184
+ VideoResult,
185
+ VideoResolution,
186
+ VideoAspectRatio,
187
+ VideoModel,
188
+ VideoStyle,
189
+ VideoMetadata,
190
+ VideoFromImageOptions,
191
+ VideoExtendOptions,
192
+ VideoEditOptions,
193
+ } from './video.js'
194
+
87
195
  // Export transport bridge (connects to digital-tools)
88
196
  export type {
89
197
  Transport,
@@ -116,3 +224,303 @@ export {
116
224
  MessageTypeMapping,
117
225
  CallTypeMapping,
118
226
  } from './transports.js'
227
+
228
+ // Export cascade context for agent coordination
229
+ export {
230
+ // Functions
231
+ createCascadeContext,
232
+ validateContext,
233
+ enrichContext,
234
+ serializeContext,
235
+ deserializeContext,
236
+ mergeContexts,
237
+ diffContexts,
238
+ createContextVersion,
239
+ // Schemas
240
+ AgentCascadeContextSchema,
241
+ AgentTierSchema,
242
+ ContextVersionSchema,
243
+ AgentRefSchema,
244
+ TaskPrioritySchema,
245
+ TaskInfoSchema,
246
+ ExecutionPhaseSchema,
247
+ ExecutionStateSchema,
248
+ TraceEntrySchema,
249
+ } from './cascade-context.js'
250
+
251
+ export type {
252
+ AgentCascadeContext,
253
+ AgentTier,
254
+ AgentRef,
255
+ ContextVersion,
256
+ ContextEnrichment,
257
+ ValidationResult,
258
+ TaskPriority,
259
+ TaskInfo,
260
+ ExecutionPhase,
261
+ ExecutionState,
262
+ TraceEntry,
263
+ ContextChange,
264
+ ContextDiff,
265
+ } from './cascade-context.js'
266
+
267
+ // Export agent-to-agent communication layer
268
+ export {
269
+ // Message Bus
270
+ AgentMessageBus,
271
+ createMessageBus,
272
+ // Core Functions
273
+ sendToAgent,
274
+ broadcastToGroup,
275
+ requestFromAgent,
276
+ onMessage,
277
+ acknowledge,
278
+ // Coordination Patterns
279
+ requestResponse,
280
+ fanOut,
281
+ fanIn,
282
+ pipeline,
283
+ // Handoff Protocol
284
+ initiateHandoff,
285
+ acceptHandoff,
286
+ rejectHandoff,
287
+ completeHandoff,
288
+ } from './agent-comms.js'
289
+
290
+ export type {
291
+ // Message Types
292
+ AgentMessage,
293
+ MessageEnvelope,
294
+ MessageAck,
295
+ MessageType,
296
+ MessagePriority,
297
+ DeliveryStatus,
298
+ // Handoff Types
299
+ HandoffRequest,
300
+ HandoffResult,
301
+ HandoffStatus,
302
+ // Coordination Types
303
+ CoordinationPattern,
304
+ // Handler Types
305
+ MessageHandler,
306
+ SubscribeOptions,
307
+ // Options Types
308
+ MessageBusOptions,
309
+ SendOptions,
310
+ RequestOptions,
311
+ OnMessageOptions,
312
+ RequestResponseOptions,
313
+ FanOutOptions,
314
+ FanOutResult,
315
+ FanInOptions,
316
+ PipelineOptions,
317
+ InitiateHandoffOptions,
318
+ RejectHandoffOptions,
319
+ CompleteHandoffOptions,
320
+ } from './agent-comms.js'
321
+
322
+ // Export load balancing and routing for agent coordination
323
+ export {
324
+ // Balancer Factories
325
+ createRoundRobinBalancer,
326
+ createLeastBusyBalancer,
327
+ createCapabilityRouter,
328
+ createPriorityQueueBalancer,
329
+ createAgentAvailabilityTracker,
330
+ createCompositeBalancer,
331
+ createRoutingRuleEngine,
332
+ // Metrics
333
+ collectRoutingMetrics,
334
+ resetRoutingMetrics,
335
+ } from './load-balancing.js'
336
+
337
+ export type {
338
+ // Core Types
339
+ LoadBalancer,
340
+ BalancerStrategy,
341
+ AgentInfo,
342
+ TaskRequest,
343
+ RouteResult,
344
+ // Availability Types
345
+ AgentAvailability,
346
+ // Rule Types
347
+ RoutingRule,
348
+ RoutingRuleCondition,
349
+ // Metrics Types
350
+ RoutingMetrics,
351
+ // Composite Types
352
+ CompositeBalancerConfig,
353
+ } from './load-balancing.js'
354
+
355
+ // Export Slack transport adapter
356
+ export {
357
+ SlackTransport,
358
+ createSlackTransport,
359
+ registerSlackTransport,
360
+ // Block Kit helpers
361
+ slackSection,
362
+ slackHeader,
363
+ slackDivider,
364
+ slackContext,
365
+ slackButton,
366
+ slackActions,
367
+ } from './transports/slack.js'
368
+
369
+ export type {
370
+ SlackTransportConfig,
371
+ SlackBlockType,
372
+ SlackTextObject,
373
+ SlackButtonElement,
374
+ SlackConfirmDialog,
375
+ SlackSectionBlock,
376
+ SlackDividerBlock,
377
+ SlackHeaderBlock,
378
+ SlackContextBlock,
379
+ SlackActionsBlock,
380
+ SlackBlock,
381
+ SlackMessage,
382
+ SlackApiResponse,
383
+ SlackPostMessageResponse,
384
+ SlackUserInfoResponse,
385
+ SlackConversationInfoResponse,
386
+ SlackInteractionPayload,
387
+ SlackActionPayload,
388
+ SlackWebhookRequest,
389
+ WebhookHandlerResult,
390
+ } from './transports/slack.js'
391
+
392
+ // Export Email transport adapter
393
+ export {
394
+ EmailTransport,
395
+ createEmailTransport,
396
+ createEmailTransportWithProvider,
397
+ createResendProvider,
398
+ // Template generators
399
+ generateNotificationEmail,
400
+ generateApprovalEmail,
401
+ // Reply parsing
402
+ parseApprovalReply,
403
+ // Type guards
404
+ isEmailTransportConfig,
405
+ isApproved,
406
+ isRejected,
407
+ } from './transports/email.js'
408
+
409
+ export type {
410
+ // Provider types
411
+ EmailProvider,
412
+ EmailMessage,
413
+ EmailSendResult,
414
+ EmailAttachment,
415
+ EmailTag,
416
+ // Configuration types
417
+ EmailTransportConfig,
418
+ EmailTemplateOptions,
419
+ // Approval types
420
+ ApprovalRequestData,
421
+ ParsedEmailReply,
422
+ InboundEmail,
423
+ } from './transports/email.js'
424
+
425
+ // Export error escalation for multi-level error handling
426
+ export {
427
+ // Error Classification
428
+ getErrorSeverity,
429
+ getErrorCategory,
430
+ createClassifiedError,
431
+ classifyError,
432
+ isEscalatable,
433
+ preserveContext,
434
+ buildErrorChain,
435
+ // Escalation Routing
436
+ createEscalationPolicy,
437
+ getNextEscalationTier,
438
+ determineEscalationPath,
439
+ shouldEscalate,
440
+ detectCircularEscalation,
441
+ validateEscalationPath,
442
+ // Recovery Patterns
443
+ calculateBackoff,
444
+ createRetryState,
445
+ shouldRetry,
446
+ selectFallbackAgent,
447
+ getDegradationLevel,
448
+ createRecoveryState,
449
+ updateRecoveryState,
450
+ isRecoverable,
451
+ // Escalation Engine
452
+ createEscalationEngine,
453
+ } from './error-escalation.js'
454
+
455
+ export type {
456
+ // Error Classification Types
457
+ ErrorSeverity,
458
+ ErrorCategory,
459
+ ClassifiedError,
460
+ ErrorContext,
461
+ ErrorChain,
462
+ SeverityOptions,
463
+ ErrorChainOptions,
464
+ // Escalation Routing Types
465
+ EscalationPath,
466
+ EscalationPolicy,
467
+ EscalationPolicyOptions,
468
+ EscalationRule,
469
+ EscalationThreshold,
470
+ EscalationResult,
471
+ EscalationValidationResult as ErrorEscalationValidationResult,
472
+ TierPolicyConfig,
473
+ ErrorHistoryEntry,
474
+ // Recovery Pattern Types
475
+ RetryConfig,
476
+ RetryState,
477
+ FallbackConfig,
478
+ AgentForFallback,
479
+ DegradationLevel,
480
+ DegradationOptions,
481
+ RecoveryState,
482
+ RecoveryStateOptions,
483
+ RecoveryStateUpdate,
484
+ // Engine Types
485
+ EscalationEngine,
486
+ EscalationEngineOptions,
487
+ HandleErrorOptions,
488
+ EscalationMetrics,
489
+ } from './error-escalation.js'
490
+
491
+ // Export runtime integration for human request processing
492
+ export {
493
+ // Classes
494
+ HumanRequestProcessor,
495
+ InMemoryRequestStore,
496
+ // Factory functions
497
+ createHumanRequestProcessor,
498
+ } from './runtime.js'
499
+
500
+ export type {
501
+ // Request types
502
+ HumanRequest,
503
+ HumanRequestStore,
504
+ RequestStatus,
505
+ RequestType,
506
+ RequestResult,
507
+ CreateRequestData,
508
+ UpdateRequestData,
509
+ // Processor types
510
+ ProcessorConfig,
511
+ TransportAdapters,
512
+ SubmitResult,
513
+ SubmitRequestData,
514
+ WebhookPayload,
515
+ WebhookResult,
516
+ CompleteCallbackData,
517
+ TimeoutCallbackData,
518
+ CancelResult,
519
+ } from './runtime.js'
520
+
521
+ // Export logger interface for error logging
522
+ export type { Logger } from './logger.js'
523
+ export { noopLogger, createConsoleLogger } from './logger.js'
524
+
525
+ // Export ID generation utilities
526
+ export { generateRequestId } from './utils/id.js'
package/src/is.ts CHANGED
@@ -1,5 +1,29 @@
1
1
  /**
2
2
  * Type validation and checking functionality for digital workers
3
+ *
4
+ * IMPORTANT: Schema Validation vs Boolean Assertion
5
+ * --------------------------------------------------
6
+ * This module provides comprehensive type/schema validation,
7
+ * NOT simple boolean assertions.
8
+ *
9
+ * - `digital-workers.is()` - Validates values against types or schemas,
10
+ * returns detailed validation results with errors and optional coercion.
11
+ *
12
+ * - `ai-functions.is()` - Boolean assertion via LLM (e.g., `is\`${x} is valid\``)
13
+ * returns true/false based on natural language checking.
14
+ *
15
+ * Use digital-workers when you need:
16
+ * - Type validation with error messages
17
+ * - Schema validation with field-level errors
18
+ * - Value coercion (string to number, etc.)
19
+ * - Structured validation results
20
+ *
21
+ * Use ai-functions when you need:
22
+ * - Natural language boolean checks
23
+ * - LLM-based semantic validation
24
+ * - Template literal assertions
25
+ *
26
+ * @module
3
27
  */
4
28
 
5
29
  import { generateObject } from 'ai-functions'
@@ -7,26 +31,35 @@ import { schema as convertSchema, type SimpleSchema } from 'ai-functions'
7
31
  import type { TypeCheckResult, IsOptions } from './types.js'
8
32
 
9
33
  /**
10
- * Check if a value matches an expected type or schema
34
+ * Validate a value against a type or schema with detailed results.
11
35
  *
12
- * Uses AI-powered validation for complex types and schemas.
13
- * Can also perform type coercion when enabled.
36
+ * **Key Difference from ai-functions.is():**
37
+ * Unlike `ai-functions.is()` which is a boolean assertion using natural
38
+ * language (e.g., `is\`${email} is valid\`` returns true/false), this
39
+ * function performs structured type/schema validation and returns a
40
+ * `TypeCheckResult` with:
41
+ * - Validation status
42
+ * - Error messages for invalid fields
43
+ * - Optionally coerced values
44
+ *
45
+ * This is a **validation primitive**, not a boolean assertion primitive.
14
46
  *
15
47
  * @param value - The value to check
16
- * @param type - Type name or schema to validate against
17
- * @param options - Validation options
18
- * @returns Promise resolving to validation result
48
+ * @param type - Type name ('email', 'url', 'number') or schema to validate against
49
+ * @param options - Validation options (coerce, strict)
50
+ * @returns Promise resolving to TypeCheckResult with valid, value, and errors
19
51
  *
20
52
  * @example
21
53
  * ```ts
22
- * // Simple type checking
54
+ * // Simple type checking with result object
23
55
  * const result = await is('hello@example.com', 'email')
24
56
  * console.log(result.valid) // true
57
+ * console.log(result.errors) // undefined when valid
25
58
  * ```
26
59
  *
27
60
  * @example
28
61
  * ```ts
29
- * // Schema validation
62
+ * // Schema validation with detailed errors
30
63
  * const result = await is(
31
64
  * { name: 'John', age: 30 },
32
65
  * {
@@ -41,11 +74,13 @@ import type { TypeCheckResult, IsOptions } from './types.js'
41
74
  *
42
75
  * @example
43
76
  * ```ts
44
- * // With coercion
77
+ * // With coercion - transforms value to target type
45
78
  * const result = await is('123', 'number', { coerce: true })
46
79
  * console.log(result.valid) // true
47
- * console.log(result.value) // 123 (as number)
80
+ * console.log(result.value) // 123 (as number, not string)
48
81
  * ```
82
+ *
83
+ * @see {@link ai-functions#is} for natural language boolean assertions
49
84
  */
50
85
  export async function is(
51
86
  value: unknown,
@@ -102,8 +137,7 @@ async function validateSimpleType(
102
137
 
103
138
  return {
104
139
  valid: isValid,
105
- value: isValid ? value : undefined,
106
- errors: isValid ? undefined : [`Value is not a valid ${type}`],
140
+ ...(isValid ? { value } : { errors: [`Value is not a valid ${type}`] }),
107
141
  }
108
142
  }
109
143
 
@@ -118,7 +152,11 @@ async function validateSimpleType(
118
152
  system: `You are a type validation expert. Determine if a value matches an expected type.
119
153
 
120
154
  ${coerce ? 'If the value can be coerced to the expected type, provide the coerced value.' : ''}
121
- ${strict ? 'Be strict in your validation - require exact type matches.' : 'Be flexible - allow reasonable type conversions.'}`,
155
+ ${
156
+ strict
157
+ ? 'Be strict in your validation - require exact type matches.'
158
+ : 'Be flexible - allow reasonable type conversions.'
159
+ }`,
122
160
  prompt: `Validate if this value matches the expected type:
123
161
 
124
162
  Value: ${JSON.stringify(value)}
@@ -136,7 +174,7 @@ Determine if the value is valid for this type.`,
136
174
  return {
137
175
  valid: validation.valid,
138
176
  value: coerce && validation.coercedValue !== undefined ? validation.coercedValue : value,
139
- errors: validation.valid ? undefined : validation.errors,
177
+ ...(!validation.valid && { errors: validation.errors }),
140
178
  }
141
179
  }
142
180
 
@@ -201,7 +239,7 @@ Check if the value matches the schema structure and types.`,
201
239
  return {
202
240
  valid: validation.valid,
203
241
  value: coerce && validation.coercedValue !== undefined ? validation.coercedValue : value,
204
- errors: validation.valid ? undefined : validation.errors,
242
+ ...(!validation.valid && { errors: validation.errors }),
205
243
  }
206
244
  }
207
245
  }
@@ -209,10 +247,7 @@ Check if the value matches the schema structure and types.`,
209
247
  /**
210
248
  * Try to coerce a value to a specific type
211
249
  */
212
- function coerceValue(
213
- value: unknown,
214
- type: string
215
- ): { success: boolean; value?: unknown } {
250
+ function coerceValue(value: unknown, type: string): { success: boolean; value?: unknown } {
216
251
  try {
217
252
  switch (type) {
218
253
  case 'string':
@@ -266,8 +301,7 @@ is.email = async (value: unknown): Promise<TypeCheckResult> => {
266
301
 
267
302
  return {
268
303
  valid,
269
- value: valid ? value : undefined,
270
- errors: valid ? undefined : ['Invalid email format'],
304
+ ...(valid ? { value } : { errors: ['Invalid email format'] }),
271
305
  }
272
306
  }
273
307
 
@@ -310,10 +344,11 @@ is.date = async (value: unknown, options: IsOptions = {}): Promise<TypeCheckResu
310
344
  const { coerce } = options
311
345
 
312
346
  if (value instanceof Date) {
347
+ const isValid = !isNaN(value.getTime())
313
348
  return {
314
- valid: !isNaN(value.getTime()),
349
+ valid: isValid,
315
350
  value,
316
- errors: isNaN(value.getTime()) ? ['Invalid date'] : undefined,
351
+ ...(!isValid && { errors: ['Invalid date'] }),
317
352
  }
318
353
  }
319
354
 
@@ -360,8 +395,7 @@ is.custom = async (
360
395
  const valid = await validator(value)
361
396
  return {
362
397
  valid,
363
- value: valid ? value : undefined,
364
- errors: valid ? undefined : ['Custom validation failed'],
398
+ ...(valid ? { value } : { errors: ['Custom validation failed'] }),
365
399
  }
366
400
  } catch (error) {
367
401
  return {