digital-workers 0.1.1 → 2.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.
- package/.turbo/turbo-build.log +5 -0
- package/CHANGELOG.md +9 -0
- package/README.md +290 -106
- package/dist/actions.d.ts +95 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +437 -0
- package/dist/actions.js.map +1 -0
- package/dist/approve.d.ts +49 -0
- package/dist/approve.d.ts.map +1 -0
- package/dist/approve.js +235 -0
- package/dist/approve.js.map +1 -0
- package/dist/ask.d.ts +42 -0
- package/dist/ask.d.ts.map +1 -0
- package/dist/ask.js +227 -0
- package/dist/ask.js.map +1 -0
- package/dist/decide.d.ts +62 -0
- package/dist/decide.d.ts.map +1 -0
- package/dist/decide.js +245 -0
- package/dist/decide.js.map +1 -0
- package/dist/do.d.ts +63 -0
- package/dist/do.d.ts.map +1 -0
- package/dist/do.js +228 -0
- package/dist/do.js.map +1 -0
- package/dist/generate.d.ts +61 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +299 -0
- package/dist/generate.js.map +1 -0
- package/dist/goals.d.ts +89 -0
- package/dist/goals.d.ts.map +1 -0
- package/dist/goals.js +206 -0
- package/dist/goals.js.map +1 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/is.d.ts +54 -0
- package/dist/is.d.ts.map +1 -0
- package/dist/is.js +318 -0
- package/dist/is.js.map +1 -0
- package/dist/kpis.d.ts +103 -0
- package/dist/kpis.d.ts.map +1 -0
- package/dist/kpis.js +271 -0
- package/dist/kpis.js.map +1 -0
- package/dist/notify.d.ts +47 -0
- package/dist/notify.d.ts.map +1 -0
- package/dist/notify.js +220 -0
- package/dist/notify.js.map +1 -0
- package/dist/role.d.ts +53 -0
- package/dist/role.d.ts.map +1 -0
- package/dist/role.js +111 -0
- package/dist/role.js.map +1 -0
- package/dist/team.d.ts +61 -0
- package/dist/team.d.ts.map +1 -0
- package/dist/team.js +131 -0
- package/dist/team.js.map +1 -0
- package/dist/transports.d.ts +164 -0
- package/dist/transports.d.ts.map +1 -0
- package/dist/transports.js +358 -0
- package/dist/transports.js.map +1 -0
- package/dist/types.d.ts +693 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +72 -0
- package/dist/types.js.map +1 -0
- package/package.json +27 -61
- package/src/actions.ts +615 -0
- package/src/approve.ts +317 -0
- package/src/ask.ts +304 -0
- package/src/decide.ts +295 -0
- package/src/do.ts +275 -0
- package/src/generate.ts +364 -0
- package/src/goals.ts +220 -0
- package/src/index.ts +118 -0
- package/src/is.ts +372 -0
- package/src/kpis.ts +348 -0
- package/src/notify.ts +303 -0
- package/src/role.ts +116 -0
- package/src/team.ts +142 -0
- package/src/transports.ts +504 -0
- package/src/types.ts +843 -0
- package/test/actions.test.ts +546 -0
- package/test/standalone.test.ts +299 -0
- package/test/types.test.ts +460 -0
- package/tsconfig.json +9 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,843 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for digital-workers
|
|
3
|
+
*
|
|
4
|
+
* Digital workers (Agents and Humans) communicate through Actions that integrate
|
|
5
|
+
* with the ai-workflows system. Worker actions (notify, ask, approve, decide)
|
|
6
|
+
* are durable workflow actions with Actor/Object semantics.
|
|
7
|
+
*
|
|
8
|
+
* ## Key Concepts
|
|
9
|
+
*
|
|
10
|
+
* - **Worker**: Common interface for Agent and Human
|
|
11
|
+
* - **Contacts**: How a worker can be reached (email, slack, phone, etc.)
|
|
12
|
+
* - **Action**: Durable workflow action (notify, ask, approve, decide)
|
|
13
|
+
* - **Team**: Group of workers with shared contacts
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { SimpleSchema } from 'ai-functions'
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Worker Types
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Worker type - either an AI agent or a human
|
|
26
|
+
*/
|
|
27
|
+
export type WorkerType = 'agent' | 'human'
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Worker status
|
|
31
|
+
*/
|
|
32
|
+
export type WorkerStatus =
|
|
33
|
+
| 'available' // Ready to accept work
|
|
34
|
+
| 'busy' // Currently working
|
|
35
|
+
| 'away' // Not available (break, offline)
|
|
36
|
+
| 'offline' // Disconnected
|
|
37
|
+
|
|
38
|
+
// ============================================================================
|
|
39
|
+
// Contact Channel Types
|
|
40
|
+
// ============================================================================
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Contact channel names - how workers can be reached
|
|
44
|
+
*/
|
|
45
|
+
export type ContactChannel =
|
|
46
|
+
| 'email' // Email communication
|
|
47
|
+
| 'slack' // Slack workspace
|
|
48
|
+
| 'teams' // Microsoft Teams
|
|
49
|
+
| 'discord' // Discord server
|
|
50
|
+
| 'phone' // Voice calls
|
|
51
|
+
| 'sms' // SMS text messages
|
|
52
|
+
| 'whatsapp' // WhatsApp messaging
|
|
53
|
+
| 'telegram' // Telegram messaging
|
|
54
|
+
| 'web' // Web UI/dashboard
|
|
55
|
+
| 'api' // Programmatic API
|
|
56
|
+
| 'webhook' // Webhook callbacks
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Email contact - simple string or config object
|
|
60
|
+
*/
|
|
61
|
+
export interface EmailContact {
|
|
62
|
+
address: string
|
|
63
|
+
name?: string
|
|
64
|
+
verified?: boolean
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Slack contact - mention, channel, or config
|
|
69
|
+
*/
|
|
70
|
+
export interface SlackContact {
|
|
71
|
+
workspace?: string
|
|
72
|
+
user?: string
|
|
73
|
+
channel?: string
|
|
74
|
+
botToken?: string
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Teams contact
|
|
79
|
+
*/
|
|
80
|
+
export interface TeamsContact {
|
|
81
|
+
tenant?: string
|
|
82
|
+
user?: string
|
|
83
|
+
team?: string
|
|
84
|
+
channel?: string
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Discord contact
|
|
89
|
+
*/
|
|
90
|
+
export interface DiscordContact {
|
|
91
|
+
server?: string
|
|
92
|
+
user?: string
|
|
93
|
+
channel?: string
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Phone contact
|
|
98
|
+
*/
|
|
99
|
+
export interface PhoneContact {
|
|
100
|
+
number: string
|
|
101
|
+
country?: string
|
|
102
|
+
verified?: boolean
|
|
103
|
+
voice?: string
|
|
104
|
+
language?: string
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* SMS contact
|
|
109
|
+
*/
|
|
110
|
+
export interface SmsContact {
|
|
111
|
+
number: string
|
|
112
|
+
verified?: boolean
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* WhatsApp contact
|
|
117
|
+
*/
|
|
118
|
+
export interface WhatsAppContact {
|
|
119
|
+
number: string
|
|
120
|
+
verified?: boolean
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Telegram contact
|
|
125
|
+
*/
|
|
126
|
+
export interface TelegramContact {
|
|
127
|
+
user?: string
|
|
128
|
+
chat?: string
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Web UI contact
|
|
133
|
+
*/
|
|
134
|
+
export interface WebContact {
|
|
135
|
+
url?: string
|
|
136
|
+
userId?: string
|
|
137
|
+
pushEnabled?: boolean
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* API contact (for agents)
|
|
142
|
+
*/
|
|
143
|
+
export interface ApiContact {
|
|
144
|
+
endpoint: string
|
|
145
|
+
auth?: 'bearer' | 'api-key' | 'oauth' | 'none'
|
|
146
|
+
version?: string
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Webhook contact
|
|
151
|
+
*/
|
|
152
|
+
export interface WebhookContact {
|
|
153
|
+
url: string
|
|
154
|
+
secret?: string
|
|
155
|
+
events?: string[]
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Contacts - how a worker can be reached
|
|
160
|
+
*
|
|
161
|
+
* Each channel can be a simple string or a config object.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```ts
|
|
165
|
+
* contacts: {
|
|
166
|
+
* email: 'alice@company.com',
|
|
167
|
+
* slack: { workspace: 'acme', user: 'U123' },
|
|
168
|
+
* phone: '+1-555-1234',
|
|
169
|
+
* }
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
export interface Contacts {
|
|
173
|
+
email?: string | EmailContact
|
|
174
|
+
slack?: string | SlackContact
|
|
175
|
+
teams?: string | TeamsContact
|
|
176
|
+
discord?: string | DiscordContact
|
|
177
|
+
phone?: string | PhoneContact
|
|
178
|
+
sms?: string | SmsContact
|
|
179
|
+
whatsapp?: string | WhatsAppContact
|
|
180
|
+
telegram?: string | TelegramContact
|
|
181
|
+
web?: string | WebContact
|
|
182
|
+
api?: string | ApiContact
|
|
183
|
+
webhook?: string | WebhookContact
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Contact preferences for routing
|
|
188
|
+
*/
|
|
189
|
+
export interface ContactPreferences {
|
|
190
|
+
primary?: ContactChannel
|
|
191
|
+
urgent?: ContactChannel
|
|
192
|
+
fallback?: ContactChannel[]
|
|
193
|
+
quietHours?: {
|
|
194
|
+
start: string
|
|
195
|
+
end: string
|
|
196
|
+
timezone?: string
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// ============================================================================
|
|
201
|
+
// Core Worker Interface
|
|
202
|
+
// ============================================================================
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Worker - common interface for Agent and Human
|
|
206
|
+
*
|
|
207
|
+
* Workers are execution entities that can perform tasks and be reached
|
|
208
|
+
* through their configured contact channels.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```ts
|
|
212
|
+
* const alice: Worker = {
|
|
213
|
+
* id: 'user_alice',
|
|
214
|
+
* name: 'Alice',
|
|
215
|
+
* type: 'human',
|
|
216
|
+
* status: 'available',
|
|
217
|
+
* contacts: {
|
|
218
|
+
* email: 'alice@company.com',
|
|
219
|
+
* slack: { workspace: 'acme', user: 'U123' },
|
|
220
|
+
* phone: '+1-555-1234',
|
|
221
|
+
* },
|
|
222
|
+
* }
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
export interface Worker {
|
|
226
|
+
id: string
|
|
227
|
+
name: string
|
|
228
|
+
type: WorkerType
|
|
229
|
+
status: WorkerStatus
|
|
230
|
+
contacts: Contacts
|
|
231
|
+
preferences?: ContactPreferences
|
|
232
|
+
role?: WorkerRole
|
|
233
|
+
teams?: string[]
|
|
234
|
+
skills?: string[]
|
|
235
|
+
tools?: string[]
|
|
236
|
+
metadata?: Record<string, unknown>
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Worker reference - lightweight reference
|
|
241
|
+
*/
|
|
242
|
+
export interface WorkerRef {
|
|
243
|
+
id: string
|
|
244
|
+
type?: WorkerType
|
|
245
|
+
name?: string
|
|
246
|
+
role?: string
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// ============================================================================
|
|
250
|
+
// Team Interface
|
|
251
|
+
// ============================================================================
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Team - group of workers with shared contacts
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* ```ts
|
|
258
|
+
* const engineering: Team = {
|
|
259
|
+
* id: 'team_eng',
|
|
260
|
+
* name: 'Engineering',
|
|
261
|
+
* members: [alice, bob, deployBot],
|
|
262
|
+
* contacts: {
|
|
263
|
+
* slack: '#engineering',
|
|
264
|
+
* email: 'eng@company.com',
|
|
265
|
+
* },
|
|
266
|
+
* }
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
269
|
+
export interface Team {
|
|
270
|
+
id: string
|
|
271
|
+
name: string
|
|
272
|
+
description?: string
|
|
273
|
+
members: WorkerRef[]
|
|
274
|
+
contacts: Contacts
|
|
275
|
+
lead?: WorkerRef
|
|
276
|
+
goals?: string[]
|
|
277
|
+
metadata?: Record<string, unknown>
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// ============================================================================
|
|
281
|
+
// Action Types - Workflow Integration
|
|
282
|
+
// ============================================================================
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Worker action types
|
|
286
|
+
*
|
|
287
|
+
* These are the actions that can be performed on/by workers.
|
|
288
|
+
* They integrate with ai-workflows as durable actions.
|
|
289
|
+
*/
|
|
290
|
+
export type WorkerAction = 'notify' | 'ask' | 'approve' | 'decide' | 'do'
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Base action data - integrates with ai-workflows ActionData
|
|
294
|
+
*
|
|
295
|
+
* Every worker action has:
|
|
296
|
+
* - actor: Who is performing/initiating the action
|
|
297
|
+
* - object: Who/what is being acted upon
|
|
298
|
+
* - action: The action type
|
|
299
|
+
* - via: Channel(s) to use
|
|
300
|
+
*/
|
|
301
|
+
export interface WorkerActionData {
|
|
302
|
+
/** Who is performing/initiating the action */
|
|
303
|
+
actor: WorkerRef | string
|
|
304
|
+
/** Who/what is being acted upon */
|
|
305
|
+
object: Worker | Team | WorkerRef | string
|
|
306
|
+
/** The action being performed */
|
|
307
|
+
action: WorkerAction
|
|
308
|
+
/** Channel(s) to use */
|
|
309
|
+
via?: ContactChannel | ContactChannel[]
|
|
310
|
+
/** Action status */
|
|
311
|
+
status?: 'pending' | 'active' | 'completed' | 'failed'
|
|
312
|
+
/** Additional metadata */
|
|
313
|
+
metadata?: Record<string, unknown>
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Notify action data
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* ```ts
|
|
321
|
+
* await $.do('Worker.notify', {
|
|
322
|
+
* actor: system,
|
|
323
|
+
* object: alice,
|
|
324
|
+
* message: 'Deployment complete',
|
|
325
|
+
* via: 'slack',
|
|
326
|
+
* })
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
329
|
+
export interface NotifyActionData extends WorkerActionData {
|
|
330
|
+
action: 'notify'
|
|
331
|
+
message: string
|
|
332
|
+
priority?: 'low' | 'normal' | 'high' | 'urgent'
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Ask action data
|
|
337
|
+
*
|
|
338
|
+
* @example
|
|
339
|
+
* ```ts
|
|
340
|
+
* const answer = await $.do('Worker.ask', {
|
|
341
|
+
* actor: system,
|
|
342
|
+
* object: alice,
|
|
343
|
+
* question: 'What is the priority?',
|
|
344
|
+
* via: 'slack',
|
|
345
|
+
* schema: { priority: 'low | normal | high' },
|
|
346
|
+
* })
|
|
347
|
+
* ```
|
|
348
|
+
*/
|
|
349
|
+
export interface AskActionData extends WorkerActionData {
|
|
350
|
+
action: 'ask'
|
|
351
|
+
question: string
|
|
352
|
+
schema?: SimpleSchema
|
|
353
|
+
timeout?: number
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Approve action data
|
|
358
|
+
*
|
|
359
|
+
* @example
|
|
360
|
+
* ```ts
|
|
361
|
+
* const result = await $.do('Worker.approve', {
|
|
362
|
+
* actor: manager,
|
|
363
|
+
* object: expense,
|
|
364
|
+
* request: 'Expense: $500 for AWS',
|
|
365
|
+
* via: 'slack',
|
|
366
|
+
* })
|
|
367
|
+
* ```
|
|
368
|
+
*/
|
|
369
|
+
export interface ApproveActionData extends WorkerActionData {
|
|
370
|
+
action: 'approve'
|
|
371
|
+
request: string
|
|
372
|
+
context?: Record<string, unknown>
|
|
373
|
+
timeout?: number
|
|
374
|
+
escalate?: boolean
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Decide action data
|
|
379
|
+
*
|
|
380
|
+
* @example
|
|
381
|
+
* ```ts
|
|
382
|
+
* const decision = await $.do('Worker.decide', {
|
|
383
|
+
* actor: alice,
|
|
384
|
+
* object: 'technology choice',
|
|
385
|
+
* options: ['React', 'Vue', 'Svelte'],
|
|
386
|
+
* criteria: ['DX', 'Performance', 'Ecosystem'],
|
|
387
|
+
* })
|
|
388
|
+
* ```
|
|
389
|
+
*/
|
|
390
|
+
export interface DecideActionData extends WorkerActionData {
|
|
391
|
+
action: 'decide'
|
|
392
|
+
options: unknown[]
|
|
393
|
+
context?: string | Record<string, unknown>
|
|
394
|
+
criteria?: string[]
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Do action data - execute a task
|
|
399
|
+
*
|
|
400
|
+
* @example
|
|
401
|
+
* ```ts
|
|
402
|
+
* const result = await $.do('Worker.do', {
|
|
403
|
+
* actor: deployBot,
|
|
404
|
+
* object: 'production',
|
|
405
|
+
* instruction: 'Deploy v2.1.0',
|
|
406
|
+
* })
|
|
407
|
+
* ```
|
|
408
|
+
*/
|
|
409
|
+
export interface DoActionData extends WorkerActionData {
|
|
410
|
+
action: 'do'
|
|
411
|
+
instruction: string
|
|
412
|
+
timeout?: number
|
|
413
|
+
maxRetries?: number
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// ============================================================================
|
|
417
|
+
// Action Results
|
|
418
|
+
// ============================================================================
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Notify result
|
|
422
|
+
*/
|
|
423
|
+
export interface NotifyResult {
|
|
424
|
+
sent: boolean
|
|
425
|
+
via: ContactChannel[]
|
|
426
|
+
recipients?: WorkerRef[]
|
|
427
|
+
sentAt?: Date
|
|
428
|
+
messageId?: string
|
|
429
|
+
delivery?: Array<{
|
|
430
|
+
channel: ContactChannel
|
|
431
|
+
status: 'sent' | 'delivered' | 'failed'
|
|
432
|
+
error?: string
|
|
433
|
+
}>
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Ask result
|
|
438
|
+
*/
|
|
439
|
+
export interface AskResult<T = string> {
|
|
440
|
+
answer: T
|
|
441
|
+
answeredBy?: WorkerRef
|
|
442
|
+
answeredAt?: Date
|
|
443
|
+
via?: ContactChannel
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Approve result
|
|
448
|
+
*/
|
|
449
|
+
export interface ApprovalResult {
|
|
450
|
+
approved: boolean
|
|
451
|
+
approvedBy?: WorkerRef
|
|
452
|
+
approvedAt?: Date
|
|
453
|
+
notes?: string
|
|
454
|
+
via?: ContactChannel
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Decide result
|
|
459
|
+
*/
|
|
460
|
+
export interface DecideResult<T = string> {
|
|
461
|
+
choice: T
|
|
462
|
+
reasoning: string
|
|
463
|
+
confidence: number
|
|
464
|
+
alternatives?: Array<{ option: T; score: number }>
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Do result
|
|
469
|
+
*/
|
|
470
|
+
export interface DoResult<T = unknown> {
|
|
471
|
+
result: T
|
|
472
|
+
success: boolean
|
|
473
|
+
error?: string
|
|
474
|
+
duration?: number
|
|
475
|
+
steps?: Array<{
|
|
476
|
+
action: string
|
|
477
|
+
result: unknown
|
|
478
|
+
timestamp: Date
|
|
479
|
+
}>
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// ============================================================================
|
|
483
|
+
// Worker Verbs - Following ai-database Verb pattern
|
|
484
|
+
// ============================================================================
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Worker verbs following the ai-database conjugation pattern
|
|
488
|
+
*
|
|
489
|
+
* Each verb has:
|
|
490
|
+
* - action: Base form (notify, ask, approve, decide)
|
|
491
|
+
* - actor: Who does it (notifier, asker, approver, decider)
|
|
492
|
+
* - activity: Gerund (notifying, asking, approving, deciding)
|
|
493
|
+
* - reverse: Past forms (notifiedAt, notifiedBy, askedAt, etc.)
|
|
494
|
+
*/
|
|
495
|
+
export const WorkerVerbs = {
|
|
496
|
+
notify: {
|
|
497
|
+
action: 'notify',
|
|
498
|
+
actor: 'notifier',
|
|
499
|
+
act: 'notifies',
|
|
500
|
+
activity: 'notifying',
|
|
501
|
+
result: 'notification',
|
|
502
|
+
reverse: { at: 'notifiedAt', by: 'notifiedBy', via: 'notifiedVia' },
|
|
503
|
+
},
|
|
504
|
+
ask: {
|
|
505
|
+
action: 'ask',
|
|
506
|
+
actor: 'asker',
|
|
507
|
+
act: 'asks',
|
|
508
|
+
activity: 'asking',
|
|
509
|
+
result: 'question',
|
|
510
|
+
reverse: { at: 'askedAt', by: 'askedBy', via: 'askedVia' },
|
|
511
|
+
},
|
|
512
|
+
approve: {
|
|
513
|
+
action: 'approve',
|
|
514
|
+
actor: 'approver',
|
|
515
|
+
act: 'approves',
|
|
516
|
+
activity: 'approving',
|
|
517
|
+
result: 'approval',
|
|
518
|
+
reverse: { at: 'approvedAt', by: 'approvedBy', via: 'approvedVia' },
|
|
519
|
+
inverse: 'reject',
|
|
520
|
+
},
|
|
521
|
+
decide: {
|
|
522
|
+
action: 'decide',
|
|
523
|
+
actor: 'decider',
|
|
524
|
+
act: 'decides',
|
|
525
|
+
activity: 'deciding',
|
|
526
|
+
result: 'decision',
|
|
527
|
+
reverse: { at: 'decidedAt', by: 'decidedBy' },
|
|
528
|
+
},
|
|
529
|
+
do: {
|
|
530
|
+
action: 'do',
|
|
531
|
+
actor: 'doer',
|
|
532
|
+
act: 'does',
|
|
533
|
+
activity: 'doing',
|
|
534
|
+
result: 'task',
|
|
535
|
+
reverse: { at: 'doneAt', by: 'doneBy' },
|
|
536
|
+
},
|
|
537
|
+
} as const
|
|
538
|
+
|
|
539
|
+
// ============================================================================
|
|
540
|
+
// Workflow Integration Types
|
|
541
|
+
// ============================================================================
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Worker event names for workflow registration
|
|
545
|
+
*
|
|
546
|
+
* These events can be handled via $.on.Worker.notify, $.on.Worker.ask, etc.
|
|
547
|
+
*/
|
|
548
|
+
export type WorkerEvent =
|
|
549
|
+
| 'Worker.notify'
|
|
550
|
+
| 'Worker.ask'
|
|
551
|
+
| 'Worker.approve'
|
|
552
|
+
| 'Worker.decide'
|
|
553
|
+
| 'Worker.do'
|
|
554
|
+
// Result events
|
|
555
|
+
| 'Worker.notified'
|
|
556
|
+
| 'Worker.answered'
|
|
557
|
+
| 'Worker.approved'
|
|
558
|
+
| 'Worker.rejected'
|
|
559
|
+
| 'Worker.decided'
|
|
560
|
+
| 'Worker.done'
|
|
561
|
+
| 'Worker.failed'
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Worker context extension for WorkflowContext
|
|
565
|
+
*
|
|
566
|
+
* Provides convenience methods on $ for worker actions.
|
|
567
|
+
*
|
|
568
|
+
* @example
|
|
569
|
+
* ```ts
|
|
570
|
+
* Workflow($ => {
|
|
571
|
+
* $.on.Expense.submitted(async (expense, $) => {
|
|
572
|
+
* // Use worker actions via $
|
|
573
|
+
* await $.notify(finance, `New expense: ${expense.amount}`)
|
|
574
|
+
*
|
|
575
|
+
* const approval = await $.approve(expense.description, manager, {
|
|
576
|
+
* via: 'slack',
|
|
577
|
+
* context: { amount: expense.amount },
|
|
578
|
+
* })
|
|
579
|
+
*
|
|
580
|
+
* if (approval.approved) {
|
|
581
|
+
* await $.notify(expense.submitter, 'Your expense was approved!')
|
|
582
|
+
* }
|
|
583
|
+
* })
|
|
584
|
+
* })
|
|
585
|
+
* ```
|
|
586
|
+
*/
|
|
587
|
+
export interface WorkerContext {
|
|
588
|
+
/**
|
|
589
|
+
* Send a notification to a worker/team
|
|
590
|
+
*/
|
|
591
|
+
notify(
|
|
592
|
+
target: Worker | Team | WorkerRef | string,
|
|
593
|
+
message: string,
|
|
594
|
+
options?: NotifyOptions
|
|
595
|
+
): Promise<NotifyResult>
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Ask a question to a worker/team
|
|
599
|
+
*/
|
|
600
|
+
ask<T = string>(
|
|
601
|
+
target: Worker | Team | WorkerRef | string,
|
|
602
|
+
question: string,
|
|
603
|
+
options?: AskOptions
|
|
604
|
+
): Promise<AskResult<T>>
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Request approval from a worker/team
|
|
608
|
+
*/
|
|
609
|
+
approve(
|
|
610
|
+
request: string,
|
|
611
|
+
target: Worker | Team | WorkerRef | string,
|
|
612
|
+
options?: ApproveOptions
|
|
613
|
+
): Promise<ApprovalResult>
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Make a decision (AI or human)
|
|
617
|
+
*/
|
|
618
|
+
decide<T = string>(
|
|
619
|
+
options: DecideOptions<T>
|
|
620
|
+
): Promise<DecideResult<T>>
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// ============================================================================
|
|
624
|
+
// Action Options
|
|
625
|
+
// ============================================================================
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Base options for worker actions
|
|
629
|
+
*/
|
|
630
|
+
export interface ActionOptions {
|
|
631
|
+
via?: ContactChannel | ContactChannel[]
|
|
632
|
+
timeout?: number
|
|
633
|
+
context?: Record<string, unknown>
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Notify options
|
|
638
|
+
*/
|
|
639
|
+
export interface NotifyOptions extends ActionOptions {
|
|
640
|
+
priority?: 'low' | 'normal' | 'high' | 'urgent'
|
|
641
|
+
fallback?: boolean
|
|
642
|
+
metadata?: Record<string, unknown>
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Ask options
|
|
647
|
+
*/
|
|
648
|
+
export interface AskOptions extends ActionOptions {
|
|
649
|
+
schema?: SimpleSchema
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Approve options
|
|
654
|
+
*/
|
|
655
|
+
export interface ApproveOptions extends ActionOptions {
|
|
656
|
+
escalate?: boolean
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Decide options
|
|
661
|
+
*/
|
|
662
|
+
export interface DecideOptions<T = string> {
|
|
663
|
+
options: T[]
|
|
664
|
+
context?: string | Record<string, unknown>
|
|
665
|
+
criteria?: string[]
|
|
666
|
+
includeReasoning?: boolean
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// ============================================================================
|
|
670
|
+
// Role and Goals
|
|
671
|
+
// ============================================================================
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Worker role definition
|
|
675
|
+
*/
|
|
676
|
+
export interface WorkerRole {
|
|
677
|
+
name: string
|
|
678
|
+
description: string
|
|
679
|
+
responsibilities: string[]
|
|
680
|
+
skills?: string[]
|
|
681
|
+
permissions?: string[]
|
|
682
|
+
type?: 'ai' | 'human' | 'hybrid'
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
/**
|
|
686
|
+
* Worker goals
|
|
687
|
+
*/
|
|
688
|
+
export interface WorkerGoals {
|
|
689
|
+
shortTerm: string[]
|
|
690
|
+
longTerm: string[]
|
|
691
|
+
strategic?: string[]
|
|
692
|
+
metrics?: KPI[]
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* KPI definition
|
|
697
|
+
*/
|
|
698
|
+
export interface KPI {
|
|
699
|
+
name: string
|
|
700
|
+
description: string
|
|
701
|
+
current: number
|
|
702
|
+
target: number
|
|
703
|
+
unit: string
|
|
704
|
+
trend?: 'up' | 'down' | 'stable'
|
|
705
|
+
period?: string
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* OKR definition
|
|
710
|
+
*/
|
|
711
|
+
export interface OKR {
|
|
712
|
+
objective: string
|
|
713
|
+
keyResults: Array<{
|
|
714
|
+
name: string
|
|
715
|
+
current: number
|
|
716
|
+
target: number
|
|
717
|
+
unit: string
|
|
718
|
+
}>
|
|
719
|
+
owner?: WorkerRef
|
|
720
|
+
dueDate?: Date
|
|
721
|
+
progress?: number
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// ============================================================================
|
|
725
|
+
// Utility Types
|
|
726
|
+
// ============================================================================
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* Target for an action - Worker, Team, or reference
|
|
730
|
+
*/
|
|
731
|
+
export type ActionTarget = Worker | Team | WorkerRef | string
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Union of all action data types
|
|
735
|
+
*/
|
|
736
|
+
export type AnyWorkerActionData =
|
|
737
|
+
| NotifyActionData
|
|
738
|
+
| AskActionData
|
|
739
|
+
| ApproveActionData
|
|
740
|
+
| DecideActionData
|
|
741
|
+
| DoActionData
|
|
742
|
+
|
|
743
|
+
// ============================================================================
|
|
744
|
+
// Backwards Compatibility Aliases
|
|
745
|
+
// ============================================================================
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
* @deprecated Use DecideResult instead
|
|
749
|
+
*/
|
|
750
|
+
export type Decision<T = string> = DecideResult<T>
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* @deprecated Use DoResult instead
|
|
754
|
+
*/
|
|
755
|
+
export type TaskResult<T = unknown> = DoResult<T>
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* @deprecated Use ApproveOptions instead
|
|
759
|
+
*/
|
|
760
|
+
export type ApprovalOptions = ApproveOptions
|
|
761
|
+
|
|
762
|
+
/**
|
|
763
|
+
* Options for task execution
|
|
764
|
+
*/
|
|
765
|
+
export interface DoOptions {
|
|
766
|
+
maxRetries?: number
|
|
767
|
+
timeout?: number
|
|
768
|
+
background?: boolean
|
|
769
|
+
context?: Record<string, unknown>
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
// ============================================================================
|
|
773
|
+
// Generation Types
|
|
774
|
+
// ============================================================================
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* Content type for generation
|
|
778
|
+
*/
|
|
779
|
+
export type GenerationType =
|
|
780
|
+
| 'text'
|
|
781
|
+
| 'code'
|
|
782
|
+
| 'structured'
|
|
783
|
+
| 'image'
|
|
784
|
+
| 'video'
|
|
785
|
+
| 'audio'
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Options for content generation
|
|
789
|
+
*/
|
|
790
|
+
export interface GenerateOptions {
|
|
791
|
+
type?: GenerationType
|
|
792
|
+
model?: string
|
|
793
|
+
instructions?: string
|
|
794
|
+
schema?: import('ai-functions').SimpleSchema
|
|
795
|
+
maxTokens?: number
|
|
796
|
+
temperature?: number
|
|
797
|
+
format?: string
|
|
798
|
+
language?: string
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Result of content generation
|
|
803
|
+
*/
|
|
804
|
+
export interface GenerateResult<T = string> {
|
|
805
|
+
content: T
|
|
806
|
+
type: GenerationType
|
|
807
|
+
model?: string
|
|
808
|
+
tokensUsed?: number
|
|
809
|
+
cached?: boolean
|
|
810
|
+
metadata?: Record<string, unknown>
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
// ============================================================================
|
|
814
|
+
// Type Checking Types
|
|
815
|
+
// ============================================================================
|
|
816
|
+
|
|
817
|
+
/**
|
|
818
|
+
* Options for type checking
|
|
819
|
+
*/
|
|
820
|
+
export interface IsOptions {
|
|
821
|
+
coerce?: boolean
|
|
822
|
+
strict?: boolean
|
|
823
|
+
errorMessages?: Record<string, string>
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Result of type checking
|
|
828
|
+
*/
|
|
829
|
+
export interface TypeCheckResult<T = unknown> {
|
|
830
|
+
valid: boolean
|
|
831
|
+
value?: T
|
|
832
|
+
errors?: string[]
|
|
833
|
+
coerced?: boolean
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
// ============================================================================
|
|
837
|
+
// Team Alias
|
|
838
|
+
// ============================================================================
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* @deprecated Use Team instead
|
|
842
|
+
*/
|
|
843
|
+
export type WorkerTeam = Team
|