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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +17 -0
- package/README.md +2 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +33 -21
- package/dist/actions.js.map +1 -1
- package/dist/agent-comms.d.ts.map +1 -1
- package/dist/agent-comms.js +36 -25
- package/dist/agent-comms.js.map +1 -1
- package/dist/approve.d.ts +40 -8
- package/dist/approve.d.ts.map +1 -1
- package/dist/approve.js +86 -20
- package/dist/approve.js.map +1 -1
- package/dist/ask.d.ts +38 -7
- package/dist/ask.d.ts.map +1 -1
- package/dist/ask.js +85 -25
- package/dist/ask.js.map +1 -1
- package/dist/browse.d.ts +223 -0
- package/dist/browse.d.ts.map +1 -0
- package/dist/browse.js +392 -0
- package/dist/browse.js.map +1 -0
- package/dist/capability-tiers.js +3 -3
- package/dist/capability-tiers.js.map +1 -1
- package/dist/cascade-context.d.ts +28 -28
- package/dist/client.d.ts +162 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +64 -0
- package/dist/client.js.map +1 -0
- package/dist/decide.d.ts +42 -6
- package/dist/decide.d.ts.map +1 -1
- package/dist/decide.js +54 -11
- package/dist/decide.js.map +1 -1
- package/dist/do.d.ts +36 -7
- package/dist/do.d.ts.map +1 -1
- package/dist/do.js +82 -39
- package/dist/do.js.map +1 -1
- package/dist/error-escalation.d.ts.map +1 -1
- package/dist/error-escalation.js +38 -38
- package/dist/error-escalation.js.map +1 -1
- package/dist/generate.d.ts +48 -7
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +49 -8
- package/dist/generate.js.map +1 -1
- package/dist/goals.d.ts +10 -9
- package/dist/goals.d.ts.map +1 -1
- package/dist/goals.js +30 -24
- package/dist/goals.js.map +1 -1
- package/dist/image.d.ts +189 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +528 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +49 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +58 -2
- package/dist/index.js.map +1 -1
- package/dist/is.d.ts +45 -10
- package/dist/is.d.ts.map +1 -1
- package/dist/is.js +56 -21
- package/dist/is.js.map +1 -1
- package/dist/kpis.d.ts +24 -15
- package/dist/kpis.d.ts.map +1 -1
- package/dist/kpis.js +16 -14
- package/dist/kpis.js.map +1 -1
- package/dist/load-balancing.d.ts.map +1 -1
- package/dist/load-balancing.js +124 -38
- package/dist/load-balancing.js.map +1 -1
- package/dist/logger.d.ts +76 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +39 -0
- package/dist/logger.js.map +1 -0
- package/dist/notify.d.ts +38 -9
- package/dist/notify.d.ts.map +1 -1
- package/dist/notify.js +72 -17
- package/dist/notify.js.map +1 -1
- package/dist/role.d.ts +5 -4
- package/dist/role.d.ts.map +1 -1
- package/dist/role.js +13 -10
- package/dist/role.js.map +1 -1
- package/dist/runtime.d.ts +310 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +510 -0
- package/dist/runtime.js.map +1 -0
- package/dist/team.d.ts +11 -6
- package/dist/team.d.ts.map +1 -1
- package/dist/team.js +22 -15
- package/dist/team.js.map +1 -1
- package/dist/transports/email.d.ts +318 -0
- package/dist/transports/email.d.ts.map +1 -0
- package/dist/transports/email.js +779 -0
- package/dist/transports/email.js.map +1 -0
- package/dist/transports/slack.d.ts +515 -0
- package/dist/transports/slack.d.ts.map +1 -0
- package/dist/transports/slack.js +844 -0
- package/dist/transports/slack.js.map +1 -0
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +44 -25
- package/dist/transports.js.map +1 -1
- package/dist/types.d.ts +141 -19
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/id.d.ts +19 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +21 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/video.d.ts +203 -0
- package/dist/video.d.ts.map +1 -0
- package/dist/video.js +528 -0
- package/dist/video.js.map +1 -0
- package/dist/worker.d.ts +343 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +698 -0
- package/dist/worker.js.map +1 -0
- package/package.json +32 -14
- package/src/actions.ts +39 -30
- package/src/agent-comms.ts +54 -92
- package/src/approve.ts +91 -20
- package/src/ask.ts +99 -25
- package/src/browse.ts +627 -0
- package/src/capability-tiers.ts +5 -5
- package/src/client.ts +221 -0
- package/src/decide.ts +81 -35
- package/src/do.ts +98 -52
- package/src/error-escalation.ts +55 -67
- package/src/generate.ts +52 -18
- package/src/goals.ts +36 -27
- package/src/image.ts +816 -0
- package/src/index.ts +187 -2
- package/src/is.ts +59 -25
- package/src/kpis.ts +41 -36
- package/src/load-balancing.ts +132 -46
- package/src/logger.ts +93 -0
- package/src/notify.ts +78 -17
- package/src/role.ts +30 -20
- package/src/runtime.ts +796 -0
- package/src/team.ts +24 -19
- package/src/transports/email.ts +1160 -0
- package/src/transports/slack.ts +1320 -0
- package/src/transports.ts +58 -43
- package/src/types.ts +174 -46
- package/src/utils/id.ts +21 -0
- package/src/video.ts +906 -0
- package/src/worker.ts +1007 -0
- package/test/approve.test.ts +305 -0
- package/test/ask.test.ts +274 -0
- package/test/browse.test.ts +361 -0
- package/test/decide.test.ts +252 -0
- package/test/do.test.ts +144 -0
- package/test/error-logging.test.ts +357 -0
- package/test/generate.test.ts +319 -0
- package/test/image.test.ts +398 -0
- package/test/is.test.ts +287 -0
- package/test/load-balancing-safety.test.ts +404 -0
- package/test/notify.test.ts +434 -0
- package/test/primitives.test.ts +320 -0
- package/test/runtime-integration.test.ts +892 -0
- package/test/transports/crypto.test.ts +230 -0
- package/test/transports/email.test.ts +866 -0
- package/test/transports/id-generation.test.ts +91 -0
- package/test/transports/slack.test.ts +760 -0
- package/test/type-safety.test.ts +834 -0
- package/test/types.test.ts +60 -2
- package/test/video.test.ts +530 -0
- package/test/worker.test.ts +1433 -0
- package/tsconfig.json +4 -1
- package/vitest.config.ts +42 -0
- package/wrangler.jsonc +36 -0
- package/LICENSE +0 -21
- package/src/actions.js +0 -436
- package/src/approve.js +0 -234
- package/src/ask.js +0 -226
- package/src/decide.js +0 -244
- package/src/do.js +0 -227
- package/src/generate.js +0 -298
- package/src/goals.js +0 -205
- package/src/index.js +0 -68
- package/src/is.js +0 -317
- package/src/kpis.js +0 -270
- package/src/notify.js +0 -219
- package/src/role.js +0 -110
- package/src/team.js +0 -130
- package/src/transports.js +0 -357
- package/src/types.js +0 -71
package/src/approve.ts
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Approval request functionality for digital workers
|
|
3
|
+
*
|
|
4
|
+
* IMPORTANT: Worker Routing vs LLM Content Generation
|
|
5
|
+
* ---------------------------------------------------
|
|
6
|
+
* This module provides real approval workflows, NOT LLM-generated approval content.
|
|
7
|
+
*
|
|
8
|
+
* - `digital-workers.approve()` - Routes approval requests to Workers (Humans
|
|
9
|
+
* or AI Agents) via communication channels and waits for actual approval.
|
|
10
|
+
*
|
|
11
|
+
* - `ai-functions.approve()` - Generates approval request content via LLM
|
|
12
|
+
* for use in human interaction UIs.
|
|
13
|
+
*
|
|
14
|
+
* Use digital-workers when you need:
|
|
15
|
+
* - Real approval workflows with actual approvers
|
|
16
|
+
* - Routing to specific people via Slack, email, SMS
|
|
17
|
+
* - Approval audit trails (who, when, via what channel)
|
|
18
|
+
* - Multi-approver workflows (any/all must approve)
|
|
19
|
+
*
|
|
20
|
+
* Use ai-functions when you need:
|
|
21
|
+
* - LLM-generated approval request content
|
|
22
|
+
* - Generating UI/UX for approval flows
|
|
23
|
+
* - Approval request templates
|
|
24
|
+
*
|
|
25
|
+
* @module
|
|
3
26
|
*/
|
|
4
27
|
|
|
5
28
|
import type {
|
|
@@ -14,32 +37,41 @@ import type {
|
|
|
14
37
|
} from './types.js'
|
|
15
38
|
|
|
16
39
|
/**
|
|
17
|
-
*
|
|
40
|
+
* Route an approval request to a Worker (Human or AI Agent) and wait for response.
|
|
18
41
|
*
|
|
19
|
-
*
|
|
42
|
+
* **Key Difference from ai-functions.approve():**
|
|
43
|
+
* Unlike `ai-functions.approve()` which generates approval request content
|
|
44
|
+
* using the LLM, this function routes the request to an actual approver via
|
|
45
|
+
* real communication channels (Slack, email, SMS) and waits for their response.
|
|
46
|
+
*
|
|
47
|
+
* This is a **workflow approval primitive**, not a content generation primitive.
|
|
20
48
|
*
|
|
21
49
|
* @param request - What is being requested for approval
|
|
22
|
-
* @param target - The worker or team to request approval from
|
|
23
|
-
* @param options - Approval options
|
|
24
|
-
* @returns Promise resolving to approval result
|
|
50
|
+
* @param target - The worker or team to request approval from (routes to their channels)
|
|
51
|
+
* @param options - Approval options including channel, timeout, and context
|
|
52
|
+
* @returns Promise resolving to approval result with metadata (who approved, when, notes)
|
|
25
53
|
*
|
|
26
54
|
* @example
|
|
27
55
|
* ```ts
|
|
28
|
-
* // Request approval from a
|
|
56
|
+
* // Request approval from a human via Slack
|
|
29
57
|
* const result = await approve('Expense: $500 for AWS', manager, {
|
|
30
58
|
* via: 'slack',
|
|
31
59
|
* context: { amount: 500, category: 'Infrastructure' },
|
|
32
60
|
* })
|
|
33
61
|
*
|
|
34
62
|
* if (result.approved) {
|
|
35
|
-
* console.log(`Approved by ${result.approvedBy?.name}`)
|
|
63
|
+
* console.log(`Approved by ${result.approvedBy?.name} at ${result.approvedAt}`)
|
|
36
64
|
* }
|
|
37
65
|
*
|
|
38
|
-
* // Request approval from a team
|
|
66
|
+
* // Request approval from a team (routes to lead or available member)
|
|
39
67
|
* const result = await approve('Deploy v2.1.0 to production', opsTeam, {
|
|
40
68
|
* via: 'slack',
|
|
41
69
|
* })
|
|
42
70
|
* ```
|
|
71
|
+
*
|
|
72
|
+
* @see {@link ai-functions#approve} for LLM-generated approval request content
|
|
73
|
+
* @see {@link approve.all} for multi-approver workflows (all must approve)
|
|
74
|
+
* @see {@link approve.any} for multi-approver workflows (any can approve)
|
|
43
75
|
*/
|
|
44
76
|
export async function approve(
|
|
45
77
|
request: string,
|
|
@@ -60,8 +92,8 @@ export async function approve(
|
|
|
60
92
|
|
|
61
93
|
// Send the approval request and wait for response
|
|
62
94
|
const response = await sendApprovalRequest(channel, request, contacts, {
|
|
63
|
-
timeout,
|
|
64
|
-
context,
|
|
95
|
+
...(timeout !== undefined && { timeout }),
|
|
96
|
+
...(context !== undefined && { context }),
|
|
65
97
|
approver,
|
|
66
98
|
escalate,
|
|
67
99
|
})
|
|
@@ -70,7 +102,7 @@ export async function approve(
|
|
|
70
102
|
approved: response.approved,
|
|
71
103
|
approvedBy: approver,
|
|
72
104
|
approvedAt: new Date(),
|
|
73
|
-
notes: response.notes,
|
|
105
|
+
...(response.notes !== undefined && { notes: response.notes }),
|
|
74
106
|
via: channel,
|
|
75
107
|
}
|
|
76
108
|
}
|
|
@@ -300,18 +332,57 @@ async function sendApprovalRequest(
|
|
|
300
332
|
throw new Error(`No ${channel} contact configured`)
|
|
301
333
|
}
|
|
302
334
|
|
|
303
|
-
//
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
// 4. Handle timeout and escalation
|
|
335
|
+
// Import transport functions dynamically to avoid circular dependencies
|
|
336
|
+
const { channelToTransport, sendViaTransport, hasTransport, resolveAddress } = await import(
|
|
337
|
+
'./transports.js'
|
|
338
|
+
)
|
|
308
339
|
|
|
309
|
-
|
|
310
|
-
|
|
340
|
+
const transport = channelToTransport(channel)
|
|
341
|
+
const address = resolveAddress(contacts, channel)
|
|
342
|
+
|
|
343
|
+
// If transport is registered, use it for real delivery
|
|
344
|
+
if (hasTransport(transport) && address) {
|
|
345
|
+
const { generateRequestId } = await import('./utils/id.js')
|
|
346
|
+
const requestId = generateRequestId('apr')
|
|
347
|
+
|
|
348
|
+
const payload = {
|
|
349
|
+
to: address.value,
|
|
350
|
+
body: request,
|
|
351
|
+
type: 'approval' as const,
|
|
352
|
+
priority: 'normal' as const,
|
|
353
|
+
threadId: requestId,
|
|
354
|
+
actions: [
|
|
355
|
+
{ id: 'approve', label: 'Approve', style: 'primary' as const, value: true },
|
|
356
|
+
{ id: 'reject', label: 'Reject', style: 'danger' as const, value: false },
|
|
357
|
+
],
|
|
358
|
+
metadata: {
|
|
359
|
+
...options.context,
|
|
360
|
+
approver: options.approver,
|
|
361
|
+
escalate: options.escalate,
|
|
362
|
+
},
|
|
363
|
+
...(options.timeout !== undefined && { timeout: options.timeout }),
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const result = await sendViaTransport(transport, payload)
|
|
367
|
+
|
|
368
|
+
if (result.success) {
|
|
369
|
+
// For real transports, we need to wait for a response
|
|
370
|
+
// This would integrate with the runtime's HumanRequestProcessor
|
|
371
|
+
// For now, return pending state - the response comes via webhook
|
|
372
|
+
return {
|
|
373
|
+
approved: false,
|
|
374
|
+
notes: `Approval request sent via ${transport}. Awaiting response. Request ID: ${requestId}`,
|
|
375
|
+
}
|
|
376
|
+
} else {
|
|
377
|
+
throw new Error(`Failed to send approval request via ${transport}: ${result.error}`)
|
|
378
|
+
}
|
|
379
|
+
}
|
|
311
380
|
|
|
312
|
-
//
|
|
381
|
+
// No transport registered - return pending state
|
|
382
|
+
// In a real workflow, this would be processed when a transport is configured
|
|
383
|
+
// or the runtime handles the request via HumanRequestProcessor
|
|
313
384
|
return {
|
|
314
385
|
approved: false,
|
|
315
|
-
notes:
|
|
386
|
+
notes: `Approval request pending - no transport registered for ${channel}. Configure a transport handler to enable real delivery.`,
|
|
316
387
|
}
|
|
317
388
|
}
|
package/src/ask.ts
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Question/answer functionality for digital workers
|
|
3
|
+
*
|
|
4
|
+
* IMPORTANT: Worker Routing vs Direct LLM Calls
|
|
5
|
+
* ---------------------------------------------
|
|
6
|
+
* This module provides worker-routed question handling, NOT direct LLM queries.
|
|
7
|
+
*
|
|
8
|
+
* - `digital-workers.ask()` - Routes questions to Workers (AI Agents or Humans)
|
|
9
|
+
* via communication channels (Slack, email, SMS, etc.) and waits for response.
|
|
10
|
+
*
|
|
11
|
+
* - `ai-functions.ask()` - Generates content for human interaction via LLM.
|
|
12
|
+
*
|
|
13
|
+
* Use digital-workers when you need:
|
|
14
|
+
* - To ask a specific person or team via real channels
|
|
15
|
+
* - Human responses with accountability (who answered)
|
|
16
|
+
* - Channel-based communication (Slack, email, SMS)
|
|
17
|
+
* - Team coordination and escalation
|
|
18
|
+
*
|
|
19
|
+
* Use ai-functions when you need:
|
|
20
|
+
* - LLM-generated question/answer content
|
|
21
|
+
* - Generating UI for human input
|
|
22
|
+
* - Direct AI text generation
|
|
23
|
+
*
|
|
24
|
+
* @module
|
|
3
25
|
*/
|
|
4
26
|
|
|
5
27
|
import { generateObject } from 'ai-functions'
|
|
@@ -16,24 +38,31 @@ import type {
|
|
|
16
38
|
} from './types.js'
|
|
17
39
|
|
|
18
40
|
/**
|
|
19
|
-
*
|
|
41
|
+
* Route a question to a Worker (AI Agent or Human) via communication channels.
|
|
20
42
|
*
|
|
21
|
-
*
|
|
43
|
+
* **Key Difference from ai-functions.ask():**
|
|
44
|
+
* Unlike `ai-functions.ask()` which generates content for human interaction
|
|
45
|
+
* using the LLM, this function routes the question to an actual Worker (person
|
|
46
|
+
* or AI agent) via real communication channels (Slack, email, SMS, etc.) and
|
|
47
|
+
* waits for their response.
|
|
22
48
|
*
|
|
23
|
-
*
|
|
49
|
+
* This is a **worker communication primitive**, not a direct LLM primitive.
|
|
50
|
+
*
|
|
51
|
+
* @param target - The worker or team to ask (routes to their configured channels)
|
|
24
52
|
* @param question - The question to ask
|
|
25
|
-
* @param options - Ask options
|
|
26
|
-
* @returns Promise resolving to the answer
|
|
53
|
+
* @param options - Ask options including channel, schema, and timeout
|
|
54
|
+
* @returns Promise resolving to the answer with metadata (who answered, when, via what channel)
|
|
27
55
|
*
|
|
28
56
|
* @example
|
|
29
57
|
* ```ts
|
|
30
|
-
* // Ask a
|
|
58
|
+
* // Ask a human via Slack
|
|
31
59
|
* const result = await ask(alice, 'What is the company holiday policy?', {
|
|
32
60
|
* via: 'slack',
|
|
33
61
|
* })
|
|
34
62
|
* console.log(result.answer)
|
|
63
|
+
* console.log(`Answered by ${result.answeredBy.name} at ${result.answeredAt}`)
|
|
35
64
|
*
|
|
36
|
-
* // Ask with structured response
|
|
65
|
+
* // Ask with structured response schema
|
|
37
66
|
* const result = await ask(ceo, 'What are our Q1 priorities?', {
|
|
38
67
|
* via: 'email',
|
|
39
68
|
* schema: {
|
|
@@ -42,6 +71,8 @@ import type {
|
|
|
42
71
|
* },
|
|
43
72
|
* })
|
|
44
73
|
* ```
|
|
74
|
+
*
|
|
75
|
+
* @see {@link ai-functions#ask} for LLM-generated human interaction content
|
|
45
76
|
*/
|
|
46
77
|
export async function ask<T = string>(
|
|
47
78
|
target: ActionTarget,
|
|
@@ -62,9 +93,9 @@ export async function ask<T = string>(
|
|
|
62
93
|
|
|
63
94
|
// Send the question and wait for response
|
|
64
95
|
const response = await sendQuestion<T>(channel, question, contacts, {
|
|
65
|
-
schema,
|
|
66
|
-
timeout,
|
|
67
|
-
context,
|
|
96
|
+
...(schema !== undefined && { schema }),
|
|
97
|
+
...(timeout !== undefined && { timeout }),
|
|
98
|
+
...(context !== undefined && { context }),
|
|
68
99
|
recipient,
|
|
69
100
|
})
|
|
70
101
|
|
|
@@ -97,9 +128,13 @@ ask.ai = async <T = string>(
|
|
|
97
128
|
model: 'sonnet',
|
|
98
129
|
schema,
|
|
99
130
|
prompt: question,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
131
|
+
...(context !== undefined && {
|
|
132
|
+
system: `Use the following context to answer the question:\n\n${JSON.stringify(
|
|
133
|
+
context,
|
|
134
|
+
null,
|
|
135
|
+
2
|
|
136
|
+
)}`,
|
|
137
|
+
}),
|
|
103
138
|
})
|
|
104
139
|
return result.object as T
|
|
105
140
|
}
|
|
@@ -108,9 +143,13 @@ ask.ai = async <T = string>(
|
|
|
108
143
|
model: 'sonnet',
|
|
109
144
|
schema: { answer: 'The answer to the question' },
|
|
110
145
|
prompt: question,
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
146
|
+
...(context !== undefined && {
|
|
147
|
+
system: `Use the following context to answer the question:\n\n${JSON.stringify(
|
|
148
|
+
context,
|
|
149
|
+
null,
|
|
150
|
+
2
|
|
151
|
+
)}`,
|
|
152
|
+
}),
|
|
114
153
|
})
|
|
115
154
|
|
|
116
155
|
return (result.object as { answer: T }).answer
|
|
@@ -288,17 +327,52 @@ async function sendQuestion<T>(
|
|
|
288
327
|
throw new Error(`No ${channel} contact configured`)
|
|
289
328
|
}
|
|
290
329
|
|
|
291
|
-
//
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
// 4. Parse and validate the response
|
|
330
|
+
// Import transport functions dynamically to avoid circular dependencies
|
|
331
|
+
const { channelToTransport, sendViaTransport, hasTransport, resolveAddress } = await import(
|
|
332
|
+
'./transports.js'
|
|
333
|
+
)
|
|
296
334
|
|
|
297
|
-
|
|
298
|
-
|
|
335
|
+
const transport = channelToTransport(channel)
|
|
336
|
+
const address = resolveAddress(contacts, channel)
|
|
337
|
+
|
|
338
|
+
// If transport is registered, use it for real delivery
|
|
339
|
+
if (hasTransport(transport) && address) {
|
|
340
|
+
const { generateRequestId } = await import('./utils/id.js')
|
|
341
|
+
const requestId = generateRequestId('ask')
|
|
342
|
+
|
|
343
|
+
const payload = {
|
|
344
|
+
to: address.value,
|
|
345
|
+
body: question,
|
|
346
|
+
type: 'question' as const,
|
|
347
|
+
priority: 'normal' as const,
|
|
348
|
+
threadId: requestId,
|
|
349
|
+
...(options.schema !== undefined && { schema: options.schema }),
|
|
350
|
+
...(options.timeout !== undefined && { timeout: options.timeout }),
|
|
351
|
+
metadata: {
|
|
352
|
+
...options.context,
|
|
353
|
+
recipient: options.recipient,
|
|
354
|
+
},
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const result = await sendViaTransport(transport, payload)
|
|
358
|
+
|
|
359
|
+
if (result.success) {
|
|
360
|
+
// For real transports, we need to wait for a response
|
|
361
|
+
// This would integrate with the runtime's HumanRequestProcessor
|
|
362
|
+
// For now, return pending state - the response comes via webhook
|
|
363
|
+
return {
|
|
364
|
+
answer: `Question sent via ${transport}. Awaiting response. Request ID: ${requestId}` as T,
|
|
365
|
+
}
|
|
366
|
+
} else {
|
|
367
|
+
throw new Error(`Failed to send question via ${transport}: ${result.error}`)
|
|
368
|
+
}
|
|
369
|
+
}
|
|
299
370
|
|
|
300
|
-
//
|
|
371
|
+
// No transport registered - return pending state
|
|
372
|
+
// In a real workflow, this would be processed when a transport is configured
|
|
373
|
+
// or the runtime handles the request via HumanRequestProcessor
|
|
301
374
|
return {
|
|
302
|
-
answer:
|
|
375
|
+
answer:
|
|
376
|
+
`Question pending - no transport registered for ${channel}. Configure a transport handler to enable real delivery.` as T,
|
|
303
377
|
}
|
|
304
378
|
}
|