human-in-the-loop 0.1.0 → 2.0.2

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/src/helpers.ts ADDED
@@ -0,0 +1,379 @@
1
+ /**
2
+ * Helper functions for common human-in-the-loop patterns
3
+ */
4
+
5
+ import type {
6
+ Role,
7
+ Team,
8
+ Goals,
9
+ KPIs,
10
+ OKRs,
11
+ Human as HumanType,
12
+ ApprovalResponse,
13
+ ReviewResponse,
14
+ } from './types.js'
15
+ import { Human } from './human.js'
16
+
17
+ /**
18
+ * Create a default Human instance for convenience
19
+ */
20
+ const defaultHuman = Human()
21
+
22
+ /**
23
+ * Define a human role
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const techLead = Role({
28
+ * id: 'tech-lead',
29
+ * name: 'Tech Lead',
30
+ * capabilities: ['approve-prs', 'deploy-prod'],
31
+ * escalatesTo: 'engineering-manager',
32
+ * })
33
+ * ```
34
+ */
35
+ export function Role(role: Role): Role {
36
+ return defaultHuman.defineRole(role)
37
+ }
38
+
39
+ /**
40
+ * Define a team
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * const engineering = Team({
45
+ * id: 'engineering',
46
+ * name: 'Engineering Team',
47
+ * members: ['alice', 'bob', 'charlie'],
48
+ * lead: 'alice',
49
+ * })
50
+ * ```
51
+ */
52
+ export function Team(team: Team): Team {
53
+ return defaultHuman.defineTeam(team)
54
+ }
55
+
56
+ /**
57
+ * Define goals for a team or individual
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * const q1Goals = Goals({
62
+ * id: 'q1-2024',
63
+ * objectives: [
64
+ * 'Launch v2.0',
65
+ * 'Improve performance by 50%',
66
+ * ],
67
+ * targetDate: new Date('2024-03-31'),
68
+ * })
69
+ * ```
70
+ */
71
+ export function Goals(goals: Goals): Goals {
72
+ return defaultHuman.defineGoals(goals)
73
+ }
74
+
75
+ /**
76
+ * Request approval from a human
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * const result = await approve({
81
+ * title: 'Deploy to production',
82
+ * description: 'Deploy v2.0.0 to production',
83
+ * subject: 'Production Deployment',
84
+ * input: { version: '2.0.0', environment: 'prod' },
85
+ * assignee: 'tech-lead@example.com',
86
+ * priority: 'high',
87
+ * })
88
+ *
89
+ * if (result.approved) {
90
+ * await deploy()
91
+ * }
92
+ * ```
93
+ */
94
+ export async function approve<TData = unknown>(params: {
95
+ title: string
96
+ description: string
97
+ subject: string
98
+ input: TData
99
+ assignee?: string | string[]
100
+ role?: string
101
+ team?: string
102
+ priority?: 'low' | 'normal' | 'high' | 'critical'
103
+ timeout?: number
104
+ escalatesTo?: string | string[]
105
+ requiresApproval?: boolean
106
+ approvers?: string[]
107
+ metadata?: Record<string, unknown>
108
+ }): Promise<ApprovalResponse> {
109
+ return defaultHuman.approve(params)
110
+ }
111
+
112
+ /**
113
+ * Ask a question to a human
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * const answer = await ask({
118
+ * title: 'Product naming',
119
+ * question: 'What should we name the new feature?',
120
+ * context: { feature: 'AI Assistant' },
121
+ * assignee: 'product-manager@example.com',
122
+ * })
123
+ * ```
124
+ */
125
+ export async function ask(params: {
126
+ title: string
127
+ question: string
128
+ context?: unknown
129
+ assignee?: string | string[]
130
+ role?: string
131
+ team?: string
132
+ priority?: 'low' | 'normal' | 'high' | 'critical'
133
+ timeout?: number
134
+ suggestions?: string[]
135
+ metadata?: Record<string, unknown>
136
+ }): Promise<string> {
137
+ return defaultHuman.ask(params)
138
+ }
139
+
140
+ /**
141
+ * Request a human to perform a task
142
+ *
143
+ * This uses the digital-workers interface for humans
144
+ *
145
+ * @example
146
+ * ```ts
147
+ * const result = await do({
148
+ * title: 'Review code',
149
+ * instructions: 'Review the PR and provide feedback',
150
+ * input: { prUrl: 'https://github.com/...' },
151
+ * assignee: 'senior-dev@example.com',
152
+ * })
153
+ * ```
154
+ */
155
+ export async function do_<TInput = unknown, TOutput = unknown>(params: {
156
+ title: string
157
+ instructions: string
158
+ input: TInput
159
+ assignee?: string | string[]
160
+ role?: string
161
+ team?: string
162
+ priority?: 'low' | 'normal' | 'high' | 'critical'
163
+ timeout?: number
164
+ tools?: any[]
165
+ estimatedEffort?: string
166
+ metadata?: Record<string, unknown>
167
+ }): Promise<TOutput> {
168
+ return defaultHuman.do(params)
169
+ }
170
+
171
+ // Export as 'do' for the API, but define as 'do_' to avoid reserved keyword
172
+ export { do_ as do }
173
+
174
+ /**
175
+ * Request a human to make a decision
176
+ *
177
+ * @example
178
+ * ```ts
179
+ * const choice = await decide({
180
+ * title: 'Pick deployment strategy',
181
+ * options: ['blue-green', 'canary', 'rolling'],
182
+ * context: { risk: 'high', users: 100000 },
183
+ * assignee: 'devops-lead@example.com',
184
+ * })
185
+ * ```
186
+ */
187
+ export async function decide<TOptions extends string = string>(params: {
188
+ title: string
189
+ description?: string
190
+ options: TOptions[]
191
+ context?: unknown
192
+ assignee?: string | string[]
193
+ role?: string
194
+ team?: string
195
+ priority?: 'low' | 'normal' | 'high' | 'critical'
196
+ timeout?: number
197
+ criteria?: string[]
198
+ metadata?: Record<string, unknown>
199
+ }): Promise<TOptions> {
200
+ return defaultHuman.decide(params)
201
+ }
202
+
203
+ /**
204
+ * Request generation/content creation from a human
205
+ *
206
+ * This is a specialized form of do() for content generation
207
+ *
208
+ * @example
209
+ * ```ts
210
+ * const content = await generate({
211
+ * title: 'Write blog post',
212
+ * instructions: 'Write a blog post about our new feature',
213
+ * input: { topic: 'AI Assistant', targetAudience: 'developers' },
214
+ * assignee: 'content-writer@example.com',
215
+ * })
216
+ * ```
217
+ */
218
+ export async function generate<TInput = unknown>(params: {
219
+ title: string
220
+ instructions: string
221
+ input: TInput
222
+ assignee?: string | string[]
223
+ role?: string
224
+ team?: string
225
+ priority?: 'low' | 'normal' | 'high' | 'critical'
226
+ timeout?: number
227
+ metadata?: Record<string, unknown>
228
+ }): Promise<string> {
229
+ return defaultHuman.do<TInput, string>(params)
230
+ }
231
+
232
+ /**
233
+ * Type checking/validation request
234
+ *
235
+ * Ask a human to validate data or check type compliance
236
+ *
237
+ * @example
238
+ * ```ts
239
+ * const valid = await is({
240
+ * title: 'Validate user data',
241
+ * question: 'Is this user data valid and complete?',
242
+ * input: userData,
243
+ * assignee: 'data-specialist@example.com',
244
+ * })
245
+ * ```
246
+ */
247
+ export async function is(params: {
248
+ title: string
249
+ question: string
250
+ input: unknown
251
+ assignee?: string | string[]
252
+ role?: string
253
+ team?: string
254
+ priority?: 'low' | 'normal' | 'high' | 'critical'
255
+ timeout?: number
256
+ metadata?: Record<string, unknown>
257
+ }): Promise<boolean> {
258
+ const result = await defaultHuman.decide<'true' | 'false'>({
259
+ title: params.title,
260
+ description: params.question,
261
+ options: ['true', 'false'],
262
+ context: params.input,
263
+ assignee: params.assignee,
264
+ role: params.role,
265
+ team: params.team,
266
+ priority: params.priority,
267
+ timeout: params.timeout,
268
+ metadata: params.metadata,
269
+ })
270
+
271
+ return result === 'true'
272
+ }
273
+
274
+ /**
275
+ * Send a notification to a human
276
+ *
277
+ * @example
278
+ * ```ts
279
+ * await notify({
280
+ * type: 'info',
281
+ * title: 'Deployment complete',
282
+ * message: 'Version 2.0.0 deployed successfully',
283
+ * recipient: 'team@example.com',
284
+ * channels: ['slack', 'email'],
285
+ * })
286
+ * ```
287
+ */
288
+ export async function notify(params: {
289
+ type: 'info' | 'warning' | 'error' | 'success'
290
+ title: string
291
+ message: string
292
+ recipient: string | string[]
293
+ channels?: ('slack' | 'email' | 'sms' | 'web')[]
294
+ priority?: 'low' | 'normal' | 'high' | 'critical'
295
+ data?: unknown
296
+ }): Promise<void> {
297
+ await defaultHuman.notify(params)
298
+ }
299
+
300
+ /**
301
+ * Track Key Performance Indicators
302
+ *
303
+ * @example
304
+ * ```ts
305
+ * kpis({
306
+ * id: 'monthly-revenue',
307
+ * name: 'Monthly Revenue',
308
+ * value: 150000,
309
+ * target: 200000,
310
+ * unit: 'USD',
311
+ * trend: 'up',
312
+ * })
313
+ * ```
314
+ */
315
+ export function kpis(kpis: KPIs): KPIs {
316
+ return defaultHuman.trackKPIs(kpis)
317
+ }
318
+
319
+ /**
320
+ * Define Objectives and Key Results
321
+ *
322
+ * @example
323
+ * ```ts
324
+ * okrs({
325
+ * id: 'q1-2024-growth',
326
+ * objective: 'Accelerate user growth',
327
+ * keyResults: [
328
+ * {
329
+ * description: 'Increase active users by 50%',
330
+ * progress: 0.3,
331
+ * current: 13000,
332
+ * target: 15000,
333
+ * },
334
+ * {
335
+ * description: 'Achieve 95% customer satisfaction',
336
+ * progress: 0.85,
337
+ * current: 0.93,
338
+ * target: 0.95,
339
+ * },
340
+ * ],
341
+ * period: 'Q1 2024',
342
+ * owner: 'ceo@example.com',
343
+ * })
344
+ * ```
345
+ */
346
+ export function okrs(okrs: OKRs): OKRs {
347
+ return defaultHuman.defineOKRs(okrs)
348
+ }
349
+
350
+ /**
351
+ * Register a human worker in the system
352
+ *
353
+ * @example
354
+ * ```ts
355
+ * const alice = registerHuman({
356
+ * id: 'alice',
357
+ * name: 'Alice Smith',
358
+ * email: 'alice@example.com',
359
+ * roles: ['tech-lead', 'developer'],
360
+ * teams: ['engineering', 'frontend'],
361
+ * channels: {
362
+ * slack: '@alice',
363
+ * email: 'alice@example.com',
364
+ * },
365
+ * })
366
+ * ```
367
+ */
368
+ export function registerHuman(human: HumanType): HumanType {
369
+ return defaultHuman.registerHuman(human)
370
+ }
371
+
372
+ /**
373
+ * Get the default Human manager instance
374
+ *
375
+ * Use this to access the underlying HumanManager for advanced operations
376
+ */
377
+ export function getDefaultHuman(): ReturnType<typeof Human> {
378
+ return defaultHuman
379
+ }