digital-workers 2.1.3 → 2.4.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 (183) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +17 -0
  3. package/README.md +2 -0
  4. package/dist/actions.d.ts.map +1 -1
  5. package/dist/actions.js +33 -21
  6. package/dist/actions.js.map +1 -1
  7. package/dist/agent-comms.d.ts.map +1 -1
  8. package/dist/agent-comms.js +36 -25
  9. package/dist/agent-comms.js.map +1 -1
  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.js +3 -3
  23. package/dist/capability-tiers.js.map +1 -1
  24. package/dist/cascade-context.d.ts +28 -28
  25. package/dist/client.d.ts +162 -0
  26. package/dist/client.d.ts.map +1 -0
  27. package/dist/client.js +64 -0
  28. package/dist/client.js.map +1 -0
  29. package/dist/decide.d.ts +42 -6
  30. package/dist/decide.d.ts.map +1 -1
  31. package/dist/decide.js +54 -11
  32. package/dist/decide.js.map +1 -1
  33. package/dist/do.d.ts +36 -7
  34. package/dist/do.d.ts.map +1 -1
  35. package/dist/do.js +82 -39
  36. package/dist/do.js.map +1 -1
  37. package/dist/error-escalation.d.ts.map +1 -1
  38. package/dist/error-escalation.js +38 -38
  39. package/dist/error-escalation.js.map +1 -1
  40. package/dist/generate.d.ts +48 -7
  41. package/dist/generate.d.ts.map +1 -1
  42. package/dist/generate.js +49 -8
  43. package/dist/generate.js.map +1 -1
  44. package/dist/goals.d.ts +10 -9
  45. package/dist/goals.d.ts.map +1 -1
  46. package/dist/goals.js +30 -24
  47. package/dist/goals.js.map +1 -1
  48. package/dist/image.d.ts +189 -0
  49. package/dist/image.d.ts.map +1 -0
  50. package/dist/image.js +528 -0
  51. package/dist/image.js.map +1 -0
  52. package/dist/index.d.ts +49 -2
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +58 -2
  55. package/dist/index.js.map +1 -1
  56. package/dist/is.d.ts +45 -10
  57. package/dist/is.d.ts.map +1 -1
  58. package/dist/is.js +56 -21
  59. package/dist/is.js.map +1 -1
  60. package/dist/kpis.d.ts +24 -15
  61. package/dist/kpis.d.ts.map +1 -1
  62. package/dist/kpis.js +16 -14
  63. package/dist/kpis.js.map +1 -1
  64. package/dist/load-balancing.d.ts.map +1 -1
  65. package/dist/load-balancing.js +124 -38
  66. package/dist/load-balancing.js.map +1 -1
  67. package/dist/logger.d.ts +76 -0
  68. package/dist/logger.d.ts.map +1 -0
  69. package/dist/logger.js +39 -0
  70. package/dist/logger.js.map +1 -0
  71. package/dist/notify.d.ts +38 -9
  72. package/dist/notify.d.ts.map +1 -1
  73. package/dist/notify.js +72 -17
  74. package/dist/notify.js.map +1 -1
  75. package/dist/role.d.ts +5 -4
  76. package/dist/role.d.ts.map +1 -1
  77. package/dist/role.js +13 -10
  78. package/dist/role.js.map +1 -1
  79. package/dist/runtime.d.ts +310 -0
  80. package/dist/runtime.d.ts.map +1 -0
  81. package/dist/runtime.js +510 -0
  82. package/dist/runtime.js.map +1 -0
  83. package/dist/team.d.ts +11 -6
  84. package/dist/team.d.ts.map +1 -1
  85. package/dist/team.js +22 -15
  86. package/dist/team.js.map +1 -1
  87. package/dist/transports/email.d.ts +318 -0
  88. package/dist/transports/email.d.ts.map +1 -0
  89. package/dist/transports/email.js +779 -0
  90. package/dist/transports/email.js.map +1 -0
  91. package/dist/transports/slack.d.ts +515 -0
  92. package/dist/transports/slack.d.ts.map +1 -0
  93. package/dist/transports/slack.js +844 -0
  94. package/dist/transports/slack.js.map +1 -0
  95. package/dist/transports.d.ts.map +1 -1
  96. package/dist/transports.js +44 -25
  97. package/dist/transports.js.map +1 -1
  98. package/dist/types.d.ts +141 -19
  99. package/dist/types.d.ts.map +1 -1
  100. package/dist/types.js +5 -0
  101. package/dist/types.js.map +1 -1
  102. package/dist/utils/id.d.ts +19 -0
  103. package/dist/utils/id.d.ts.map +1 -0
  104. package/dist/utils/id.js +21 -0
  105. package/dist/utils/id.js.map +1 -0
  106. package/dist/video.d.ts +203 -0
  107. package/dist/video.d.ts.map +1 -0
  108. package/dist/video.js +528 -0
  109. package/dist/video.js.map +1 -0
  110. package/dist/worker.d.ts +343 -0
  111. package/dist/worker.d.ts.map +1 -0
  112. package/dist/worker.js +698 -0
  113. package/dist/worker.js.map +1 -0
  114. package/package.json +32 -14
  115. package/src/actions.ts +39 -30
  116. package/src/agent-comms.ts +54 -92
  117. package/src/approve.ts +91 -20
  118. package/src/ask.ts +99 -25
  119. package/src/browse.ts +627 -0
  120. package/src/capability-tiers.ts +5 -5
  121. package/src/client.ts +221 -0
  122. package/src/decide.ts +81 -35
  123. package/src/do.ts +98 -52
  124. package/src/error-escalation.ts +55 -67
  125. package/src/generate.ts +52 -18
  126. package/src/goals.ts +36 -27
  127. package/src/image.ts +816 -0
  128. package/src/index.ts +187 -2
  129. package/src/is.ts +59 -25
  130. package/src/kpis.ts +41 -36
  131. package/src/load-balancing.ts +132 -46
  132. package/src/logger.ts +93 -0
  133. package/src/notify.ts +78 -17
  134. package/src/role.ts +30 -20
  135. package/src/runtime.ts +796 -0
  136. package/src/team.ts +24 -19
  137. package/src/transports/email.ts +1160 -0
  138. package/src/transports/slack.ts +1320 -0
  139. package/src/transports.ts +58 -43
  140. package/src/types.ts +174 -46
  141. package/src/utils/id.ts +21 -0
  142. package/src/video.ts +906 -0
  143. package/src/worker.ts +1007 -0
  144. package/test/approve.test.ts +305 -0
  145. package/test/ask.test.ts +274 -0
  146. package/test/browse.test.ts +361 -0
  147. package/test/decide.test.ts +252 -0
  148. package/test/do.test.ts +144 -0
  149. package/test/error-logging.test.ts +357 -0
  150. package/test/generate.test.ts +319 -0
  151. package/test/image.test.ts +398 -0
  152. package/test/is.test.ts +287 -0
  153. package/test/load-balancing-safety.test.ts +404 -0
  154. package/test/notify.test.ts +434 -0
  155. package/test/primitives.test.ts +320 -0
  156. package/test/runtime-integration.test.ts +892 -0
  157. package/test/transports/crypto.test.ts +230 -0
  158. package/test/transports/email.test.ts +866 -0
  159. package/test/transports/id-generation.test.ts +91 -0
  160. package/test/transports/slack.test.ts +760 -0
  161. package/test/type-safety.test.ts +834 -0
  162. package/test/types.test.ts +60 -2
  163. package/test/video.test.ts +530 -0
  164. package/test/worker.test.ts +1433 -0
  165. package/tsconfig.json +4 -1
  166. package/vitest.config.ts +42 -0
  167. package/wrangler.jsonc +36 -0
  168. package/LICENSE +0 -21
  169. package/src/actions.js +0 -436
  170. package/src/approve.js +0 -234
  171. package/src/ask.js +0 -226
  172. package/src/decide.js +0 -244
  173. package/src/do.js +0 -227
  174. package/src/generate.js +0 -298
  175. package/src/goals.js +0 -205
  176. package/src/index.js +0 -68
  177. package/src/is.js +0 -317
  178. package/src/kpis.js +0 -270
  179. package/src/notify.js +0 -219
  180. package/src/role.js +0 -110
  181. package/src/team.js +0 -130
  182. package/src/transports.js +0 -357
  183. package/src/types.js +0 -71
package/src/transports.ts CHANGED
@@ -29,23 +29,23 @@ import type {
29
29
  * Communication transport - maps contact channels to delivery mechanisms
30
30
  */
31
31
  export type Transport =
32
- | 'email' // Email transport (SendGrid, Resend, etc.)
33
- | 'sms' // SMS transport (Twilio, etc.)
34
- | 'voice' // Voice call transport (Vapi, Twilio, etc.)
35
- | 'slack' // Slack API
36
- | 'teams' // Microsoft Teams API
37
- | 'discord' // Discord API
38
- | 'whatsapp' // WhatsApp Business API
39
- | 'telegram' // Telegram Bot API
40
- | 'web' // Web push/in-app
41
- | 'webhook' // Generic webhook
32
+ | 'email' // Email transport (SendGrid, Resend, etc.)
33
+ | 'sms' // SMS transport (Twilio, etc.)
34
+ | 'voice' // Voice call transport (Vapi, Twilio, etc.)
35
+ | 'slack' // Slack API
36
+ | 'teams' // Microsoft Teams API
37
+ | 'discord' // Discord API
38
+ | 'whatsapp' // WhatsApp Business API
39
+ | 'telegram' // Telegram Bot API
40
+ | 'web' // Web push/in-app
41
+ | 'webhook' // Generic webhook
42
42
 
43
43
  /**
44
44
  * Transport configuration
45
45
  */
46
46
  export interface TransportConfig {
47
47
  transport: Transport
48
- provider?: string // Specific provider (e.g., 'sendgrid', 'resend')
48
+ provider?: string // Specific provider (e.g., 'sendgrid', 'resend')
49
49
  apiKey?: string
50
50
  apiUrl?: string
51
51
  options?: Record<string, unknown>
@@ -73,7 +73,7 @@ export interface MessagePayload {
73
73
 
74
74
  // Interactive (for questions/approvals)
75
75
  actions?: MessageAction[]
76
- schema?: unknown // SimpleSchema from ai-functions
76
+ schema?: unknown // SimpleSchema from ai-functions
77
77
  timeout?: number
78
78
  }
79
79
 
@@ -151,16 +151,16 @@ export function getTeamTransports(team: Team): Transport[] {
151
151
 
152
152
  // Add team-level contacts
153
153
  const contacts = team.contacts
154
- if (contacts.email) transports.add('email')
155
- if (contacts.slack) transports.add('slack')
156
- if (contacts.teams) transports.add('teams')
157
- if (contacts.discord) transports.add('discord')
158
- if (contacts.phone) transports.add('voice')
159
- if (contacts.sms) transports.add('sms')
160
- if (contacts.whatsapp) transports.add('whatsapp')
161
- if (contacts.telegram) transports.add('telegram')
162
- if (contacts.web) transports.add('web')
163
- if (contacts.webhook) transports.add('webhook')
154
+ if (contacts?.['email']) transports.add('email')
155
+ if (contacts?.['slack']) transports.add('slack')
156
+ if (contacts?.['teams']) transports.add('teams')
157
+ if (contacts?.['discord']) transports.add('discord')
158
+ if (contacts?.['phone']) transports.add('voice')
159
+ if (contacts?.['sms']) transports.add('sms')
160
+ if (contacts?.['whatsapp']) transports.add('whatsapp')
161
+ if (contacts?.['telegram']) transports.add('telegram')
162
+ if (contacts?.['web']) transports.add('web')
163
+ if (contacts?.['webhook']) transports.add('webhook')
164
164
 
165
165
  return Array.from(transports)
166
166
  }
@@ -196,7 +196,11 @@ export function resolveAddress(contacts: Contacts, channel: ContactChannel): Add
196
196
  switch (channel) {
197
197
  case 'email':
198
198
  const emailContact = contact as { address: string; name?: string }
199
- return { transport, value: emailContact.address, name: emailContact.name }
199
+ return {
200
+ transport,
201
+ value: emailContact.address,
202
+ ...(emailContact.name !== undefined && { name: emailContact.name }),
203
+ }
200
204
  case 'phone':
201
205
  case 'sms':
202
206
  case 'whatsapp':
@@ -246,8 +250,17 @@ export function resolveAddress(contacts: Contacts, channel: ContactChannel): Add
246
250
  export function resolveWorkerAddresses(worker: Worker): Address[] {
247
251
  const addresses: Address[] = []
248
252
  const channels: ContactChannel[] = [
249
- 'email', 'slack', 'teams', 'discord', 'phone', 'sms',
250
- 'whatsapp', 'telegram', 'web', 'api', 'webhook',
253
+ 'email',
254
+ 'slack',
255
+ 'teams',
256
+ 'discord',
257
+ 'phone',
258
+ 'sms',
259
+ 'whatsapp',
260
+ 'telegram',
261
+ 'web',
262
+ 'api',
263
+ 'webhook',
251
264
  ]
252
265
 
253
266
  for (const channel of channels) {
@@ -365,9 +378,7 @@ export async function sendToMultipleTransports(
365
378
  configs?: Record<Transport, TransportConfig>
366
379
  ): Promise<DeliveryResult[]> {
367
380
  const results = await Promise.all(
368
- transports.map(transport =>
369
- sendViaTransport(transport, payload, configs?.[transport])
370
- )
381
+ transports.map((transport) => sendViaTransport(transport, payload, configs?.[transport]))
371
382
  )
372
383
  return results
373
384
  }
@@ -385,7 +396,7 @@ export function buildNotifyPayload(action: NotifyActionData): MessagePayload {
385
396
  body: action.message,
386
397
  type: 'notification',
387
398
  priority: action.priority || 'normal',
388
- metadata: action.metadata,
399
+ ...(action.metadata !== undefined && { metadata: action.metadata }),
389
400
  }
390
401
  }
391
402
 
@@ -397,9 +408,9 @@ export function buildAskPayload(action: AskActionData): MessagePayload {
397
408
  to: resolveActionTarget(action.object),
398
409
  body: action.question,
399
410
  type: 'question',
400
- schema: action.schema,
401
- timeout: action.timeout,
402
- metadata: action.metadata,
411
+ ...(action.schema !== undefined && { schema: action.schema }),
412
+ ...(action.timeout !== undefined && { timeout: action.timeout }),
413
+ ...(action.metadata !== undefined && { metadata: action.metadata }),
403
414
  }
404
415
  }
405
416
 
@@ -411,7 +422,7 @@ export function buildApprovePayload(action: ApproveActionData): MessagePayload {
411
422
  to: resolveActionTarget(action.object),
412
423
  body: action.request,
413
424
  type: 'approval',
414
- timeout: action.timeout,
425
+ ...(action.timeout !== undefined && { timeout: action.timeout }),
415
426
  actions: [
416
427
  { id: 'approve', label: 'Approve', style: 'primary', value: true },
417
428
  { id: 'reject', label: 'Reject', style: 'danger', value: false },
@@ -450,7 +461,7 @@ export const MessageTypeMapping = {
450
461
  discord: 'chat',
451
462
  whatsapp: 'text',
452
463
  telegram: 'text',
453
- voice: 'voicemail', // For voicemail messages
464
+ voice: 'voicemail', // For voicemail messages
454
465
  } as const
455
466
 
456
467
  /**
@@ -490,15 +501,19 @@ export function toDigitalToolsMessage(
490
501
  /**
491
502
  * Convert digital-tools Message to worker notification format
492
503
  */
493
- export function fromDigitalToolsMessage(
494
- message: Record<string, unknown>
495
- ): Partial<MessagePayload> {
504
+ export function fromDigitalToolsMessage(message: Record<string, unknown>): Partial<MessagePayload> {
505
+ const to = message['to'] as string | string[]
506
+ const from = message['from'] as string | undefined
507
+ const subject = message['subject'] as string | undefined
508
+ const body = message['body'] as string
509
+ const html = message['html'] as string | undefined
510
+ const metadata = message['metadata'] as Record<string, unknown> | undefined
496
511
  return {
497
- to: message.to as string | string[],
498
- from: message.from as string | undefined,
499
- subject: message.subject as string | undefined,
500
- body: message.body as string,
501
- html: message.html as string | undefined,
502
- metadata: message.metadata as Record<string, unknown> | undefined,
512
+ to,
513
+ body,
514
+ ...(from !== undefined && { from }),
515
+ ...(subject !== undefined && { subject }),
516
+ ...(html !== undefined && { html }),
517
+ ...(metadata !== undefined && { metadata }),
503
518
  }
504
519
  }
package/src/types.ts CHANGED
@@ -17,8 +17,41 @@
17
17
  */
18
18
 
19
19
  import type { SimpleSchema } from 'ai-functions'
20
+ import type { Thing, ThingRef } from 'digital-objects'
21
+ import type { ThingRef as SchemaThingRef } from 'schema.org.ai'
20
22
  import type { CapabilityTier, CapabilityProfile } from './capability-tiers.js'
21
23
 
24
+ // Import consolidated types from org.ai
25
+ import type { Role, Team, Goal, Goals, KPI, OKR, TeamMember, KeyResult } from 'org.ai'
26
+
27
+ // Re-export org.ai types for convenience
28
+ export type { Role, Team, Goal, Goals, KPI, OKR, TeamMember, KeyResult }
29
+
30
+ // Re-export digital-objects core types used by Worker/Role surfaces
31
+ export type { Thing, ThingRef }
32
+
33
+ // ============================================================================
34
+ // Identity (SVO co-design — aip-ttfk)
35
+ // ============================================================================
36
+
37
+ /**
38
+ * IdentityRef — reference to an `id.org.ai` Identity record.
39
+ *
40
+ * Widened from the `string`-only placeholder introduced in aip-ttfk to the
41
+ * `schema.org.ai` `ThingRef` shape now that the upstream package has shipped
42
+ * (`schema.org.ai@^0.1.0`). Two shapes are accepted:
43
+ * - bare string `$id` (back-compat with the original `IdentityRef = string`)
44
+ * - `{ $id, $type, name? }` typed reference, so callers can route by class
45
+ * without first resolving the Identity record.
46
+ *
47
+ * Per the SVO co-design plan (`docs/plans/2026-05-05-svo-co-design.md`,
48
+ * step 4), a `Worker` carries an `IdentityRef` so AuthBroker and
49
+ * PaymentBroker can gate Tool invocations on the worker's scopes and
50
+ * funding instruments. The typed form lets `Worker.resolve()` skip a
51
+ * fetch when `$type` is already known.
52
+ */
53
+ export type IdentityRef = SchemaThingRef
54
+
22
55
  // ============================================================================
23
56
  // Worker Types
24
57
  // ============================================================================
@@ -32,10 +65,10 @@ export type WorkerType = 'agent' | 'human'
32
65
  * Worker status
33
66
  */
34
67
  export type WorkerStatus =
35
- | 'available' // Ready to accept work
36
- | 'busy' // Currently working
37
- | 'away' // Not available (break, offline)
38
- | 'offline' // Disconnected
68
+ | 'available' // Ready to accept work
69
+ | 'busy' // Currently working
70
+ | 'away' // Not available (break, offline)
71
+ | 'offline' // Disconnected
39
72
 
40
73
  // ============================================================================
41
74
  // Contact Channel Types
@@ -45,17 +78,17 @@ export type WorkerStatus =
45
78
  * Contact channel names - how workers can be reached
46
79
  */
47
80
  export type ContactChannel =
48
- | 'email' // Email communication
49
- | 'slack' // Slack workspace
50
- | 'teams' // Microsoft Teams
51
- | 'discord' // Discord server
52
- | 'phone' // Voice calls
53
- | 'sms' // SMS text messages
54
- | 'whatsapp' // WhatsApp messaging
55
- | 'telegram' // Telegram messaging
56
- | 'web' // Web UI/dashboard
57
- | 'api' // Programmatic API
58
- | 'webhook' // Webhook callbacks
81
+ | 'email' // Email communication
82
+ | 'slack' // Slack workspace
83
+ | 'teams' // Microsoft Teams
84
+ | 'discord' // Discord server
85
+ | 'phone' // Voice calls
86
+ | 'sms' // SMS text messages
87
+ | 'whatsapp' // WhatsApp messaging
88
+ | 'telegram' // Telegram messaging
89
+ | 'web' // Web UI/dashboard
90
+ | 'api' // Programmatic API
91
+ | 'webhook' // Webhook callbacks
59
92
 
60
93
  /**
61
94
  * Email contact - simple string or config object
@@ -239,6 +272,13 @@ export interface Worker {
239
272
  capabilityTier?: CapabilityTier
240
273
  /** Full capability profile for detailed configuration */
241
274
  capabilityProfile?: CapabilityProfile
275
+ /**
276
+ * Reference to this Worker's `id.org.ai` Identity record (DID + scopes +
277
+ * payment instruments). Optional for backward compatibility — populated
278
+ * by deployments that have wired up an `id.org.ai` AuthBroker/
279
+ * PaymentBroker. SVO co-design step 4 (aip-ttfk).
280
+ */
281
+ identity?: IdentityRef
242
282
  metadata?: Record<string, unknown>
243
283
  }
244
284
 
@@ -259,11 +299,15 @@ export interface WorkerRef {
259
299
  // ============================================================================
260
300
 
261
301
  /**
262
- * Team - group of workers with shared contacts
302
+ * WorkerTeam - group of workers with shared contacts
303
+ *
304
+ * This is the digital-workers team interface that includes
305
+ * worker-specific contact channels. For the base Team type,
306
+ * use Team from org.ai.
263
307
  *
264
308
  * @example
265
309
  * ```ts
266
- * const engineering: Team = {
310
+ * const engineering: WorkerTeam = {
267
311
  * id: 'team_eng',
268
312
  * name: 'Engineering',
269
313
  * members: [alice, bob, deployBot],
@@ -274,14 +318,22 @@ export interface WorkerRef {
274
318
  * }
275
319
  * ```
276
320
  */
277
- export interface Team {
321
+ export interface WorkerTeam {
322
+ /** Team identifier */
278
323
  id: string
324
+ /** Team name */
279
325
  name: string
326
+ /** Team description */
280
327
  description?: string
328
+ /** Team members as WorkerRefs */
281
329
  members: WorkerRef[]
330
+ /** Worker-specific contact channels */
282
331
  contacts: Contacts
332
+ /** Team lead as WorkerRef */
283
333
  lead?: WorkerRef
334
+ /** Team goals */
284
335
  goals?: string[]
336
+ /** Additional metadata */
285
337
  metadata?: Record<string, unknown>
286
338
  }
287
339
 
@@ -623,9 +675,7 @@ export interface WorkerContext {
623
675
  /**
624
676
  * Make a decision (AI or human)
625
677
  */
626
- decide<T = string>(
627
- options: DecideOptions<T>
628
- ): Promise<DecideResult<T>>
678
+ decide<T = string>(options: DecideOptions<T>): Promise<DecideResult<T>>
629
679
  }
630
680
 
631
681
  // ============================================================================
@@ -679,53 +729,139 @@ export interface DecideOptions<T = string> {
679
729
  // ============================================================================
680
730
 
681
731
  /**
682
- * Worker role definition
732
+ * OrgRole a slot in an org structure (e.g., 'CEO', 'PDM') filled by a
733
+ * specific Person or Agent.
734
+ *
735
+ * SVO co-design step 4 (aip-ttfk). This is the Noun-extending Role from
736
+ * `docs/plans/2026-05-05-svo-co-design.md`: a `Thing` whose data records
737
+ * the slot's current `filler` and an optional `fallbackChain` for when
738
+ * the filler is unavailable. A `Worker` whose `id` references an
739
+ * `OrgRole` resolves to the current filler at invocation time.
740
+ *
741
+ * NAMING NOTE: the design doc calls this type `Role`, but `Role` is
742
+ * already imported from `org.ai` and re-exported above as a different
743
+ * concept (a job-description-shaped HR Role with skills, permissions,
744
+ * responsibilities). Renamed here to `OrgRole` to avoid the collision;
745
+ * see the aip-ttfk bead comment for the surfaced conflict.
746
+ *
747
+ * @example
748
+ * ```ts
749
+ * const ceo: OrgRole = {
750
+ * id: 'role_ceo',
751
+ * noun: 'OrgRole',
752
+ * data: {
753
+ * $type: 'Role',
754
+ * name: 'CEO',
755
+ * filler: 'person_priya',
756
+ * fallbackChain: ['person_alex'],
757
+ * },
758
+ * createdAt: new Date(),
759
+ * updatedAt: new Date(),
760
+ * }
761
+ * ```
762
+ */
763
+ export interface OrgRole
764
+ extends Thing<{
765
+ $type: 'Role'
766
+ /** Display name of the slot (e.g., 'CEO', 'PDM') */
767
+ name: string
768
+ /** Current filler — a Person or Agent ThingRef */
769
+ filler: ThingRef
770
+ /** Fallback fillers tried in order if `filler` is unavailable */
771
+ fallbackChain?: ThingRef[]
772
+ }> {}
773
+
774
+ /**
775
+ * WorkerRole - extends Role from org.ai with worker-specific requirements
776
+ *
777
+ * Inherits all fields from the base Role type (id, name, description, skills,
778
+ * permissions, tools, outputs, type, department, etc.) and makes responsibilities
779
+ * required for worker role definitions.
780
+ *
781
+ * @example
782
+ * ```ts
783
+ * const engineerRole: WorkerRole = {
784
+ * id: 'role_engineer',
785
+ * name: 'Software Engineer',
786
+ * description: 'Builds and maintains software',
787
+ * skills: ['typescript', 'react', 'node'],
788
+ * responsibilities: ['write code', 'review PRs', 'fix bugs'],
789
+ * }
790
+ * ```
683
791
  */
684
- export interface WorkerRole {
685
- name: string
686
- description: string
792
+ export interface WorkerRole extends Role {
793
+ /** List of responsibilities (required for worker roles) */
687
794
  responsibilities: string[]
688
- skills?: string[]
689
- permissions?: string[]
690
- type?: 'ai' | 'human' | 'hybrid'
691
795
  }
692
796
 
693
797
  /**
694
- * Worker goals
798
+ * WorkerGoals - categorized goals with metrics
799
+ *
800
+ * Organizes goals by timeframe (short-term, long-term, strategic)
801
+ * and includes associated KPI metrics for tracking.
802
+ *
803
+ * Note: org.ai's Goals is a simpler type (Goal[]). WorkerGoals
804
+ * provides additional structure for worker/team goal planning
805
+ * with string-based goals for simplicity.
695
806
  */
696
807
  export interface WorkerGoals {
808
+ /** Short-term goals (days to weeks) */
697
809
  shortTerm: string[]
810
+ /** Long-term goals (months to year) */
698
811
  longTerm: string[]
812
+ /** Strategic goals (multi-year vision) */
699
813
  strategic?: string[]
700
- metrics?: KPI[]
814
+ /** Associated KPI metrics */
815
+ metrics?: WorkerKPI[]
701
816
  }
702
817
 
703
818
  /**
704
- * KPI definition
819
+ * WorkerKPI - simplified KPI for worker goals
820
+ *
821
+ * A simpler KPI interface used in WorkerGoals.metrics.
822
+ * For the full KPI type with id, category, history, etc.,
823
+ * use KPI from org.ai.
705
824
  */
706
- export interface KPI {
825
+ export interface WorkerKPI {
826
+ /** KPI name */
707
827
  name: string
828
+ /** Description of what this measures */
708
829
  description: string
830
+ /** Current value */
709
831
  current: number
832
+ /** Target value */
710
833
  target: number
834
+ /** Unit of measurement */
711
835
  unit: string
836
+ /** Trend direction */
712
837
  trend?: 'up' | 'down' | 'stable'
838
+ /** Measurement period */
713
839
  period?: string
714
840
  }
715
841
 
716
842
  /**
717
- * OKR definition
843
+ * WorkerOKR - worker-specific OKR definition
844
+ *
845
+ * Uses WorkerRef for owner and simplified key results with
846
+ * required `current` and `target` fields for progress tracking.
847
+ * For the full org.ai OKR with `id`, `status`, `period`, etc.,
848
+ * import OKR from 'org.ai' directly.
718
849
  */
719
- export interface OKR {
850
+ export interface WorkerOKR {
851
+ /** The objective - what you want to achieve */
720
852
  objective: string
853
+ /** Measurable key results */
721
854
  keyResults: Array<{
722
855
  name: string
723
856
  current: number
724
857
  target: number
725
858
  unit: string
726
859
  }>
860
+ /** Owner as WorkerRef */
727
861
  owner?: WorkerRef
862
+ /** Due date */
728
863
  dueDate?: Date
864
+ /** Overall progress percentage */
729
865
  progress?: number
730
866
  }
731
867
 
@@ -784,13 +920,7 @@ export interface DoOptions {
784
920
  /**
785
921
  * Content type for generation
786
922
  */
787
- export type GenerationType =
788
- | 'text'
789
- | 'code'
790
- | 'structured'
791
- | 'image'
792
- | 'video'
793
- | 'audio'
923
+ export type GenerationType = 'text' | 'code' | 'structured' | 'image' | 'video' | 'audio'
794
924
 
795
925
  /**
796
926
  * Options for content generation
@@ -842,10 +972,8 @@ export interface TypeCheckResult<T = unknown> {
842
972
  }
843
973
 
844
974
  // ============================================================================
845
- // Team Alias
975
+ // Team Alias - Backwards Compatibility
846
976
  // ============================================================================
847
977
 
848
- /**
849
- * @deprecated Use Team instead
850
- */
851
- export type WorkerTeam = Team
978
+ // WorkerTeam is now the primary type that extends Team from org.ai
979
+ // The base Team type is re-exported from org.ai
@@ -0,0 +1,21 @@
1
+ /**
2
+ * ID generation utilities for request tracking across transports
3
+ */
4
+
5
+ /**
6
+ * Generate a unique request ID with the specified prefix.
7
+ *
8
+ * Format: `{prefix}_{timestamp}_{random}`
9
+ * - prefix: Customizable identifier (default: 'req')
10
+ * - timestamp: Unix timestamp in milliseconds
11
+ * - random: 9-character base36 random string
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * generateRequestId() // 'req_1706454932123_k7x3m9n2p'
16
+ * generateRequestId('apr') // 'apr_1706454932123_k7x3m9n2p'
17
+ * ```
18
+ */
19
+ export function generateRequestId(prefix: string = 'req'): string {
20
+ return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`
21
+ }