@windagency/valora 2.1.4 → 2.2.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/README.md +2 -2
- package/data/commands/_meta/schema.json +5 -0
- package/data/commands/create-backlog.md +4 -0
- package/data/commands/create-prd.md +3 -0
- package/data/commands/generate-docs.md +4 -0
- package/data/commands/implement.md +2 -0
- package/data/commands/plan-architecture.md +1 -0
- package/data/commands/plan-implementation.md +2 -0
- package/data/commands/refine-specs.md +2 -0
- package/data/commands/refine-task.md +2 -0
- package/data/commands/review-code.md +1 -0
- package/data/commands/review-functional.md +1 -0
- package/data/commands/review-plan.md +5 -0
- package/dist/batch/batch-eligibility.d.ts +17 -0
- package/dist/batch/batch-eligibility.d.ts.map +1 -0
- package/dist/batch/batch-eligibility.js +22 -0
- package/dist/batch/batch-eligibility.js.map +1 -0
- package/dist/batch/batch-orchestrator.d.ts +35 -0
- package/dist/batch/batch-orchestrator.d.ts.map +1 -0
- package/dist/batch/batch-orchestrator.js +121 -0
- package/dist/batch/batch-orchestrator.js.map +1 -0
- package/dist/batch/batch-provider.interface.d.ts +14 -0
- package/dist/batch/batch-provider.interface.d.ts.map +1 -0
- package/dist/batch/batch-provider.interface.js +9 -0
- package/dist/batch/batch-provider.interface.js.map +1 -0
- package/dist/batch/batch-session.d.ts +29 -0
- package/dist/batch/batch-session.d.ts.map +1 -0
- package/dist/batch/batch-session.js +91 -0
- package/dist/batch/batch-session.js.map +1 -0
- package/dist/batch/batch.types.d.ts +48 -0
- package/dist/batch/batch.types.d.ts.map +1 -0
- package/dist/batch/batch.types.js +5 -0
- package/dist/batch/batch.types.js.map +1 -0
- package/dist/batch/providers/anthropic.batch-provider.d.ts +33 -0
- package/dist/batch/providers/anthropic.batch-provider.d.ts.map +1 -0
- package/dist/batch/providers/anthropic.batch-provider.js +106 -0
- package/dist/batch/providers/anthropic.batch-provider.js.map +1 -0
- package/dist/batch/providers/google.batch-provider.d.ts +32 -0
- package/dist/batch/providers/google.batch-provider.d.ts.map +1 -0
- package/dist/batch/providers/google.batch-provider.js +41 -0
- package/dist/batch/providers/google.batch-provider.js.map +1 -0
- package/dist/batch/providers/openai.batch-provider.d.ts +32 -0
- package/dist/batch/providers/openai.batch-provider.d.ts.map +1 -0
- package/dist/batch/providers/openai.batch-provider.js +151 -0
- package/dist/batch/providers/openai.batch-provider.js.map +1 -0
- package/dist/cli/command-executor.d.ts +5 -0
- package/dist/cli/command-executor.d.ts.map +1 -1
- package/dist/cli/command-executor.js +63 -11
- package/dist/cli/command-executor.js.map +1 -1
- package/dist/cli/commands/batch.command.d.ts +14 -0
- package/dist/cli/commands/batch.command.d.ts.map +1 -0
- package/dist/cli/commands/batch.command.js +174 -0
- package/dist/cli/commands/batch.command.js.map +1 -0
- package/dist/cli/commands/monitoring.d.ts.map +1 -1
- package/dist/cli/commands/monitoring.js +119 -0
- package/dist/cli/commands/monitoring.js.map +1 -1
- package/dist/cli/flags.d.ts +1 -0
- package/dist/cli/flags.d.ts.map +1 -1
- package/dist/cli/flags.js +1 -0
- package/dist/cli/flags.js.map +1 -1
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/result-presenter.d.ts +6 -2
- package/dist/cli/result-presenter.d.ts.map +1 -1
- package/dist/cli/result-presenter.js +22 -12
- package/dist/cli/result-presenter.js.map +1 -1
- package/dist/cli/types/cli-options.types.d.ts +1 -0
- package/dist/cli/types/cli-options.types.d.ts.map +1 -1
- package/dist/config/schema.d.ts +87 -12
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +1 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/executor/stage-executor.d.ts +26 -5
- package/dist/executor/stage-executor.d.ts.map +1 -1
- package/dist/executor/stage-executor.js +180 -14
- package/dist/executor/stage-executor.js.map +1 -1
- package/dist/executor/tool-execution.service.d.ts +10 -0
- package/dist/executor/tool-execution.service.d.ts.map +1 -1
- package/dist/executor/tool-execution.service.js +40 -6
- package/dist/executor/tool-execution.service.js.map +1 -1
- package/dist/executor/variable-resolution.service.d.ts.map +1 -1
- package/dist/executor/variable-resolution.service.js +1 -2
- package/dist/executor/variable-resolution.service.js.map +1 -1
- package/dist/executor/variables.d.ts +1 -5
- package/dist/executor/variables.d.ts.map +1 -1
- package/dist/executor/variables.js +0 -21
- package/dist/executor/variables.js.map +1 -1
- package/dist/llm/providers/anthropic.provider.d.ts +30 -1
- package/dist/llm/providers/anthropic.provider.d.ts.map +1 -1
- package/dist/llm/providers/anthropic.provider.js +163 -6
- package/dist/llm/providers/anthropic.provider.js.map +1 -1
- package/dist/llm/providers/google.provider.d.ts +9 -0
- package/dist/llm/providers/google.provider.d.ts.map +1 -1
- package/dist/llm/providers/google.provider.js +25 -10
- package/dist/llm/providers/google.provider.js.map +1 -1
- package/dist/llm/providers/openai.provider.d.ts +17 -1
- package/dist/llm/providers/openai.provider.d.ts.map +1 -1
- package/dist/llm/providers/openai.provider.js +93 -25
- package/dist/llm/providers/openai.provider.js.map +1 -1
- package/dist/output/processing-feedback.d.ts +14 -0
- package/dist/output/processing-feedback.d.ts.map +1 -1
- package/dist/output/processing-feedback.js +46 -7
- package/dist/output/processing-feedback.js.map +1 -1
- package/dist/package.json +3 -3
- package/dist/session/context.d.ts +2 -0
- package/dist/session/context.d.ts.map +1 -1
- package/dist/session/context.js +43 -13
- package/dist/session/context.js.map +1 -1
- package/dist/tsconfig.json +1 -0
- package/dist/types/command.types.d.ts +14 -0
- package/dist/types/command.types.d.ts.map +1 -1
- package/dist/types/command.types.js.map +1 -1
- package/dist/types/llm.types.d.ts +4 -0
- package/dist/types/llm.types.d.ts.map +1 -1
- package/dist/ui/dashboard/detail-panels/spending-panel.d.ts +9 -0
- package/dist/ui/dashboard/detail-panels/spending-panel.d.ts.map +1 -0
- package/dist/ui/dashboard/detail-panels/spending-panel.js +28 -0
- package/dist/ui/dashboard/detail-panels/spending-panel.js.map +1 -0
- package/dist/ui/dashboard/hooks/use-navigation.js +1 -1
- package/dist/ui/dashboard/hooks/use-navigation.js.map +1 -1
- package/dist/ui/dashboard/index.d.ts +1 -0
- package/dist/ui/dashboard/index.d.ts.map +1 -1
- package/dist/ui/dashboard/index.js +1 -0
- package/dist/ui/dashboard/index.js.map +1 -1
- package/dist/ui/dashboard/types.d.ts +1 -1
- package/dist/ui/dashboard/types.d.ts.map +1 -1
- package/dist/ui/dashboard/views/session-details-view.d.ts.map +1 -1
- package/dist/ui/dashboard/views/session-details-view.js +5 -1
- package/dist/ui/dashboard/views/session-details-view.js.map +1 -1
- package/dist/utils/spending-tracker.d.ts +64 -0
- package/dist/utils/spending-tracker.d.ts.map +1 -0
- package/dist/utils/spending-tracker.js +107 -0
- package/dist/utils/spending-tracker.js.map +1 -0
- package/dist/utils/token-estimator.d.ts +31 -5
- package/dist/utils/token-estimator.d.ts.map +1 -1
- package/dist/utils/token-estimator.js +42 -20
- package/dist/utils/token-estimator.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
</p>
|
|
18
18
|
|
|
19
19
|
<p align="center">
|
|
20
|
-
<img src="https://img.shields.io/badge/version-2.1
|
|
20
|
+
<img src="https://img.shields.io/badge/version-2.2.1-blue?style=flat-square" alt="Version" />
|
|
21
21
|
<img src="https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen?style=flat-square&logo=node.js" alt="Node" />
|
|
22
22
|
<img src="https://img.shields.io/badge/typescript-5.x-3178c6?style=flat-square&logo=typescript" alt="TypeScript" />
|
|
23
23
|
<img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="License" />
|
|
@@ -176,7 +176,7 @@ npm install -g @windagency/valora # npm
|
|
|
176
176
|
|
|
177
177
|
# Verify installation
|
|
178
178
|
valora --version
|
|
179
|
-
# Should output: 2.1
|
|
179
|
+
# Should output: 2.2.1
|
|
180
180
|
```
|
|
181
181
|
|
|
182
182
|
### Project Setup
|
|
@@ -213,6 +213,11 @@
|
|
|
213
213
|
"minimum": 1000,
|
|
214
214
|
"maximum": 300000,
|
|
215
215
|
"default": 30000
|
|
216
|
+
},
|
|
217
|
+
"failure_policy": {
|
|
218
|
+
"type": "string",
|
|
219
|
+
"description": "Controls how tool failures affect stage success. 'strict' = all failures count, 'tolerant' = only fatal (mutating) failures count, 'lenient' = never hard-stop.",
|
|
220
|
+
"enum": ["strict", "tolerant", "lenient"]
|
|
216
221
|
}
|
|
217
222
|
},
|
|
218
223
|
"additionalProperties": false
|
|
@@ -31,6 +31,7 @@ prompts:
|
|
|
31
31
|
timeout_ms: 30000
|
|
32
32
|
- stage: onboard
|
|
33
33
|
prompt: onboard.analyze-requirements
|
|
34
|
+
batch: true
|
|
34
35
|
required: true
|
|
35
36
|
inputs:
|
|
36
37
|
source_document: $STAGE_context.prd_document
|
|
@@ -43,6 +44,7 @@ prompts:
|
|
|
43
44
|
timeout_ms: 60000
|
|
44
45
|
- stage: breakdown
|
|
45
46
|
prompt: plan.decompose-tasks
|
|
47
|
+
batch: true
|
|
46
48
|
required: true
|
|
47
49
|
inputs:
|
|
48
50
|
analysis: $STAGE_onboard.requirement_analysis
|
|
@@ -56,6 +58,7 @@ prompts:
|
|
|
56
58
|
timeout_ms: 90000
|
|
57
59
|
- stage: review
|
|
58
60
|
prompt: review.validate-backlog
|
|
61
|
+
batch: true
|
|
59
62
|
required: true
|
|
60
63
|
inputs:
|
|
61
64
|
tasks: $STAGE_breakdown.task_list
|
|
@@ -67,6 +70,7 @@ prompts:
|
|
|
67
70
|
timeout_ms: 60000
|
|
68
71
|
- stage: generate
|
|
69
72
|
prompt: documentation.generate-backlog-artifacts
|
|
73
|
+
batch: true
|
|
70
74
|
required: true
|
|
71
75
|
inputs:
|
|
72
76
|
task_list: $STAGE_breakdown.task_list
|
|
@@ -31,6 +31,7 @@ prompts:
|
|
|
31
31
|
- project_type
|
|
32
32
|
- stage: onboard
|
|
33
33
|
prompt: onboard.analyze-requirements
|
|
34
|
+
batch: true
|
|
34
35
|
required: true
|
|
35
36
|
inputs:
|
|
36
37
|
source_document: $STAGE_context.specifications
|
|
@@ -59,6 +60,7 @@ prompts:
|
|
|
59
60
|
- questions_skipped
|
|
60
61
|
- stage: documentation
|
|
61
62
|
prompt: documentation.generate-prd
|
|
63
|
+
batch: true
|
|
62
64
|
required: true
|
|
63
65
|
inputs:
|
|
64
66
|
specifications: $STAGE_context.specifications
|
|
@@ -71,6 +73,7 @@ prompts:
|
|
|
71
73
|
- executive_summary
|
|
72
74
|
- stage: review
|
|
73
75
|
prompt: review.validate-completeness
|
|
76
|
+
batch: true
|
|
74
77
|
required: true
|
|
75
78
|
inputs:
|
|
76
79
|
document: $STAGE_documentation.prd_document
|
|
@@ -53,6 +53,7 @@ prompts:
|
|
|
53
53
|
timeout_ms: 60000
|
|
54
54
|
- stage: generateInfra
|
|
55
55
|
prompt: documentation.generate-infrastructure-docs
|
|
56
|
+
batch: true
|
|
56
57
|
required: false
|
|
57
58
|
conditional: $STAGE_analyze.domain_assignments.infrastructure
|
|
58
59
|
parallel: true
|
|
@@ -73,6 +74,7 @@ prompts:
|
|
|
73
74
|
timeout_ms: 180000
|
|
74
75
|
- stage: generateBackend
|
|
75
76
|
prompt: documentation.generate-backend-docs
|
|
77
|
+
batch: true
|
|
76
78
|
required: false
|
|
77
79
|
conditional: $STAGE_analyze.domain_assignments.backend
|
|
78
80
|
parallel: true
|
|
@@ -92,6 +94,7 @@ prompts:
|
|
|
92
94
|
timeout_ms: 180000
|
|
93
95
|
- stage: generateFrontend
|
|
94
96
|
prompt: documentation.generate-frontend-docs
|
|
97
|
+
batch: true
|
|
95
98
|
required: false
|
|
96
99
|
conditional: $STAGE_analyze.domain_assignments.frontend
|
|
97
100
|
parallel: true
|
|
@@ -110,6 +113,7 @@ prompts:
|
|
|
110
113
|
timeout_ms: 180000
|
|
111
114
|
- stage: review
|
|
112
115
|
prompt: review.validate-documentation
|
|
116
|
+
batch: true
|
|
113
117
|
required: true
|
|
114
118
|
inputs:
|
|
115
119
|
infrastructure_docs: $STAGE_generateInfra
|
|
@@ -33,6 +33,7 @@ prompts:
|
|
|
33
33
|
- stage: context
|
|
34
34
|
prompt: context.load-implementation-context
|
|
35
35
|
required: true
|
|
36
|
+
failure_policy: tolerant
|
|
36
37
|
inputs:
|
|
37
38
|
implementation_plan: $ARG_1
|
|
38
39
|
agent_type: $ARG_agent
|
|
@@ -48,6 +49,7 @@ prompts:
|
|
|
48
49
|
- stage: review
|
|
49
50
|
prompt: code.validate-prerequisites
|
|
50
51
|
required: true
|
|
52
|
+
failure_policy: tolerant
|
|
51
53
|
inputs:
|
|
52
54
|
plan_summary: $STAGE_context.plan_summary
|
|
53
55
|
dependencies: $STAGE_context.dependencies
|
|
@@ -38,6 +38,7 @@ prompts:
|
|
|
38
38
|
- execution_order
|
|
39
39
|
- stage: risks
|
|
40
40
|
prompt: plan.assess-risks
|
|
41
|
+
batch: true
|
|
41
42
|
required: true
|
|
42
43
|
inputs:
|
|
43
44
|
architecture: $STAGE_load-arch.result
|
|
@@ -50,6 +51,7 @@ prompts:
|
|
|
50
51
|
- risk_score
|
|
51
52
|
- stage: breakdown
|
|
52
53
|
prompt: plan.breakdown-implementation
|
|
54
|
+
batch: true
|
|
53
55
|
required: true
|
|
54
56
|
inputs:
|
|
55
57
|
architecture: $STAGE_load-arch.result
|
|
@@ -25,6 +25,7 @@ prompts:
|
|
|
25
25
|
- initial_scope
|
|
26
26
|
- stage: onboard
|
|
27
27
|
prompt: onboard.refine-specifications
|
|
28
|
+
batch: true
|
|
28
29
|
required: true
|
|
29
30
|
inputs:
|
|
30
31
|
user_intent: $STAGE_context.user_intent
|
|
@@ -39,6 +40,7 @@ prompts:
|
|
|
39
40
|
- clarifying_questions
|
|
40
41
|
- stage: review
|
|
41
42
|
prompt: review.validate-completeness
|
|
43
|
+
batch: true
|
|
42
44
|
required: true
|
|
43
45
|
inputs:
|
|
44
46
|
document: $STAGE_onboard.refined_specifications
|
|
@@ -27,6 +27,7 @@ prompts:
|
|
|
27
27
|
- linked_requirements
|
|
28
28
|
- stage: analyze
|
|
29
29
|
prompt: onboard.analyze-clarity
|
|
30
|
+
batch: true
|
|
30
31
|
required: true
|
|
31
32
|
inputs:
|
|
32
33
|
task_context: $STAGE_context.result
|
|
@@ -48,6 +49,7 @@ prompts:
|
|
|
48
49
|
- assumptions_made
|
|
49
50
|
- stage: review
|
|
50
51
|
prompt: review.validate-testability
|
|
52
|
+
batch: true
|
|
51
53
|
required: true
|
|
52
54
|
inputs:
|
|
53
55
|
task_context: $STAGE_context.result
|
|
@@ -27,6 +27,7 @@ prompts:
|
|
|
27
27
|
- complexity_assessment
|
|
28
28
|
- stage: completeness
|
|
29
29
|
prompt: review.validate-completeness
|
|
30
|
+
batch: true
|
|
30
31
|
required: true
|
|
31
32
|
inputs:
|
|
32
33
|
document_type: 'plan'
|
|
@@ -49,6 +50,7 @@ prompts:
|
|
|
49
50
|
- blockers_identified
|
|
50
51
|
- stage: risks
|
|
51
52
|
prompt: review.validate-risk-coverage
|
|
53
|
+
batch: true
|
|
52
54
|
required: true
|
|
53
55
|
parallel: true
|
|
54
56
|
inputs:
|
|
@@ -60,6 +62,7 @@ prompts:
|
|
|
60
62
|
- mitigation_gaps
|
|
61
63
|
- stage: steps
|
|
62
64
|
prompt: review.validate-step-quality
|
|
65
|
+
batch: true
|
|
63
66
|
required: true
|
|
64
67
|
parallel: true
|
|
65
68
|
inputs:
|
|
@@ -70,6 +73,7 @@ prompts:
|
|
|
70
73
|
- actionability_issues
|
|
71
74
|
- stage: tests
|
|
72
75
|
prompt: review.validate-test-strategy
|
|
76
|
+
batch: true
|
|
73
77
|
required: true
|
|
74
78
|
parallel: true
|
|
75
79
|
inputs:
|
|
@@ -79,6 +83,7 @@ prompts:
|
|
|
79
83
|
- testing_gaps
|
|
80
84
|
- stage: synthesis
|
|
81
85
|
prompt: review.synthesize-plan-assessment
|
|
86
|
+
batch: true
|
|
82
87
|
required: true
|
|
83
88
|
inputs:
|
|
84
89
|
completeness_score: $STAGE_completeness.completeness_score
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch eligibility checks
|
|
3
|
+
*
|
|
4
|
+
* A stage is batch-eligible when all three conditions hold:
|
|
5
|
+
* 1. stage.batch === true (explicit opt-in)
|
|
6
|
+
* 2. --batch flag is set (user intent)
|
|
7
|
+
* 3. provider.isBatchableProvider() (provider capability)
|
|
8
|
+
*/
|
|
9
|
+
import type { ExecutionContext } from '../executor/execution-context.js';
|
|
10
|
+
import type { PipelineStage } from '../types/command.types.js';
|
|
11
|
+
import type { LLMProvider } from '../types/llm.types.js';
|
|
12
|
+
export interface EligibilityResult {
|
|
13
|
+
eligible: boolean;
|
|
14
|
+
reason?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function isEligible(stage: PipelineStage, executionContext: ExecutionContext, provider: LLMProvider): EligibilityResult;
|
|
17
|
+
//# sourceMappingURL=batch-eligibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-eligibility.d.ts","sourceRoot":"","sources":["../../src/batch/batch-eligibility.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAInD,MAAM,WAAW,iBAAiB;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,UAAU,CACzB,KAAK,EAAE,aAAa,EACpB,gBAAgB,EAAE,gBAAgB,EAClC,QAAQ,EAAE,WAAW,GACnB,iBAAiB,CAcnB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch eligibility checks
|
|
3
|
+
*
|
|
4
|
+
* A stage is batch-eligible when all three conditions hold:
|
|
5
|
+
* 1. stage.batch === true (explicit opt-in)
|
|
6
|
+
* 2. --batch flag is set (user intent)
|
|
7
|
+
* 3. provider.isBatchableProvider() (provider capability)
|
|
8
|
+
*/
|
|
9
|
+
import { isBatchableProvider } from './batch-provider.interface.js';
|
|
10
|
+
export function isEligible(stage, executionContext, provider) {
|
|
11
|
+
if (!stage.batch) {
|
|
12
|
+
return { eligible: false, reason: 'stage does not have batch: true' };
|
|
13
|
+
}
|
|
14
|
+
if (!executionContext.flags['batch']) {
|
|
15
|
+
return { eligible: false, reason: '--batch flag not set' };
|
|
16
|
+
}
|
|
17
|
+
if (!isBatchableProvider(provider)) {
|
|
18
|
+
return { eligible: false, reason: `provider "${provider.name}" does not support batch API` };
|
|
19
|
+
}
|
|
20
|
+
return { eligible: true };
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=batch-eligibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-eligibility.js","sourceRoot":"","sources":["../../src/batch/batch-eligibility.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAOjE,MAAM,UAAU,UAAU,CACzB,KAAoB,EACpB,gBAAkC,EAClC,QAAqB;IAErB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAC;IACvE,CAAC;IAED,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;IAC5D,CAAC;IAED,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,QAAQ,CAAC,IAAI,8BAA8B,EAAE,CAAC;IAC9F,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BatchOrchestrator - Submit, poll, and retrieve batch results
|
|
3
|
+
*
|
|
4
|
+
* Polling backoff: 30s → 60s → 2m → 5m (cap). Max wait default: 26h.
|
|
5
|
+
*/
|
|
6
|
+
import type { BatchableProvider } from './batch-provider.interface.js';
|
|
7
|
+
import type { BatchRequest, BatchResult, BatchStatusInfo, BatchSubmission, PersistedBatch } from './batch.types.js';
|
|
8
|
+
export declare class BatchOrchestrator {
|
|
9
|
+
/**
|
|
10
|
+
* Submit a set of requests to the batch provider and persist state.
|
|
11
|
+
*/
|
|
12
|
+
submit(requests: BatchRequest[], provider: BatchableProvider): Promise<BatchSubmission>;
|
|
13
|
+
/**
|
|
14
|
+
* Block until the batch completes (or max wait is reached), then return results.
|
|
15
|
+
*/
|
|
16
|
+
waitForResults(localId: string, provider: BatchableProvider, maxWaitMs?: number): Promise<BatchResult[]>;
|
|
17
|
+
/**
|
|
18
|
+
* Non-blocking: return current status from provider (and update persisted state).
|
|
19
|
+
*/
|
|
20
|
+
getStatus(localId: string, provider: BatchableProvider): Promise<BatchStatusInfo>;
|
|
21
|
+
/**
|
|
22
|
+
* Retrieve completed results (from provider, with disk caching).
|
|
23
|
+
*/
|
|
24
|
+
getResults(localId: string, provider: BatchableProvider): Promise<BatchResult[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Cancel a batch job and update persisted state.
|
|
27
|
+
*/
|
|
28
|
+
cancel(localId: string, provider: BatchableProvider): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* List all known batches from disk.
|
|
31
|
+
*/
|
|
32
|
+
list(): PersistedBatch[];
|
|
33
|
+
}
|
|
34
|
+
export declare function getBatchOrchestrator(): BatchOrchestrator;
|
|
35
|
+
//# sourceMappingURL=batch-orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-orchestrator.d.ts","sourceRoot":"","sources":["../../src/batch/batch-orchestrator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAajH,qBAAa,iBAAiB;IAC7B;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IAiB7F;;OAEG;IACG,cAAc,CACnB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,SAAsB,GAC7B,OAAO,CAAC,WAAW,EAAE,CAAC;IA+BzB;;OAEG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IAgBvF;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAgBtF;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAazE;;OAEG;IACH,IAAI,IAAI,cAAc,EAAE;CAGxB;AAaD,wBAAgB,oBAAoB,IAAI,iBAAiB,CAGxD"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BatchOrchestrator - Submit, poll, and retrieve batch results
|
|
3
|
+
*
|
|
4
|
+
* Polling backoff: 30s → 60s → 2m → 5m (cap). Max wait default: 26h.
|
|
5
|
+
*/
|
|
6
|
+
import { getLogger } from '../output/logger.js';
|
|
7
|
+
import { generateLocalId, listBatches, loadBatch, persistBatch, updateBatch } from './batch-session.js';
|
|
8
|
+
const DEFAULT_MAX_WAIT_MS = 26 * 60 * 60 * 1000; // 26 hours
|
|
9
|
+
const POLL_INTERVALS_MS = [
|
|
10
|
+
30_000, // 30 s
|
|
11
|
+
60_000, // 60 s
|
|
12
|
+
2 * 60_000, // 2 min
|
|
13
|
+
5 * 60_000 // 5 min (cap)
|
|
14
|
+
];
|
|
15
|
+
export class BatchOrchestrator {
|
|
16
|
+
/**
|
|
17
|
+
* Submit a set of requests to the batch provider and persist state.
|
|
18
|
+
*/
|
|
19
|
+
async submit(requests, provider) {
|
|
20
|
+
const logger = getLogger();
|
|
21
|
+
const localId = generateLocalId();
|
|
22
|
+
logger.info(`Submitting batch of ${requests.length} request(s) to ${provider.name}`, { localId });
|
|
23
|
+
const submission = await provider.submitBatch(requests);
|
|
24
|
+
// Use the localId we generated (submitBatch may generate its own, but we want ours for disk)
|
|
25
|
+
submission.localId = localId;
|
|
26
|
+
const persisted = { localId, requests, submission };
|
|
27
|
+
persistBatch(persisted);
|
|
28
|
+
logger.info(`Batch submitted`, { batchId: submission.batchId, localId, provider: provider.name });
|
|
29
|
+
return submission;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Block until the batch completes (or max wait is reached), then return results.
|
|
33
|
+
*/
|
|
34
|
+
async waitForResults(localId, provider, maxWaitMs = DEFAULT_MAX_WAIT_MS) {
|
|
35
|
+
const logger = getLogger();
|
|
36
|
+
const deadline = Date.now() + maxWaitMs;
|
|
37
|
+
let attempt = 0;
|
|
38
|
+
while (Date.now() < deadline) {
|
|
39
|
+
const status = await this.getStatus(localId, provider);
|
|
40
|
+
logger.info(`Batch status: ${status.status}`, {
|
|
41
|
+
batchId: status.batchId,
|
|
42
|
+
completed: status.completedCount,
|
|
43
|
+
failed: status.failedCount,
|
|
44
|
+
total: status.totalCount
|
|
45
|
+
});
|
|
46
|
+
if (status.status === 'completed') {
|
|
47
|
+
return this.getResults(localId, provider);
|
|
48
|
+
}
|
|
49
|
+
if (status.status === 'failed' || status.status === 'cancelled' || status.status === 'expired') {
|
|
50
|
+
throw new Error(`Batch ${localId} ended with status: ${status.status}`);
|
|
51
|
+
}
|
|
52
|
+
const waitMs = nextPollInterval(attempt);
|
|
53
|
+
logger.debug(`Waiting ${waitMs}ms before next poll (attempt ${attempt + 1})`);
|
|
54
|
+
await sleep(waitMs);
|
|
55
|
+
attempt++;
|
|
56
|
+
}
|
|
57
|
+
throw new Error(`Batch ${localId} did not complete within ${Math.round(maxWaitMs / 3600000)}h`);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Non-blocking: return current status from provider (and update persisted state).
|
|
61
|
+
*/
|
|
62
|
+
async getStatus(localId, provider) {
|
|
63
|
+
const batch = loadBatch(localId);
|
|
64
|
+
if (!batch) {
|
|
65
|
+
throw new Error(`Batch not found: ${localId}`);
|
|
66
|
+
}
|
|
67
|
+
const status = await provider.getBatchStatus(batch.submission.batchId);
|
|
68
|
+
// Update persisted status
|
|
69
|
+
updateBatch(localId, {
|
|
70
|
+
submission: { ...batch.submission, status: status.status }
|
|
71
|
+
});
|
|
72
|
+
return status;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Retrieve completed results (from provider, with disk caching).
|
|
76
|
+
*/
|
|
77
|
+
async getResults(localId, provider) {
|
|
78
|
+
const batch = loadBatch(localId);
|
|
79
|
+
if (!batch) {
|
|
80
|
+
throw new Error(`Batch not found: ${localId}`);
|
|
81
|
+
}
|
|
82
|
+
const results = await provider.getBatchResults(batch.submission.batchId);
|
|
83
|
+
// Update status to completed
|
|
84
|
+
updateBatch(localId, {
|
|
85
|
+
submission: { ...batch.submission, status: 'completed' }
|
|
86
|
+
});
|
|
87
|
+
return results;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Cancel a batch job and update persisted state.
|
|
91
|
+
*/
|
|
92
|
+
async cancel(localId, provider) {
|
|
93
|
+
const batch = loadBatch(localId);
|
|
94
|
+
if (!batch) {
|
|
95
|
+
throw new Error(`Batch not found: ${localId}`);
|
|
96
|
+
}
|
|
97
|
+
await provider.cancelBatch(batch.submission.batchId);
|
|
98
|
+
updateBatch(localId, {
|
|
99
|
+
submission: { ...batch.submission, status: 'cancelled' }
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* List all known batches from disk.
|
|
104
|
+
*/
|
|
105
|
+
list() {
|
|
106
|
+
return listBatches();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function nextPollInterval(attempt) {
|
|
110
|
+
const idx = Math.min(attempt, POLL_INTERVALS_MS.length - 1);
|
|
111
|
+
return POLL_INTERVALS_MS[idx] ?? POLL_INTERVALS_MS[POLL_INTERVALS_MS.length - 1] ?? 5 * 60_000;
|
|
112
|
+
}
|
|
113
|
+
function sleep(ms) {
|
|
114
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
115
|
+
}
|
|
116
|
+
let orchestratorInstance = null;
|
|
117
|
+
export function getBatchOrchestrator() {
|
|
118
|
+
orchestratorInstance ??= new BatchOrchestrator();
|
|
119
|
+
return orchestratorInstance;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=batch-orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-orchestrator.js","sourceRoot":"","sources":["../../src/batch/batch-orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BatchableProvider interface and runtime type guard
|
|
3
|
+
*/
|
|
4
|
+
import type { LLMProvider } from '../types/llm.types.js';
|
|
5
|
+
import type { BatchRequest, BatchResult, BatchStatusInfo, BatchSubmission } from './batch.types.js';
|
|
6
|
+
export interface BatchableProvider extends LLMProvider {
|
|
7
|
+
cancelBatch(batchId: string): Promise<void>;
|
|
8
|
+
getBatchResults(batchId: string): Promise<BatchResult[]>;
|
|
9
|
+
getBatchStatus(batchId: string): Promise<BatchStatusInfo>;
|
|
10
|
+
submitBatch(requests: BatchRequest[]): Promise<BatchSubmission>;
|
|
11
|
+
supportsBatch(): true;
|
|
12
|
+
}
|
|
13
|
+
export declare function isBatchableProvider(p: LLMProvider): p is BatchableProvider;
|
|
14
|
+
//# sourceMappingURL=batch-provider.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-provider.interface.d.ts","sourceRoot":"","sources":["../../src/batch/batch-provider.interface.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEjG,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACrD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACzD,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC1D,WAAW,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAChE,aAAa,IAAI,IAAI,CAAC;CACtB;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,IAAI,iBAAiB,CAM1E"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BatchableProvider interface and runtime type guard
|
|
3
|
+
*/
|
|
4
|
+
export function isBatchableProvider(p) {
|
|
5
|
+
return ('supportsBatch' in p &&
|
|
6
|
+
typeof p.supportsBatch === 'function' &&
|
|
7
|
+
p.supportsBatch() === true);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=batch-provider.interface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-provider.interface.js","sourceRoot":"","sources":["../../src/batch/batch-provider.interface.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,MAAM,UAAU,mBAAmB,CAAC,CAAc;IACjD,OAAO,CACN,eAAe,IAAI,CAAC;QACpB,OAAQ,CAAuB,CAAC,aAAa,KAAK,UAAU;QAC3D,CAAuB,CAAC,aAAa,EAAE,KAAK,IAAI,CACjD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BatchSession - Persists batch job state to .valora/batches/<localId>.json
|
|
3
|
+
*/
|
|
4
|
+
import type { PersistedBatch } from './batch.types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Generate a short unique local ID for a batch job
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateLocalId(): string;
|
|
9
|
+
/**
|
|
10
|
+
* Persist a batch to disk
|
|
11
|
+
*/
|
|
12
|
+
export declare function persistBatch(batch: PersistedBatch): void;
|
|
13
|
+
/**
|
|
14
|
+
* Load a batch from disk by local ID
|
|
15
|
+
*/
|
|
16
|
+
export declare function loadBatch(localId: string): null | PersistedBatch;
|
|
17
|
+
/**
|
|
18
|
+
* Update a persisted batch with partial data
|
|
19
|
+
*/
|
|
20
|
+
export declare function updateBatch(localId: string, partial: Partial<PersistedBatch>): void;
|
|
21
|
+
/**
|
|
22
|
+
* List all persisted batches
|
|
23
|
+
*/
|
|
24
|
+
export declare function listBatches(): PersistedBatch[];
|
|
25
|
+
/**
|
|
26
|
+
* Remove a persisted batch from disk
|
|
27
|
+
*/
|
|
28
|
+
export declare function removeBatch(localId: string): void;
|
|
29
|
+
//# sourceMappingURL=batch-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-session.d.ts","sourceRoot":"","sources":["../../src/batch/batch-session.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAgBpD;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAKxC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAIxD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CAWhE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAMnF;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,cAAc,EAAE,CAe9C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKjD"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BatchSession - Persists batch job state to .valora/batches/<localId>.json
|
|
3
|
+
*/
|
|
4
|
+
import { createHash, randomBytes } from 'crypto';
|
|
5
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from 'fs';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import { getLogger } from '../output/logger.js';
|
|
8
|
+
import { getRuntimeDataDir } from '../utils/paths.js';
|
|
9
|
+
const getBatchDir = () => join(getRuntimeDataDir(), 'batches');
|
|
10
|
+
function batchFilePath(localId) {
|
|
11
|
+
return join(getBatchDir(), `${localId}.json`);
|
|
12
|
+
}
|
|
13
|
+
function ensureBatchDir() {
|
|
14
|
+
const dir = getBatchDir();
|
|
15
|
+
if (!existsSync(dir)) {
|
|
16
|
+
mkdirSync(dir, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
return dir;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Generate a short unique local ID for a batch job
|
|
22
|
+
*/
|
|
23
|
+
export function generateLocalId() {
|
|
24
|
+
return createHash('sha256')
|
|
25
|
+
.update(`${Date.now()}-${randomBytes(8).toString('hex')}`)
|
|
26
|
+
.digest('hex')
|
|
27
|
+
.substring(0, 16);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Persist a batch to disk
|
|
31
|
+
*/
|
|
32
|
+
export function persistBatch(batch) {
|
|
33
|
+
const dir = ensureBatchDir();
|
|
34
|
+
const filePath = join(dir, `${batch.localId}.json`);
|
|
35
|
+
writeFileSync(filePath, JSON.stringify(batch, null, 2), 'utf-8');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Load a batch from disk by local ID
|
|
39
|
+
*/
|
|
40
|
+
export function loadBatch(localId) {
|
|
41
|
+
const filePath = batchFilePath(localId);
|
|
42
|
+
if (!existsSync(filePath)) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
return JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
getLogger().warn(`Failed to load batch ${localId}`, { error: error.message });
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Update a persisted batch with partial data
|
|
55
|
+
*/
|
|
56
|
+
export function updateBatch(localId, partial) {
|
|
57
|
+
const existing = loadBatch(localId);
|
|
58
|
+
if (!existing) {
|
|
59
|
+
throw new Error(`Batch not found: ${localId}`);
|
|
60
|
+
}
|
|
61
|
+
persistBatch({ ...existing, ...partial });
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* List all persisted batches
|
|
65
|
+
*/
|
|
66
|
+
export function listBatches() {
|
|
67
|
+
const dir = getBatchDir();
|
|
68
|
+
if (!existsSync(dir)) {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
const files = readdirSync(dir).filter((f) => f.endsWith('.json'));
|
|
72
|
+
const batches = [];
|
|
73
|
+
for (const file of files) {
|
|
74
|
+
const localId = file.replace('.json', '');
|
|
75
|
+
const batch = loadBatch(localId);
|
|
76
|
+
if (batch) {
|
|
77
|
+
batches.push(batch);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return batches;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Remove a persisted batch from disk
|
|
84
|
+
*/
|
|
85
|
+
export function removeBatch(localId) {
|
|
86
|
+
const filePath = batchFilePath(localId);
|
|
87
|
+
if (existsSync(filePath)) {
|
|
88
|
+
unlinkSync(filePath);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=batch-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-session.js","sourceRoot":"","sources":["../../src/batch/batch-session.ts"],"names":[],"mappings":"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"}
|