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/error-escalation.ts
CHANGED
|
@@ -424,25 +424,28 @@ export function createClassifiedError(
|
|
|
424
424
|
original,
|
|
425
425
|
severity: options.severity,
|
|
426
426
|
category: options.category,
|
|
427
|
-
tier: options.tier,
|
|
428
|
-
agentId: options.agentId,
|
|
429
|
-
taskId: options.taskId,
|
|
430
427
|
timestamp: new Date(),
|
|
431
|
-
stack: original.stack,
|
|
432
|
-
|
|
433
|
-
|
|
428
|
+
...(original.stack !== undefined && { stack: original.stack }),
|
|
429
|
+
...(options.tier !== undefined && { tier: options.tier }),
|
|
430
|
+
...(options.agentId !== undefined && { agentId: options.agentId }),
|
|
431
|
+
...(options.taskId !== undefined && { taskId: options.taskId }),
|
|
432
|
+
...(options.previousError !== undefined && { previousError: options.previousError }),
|
|
433
|
+
...(options.context !== undefined && { context: options.context }),
|
|
434
434
|
}
|
|
435
435
|
}
|
|
436
436
|
|
|
437
437
|
/**
|
|
438
438
|
* Classify an error automatically
|
|
439
439
|
*/
|
|
440
|
-
export function classifyError(
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
440
|
+
export function classifyError(
|
|
441
|
+
error: Error,
|
|
442
|
+
options: Partial<{
|
|
443
|
+
tier: CapabilityTier
|
|
444
|
+
agentId: string
|
|
445
|
+
taskId: string
|
|
446
|
+
context: ErrorContext
|
|
447
|
+
}> = {}
|
|
448
|
+
): ClassifiedError {
|
|
446
449
|
const severity = getErrorSeverity(error)
|
|
447
450
|
const category = getErrorCategory(error)
|
|
448
451
|
|
|
@@ -531,9 +534,11 @@ export function createEscalationPolicy(options: EscalationPolicyOptions): Escala
|
|
|
531
534
|
return {
|
|
532
535
|
maxEscalationDepth: options.maxEscalationDepth ?? 10,
|
|
533
536
|
allowSkipTiers: options.allowSkipTiers ?? false,
|
|
534
|
-
|
|
537
|
+
...(options.skipTierThreshold !== undefined && {
|
|
538
|
+
skipTierThreshold: options.skipTierThreshold,
|
|
539
|
+
}),
|
|
535
540
|
rules: options.rules ?? [],
|
|
536
|
-
tierPolicies: options.tierPolicies,
|
|
541
|
+
...(options.tierPolicies !== undefined && { tierPolicies: options.tierPolicies }),
|
|
537
542
|
}
|
|
538
543
|
}
|
|
539
544
|
|
|
@@ -548,7 +553,7 @@ export function getNextEscalationTier(
|
|
|
548
553
|
|
|
549
554
|
// Check custom rules first
|
|
550
555
|
const applicableRules = policy.rules
|
|
551
|
-
.filter(rule => rule.fromTier === currentTier && rule.condition(error))
|
|
556
|
+
.filter((rule) => rule.fromTier === currentTier && rule.condition(error))
|
|
552
557
|
.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))
|
|
553
558
|
|
|
554
559
|
if (applicableRules.length > 0) {
|
|
@@ -608,17 +613,13 @@ export function shouldEscalate(
|
|
|
608
613
|
// Filter by time window if specified
|
|
609
614
|
let relevantErrors = errorHistory
|
|
610
615
|
if (timeWindow) {
|
|
611
|
-
relevantErrors = errorHistory.filter(
|
|
612
|
-
entry => now - entry.timestamp <= timeWindow
|
|
613
|
-
)
|
|
616
|
+
relevantErrors = errorHistory.filter((entry) => now - entry.timestamp <= timeWindow)
|
|
614
617
|
}
|
|
615
618
|
|
|
616
619
|
// Calculate weighted count if severity multiplier is specified
|
|
617
620
|
if (severityMultiplier) {
|
|
618
621
|
const weightedCount = relevantErrors.reduce((sum, entry) => {
|
|
619
|
-
const multiplier = entry.severity
|
|
620
|
-
? (severityMultiplier[entry.severity] ?? 1)
|
|
621
|
-
: 1
|
|
622
|
+
const multiplier = entry.severity ? severityMultiplier[entry.severity] ?? 1 : 1
|
|
622
623
|
return sum + multiplier
|
|
623
624
|
}, 0)
|
|
624
625
|
return weightedCount >= errorCount
|
|
@@ -630,10 +631,7 @@ export function shouldEscalate(
|
|
|
630
631
|
/**
|
|
631
632
|
* Detect circular escalation
|
|
632
633
|
*/
|
|
633
|
-
export function detectCircularEscalation(
|
|
634
|
-
path: EscalationPath,
|
|
635
|
-
history: CapabilityTier[]
|
|
636
|
-
): boolean {
|
|
634
|
+
export function detectCircularEscalation(path: EscalationPath, history: CapabilityTier[]): boolean {
|
|
637
635
|
// If we're going back to a tier we've already visited, it's circular
|
|
638
636
|
if (history.includes(path.toTier)) {
|
|
639
637
|
return true
|
|
@@ -642,7 +640,7 @@ export function detectCircularEscalation(
|
|
|
642
640
|
// Check for de-escalation (going to a lower tier)
|
|
643
641
|
if (TIER_ORDER[path.toTier] < TIER_ORDER[path.fromTier]) {
|
|
644
642
|
// If we've already been at a tier higher than where we're going, it's circular
|
|
645
|
-
const maxTierVisited = Math.max(...history.map(t => TIER_ORDER[t]))
|
|
643
|
+
const maxTierVisited = Math.max(...history.map((t) => TIER_ORDER[t]))
|
|
646
644
|
if (TIER_ORDER[path.toTier] < maxTierVisited) {
|
|
647
645
|
return true
|
|
648
646
|
}
|
|
@@ -686,12 +684,7 @@ export function validateEscalationPath(
|
|
|
686
684
|
* Calculate backoff delay with optional jitter
|
|
687
685
|
*/
|
|
688
686
|
export function calculateBackoff(config: RetryConfig, attemptNumber: number): number {
|
|
689
|
-
const {
|
|
690
|
-
baseDelayMs,
|
|
691
|
-
maxDelayMs = Infinity,
|
|
692
|
-
backoffMultiplier = 2,
|
|
693
|
-
jitterPercent = 0,
|
|
694
|
-
} = config
|
|
687
|
+
const { baseDelayMs, maxDelayMs = Infinity, backoffMultiplier = 2, jitterPercent = 0 } = config
|
|
695
688
|
|
|
696
689
|
// Calculate exponential delay
|
|
697
690
|
let delay = baseDelayMs * Math.pow(backoffMultiplier, attemptNumber)
|
|
@@ -757,9 +750,7 @@ export function selectFallbackAgent(
|
|
|
757
750
|
agents: AgentForFallback[]
|
|
758
751
|
): AgentForFallback | null {
|
|
759
752
|
// Filter excluded agents
|
|
760
|
-
let candidates = agents.filter(
|
|
761
|
-
a => !config.excludeAgentIds?.includes(a.id)
|
|
762
|
-
)
|
|
753
|
+
let candidates = agents.filter((a) => !config.excludeAgentIds?.includes(a.id))
|
|
763
754
|
|
|
764
755
|
if (candidates.length === 0) {
|
|
765
756
|
return null
|
|
@@ -768,9 +759,9 @@ export function selectFallbackAgent(
|
|
|
768
759
|
switch (config.strategy) {
|
|
769
760
|
case 'capability-match':
|
|
770
761
|
if (config.requiredSkills && config.requiredSkills.length > 0) {
|
|
771
|
-
candidates = candidates.filter(a => {
|
|
762
|
+
candidates = candidates.filter((a) => {
|
|
772
763
|
const agentSkills = a.skills ?? []
|
|
773
|
-
return config.requiredSkills!.every(skill => agentSkills.includes(skill))
|
|
764
|
+
return config.requiredSkills!.every((skill) => agentSkills.includes(skill))
|
|
774
765
|
})
|
|
775
766
|
}
|
|
776
767
|
return candidates[0] ?? null
|
|
@@ -785,7 +776,7 @@ export function selectFallbackAgent(
|
|
|
785
776
|
|
|
786
777
|
case 'same-tier':
|
|
787
778
|
if (config.currentTier) {
|
|
788
|
-
candidates = candidates.filter(a => a.tier === config.currentTier)
|
|
779
|
+
candidates = candidates.filter((a) => a.tier === config.currentTier)
|
|
789
780
|
}
|
|
790
781
|
return candidates[0] ?? null
|
|
791
782
|
|
|
@@ -849,7 +840,7 @@ export function createRecoveryState(options: RecoveryStateOptions): RecoveryStat
|
|
|
849
840
|
return {
|
|
850
841
|
errorId: options.errorId,
|
|
851
842
|
tier: options.tier,
|
|
852
|
-
agentId: options.agentId,
|
|
843
|
+
...(options.agentId !== undefined && { agentId: options.agentId }),
|
|
853
844
|
retryState: createRetryState(),
|
|
854
845
|
escalated: false,
|
|
855
846
|
resolved: false,
|
|
@@ -886,14 +877,14 @@ export function updateRecoveryState(
|
|
|
886
877
|
escalated: true,
|
|
887
878
|
escalationPath: [...state.escalationPath, newTier],
|
|
888
879
|
lastAction: 'escalate',
|
|
889
|
-
isTerminal: update.isTerminal,
|
|
880
|
+
...(update.isTerminal !== undefined && { isTerminal: update.isTerminal }),
|
|
890
881
|
}
|
|
891
882
|
|
|
892
883
|
case 'fallback':
|
|
893
884
|
const oldAgentId = state.agentId
|
|
894
885
|
return {
|
|
895
886
|
...state,
|
|
896
|
-
agentId: update.toAgentId,
|
|
887
|
+
...(update.toAgentId !== undefined && { agentId: update.toAgentId }),
|
|
897
888
|
fallbackHistory: oldAgentId
|
|
898
889
|
? [...state.fallbackHistory, oldAgentId]
|
|
899
890
|
: state.fallbackHistory,
|
|
@@ -904,7 +895,7 @@ export function updateRecoveryState(
|
|
|
904
895
|
return {
|
|
905
896
|
...state,
|
|
906
897
|
resolved: true,
|
|
907
|
-
resolution: update.resolution,
|
|
898
|
+
...(update.resolution !== undefined && { resolution: update.resolution }),
|
|
908
899
|
lastAction: 'resolve',
|
|
909
900
|
}
|
|
910
901
|
|
|
@@ -967,10 +958,7 @@ export function createEscalationEngine(options: EscalationEngineOptions = {}): E
|
|
|
967
958
|
retriesSuccessful: 0,
|
|
968
959
|
}
|
|
969
960
|
|
|
970
|
-
async function handleError(
|
|
971
|
-
error: Error,
|
|
972
|
-
opts: HandleErrorOptions
|
|
973
|
-
): Promise<EscalationResult> {
|
|
961
|
+
async function handleError(error: Error, opts: HandleErrorOptions): Promise<EscalationResult> {
|
|
974
962
|
// Classify the error
|
|
975
963
|
const severity = opts.severity ?? getErrorSeverity(error)
|
|
976
964
|
const category = getErrorCategory(error)
|
|
@@ -978,11 +966,11 @@ export function createEscalationEngine(options: EscalationEngineOptions = {}): E
|
|
|
978
966
|
const classifiedError = createClassifiedError(error, {
|
|
979
967
|
severity,
|
|
980
968
|
category,
|
|
981
|
-
tier: opts.tier,
|
|
982
|
-
agentId: opts.agentId,
|
|
983
|
-
taskId: opts.taskId,
|
|
984
|
-
previousError: opts.previousError,
|
|
985
|
-
context: opts.context,
|
|
969
|
+
...(opts.tier !== undefined && { tier: opts.tier }),
|
|
970
|
+
...(opts.agentId !== undefined && { agentId: opts.agentId }),
|
|
971
|
+
...(opts.taskId !== undefined && { taskId: opts.taskId }),
|
|
972
|
+
...(opts.previousError !== undefined && { previousError: opts.previousError }),
|
|
973
|
+
...(opts.context !== undefined && { context: opts.context }),
|
|
986
974
|
})
|
|
987
975
|
|
|
988
976
|
// Update metrics
|
|
@@ -1036,10 +1024,11 @@ export function createEscalationEngine(options: EscalationEngineOptions = {}): E
|
|
|
1036
1024
|
} else if (opts.availableAgents && opts.availableAgents.length > 0) {
|
|
1037
1025
|
// Try fallback
|
|
1038
1026
|
action = 'fallback'
|
|
1039
|
-
fallbackAgent =
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1027
|
+
fallbackAgent =
|
|
1028
|
+
selectFallbackAgent(
|
|
1029
|
+
{ strategy: 'capability-match', excludeAgentIds: [opts.agentId ?? ''] },
|
|
1030
|
+
opts.availableAgents
|
|
1031
|
+
) ?? undefined
|
|
1043
1032
|
} else {
|
|
1044
1033
|
action = 'degrade'
|
|
1045
1034
|
degradationLevel = getDegradationLevel(severity)
|
|
@@ -1049,10 +1038,11 @@ export function createEscalationEngine(options: EscalationEngineOptions = {}): E
|
|
|
1049
1038
|
else {
|
|
1050
1039
|
if (opts.availableAgents && opts.availableAgents.length > 0) {
|
|
1051
1040
|
action = 'fallback'
|
|
1052
|
-
fallbackAgent =
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1041
|
+
fallbackAgent =
|
|
1042
|
+
selectFallbackAgent(
|
|
1043
|
+
{ strategy: 'same-tier', currentTier: 'human', excludeAgentIds: [opts.agentId ?? ''] },
|
|
1044
|
+
opts.availableAgents
|
|
1045
|
+
) ?? undefined
|
|
1056
1046
|
if (!fallbackAgent) {
|
|
1057
1047
|
action = 'terminal'
|
|
1058
1048
|
}
|
|
@@ -1065,14 +1055,12 @@ export function createEscalationEngine(options: EscalationEngineOptions = {}): E
|
|
|
1065
1055
|
handled: true,
|
|
1066
1056
|
action,
|
|
1067
1057
|
classifiedError,
|
|
1068
|
-
retryDelay,
|
|
1069
|
-
escalationPath,
|
|
1070
|
-
fallbackAgent,
|
|
1071
|
-
degradationLevel,
|
|
1072
|
-
preservedContext: opts.context,
|
|
1073
|
-
errorChain:
|
|
1074
|
-
? buildErrorChain(classifiedError)
|
|
1075
|
-
: undefined,
|
|
1058
|
+
...(retryDelay !== undefined && { retryDelay }),
|
|
1059
|
+
...(escalationPath !== undefined && { escalationPath }),
|
|
1060
|
+
...(fallbackAgent !== undefined && { fallbackAgent }),
|
|
1061
|
+
...(degradationLevel !== undefined && { degradationLevel }),
|
|
1062
|
+
...(opts.context !== undefined && { preservedContext: opts.context }),
|
|
1063
|
+
...(opts.previousError !== undefined && { errorChain: buildErrorChain(classifiedError) }),
|
|
1076
1064
|
}
|
|
1077
1065
|
}
|
|
1078
1066
|
|
package/src/generate.ts
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Content generation functionality for digital workers
|
|
3
|
+
*
|
|
4
|
+
* IMPORTANT: Worker-Context Generation vs Direct LLM Generation
|
|
5
|
+
* --------------------------------------------------------------
|
|
6
|
+
* This module provides content generation within a worker context,
|
|
7
|
+
* with rich metadata about the generation process.
|
|
8
|
+
*
|
|
9
|
+
* - `digital-workers.generate()` - Generates content with full metadata
|
|
10
|
+
* (tokens used, duration, model info) and supports multiple content types
|
|
11
|
+
* including text, code, structured, image, video, and audio.
|
|
12
|
+
*
|
|
13
|
+
* - `ai-functions.generate()` - Core generation primitive that powers all
|
|
14
|
+
* ai-functions; lower-level function with type-based dispatch.
|
|
15
|
+
*
|
|
16
|
+
* The key difference is context and metadata:
|
|
17
|
+
* - digital-workers returns `GenerateResult<T>` with content + metadata
|
|
18
|
+
* - ai-functions returns just the generated content
|
|
19
|
+
*
|
|
20
|
+
* Use digital-workers when you need:
|
|
21
|
+
* - Rich metadata about generation (tokens, duration, model)
|
|
22
|
+
* - Content type variants (text, code, structured, media)
|
|
23
|
+
* - Tone, audience, and length modifiers
|
|
24
|
+
* - Iterative refinement workflows
|
|
25
|
+
*
|
|
26
|
+
* Use ai-functions when you need:
|
|
27
|
+
* - Direct LLM generation without metadata
|
|
28
|
+
* - Template literal syntax (`ai\`prompt\``)
|
|
29
|
+
* - Promise pipelining and schema inference
|
|
30
|
+
*
|
|
31
|
+
* @module
|
|
3
32
|
*/
|
|
4
33
|
|
|
5
34
|
import { generateObject, generateText } from 'ai-functions'
|
|
@@ -7,23 +36,31 @@ import type { SimpleSchema } from 'ai-functions'
|
|
|
7
36
|
import type { GenerateResult, GenerateOptions } from './types.js'
|
|
8
37
|
|
|
9
38
|
/**
|
|
10
|
-
* Generate content
|
|
39
|
+
* Generate content with rich metadata and multiple content type support.
|
|
11
40
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
41
|
+
* **Key Difference from ai-functions.generate():**
|
|
42
|
+
* Unlike `ai-functions.generate()` which is a lower-level type-dispatch
|
|
43
|
+
* function, this function returns a `GenerateResult` wrapper with:
|
|
44
|
+
* - The generated content
|
|
45
|
+
* - Generation metadata (model, tokens, duration)
|
|
46
|
+
* - Content type information
|
|
47
|
+
*
|
|
48
|
+
* This provides better observability for worker-based content generation.
|
|
14
49
|
*
|
|
15
50
|
* @param prompt - What to generate
|
|
16
|
-
* @param options - Generation options
|
|
17
|
-
* @returns Promise resolving to
|
|
51
|
+
* @param options - Generation options (type, schema, instructions, model)
|
|
52
|
+
* @returns Promise resolving to GenerateResult with content and metadata
|
|
18
53
|
*
|
|
19
54
|
* @example
|
|
20
55
|
* ```ts
|
|
21
|
-
* // Generate text content
|
|
56
|
+
* // Generate text content with metadata
|
|
22
57
|
* const result = await generate('Write a product description for wireless earbuds', {
|
|
23
58
|
* type: 'text',
|
|
24
59
|
* instructions: 'Focus on sound quality and battery life. Keep it under 100 words.',
|
|
25
60
|
* })
|
|
26
|
-
* console.log(result.content)
|
|
61
|
+
* console.log(result.content) // The generated text
|
|
62
|
+
* console.log(result.metadata.tokens) // Tokens used
|
|
63
|
+
* console.log(result.metadata.duration) // Generation time in ms
|
|
27
64
|
* ```
|
|
28
65
|
*
|
|
29
66
|
* @example
|
|
@@ -52,18 +89,17 @@ import type { GenerateResult, GenerateOptions } from './types.js'
|
|
|
52
89
|
* instructions: 'Use TypeScript and hooks. Include prop types.',
|
|
53
90
|
* })
|
|
54
91
|
* console.log(result.content) // TypeScript React component code
|
|
92
|
+
* console.log(result.metadata.language) // 'typescript'
|
|
55
93
|
* ```
|
|
94
|
+
*
|
|
95
|
+
* @see {@link ai-functions#generate} for lower-level type-dispatch generation
|
|
96
|
+
* @see {@link ai-functions#ai} for template literal generation syntax
|
|
56
97
|
*/
|
|
57
98
|
export async function generate<T = string>(
|
|
58
99
|
prompt: string,
|
|
59
100
|
options: GenerateOptions = {}
|
|
60
101
|
): Promise<GenerateResult<T>> {
|
|
61
|
-
const {
|
|
62
|
-
type = 'text',
|
|
63
|
-
schema,
|
|
64
|
-
instructions,
|
|
65
|
-
model = 'sonnet',
|
|
66
|
-
} = options
|
|
102
|
+
const { type = 'text', schema, instructions, model = 'sonnet' } = options
|
|
67
103
|
|
|
68
104
|
const startTime = Date.now()
|
|
69
105
|
|
|
@@ -111,7 +147,7 @@ export async function generate<T = string>(
|
|
|
111
147
|
type: 'structured',
|
|
112
148
|
metadata: {
|
|
113
149
|
model,
|
|
114
|
-
tokens: result.usage?.totalTokens,
|
|
150
|
+
tokens: (result.usage as { totalTokens?: number } | undefined)?.totalTokens,
|
|
115
151
|
duration: Date.now() - startTime,
|
|
116
152
|
},
|
|
117
153
|
}
|
|
@@ -144,7 +180,7 @@ export async function generate<T = string>(
|
|
|
144
180
|
type: 'code',
|
|
145
181
|
metadata: {
|
|
146
182
|
model,
|
|
147
|
-
tokens: result.usage?.totalTokens,
|
|
183
|
+
tokens: (result.usage as { totalTokens?: number } | undefined)?.totalTokens,
|
|
148
184
|
duration: Date.now() - startTime,
|
|
149
185
|
language: codeResult.language,
|
|
150
186
|
explanation: codeResult.explanation,
|
|
@@ -199,9 +235,7 @@ generate.variations = async <T = string>(
|
|
|
199
235
|
count: number,
|
|
200
236
|
options: GenerateOptions = {}
|
|
201
237
|
): Promise<Array<GenerateResult<T>>> => {
|
|
202
|
-
return Promise.all(
|
|
203
|
-
Array.from({ length: count }, () => generate<T>(prompt, options))
|
|
204
|
-
)
|
|
238
|
+
return Promise.all(Array.from({ length: count }, () => generate<T>(prompt, options)))
|
|
205
239
|
}
|
|
206
240
|
|
|
207
241
|
/**
|
package/src/goals.ts
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
* Goals definition for digital workers
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import { calculateProgress, isOnTrack } from 'org.ai'
|
|
6
|
+
import type { WorkerGoals, WorkerKPI } from './types.js'
|
|
7
|
+
|
|
8
|
+
// Note: Goal, Goals types are re-exported from types.ts which imports from org.ai
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* Define worker goals
|
|
@@ -15,7 +18,7 @@ import type { WorkerGoals, KPI } from './types.js'
|
|
|
15
18
|
*
|
|
16
19
|
* @example
|
|
17
20
|
* ```ts
|
|
18
|
-
* const engineeringGoals =
|
|
21
|
+
* const engineeringGoals = defineGoals({
|
|
19
22
|
* shortTerm: [
|
|
20
23
|
* 'Complete Q1 roadmap features',
|
|
21
24
|
* 'Reduce bug backlog by 30%',
|
|
@@ -55,7 +58,7 @@ import type { WorkerGoals, KPI } from './types.js'
|
|
|
55
58
|
*
|
|
56
59
|
* @example
|
|
57
60
|
* ```ts
|
|
58
|
-
* const supportGoals =
|
|
61
|
+
* const supportGoals = defineGoals({
|
|
59
62
|
* shortTerm: [
|
|
60
63
|
* 'Achieve 95% customer satisfaction',
|
|
61
64
|
* 'Reduce average response time to < 5 min',
|
|
@@ -78,7 +81,7 @@ import type { WorkerGoals, KPI } from './types.js'
|
|
|
78
81
|
* })
|
|
79
82
|
* ```
|
|
80
83
|
*/
|
|
81
|
-
export function
|
|
84
|
+
export function defineGoals(definition: WorkerGoals): WorkerGoals {
|
|
82
85
|
return definition
|
|
83
86
|
}
|
|
84
87
|
|
|
@@ -91,10 +94,10 @@ export function Goals(definition: WorkerGoals): WorkerGoals {
|
|
|
91
94
|
*
|
|
92
95
|
* @example
|
|
93
96
|
* ```ts
|
|
94
|
-
* const updated =
|
|
97
|
+
* const updated = defineGoals.addShortTerm(engineeringGoals, 'Complete security audit')
|
|
95
98
|
* ```
|
|
96
99
|
*/
|
|
97
|
-
|
|
100
|
+
defineGoals.addShortTerm = (goals: WorkerGoals, goal: string): WorkerGoals => ({
|
|
98
101
|
...goals,
|
|
99
102
|
shortTerm: [...goals.shortTerm, goal],
|
|
100
103
|
})
|
|
@@ -108,10 +111,10 @@ Goals.addShortTerm = (goals: WorkerGoals, goal: string): WorkerGoals => ({
|
|
|
108
111
|
*
|
|
109
112
|
* @example
|
|
110
113
|
* ```ts
|
|
111
|
-
* const updated =
|
|
114
|
+
* const updated = defineGoals.addLongTerm(engineeringGoals, 'Build ML platform')
|
|
112
115
|
* ```
|
|
113
116
|
*/
|
|
114
|
-
|
|
117
|
+
defineGoals.addLongTerm = (goals: WorkerGoals, goal: string): WorkerGoals => ({
|
|
115
118
|
...goals,
|
|
116
119
|
longTerm: [...goals.longTerm, goal],
|
|
117
120
|
})
|
|
@@ -125,10 +128,10 @@ Goals.addLongTerm = (goals: WorkerGoals, goal: string): WorkerGoals => ({
|
|
|
125
128
|
*
|
|
126
129
|
* @example
|
|
127
130
|
* ```ts
|
|
128
|
-
* const updated =
|
|
131
|
+
* const updated = defineGoals.addStrategic(engineeringGoals, 'Become carbon neutral')
|
|
129
132
|
* ```
|
|
130
133
|
*/
|
|
131
|
-
|
|
134
|
+
defineGoals.addStrategic = (goals: WorkerGoals, goal: string): WorkerGoals => ({
|
|
132
135
|
...goals,
|
|
133
136
|
strategic: [...(goals.strategic || []), goal],
|
|
134
137
|
})
|
|
@@ -142,7 +145,7 @@ Goals.addStrategic = (goals: WorkerGoals, goal: string): WorkerGoals => ({
|
|
|
142
145
|
*
|
|
143
146
|
* @example
|
|
144
147
|
* ```ts
|
|
145
|
-
* const updated =
|
|
148
|
+
* const updated = defineGoals.addMetric(engineeringGoals, {
|
|
146
149
|
* name: 'Code Quality',
|
|
147
150
|
* description: 'Code quality score from SonarQube',
|
|
148
151
|
* current: 85,
|
|
@@ -153,7 +156,7 @@ Goals.addStrategic = (goals: WorkerGoals, goal: string): WorkerGoals => ({
|
|
|
153
156
|
* })
|
|
154
157
|
* ```
|
|
155
158
|
*/
|
|
156
|
-
|
|
159
|
+
defineGoals.addMetric = (goals: WorkerGoals, kpi: WorkerKPI): WorkerGoals => ({
|
|
157
160
|
...goals,
|
|
158
161
|
metrics: [...(goals.metrics || []), kpi],
|
|
159
162
|
})
|
|
@@ -168,22 +171,26 @@ Goals.addMetric = (goals: WorkerGoals, kpi: KPI): WorkerGoals => ({
|
|
|
168
171
|
*
|
|
169
172
|
* @example
|
|
170
173
|
* ```ts
|
|
171
|
-
* const updated =
|
|
174
|
+
* const updated = defineGoals.updateMetric(engineeringGoals, 'Deployment Frequency', {
|
|
172
175
|
* current: 8,
|
|
173
176
|
* trend: 'up',
|
|
174
177
|
* })
|
|
175
178
|
* ```
|
|
176
179
|
*/
|
|
177
|
-
|
|
180
|
+
defineGoals.updateMetric = (
|
|
178
181
|
goals: WorkerGoals,
|
|
179
182
|
name: string,
|
|
180
|
-
updates: Partial<Omit<
|
|
181
|
-
): WorkerGoals =>
|
|
182
|
-
|
|
183
|
-
metrics: goals.metrics?.map((kpi) =>
|
|
183
|
+
updates: Partial<Omit<WorkerKPI, 'name'>>
|
|
184
|
+
): WorkerGoals => {
|
|
185
|
+
const updatedMetrics = goals.metrics?.map((kpi) =>
|
|
184
186
|
kpi.name === name ? { ...kpi, ...updates } : kpi
|
|
185
|
-
)
|
|
186
|
-
}
|
|
187
|
+
)
|
|
188
|
+
const result: WorkerGoals = { ...goals }
|
|
189
|
+
if (updatedMetrics) {
|
|
190
|
+
result.metrics = updatedMetrics
|
|
191
|
+
}
|
|
192
|
+
return result
|
|
193
|
+
}
|
|
187
194
|
|
|
188
195
|
/**
|
|
189
196
|
* Get progress for a KPI (0-1)
|
|
@@ -194,12 +201,11 @@ Goals.updateMetric = (
|
|
|
194
201
|
* @example
|
|
195
202
|
* ```ts
|
|
196
203
|
* const kpi = { current: 75, target: 100 }
|
|
197
|
-
* const progress =
|
|
204
|
+
* const progress = defineGoals.progress(kpi) // 0.75
|
|
198
205
|
* ```
|
|
199
206
|
*/
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
return Math.min(1, Math.max(0, kpi.current / kpi.target))
|
|
207
|
+
defineGoals.progress = (kpi: Pick<WorkerKPI, 'current' | 'target'>): number => {
|
|
208
|
+
return calculateProgress(kpi)
|
|
203
209
|
}
|
|
204
210
|
|
|
205
211
|
/**
|
|
@@ -212,9 +218,12 @@ Goals.progress = (kpi: Pick<KPI, 'current' | 'target'>): number => {
|
|
|
212
218
|
* @example
|
|
213
219
|
* ```ts
|
|
214
220
|
* const kpi = { current: 85, target: 100 }
|
|
215
|
-
* const onTrack =
|
|
221
|
+
* const onTrack = defineGoals.onTrack(kpi) // true (85% >= 80% threshold)
|
|
216
222
|
* ```
|
|
217
223
|
*/
|
|
218
|
-
|
|
219
|
-
return
|
|
224
|
+
defineGoals.onTrack = (kpi: Pick<WorkerKPI, 'current' | 'target'>, threshold = 0.8): boolean => {
|
|
225
|
+
return isOnTrack(kpi, threshold)
|
|
220
226
|
}
|
|
227
|
+
|
|
228
|
+
// Legacy alias for backward compatibility
|
|
229
|
+
export { defineGoals as Goals }
|