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.
- package/CHANGELOG.md +23 -0
- package/README.md +136 -180
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +34 -21
- package/dist/actions.js.map +1 -1
- package/dist/agent-comms.d.ts +438 -0
- package/dist/agent-comms.d.ts.map +1 -0
- package/dist/agent-comms.js +677 -0
- package/dist/agent-comms.js.map +1 -0
- 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.d.ts +230 -0
- package/dist/capability-tiers.d.ts.map +1 -0
- package/dist/capability-tiers.js +388 -0
- package/dist/capability-tiers.js.map +1 -0
- package/dist/cascade-context.d.ts +523 -0
- package/dist/cascade-context.d.ts.map +1 -0
- package/dist/cascade-context.js +494 -0
- package/dist/cascade-context.js.map +1 -0
- 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 +416 -0
- package/dist/error-escalation.d.ts.map +1 -0
- package/dist/error-escalation.js +656 -0
- package/dist/error-escalation.js.map +1 -0
- 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 +59 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +92 -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 +395 -0
- package/dist/load-balancing.d.ts.map +1 -0
- package/dist/load-balancing.js +991 -0
- package/dist/load-balancing.js.map +1 -0
- 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 +149 -19
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -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 +24 -5
- package/src/actions.ts +48 -38
- package/src/agent-comms.ts +1200 -0
- package/src/approve.ts +91 -20
- package/src/ask.ts +99 -25
- package/src/browse.ts +627 -0
- package/src/capability-tiers.ts +545 -0
- package/src/cascade-context.ts +648 -0
- package/src/client.ts +221 -0
- package/src/decide.ts +81 -35
- package/src/do.ts +98 -52
- package/src/error-escalation.ts +1123 -0
- package/src/generate.ts +52 -18
- package/src/goals.ts +36 -27
- package/src/image.ts +816 -0
- package/src/index.ts +410 -2
- package/src/is.ts +59 -25
- package/src/kpis.ts +41 -36
- package/src/load-balancing.ts +1467 -0
- 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 +182 -46
- package/src/utils/id.ts +21 -0
- package/src/video.ts +906 -0
- package/src/worker.ts +1007 -0
- package/test/agent-comms.test.ts +1397 -0
- package/test/approve.test.ts +305 -0
- package/test/ask.test.ts +274 -0
- package/test/browse.test.ts +361 -0
- package/test/capability-tiers.test.ts +631 -0
- package/test/cascade-context.test.ts +692 -0
- package/test/decide.test.ts +252 -0
- package/test/do.test.ts +144 -0
- package/test/error-escalation.test.ts +1205 -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/load-balancing-thread-safety.test.ts +464 -0
- package/test/load-balancing.test.ts +1145 -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 +95 -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/.turbo/turbo-build.log +0 -5
- 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
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for decide() - Decision making primitive
|
|
3
|
+
*
|
|
4
|
+
* The decide() function provides structured decision-making with criteria
|
|
5
|
+
* evaluation, confidence scoring, and optional human approval. Unlike
|
|
6
|
+
* ai-functions.decide() which is an LLM-as-judge comparison, this function
|
|
7
|
+
* provides comprehensive decision analysis.
|
|
8
|
+
*
|
|
9
|
+
* These tests use real AI calls via the Cloudflare AI Gateway.
|
|
10
|
+
* Tests are skipped if AI_GATEWAY_URL is not configured.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { describe, it, expect } from 'vitest'
|
|
14
|
+
import { decide } from '../src/index.js'
|
|
15
|
+
|
|
16
|
+
// Skip tests if no gateway configured
|
|
17
|
+
const hasGateway = !!process.env.AI_GATEWAY_URL || !!process.env.ANTHROPIC_API_KEY
|
|
18
|
+
|
|
19
|
+
describe('decide() - Decision Making Primitive', () => {
|
|
20
|
+
describe('Unit Tests (no AI)', () => {
|
|
21
|
+
it('should be exported from index', () => {
|
|
22
|
+
expect(decide).toBeDefined()
|
|
23
|
+
expect(typeof decide).toBe('function')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('should have yesNo method', () => {
|
|
27
|
+
expect(decide.yesNo).toBeDefined()
|
|
28
|
+
expect(typeof decide.yesNo).toBe('function')
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('should have prioritize method', () => {
|
|
32
|
+
expect(decide.prioritize).toBeDefined()
|
|
33
|
+
expect(typeof decide.prioritize).toBe('function')
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('should have withApproval method', () => {
|
|
37
|
+
expect(decide.withApproval).toBeDefined()
|
|
38
|
+
expect(typeof decide.withApproval).toBe('function')
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
describe.skipIf(!hasGateway)('Integration Tests (with AI) - Basic Decisions', () => {
|
|
43
|
+
it('should make a decision from options', async () => {
|
|
44
|
+
const decision = await decide({
|
|
45
|
+
options: ['Option A', 'Option B', 'Option C'],
|
|
46
|
+
context: 'Choose the best option for a simple test',
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
expect(decision).toBeDefined()
|
|
50
|
+
expect(decision.choice).toBeDefined()
|
|
51
|
+
expect(['Option A', 'Option B', 'Option C']).toContain(decision.choice)
|
|
52
|
+
expect(decision.reasoning).toBeDefined()
|
|
53
|
+
expect(typeof decision.reasoning).toBe('string')
|
|
54
|
+
expect(decision.confidence).toBeDefined()
|
|
55
|
+
expect(typeof decision.confidence).toBe('number')
|
|
56
|
+
expect(decision.confidence).toBeGreaterThanOrEqual(0)
|
|
57
|
+
expect(decision.confidence).toBeLessThanOrEqual(1)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('should include alternatives in decision', async () => {
|
|
61
|
+
const decision = await decide({
|
|
62
|
+
options: ['React', 'Vue', 'Svelte'],
|
|
63
|
+
context: 'Choose a frontend framework for a small project',
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
expect(decision).toBeDefined()
|
|
67
|
+
expect(decision.alternatives).toBeDefined()
|
|
68
|
+
expect(Array.isArray(decision.alternatives)).toBe(true)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('should support criteria evaluation', async () => {
|
|
72
|
+
const decision = await decide({
|
|
73
|
+
options: ['PostgreSQL', 'MongoDB', 'Redis'],
|
|
74
|
+
context: 'Choose a database for an e-commerce application',
|
|
75
|
+
criteria: ['ACID compliance', 'Scalability', 'Ease of use', 'Community support'],
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
expect(decision).toBeDefined()
|
|
79
|
+
expect(decision.choice).toBeDefined()
|
|
80
|
+
expect(decision.reasoning).toBeDefined()
|
|
81
|
+
// Reasoning should mention criteria
|
|
82
|
+
expect(decision.reasoning.length).toBeGreaterThan(10)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('should handle object options', async () => {
|
|
86
|
+
const decision = await decide({
|
|
87
|
+
options: [
|
|
88
|
+
{ id: 'plan-a', name: 'Basic Plan', price: 10 },
|
|
89
|
+
{ id: 'plan-b', name: 'Pro Plan', price: 25 },
|
|
90
|
+
{ id: 'plan-c', name: 'Enterprise Plan', price: 100 },
|
|
91
|
+
],
|
|
92
|
+
context: 'Choose the best plan for a startup with limited budget',
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
expect(decision).toBeDefined()
|
|
96
|
+
expect(decision.choice).toBeDefined()
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('should respect includeReasoning option', async () => {
|
|
100
|
+
const decision = await decide({
|
|
101
|
+
options: ['Yes', 'No'],
|
|
102
|
+
context: 'Should we proceed?',
|
|
103
|
+
includeReasoning: true,
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
expect(decision.reasoning).toBeDefined()
|
|
107
|
+
expect(decision.reasoning.length).toBeGreaterThan(0)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('should handle complex context object', async () => {
|
|
111
|
+
const decision = await decide({
|
|
112
|
+
options: ['Approve', 'Reject', 'Request more info'],
|
|
113
|
+
context: {
|
|
114
|
+
requestType: 'Budget increase',
|
|
115
|
+
amount: 50000,
|
|
116
|
+
department: 'Engineering',
|
|
117
|
+
justification: 'Need to hire additional developer',
|
|
118
|
+
currentBudget: 200000,
|
|
119
|
+
utilizationRate: 0.95,
|
|
120
|
+
},
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
expect(decision).toBeDefined()
|
|
124
|
+
expect(decision.choice).toBeDefined()
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
describe.skipIf(!hasGateway)('Integration Tests (with AI) - Yes/No Decisions', () => {
|
|
129
|
+
it('should make binary decision', async () => {
|
|
130
|
+
const decision = await decide.yesNo(
|
|
131
|
+
'Should we deploy on Friday?',
|
|
132
|
+
'The deploy is a minor bug fix with good test coverage'
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
expect(decision).toBeDefined()
|
|
136
|
+
expect(['yes', 'no']).toContain(decision.choice)
|
|
137
|
+
expect(decision.reasoning).toBeDefined()
|
|
138
|
+
expect(decision.confidence).toBeDefined()
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
it('should handle context object in yesNo', async () => {
|
|
142
|
+
const decision = await decide.yesNo('Should we approve this expense?', {
|
|
143
|
+
amount: 500,
|
|
144
|
+
category: 'Software',
|
|
145
|
+
policy: 'Software expenses under $1000 are auto-approved',
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
expect(decision).toBeDefined()
|
|
149
|
+
expect(['yes', 'no']).toContain(decision.choice)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it('should provide confidence score for yesNo', async () => {
|
|
153
|
+
const decision = await decide.yesNo('Is this a valid email format: test@example.com?')
|
|
154
|
+
|
|
155
|
+
expect(decision.confidence).toBeGreaterThan(0)
|
|
156
|
+
})
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
describe.skipIf(!hasGateway)('Integration Tests (with AI) - Prioritization', () => {
|
|
160
|
+
it('should prioritize items', async () => {
|
|
161
|
+
const prioritized = await decide.prioritize(
|
|
162
|
+
['Feature A', 'Bug Fix B', 'Tech Debt C', 'Feature D'],
|
|
163
|
+
'Sprint planning for a 2-week sprint'
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
expect(prioritized).toBeDefined()
|
|
167
|
+
expect(Array.isArray(prioritized)).toBe(true)
|
|
168
|
+
expect(prioritized.length).toBe(4)
|
|
169
|
+
|
|
170
|
+
prioritized.forEach((item) => {
|
|
171
|
+
expect(item.choice).toBeDefined()
|
|
172
|
+
expect(item.rank).toBeDefined()
|
|
173
|
+
expect(typeof item.rank).toBe('number')
|
|
174
|
+
expect(item.reasoning).toBeDefined()
|
|
175
|
+
expect(item.confidence).toBeDefined()
|
|
176
|
+
})
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
it('should prioritize with criteria', async () => {
|
|
180
|
+
const prioritized = await decide.prioritize(
|
|
181
|
+
['Task 1', 'Task 2', 'Task 3'],
|
|
182
|
+
'Project backlog',
|
|
183
|
+
['User impact', 'Urgency', 'Effort required']
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
expect(prioritized).toBeDefined()
|
|
187
|
+
expect(prioritized.length).toBe(3)
|
|
188
|
+
|
|
189
|
+
// All items should have a rank
|
|
190
|
+
const ranks = prioritized.map((p) => p.rank)
|
|
191
|
+
expect(ranks.every((r) => typeof r === 'number')).toBe(true)
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
it('should prioritize object items', async () => {
|
|
195
|
+
const items = [
|
|
196
|
+
{ id: 1, name: 'Critical bug', severity: 'high' },
|
|
197
|
+
{ id: 2, name: 'New feature', severity: 'low' },
|
|
198
|
+
{ id: 3, name: 'Performance fix', severity: 'medium' },
|
|
199
|
+
]
|
|
200
|
+
|
|
201
|
+
const prioritized = await decide.prioritize(items, 'Bug triage session')
|
|
202
|
+
|
|
203
|
+
expect(prioritized).toBeDefined()
|
|
204
|
+
expect(prioritized.length).toBe(3)
|
|
205
|
+
})
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
describe.skipIf(!hasGateway)('Integration Tests (with AI) - Decision Quality', () => {
|
|
209
|
+
it('should provide meaningful reasoning', async () => {
|
|
210
|
+
const decision = await decide({
|
|
211
|
+
options: ['AWS', 'GCP', 'Azure'],
|
|
212
|
+
context: 'Choosing a cloud provider for a machine learning startup',
|
|
213
|
+
criteria: ['ML services', 'Pricing', 'Documentation', 'Support'],
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
expect(decision.reasoning).toBeDefined()
|
|
217
|
+
expect(decision.reasoning.length).toBeGreaterThan(50)
|
|
218
|
+
// Reasoning should be substantive
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
it('should score alternatives', async () => {
|
|
222
|
+
const decision = await decide({
|
|
223
|
+
options: ['TypeScript', 'Python', 'Go', 'Rust'],
|
|
224
|
+
context: 'Choosing a language for a CLI tool',
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
if (decision.alternatives && decision.alternatives.length > 0) {
|
|
228
|
+
decision.alternatives.forEach((alt) => {
|
|
229
|
+
expect(alt.option).toBeDefined()
|
|
230
|
+
expect(typeof alt.score).toBe('number')
|
|
231
|
+
})
|
|
232
|
+
}
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
it('should normalize confidence to 0-1 range', async () => {
|
|
236
|
+
const decision = await decide({
|
|
237
|
+
options: ['A', 'B'],
|
|
238
|
+
context: 'Simple choice',
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
expect(decision.confidence).toBeGreaterThanOrEqual(0)
|
|
242
|
+
expect(decision.confidence).toBeLessThanOrEqual(1)
|
|
243
|
+
})
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
describe('Decision with Approval', () => {
|
|
247
|
+
it('should have withApproval method that requires approver', async () => {
|
|
248
|
+
// Just verify the signature - actual approval routing is tested in approve.test.ts
|
|
249
|
+
expect(typeof decide.withApproval).toBe('function')
|
|
250
|
+
})
|
|
251
|
+
})
|
|
252
|
+
})
|
package/test/do.test.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for do() - Task execution primitive
|
|
3
|
+
*
|
|
4
|
+
* The do() function routes tasks to appropriate Workers (AI Agents or Humans)
|
|
5
|
+
* based on capability matching. Unlike ai-functions.do() which directly calls
|
|
6
|
+
* the LLM, this function provides worker coordination with retries and timeouts.
|
|
7
|
+
*
|
|
8
|
+
* These tests use real AI calls via the Cloudflare AI Gateway.
|
|
9
|
+
* Tests are skipped if AI_GATEWAY_URL is not configured.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { describe, it, expect } from 'vitest'
|
|
13
|
+
import { do as doTask } from '../src/index.js'
|
|
14
|
+
|
|
15
|
+
// Skip tests if no gateway configured
|
|
16
|
+
const hasGateway = !!process.env.AI_GATEWAY_URL || !!process.env.ANTHROPIC_API_KEY
|
|
17
|
+
|
|
18
|
+
describe('do() - Task Execution Primitive', () => {
|
|
19
|
+
describe('Unit Tests (no AI)', () => {
|
|
20
|
+
it('should be exported from index', () => {
|
|
21
|
+
expect(doTask).toBeDefined()
|
|
22
|
+
expect(typeof doTask).toBe('function')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('should have parallel method', () => {
|
|
26
|
+
expect(doTask.parallel).toBeDefined()
|
|
27
|
+
expect(typeof doTask.parallel).toBe('function')
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('should have sequence method', () => {
|
|
31
|
+
expect(doTask.sequence).toBeDefined()
|
|
32
|
+
expect(typeof doTask.sequence).toBe('function')
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('should have withDependencies method', () => {
|
|
36
|
+
expect(doTask.withDependencies).toBeDefined()
|
|
37
|
+
expect(typeof doTask.withDependencies).toBe('function')
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
describe.skipIf(!hasGateway)('Integration Tests (with AI)', () => {
|
|
42
|
+
it('should execute a simple task', async () => {
|
|
43
|
+
const result = await doTask('Calculate 2 + 2 and return the result', {
|
|
44
|
+
timeout: 30000,
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
expect(result).toBeDefined()
|
|
48
|
+
expect(typeof result.success).toBe('boolean')
|
|
49
|
+
expect(typeof result.duration).toBe('number')
|
|
50
|
+
expect(result.duration).toBeGreaterThan(0)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('should execute task with context', async () => {
|
|
54
|
+
const result = await doTask('Summarize the provided text', {
|
|
55
|
+
timeout: 30000,
|
|
56
|
+
context: {
|
|
57
|
+
text: 'Hello world. This is a simple test message.',
|
|
58
|
+
},
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
expect(result).toBeDefined()
|
|
62
|
+
expect(result.success).toBeDefined()
|
|
63
|
+
expect(result.duration).toBeGreaterThan(0)
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('should return steps array', async () => {
|
|
67
|
+
const result = await doTask('List 3 colors', {
|
|
68
|
+
timeout: 30000,
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
expect(result).toBeDefined()
|
|
72
|
+
expect(Array.isArray(result.steps)).toBe(true)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it('should handle task with structured context', async () => {
|
|
76
|
+
const result = await doTask<{ name: string; greeting: string }>(
|
|
77
|
+
'Generate a greeting for the user',
|
|
78
|
+
{
|
|
79
|
+
timeout: 30000,
|
|
80
|
+
context: {
|
|
81
|
+
user: { name: 'Alice', language: 'English' },
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
expect(result).toBeDefined()
|
|
87
|
+
expect(result.success).toBeDefined()
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('should handle timeout option', async () => {
|
|
91
|
+
// Very short timeout to test timeout behavior
|
|
92
|
+
const result = await doTask('Count from 1 to 5', {
|
|
93
|
+
timeout: 1, // 1ms timeout - will likely fail
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
// Either succeeds quickly or fails due to timeout
|
|
97
|
+
expect(result).toBeDefined()
|
|
98
|
+
expect(typeof result.success).toBe('boolean')
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('should execute parallel tasks', async () => {
|
|
102
|
+
const results = await doTask.parallel(['What is 1+1?', 'What is 2+2?', 'What is 3+3?'], {
|
|
103
|
+
timeout: 30000,
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
expect(results).toBeDefined()
|
|
107
|
+
expect(Array.isArray(results)).toBe(true)
|
|
108
|
+
expect(results.length).toBe(3)
|
|
109
|
+
results.forEach((result) => {
|
|
110
|
+
expect(result.success).toBeDefined()
|
|
111
|
+
expect(result.duration).toBeDefined()
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it('should execute sequential tasks', async () => {
|
|
116
|
+
const results = await doTask.sequence(['Say hello', 'Say goodbye'], { timeout: 30000 })
|
|
117
|
+
|
|
118
|
+
expect(results).toBeDefined()
|
|
119
|
+
expect(Array.isArray(results)).toBe(true)
|
|
120
|
+
expect(results.length).toBe(2)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it('should handle task with retries option', async () => {
|
|
124
|
+
const result = await doTask('Return the word "success"', {
|
|
125
|
+
maxRetries: 1,
|
|
126
|
+
timeout: 30000,
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
expect(result).toBeDefined()
|
|
130
|
+
expect(result.success).toBeDefined()
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it('should support background execution option', async () => {
|
|
134
|
+
const result = await doTask('Generate a random number', {
|
|
135
|
+
background: true,
|
|
136
|
+
timeout: 30000,
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
expect(result).toBeDefined()
|
|
140
|
+
// Background tasks still return a result
|
|
141
|
+
expect(result.success).toBeDefined()
|
|
142
|
+
})
|
|
143
|
+
})
|
|
144
|
+
})
|