@uluops/core 0.5.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/README.md +543 -0
- package/definitions/starter/code-validator.agent.yaml +134 -0
- package/definitions/starter/docs-validator.agent.yaml +142 -0
- package/definitions/starter/public-interface-validator.agent.yaml +138 -0
- package/definitions/starter/security-analyst.agent.yaml +144 -0
- package/definitions/starter/test-architect.agent.yaml +137 -0
- package/dist/ai/AIProvider.d.ts +198 -0
- package/dist/ai/AIProvider.d.ts.map +1 -0
- package/dist/ai/AIProvider.js +557 -0
- package/dist/ai/AIProvider.js.map +1 -0
- package/dist/ai/ModelCatalog.d.ts +78 -0
- package/dist/ai/ModelCatalog.d.ts.map +1 -0
- package/dist/ai/ModelCatalog.js +193 -0
- package/dist/ai/ModelCatalog.js.map +1 -0
- package/dist/ai/ShellExecutor.d.ts +42 -0
- package/dist/ai/ShellExecutor.d.ts.map +1 -0
- package/dist/ai/ShellExecutor.js +62 -0
- package/dist/ai/ShellExecutor.js.map +1 -0
- package/dist/ai/TokenBudgetTracker.d.ts +49 -0
- package/dist/ai/TokenBudgetTracker.d.ts.map +1 -0
- package/dist/ai/TokenBudgetTracker.js +61 -0
- package/dist/ai/TokenBudgetTracker.js.map +1 -0
- package/dist/ai/ToolAdapter.d.ts +25 -0
- package/dist/ai/ToolAdapter.d.ts.map +1 -0
- package/dist/ai/ToolAdapter.js +135 -0
- package/dist/ai/ToolAdapter.js.map +1 -0
- package/dist/ai/index.d.ts +6 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +4 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/client/UluOpsClient.d.ts +111 -0
- package/dist/client/UluOpsClient.d.ts.map +1 -0
- package/dist/client/UluOpsClient.js +329 -0
- package/dist/client/UluOpsClient.js.map +1 -0
- package/dist/constants.d.ts +6 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +9 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors/UluOpsError.d.ts +10 -0
- package/dist/errors/UluOpsError.d.ts.map +1 -0
- package/dist/errors/UluOpsError.js +13 -0
- package/dist/errors/UluOpsError.js.map +1 -0
- package/dist/errors/index.d.ts +64 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +93 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/executor/AgentExecutor.d.ts +57 -0
- package/dist/executor/AgentExecutor.d.ts.map +1 -0
- package/dist/executor/AgentExecutor.js +331 -0
- package/dist/executor/AgentExecutor.js.map +1 -0
- package/dist/executor/CommandExecutor.d.ts +33 -0
- package/dist/executor/CommandExecutor.d.ts.map +1 -0
- package/dist/executor/CommandExecutor.js +183 -0
- package/dist/executor/CommandExecutor.js.map +1 -0
- package/dist/executor/PipelineExecutor.d.ts +55 -0
- package/dist/executor/PipelineExecutor.d.ts.map +1 -0
- package/dist/executor/PipelineExecutor.js +273 -0
- package/dist/executor/PipelineExecutor.js.map +1 -0
- package/dist/executor/ToolHandler.d.ts +47 -0
- package/dist/executor/ToolHandler.d.ts.map +1 -0
- package/dist/executor/ToolHandler.js +615 -0
- package/dist/executor/ToolHandler.js.map +1 -0
- package/dist/executor/WorkflowExecutor.d.ts +55 -0
- package/dist/executor/WorkflowExecutor.d.ts.map +1 -0
- package/dist/executor/WorkflowExecutor.js +368 -0
- package/dist/executor/WorkflowExecutor.js.map +1 -0
- package/dist/executor/preflight.d.ts +8 -0
- package/dist/executor/preflight.d.ts.map +1 -0
- package/dist/executor/preflight.js +102 -0
- package/dist/executor/preflight.js.map +1 -0
- package/dist/executor/symbols.d.ts +13 -0
- package/dist/executor/symbols.d.ts.map +1 -0
- package/dist/executor/symbols.js +102 -0
- package/dist/executor/symbols.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/OutputExtractor.d.ts +52 -0
- package/dist/parser/OutputExtractor.d.ts.map +1 -0
- package/dist/parser/OutputExtractor.js +818 -0
- package/dist/parser/OutputExtractor.js.map +1 -0
- package/dist/parser/outputSchemas.d.ts +223 -0
- package/dist/parser/outputSchemas.d.ts.map +1 -0
- package/dist/parser/outputSchemas.js +73 -0
- package/dist/parser/outputSchemas.js.map +1 -0
- package/dist/registry/RegistryClient.d.ts +75 -0
- package/dist/registry/RegistryClient.d.ts.map +1 -0
- package/dist/registry/RegistryClient.js +419 -0
- package/dist/registry/RegistryClient.js.map +1 -0
- package/dist/registry/index.d.ts +2 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +2 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/types/agent.d.ts +406 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +2 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/ai.d.ts +14 -0
- package/dist/types/ai.d.ts.map +1 -0
- package/dist/types/ai.js +2 -0
- package/dist/types/ai.js.map +1 -0
- package/dist/types/command.d.ts +153 -0
- package/dist/types/command.d.ts.map +1 -0
- package/dist/types/command.js +2 -0
- package/dist/types/command.js.map +1 -0
- package/dist/types/config.d.ts +136 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/execution.d.ts +172 -0
- package/dist/types/execution.d.ts.map +1 -0
- package/dist/types/execution.js +2 -0
- package/dist/types/execution.js.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/parser.d.ts +75 -0
- package/dist/types/parser.d.ts.map +1 -0
- package/dist/types/parser.js +2 -0
- package/dist/types/parser.js.map +1 -0
- package/dist/types/pipeline.d.ts +155 -0
- package/dist/types/pipeline.d.ts.map +1 -0
- package/dist/types/pipeline.js +2 -0
- package/dist/types/pipeline.js.map +1 -0
- package/dist/types/registry.d.ts +232 -0
- package/dist/types/registry.d.ts.map +1 -0
- package/dist/types/registry.js +2 -0
- package/dist/types/registry.js.map +1 -0
- package/dist/types/tools.d.ts +29 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +2 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/types/validation.d.ts +237 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +2 -0
- package/dist/types/validation.js.map +1 -0
- package/dist/types/workflow.d.ts +131 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +2 -0
- package/dist/types/workflow.js.map +1 -0
- package/dist/utils/formatError.d.ts +6 -0
- package/dist/utils/formatError.d.ts.map +1 -0
- package/dist/utils/formatError.js +10 -0
- package/dist/utils/formatError.js.map +1 -0
- package/dist/utils/parseRef.d.ts +11 -0
- package/dist/utils/parseRef.d.ts.map +1 -0
- package/dist/utils/parseRef.js +16 -0
- package/dist/utils/parseRef.js.map +1 -0
- package/dist/utils/sumTokenMetrics.d.ts +9 -0
- package/dist/utils/sumTokenMetrics.d.ts.map +1 -0
- package/dist/utils/sumTokenMetrics.js +20 -0
- package/dist/utils/sumTokenMetrics.js.map +1 -0
- package/dist/utils/topoSort.d.ts +24 -0
- package/dist/utils/topoSort.d.ts.map +1 -0
- package/dist/utils/topoSort.js +60 -0
- package/dist/utils/topoSort.js.map +1 -0
- package/dist/validation/ValidationClient.d.ts +51 -0
- package/dist/validation/ValidationClient.d.ts.map +1 -0
- package/dist/validation/ValidationClient.js +179 -0
- package/dist/validation/ValidationClient.js.map +1 -0
- package/dist/validation/index.d.ts +2 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +2 -0
- package/dist/validation/index.js.map +1 -0
- package/package.json +76 -0
package/README.md
ADDED
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
**[UluOps](https://uluops.ai)** · Operating Intelligence as Infrastructure
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# @uluops/core
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@uluops/core)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](https://nodejs.org)
|
|
10
|
+
[](https://www.typescriptlang.org/)
|
|
11
|
+
[](test/)
|
|
12
|
+
|
|
13
|
+
The foundational execution engine for UluOps. Orchestrates AI-powered code analysis through a 4-layer execution hierarchy (Agent > Command > Workflow > Pipeline), manages LLM tool loops via Vercel AI SDK, and integrates with UluOps Registry and Validation services.
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
Requires `ULUOPS_API_KEY` and at least one AI provider key (e.g. `ANTHROPIC_API_KEY`):
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { UluOpsClient } from '@uluops/core';
|
|
21
|
+
|
|
22
|
+
const client = new UluOpsClient({
|
|
23
|
+
apiKey: process.env.ULUOPS_API_KEY,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Run a single agent
|
|
27
|
+
const result = await client.runAgent('code-validator', './src', {
|
|
28
|
+
model: 'sonnet',
|
|
29
|
+
thresholds: { pass: 80 },
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
console.log(`Score: ${result.score} | Decision: ${result.decision}`);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Table of Contents
|
|
36
|
+
|
|
37
|
+
- [Overview](#overview)
|
|
38
|
+
- [Installation](#installation)
|
|
39
|
+
- [Authentication](#authentication)
|
|
40
|
+
- [Usage](#usage)
|
|
41
|
+
- [Agent Execution](#agent-execution)
|
|
42
|
+
- [Command Execution](#command-execution)
|
|
43
|
+
- [Workflow Execution](#workflow-execution)
|
|
44
|
+
- [Pipeline Execution](#pipeline-execution)
|
|
45
|
+
- [Convenience Methods](#convenience-methods)
|
|
46
|
+
- [Discovery](#discovery)
|
|
47
|
+
- [Validation Tracking](#validation-tracking)
|
|
48
|
+
- [Architecture](#architecture)
|
|
49
|
+
- [Execution Hierarchy](#execution-hierarchy)
|
|
50
|
+
- [Configuration](#configuration)
|
|
51
|
+
- [TypeScript Support](#typescript-support)
|
|
52
|
+
- [Error Handling](#error-handling)
|
|
53
|
+
- [Dependencies](#dependencies)
|
|
54
|
+
- [Development](#development)
|
|
55
|
+
|
|
56
|
+
## Overview
|
|
57
|
+
|
|
58
|
+
The `@uluops/core` SDK provides:
|
|
59
|
+
|
|
60
|
+
- **4-Layer Execution Hierarchy** - Agent > Command > Workflow > Pipeline orchestration
|
|
61
|
+
- **AI SDK v6 Integration** - Vercel AI SDK for LLM communication with automatic tool loops (`maxSteps`) and built-in retry
|
|
62
|
+
- **Registry-Backed Model Resolution** - Model aliases resolved via UluOps Registry with provider metadata
|
|
63
|
+
- **Multi-Provider AI** - Anthropic + OpenAI + Google bundled; Mistral, Cohere, and others supported via dynamic `@ai-sdk/*` import
|
|
64
|
+
- **Filesystem Sandboxing** - ToolHandler restricts LLM file access to the target directory
|
|
65
|
+
- **Content-Addressed Integrity** - SHA-256 hash verification on all definitions
|
|
66
|
+
- **Structured Output Extraction** - 3-strategy fallback: JSON code fence > inline JSON > regex text parsing
|
|
67
|
+
- **Validation Tracking** - Automatic result submission with issue correlation, regression detection, and analytics
|
|
68
|
+
- **Local Development Support** - Load definitions from local YAML files with registry fallback
|
|
69
|
+
- **Bundled Starter Agents** - 5 built-in agents for immediate use without registry access
|
|
70
|
+
|
|
71
|
+
## Installation
|
|
72
|
+
|
|
73
|
+
Requires Node.js 18+.
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npm install @uluops/core
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Bundled Starter Agents
|
|
80
|
+
|
|
81
|
+
Get started without registry access using the bundled agent definitions:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { UluOpsClient, STARTER_DEFINITIONS_DIR } from '@uluops/core';
|
|
85
|
+
|
|
86
|
+
const client = new UluOpsClient({
|
|
87
|
+
apiKey: process.env.ULUOPS_API_KEY,
|
|
88
|
+
localDefinitions: STARTER_DEFINITIONS_DIR,
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Includes: `code-validator`, `docs-validator`, `public-interface-validator`, `security-analyst`, `test-architect`.
|
|
93
|
+
|
|
94
|
+
## Authentication
|
|
95
|
+
|
|
96
|
+
### UluOps API Key
|
|
97
|
+
|
|
98
|
+
Required for registry and validation service access:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Environment variable (recommended)
|
|
102
|
+
export ULUOPS_API_KEY=ulr_your_api_key_here
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Or pass directly in config:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const client = new UluOpsClient({ apiKey: 'ulr_your-key' });
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The SDK checks for `ULUOPS_API_KEY` then `ULU_API_KEY` environment variables. Keys use a `ulr_` prefix. Generate one at [app.uluops.ai](https://app.uluops.ai).
|
|
112
|
+
|
|
113
|
+
### AI Provider Keys
|
|
114
|
+
|
|
115
|
+
Set environment variables for the providers you want to use. The SDK auto-detects configured providers:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
export ANTHROPIC_API_KEY=your_anthropic_key
|
|
119
|
+
export OPENAI_API_KEY=your_openai_key # optional
|
|
120
|
+
export GOOGLE_API_KEY=your_google_key # optional (also accepts GOOGLE_GENERATIVE_AI_API_KEY)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Or configure explicitly:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
const client = new UluOpsClient({
|
|
127
|
+
apiKey: process.env.ULUOPS_API_KEY,
|
|
128
|
+
ai: {
|
|
129
|
+
providers: {
|
|
130
|
+
anthropic: { apiKey: process.env.ANTHROPIC_API_KEY },
|
|
131
|
+
openai: { apiKey: process.env.OPENAI_API_KEY },
|
|
132
|
+
google: { apiKey: process.env.GOOGLE_API_KEY },
|
|
133
|
+
},
|
|
134
|
+
defaultProvider: 'anthropic',
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Usage
|
|
140
|
+
|
|
141
|
+
### Agent Execution
|
|
142
|
+
|
|
143
|
+
Direct agent execution with call-time options. Best for interactive/ad-hoc validation:
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
const result = await client.runAgent('code-validator', './src', {
|
|
147
|
+
model: 'sonnet',
|
|
148
|
+
thresholds: { pass: 80, warn: 60 },
|
|
149
|
+
trackResults: true,
|
|
150
|
+
project: 'my-project',
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
console.log(`Score: ${result.score} | Decision: ${result.decision}`);
|
|
154
|
+
console.log(`Recommendations: ${result.recommendations.length}`);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Command Execution
|
|
158
|
+
|
|
159
|
+
Execute saved command configurations. Uses model, thresholds, and aggregation from the command definition. Ideal for CI/CD:
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
const result = await client.runCommand('validate', { target: './src' });
|
|
163
|
+
|
|
164
|
+
console.log(`Score: ${result.score}`);
|
|
165
|
+
console.log(`Categories:`, result.categories);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Workflow Execution
|
|
169
|
+
|
|
170
|
+
DAG-based multi-phase orchestration with quality gates. Independent phases execute in parallel; dependent phases wait for their dependencies:
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
const result = await client.runWorkflow('ship', { target: './src' });
|
|
174
|
+
|
|
175
|
+
console.log(`Overall: ${result.decision} (score: ${result.score})`);
|
|
176
|
+
|
|
177
|
+
for (const phase of result.phases) {
|
|
178
|
+
// decision: 'passed' | 'warned' | 'blocked' | 'skipped' | 'aborted'
|
|
179
|
+
console.log(` ${phase.name}: ${phase.decision} (${phase.score})`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Metrics break down phase outcomes
|
|
183
|
+
const { phasesExecuted, phasesPassed, phasesBlocked, phasesAborted } = result.metrics;
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Workflows define phase dependencies and failure behaviors in their WDL definition:
|
|
187
|
+
|
|
188
|
+
```yaml
|
|
189
|
+
orchestration:
|
|
190
|
+
on_failure: stop # stop | abort | continue | warn
|
|
191
|
+
max_parallel: 3 # optional concurrency limit
|
|
192
|
+
phases:
|
|
193
|
+
- id: lint
|
|
194
|
+
commands: [lint-validator@latest]
|
|
195
|
+
- id: test
|
|
196
|
+
commands: [test-architect@latest]
|
|
197
|
+
- id: security
|
|
198
|
+
commands: [security-analyst@latest]
|
|
199
|
+
depends_on: [lint, test] # DAG dependency — waits for lint + test
|
|
200
|
+
gate:
|
|
201
|
+
threshold: 85
|
|
202
|
+
on_fail: abort
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Auto-Routing
|
|
206
|
+
|
|
207
|
+
Universal execution — auto-detects definition type and routes to the correct executor:
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
// Routes automatically based on whether name resolves to agent, command, workflow, or pipeline
|
|
211
|
+
const result = await client.run('code-validator', { target: './src' });
|
|
212
|
+
console.log(`Decision: ${result.decision}`);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Pipeline Execution
|
|
216
|
+
|
|
217
|
+
Async multi-stage pipelines with dependency resolution:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
// Start async pipeline
|
|
221
|
+
const handle = await client.startPipeline('full-validation', {
|
|
222
|
+
target: './src',
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// Monitor progress
|
|
226
|
+
const status = await handle.status();
|
|
227
|
+
console.log(`Stage ${status.stages.length} of pipeline`);
|
|
228
|
+
|
|
229
|
+
// Wait for completion
|
|
230
|
+
const result = await handle.wait();
|
|
231
|
+
|
|
232
|
+
// Or cancel
|
|
233
|
+
await handle.cancel();
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Convenience Methods
|
|
237
|
+
|
|
238
|
+
Shorthand methods for common workflows:
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
// Run the built-in validate command
|
|
242
|
+
const result = await client.validate('./src');
|
|
243
|
+
|
|
244
|
+
// Security audit
|
|
245
|
+
const secResult = await client.security('./src');
|
|
246
|
+
|
|
247
|
+
// Code optimization analysis
|
|
248
|
+
const optResult = await client.optimize('./src');
|
|
249
|
+
|
|
250
|
+
// Ship workflow (full pre-release validation)
|
|
251
|
+
const shipResult = await client.ship('./src');
|
|
252
|
+
|
|
253
|
+
// Post-implementation validation
|
|
254
|
+
const postResult = await client.postImplementation('./src');
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Discovery
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
// List available definitions
|
|
261
|
+
const definitions = await client.list({ type: 'agent', domain: 'software' });
|
|
262
|
+
|
|
263
|
+
// Inspect a definition
|
|
264
|
+
const info = await client.describe('code-validator');
|
|
265
|
+
console.log(info.name, info.version, info.interface);
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Validation Tracking
|
|
269
|
+
|
|
270
|
+
Submit execution results, preview submissions, and query run history:
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
// Automatic tracking: results are submitted automatically when trackingEnabled is true
|
|
274
|
+
const result = await client.runAgent('code-validator', './src', {
|
|
275
|
+
trackResults: true,
|
|
276
|
+
project: 'my-project',
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// Manual submission: submit results from a custom execution
|
|
280
|
+
const response = await client.submitResults('my-project', 'post-implementation', result);
|
|
281
|
+
console.log(`Run #${response.runNumber}: ${response.dashboardUrl}`);
|
|
282
|
+
console.log(`New issues: ${response.correlation.newIssues}, Regressions: ${response.correlation.regressions}`);
|
|
283
|
+
|
|
284
|
+
// Dry run: preview what a submission would do without saving
|
|
285
|
+
const preview = await client.validateRun('my-project', 'post-implementation', result);
|
|
286
|
+
if (preview.validationErrors.length > 0) {
|
|
287
|
+
console.error('Validation errors:', preview.validationErrors);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Query history: list past runs for a project
|
|
291
|
+
const history = await client.getHistory('my-project');
|
|
292
|
+
for (const entry of history) {
|
|
293
|
+
console.log(`Run #${entry.runNumber} — ${entry.workflowType} — Score: ${entry.averageScore}`);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Run details: fetch full details for a specific run
|
|
297
|
+
const run = await client.getRun('run-uuid');
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Usage Metrics
|
|
301
|
+
|
|
302
|
+
All execution results include token usage metrics. Provider-specific token fields are mapped to a unified format:
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
const result = await client.runAgent('code-validator', './src');
|
|
306
|
+
const { metrics } = result;
|
|
307
|
+
|
|
308
|
+
console.log(`Input: ${metrics.inputTokens}, Output: ${metrics.outputTokens}`);
|
|
309
|
+
console.log(`Cache: ${metrics.cacheCreationTokens ?? 0} created, ${metrics.cacheReadTokens ?? 0} read`);
|
|
310
|
+
|
|
311
|
+
// Google Gemini 2.5+ models report thinking tokens separately from output tokens.
|
|
312
|
+
// thinking_tokens are included in totalEffectiveTokens (unlike OpenAI reasoning_tokens
|
|
313
|
+
// which are already counted within outputTokens).
|
|
314
|
+
if (metrics.thinkingTokens) {
|
|
315
|
+
console.log(`Thinking: ${metrics.thinkingTokens}`);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
console.log(`Effective total: ${metrics.totalEffectiveTokens}`);
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Architecture
|
|
322
|
+
|
|
323
|
+
```
|
|
324
|
+
UluOpsClient (facade)
|
|
325
|
+
|
|
|
326
|
+
+-- AgentExecutor (single-agent LLM execution)
|
|
327
|
+
| +-- AIProvider (AI SDK v6 wrapper, tool loop via maxSteps)
|
|
328
|
+
| +-- ToolHandler (sandboxed filesystem tools)
|
|
329
|
+
| +-- ToolAdapter (converts tools to AI SDK format)
|
|
330
|
+
| +-- OutputExtractor (3-strategy JSON parsing)
|
|
331
|
+
|
|
|
332
|
+
+-- CommandExecutor (single/multi-agent aggregation)
|
|
333
|
+
| +-- AgentExecutor
|
|
334
|
+
| +-- preflight (prerequisite checks)
|
|
335
|
+
|
|
|
336
|
+
+-- WorkflowExecutor (multi-phase orchestration with gates)
|
|
337
|
+
| +-- CommandExecutor
|
|
338
|
+
|
|
|
339
|
+
+-- PipelineExecutor (multi-stage async pipelines)
|
|
340
|
+
| +-- WorkflowExecutor
|
|
341
|
+
| +-- CommandExecutor
|
|
342
|
+
|
|
|
343
|
+
+-- RegistryClient (definition resolution + hash verification)
|
|
344
|
+
+-- ValidationClient (result submission + history)
|
|
345
|
+
+-- ModelCatalog (registry-backed model alias resolution)
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Execution Hierarchy
|
|
349
|
+
|
|
350
|
+
| Level | Definition | Description |
|
|
351
|
+
|-------|-----------|-------------|
|
|
352
|
+
| Agent | ADL | Atomic unit: single LLM with filesystem tools |
|
|
353
|
+
| Command | CDL | Wraps 1+ agents with preflight checks and aggregation |
|
|
354
|
+
| Workflow | WDL | Sequences commands into phases with gates |
|
|
355
|
+
| Pipeline | PDL | Orchestrates workflows/commands across stages |
|
|
356
|
+
|
|
357
|
+
## Configuration
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
const client = new UluOpsClient({
|
|
361
|
+
// Required
|
|
362
|
+
apiKey: 'your-api-key', // or ULUOPS_API_KEY env var
|
|
363
|
+
|
|
364
|
+
// AI Configuration
|
|
365
|
+
ai: {
|
|
366
|
+
providers: { // Provider API keys (env var fallback)
|
|
367
|
+
anthropic: { apiKey: '...' },
|
|
368
|
+
},
|
|
369
|
+
defaultProvider: 'anthropic', // Default AI provider
|
|
370
|
+
modelOverride: 'sonnet', // Override model for all executions
|
|
371
|
+
},
|
|
372
|
+
|
|
373
|
+
// Service URLs
|
|
374
|
+
registryUrl: 'https://...', // Registry API (or ULUOPS_REGISTRY_URL)
|
|
375
|
+
validationUrl: 'https://...', // Validation API (or ULUOPS_VALIDATION_URL)
|
|
376
|
+
|
|
377
|
+
// Behavior
|
|
378
|
+
trackingEnabled: true, // Auto-submit results to validation service
|
|
379
|
+
timeout: 300000, // Request timeout in ms
|
|
380
|
+
defaultProject: 'my-project', // Default project for result submission
|
|
381
|
+
debug: false, // Detailed execution logging (or ULUOPS_DEBUG)
|
|
382
|
+
defaultThinkingBudget: 10000, // Extended thinking budget (Anthropic + Google models)
|
|
383
|
+
contextBudget: 200000, // Context window budget — forces wrap-up at 80%
|
|
384
|
+
dashboardUrl: 'https://app.uluops.ai', // Dashboard link prefix for run URLs
|
|
385
|
+
|
|
386
|
+
// Local Development
|
|
387
|
+
localDefinitions: './definitions', // Load YAML definitions from local dir
|
|
388
|
+
});
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Environment Variables
|
|
392
|
+
|
|
393
|
+
| Variable | Description | Default |
|
|
394
|
+
|----------|-------------|---------|
|
|
395
|
+
| `ULUOPS_API_KEY` | Platform API key | (required) |
|
|
396
|
+
| `ANTHROPIC_API_KEY` | Anthropic provider key | - |
|
|
397
|
+
| `OPENAI_API_KEY` | OpenAI provider key | - |
|
|
398
|
+
| `GOOGLE_API_KEY` | Google/Gemini provider key | - |
|
|
399
|
+
| `GOOGLE_GENERATIVE_AI_API_KEY` | Google provider key (alternative) | - |
|
|
400
|
+
| `ULUOPS_REGISTRY_URL` | Registry API URL | `https://api.uluops.ai/api/v1/registry` |
|
|
401
|
+
| `ULUOPS_VALIDATION_URL` | Validation API URL | `https://api.uluops.ai/api/v1/ops` |
|
|
402
|
+
| `ULUOPS_TRACKING_ENABLED` | Auto-submit results | `true` |
|
|
403
|
+
| `ULUOPS_PROJECT` | Default project name | - |
|
|
404
|
+
| `ULUOPS_LOCAL_DEFINITIONS` | Local definitions path | - |
|
|
405
|
+
| `ULUOPS_DASHBOARD_URL` | Dashboard base URL for run links | `https://app.uluops.ai` |
|
|
406
|
+
| `ULUOPS_DEBUG` | Enable detailed execution logging | `false` |
|
|
407
|
+
|
|
408
|
+
## TypeScript Support
|
|
409
|
+
|
|
410
|
+
Full TypeScript support with exported types for all parameters and results:
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
import {
|
|
414
|
+
UluOpsClient,
|
|
415
|
+
// Executor types
|
|
416
|
+
type AgentResult,
|
|
417
|
+
type CommandResult,
|
|
418
|
+
type WorkflowResult,
|
|
419
|
+
type PipelineResult,
|
|
420
|
+
// Definition types
|
|
421
|
+
type AgentDefinition,
|
|
422
|
+
type CommandDefinition,
|
|
423
|
+
type WorkflowDefinition,
|
|
424
|
+
type PipelineDefinition,
|
|
425
|
+
// Config types
|
|
426
|
+
type UluOpsConfig,
|
|
427
|
+
type ExecutionInput,
|
|
428
|
+
type ExecutionOptions,
|
|
429
|
+
// Usage metrics
|
|
430
|
+
type UsageMetrics,
|
|
431
|
+
// Error classes
|
|
432
|
+
ExecutionError,
|
|
433
|
+
ConfigurationError,
|
|
434
|
+
ModelNotFoundError,
|
|
435
|
+
// Error code narrowing
|
|
436
|
+
ValidationErrorCodes,
|
|
437
|
+
} from '@uluops/core';
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Subpath Exports
|
|
441
|
+
|
|
442
|
+
For tree-shaking or importing just types/errors without pulling in the full client:
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// Import only types (zero runtime cost)
|
|
446
|
+
import type { AgentResult, ExecutionInput } from '@uluops/core/types';
|
|
447
|
+
|
|
448
|
+
// Import only error classes
|
|
449
|
+
import { ExecutionError, ConfigurationError } from '@uluops/core/errors';
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
## Error Handling
|
|
453
|
+
|
|
454
|
+
The SDK provides a structured error hierarchy:
|
|
455
|
+
|
|
456
|
+
### Core SDK Errors
|
|
457
|
+
|
|
458
|
+
| Error | Description |
|
|
459
|
+
|-------|-------------|
|
|
460
|
+
| `UluOpsError` | Base error class for all SDK errors |
|
|
461
|
+
| `ExecutionError` | Agent/command execution failures |
|
|
462
|
+
| `PreflightError` | Preflight check failures |
|
|
463
|
+
| `ConfigurationError` | Invalid configuration |
|
|
464
|
+
| `ModelNotFoundError` | Model alias not found in registry |
|
|
465
|
+
| `CapabilityError` | Model lacks required capabilities |
|
|
466
|
+
| `ValidationError` | Output validation failures. Use `ValidationErrorCodes` to narrow by code. |
|
|
467
|
+
| `WorkflowError` | Workflow phase gate failures |
|
|
468
|
+
| `PipelineError` | Pipeline stage failures |
|
|
469
|
+
| `ParseError` | Output extraction failures |
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
import { ConfigurationError, ModelNotFoundError, ExecutionError } from '@uluops/core';
|
|
473
|
+
|
|
474
|
+
try {
|
|
475
|
+
const result = await client.runAgent('code-validator', './src');
|
|
476
|
+
} catch (error) {
|
|
477
|
+
if (error instanceof ConfigurationError) {
|
|
478
|
+
console.error('Check your config:', error.message);
|
|
479
|
+
} else if (error instanceof ModelNotFoundError) {
|
|
480
|
+
console.error('Unknown model alias:', error.message);
|
|
481
|
+
} else if (error instanceof ExecutionError) {
|
|
482
|
+
console.error('Execution failed:', error.message);
|
|
483
|
+
console.log('Partial result:', error.partialResult);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### Re-exported from @uluops/sdk-core
|
|
489
|
+
|
|
490
|
+
| Error | Description |
|
|
491
|
+
|-------|-------------|
|
|
492
|
+
| `SdkApiError` | Base API error |
|
|
493
|
+
| `RateLimitError` | 429 rate limit exceeded |
|
|
494
|
+
| `UnauthorizedError` | 401 authentication failure |
|
|
495
|
+
| `ForbiddenError` | 403 access denied |
|
|
496
|
+
| `NotFoundError` | 404 resource not found |
|
|
497
|
+
| `ServiceUnavailableError` | 503 service unavailable |
|
|
498
|
+
| `NetworkError` | Connection failures |
|
|
499
|
+
| `TimeoutError` | Request timeout |
|
|
500
|
+
|
|
501
|
+
## Dependencies
|
|
502
|
+
|
|
503
|
+
| Package | Purpose |
|
|
504
|
+
|---------|---------|
|
|
505
|
+
| `@uluops/sdk-core` | Shared HTTP infrastructure (HttpClient, errors, auth) |
|
|
506
|
+
| `@uluops/registry-sdk` | Registry API client for definitions and models |
|
|
507
|
+
| `@uluops/ops-sdk` | Validation tracking API client |
|
|
508
|
+
| `ai` | Vercel AI SDK v6 - LLM communication and tool loops |
|
|
509
|
+
| `@ai-sdk/anthropic` | Anthropic provider for AI SDK |
|
|
510
|
+
| `@ai-sdk/openai` | OpenAI provider for AI SDK |
|
|
511
|
+
| `@ai-sdk/google` | Google/Gemini provider for AI SDK |
|
|
512
|
+
| `yaml` | YAML parsing for local definitions |
|
|
513
|
+
| `glob` | File globbing for ToolHandler |
|
|
514
|
+
| `zod` | Schema validation for AI SDK tools |
|
|
515
|
+
|
|
516
|
+
## Development
|
|
517
|
+
|
|
518
|
+
```bash
|
|
519
|
+
# Install dependencies
|
|
520
|
+
npm install
|
|
521
|
+
|
|
522
|
+
# Type check
|
|
523
|
+
npm run typecheck
|
|
524
|
+
|
|
525
|
+
# Run tests
|
|
526
|
+
npm test
|
|
527
|
+
|
|
528
|
+
# Run tests in watch mode
|
|
529
|
+
npm run test:watch
|
|
530
|
+
|
|
531
|
+
# Run tests with coverage
|
|
532
|
+
npm run test:coverage
|
|
533
|
+
|
|
534
|
+
# Lint
|
|
535
|
+
npm run lint
|
|
536
|
+
|
|
537
|
+
# Build
|
|
538
|
+
npm run build
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
## License
|
|
542
|
+
|
|
543
|
+
MIT
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
agent:
|
|
2
|
+
interface:
|
|
3
|
+
name: code-validator
|
|
4
|
+
version: "0.1.0"
|
|
5
|
+
displayName: "Code Validator (Starter)"
|
|
6
|
+
description: >-
|
|
7
|
+
Lightweight code quality checker for local development. Validates function
|
|
8
|
+
design, style compliance, test existence, and basic security hygiene.
|
|
9
|
+
Upgrade to premium for auto-fail rules, calibration, and deep domain knowledge.
|
|
10
|
+
agentType: validator
|
|
11
|
+
domain: software
|
|
12
|
+
tools: [Read, Grep, Glob]
|
|
13
|
+
|
|
14
|
+
defaults:
|
|
15
|
+
model: haiku
|
|
16
|
+
timeout: 120000
|
|
17
|
+
|
|
18
|
+
mission:
|
|
19
|
+
opener: >-
|
|
20
|
+
You are a code quality checker reviewing an implementation phase for
|
|
21
|
+
basic correctness, style compliance, and test presence. Read the target
|
|
22
|
+
directory and evaluate the codebase against the scoring criteria below.
|
|
23
|
+
outcome_framing: >-
|
|
24
|
+
Provide a PASS or FAIL decision on whether this code meets minimum
|
|
25
|
+
quality standards for merging.
|
|
26
|
+
|
|
27
|
+
scoring:
|
|
28
|
+
maxScore: 100
|
|
29
|
+
categories:
|
|
30
|
+
- id: code_quality
|
|
31
|
+
name: Code Quality
|
|
32
|
+
weight: 30
|
|
33
|
+
description: Function design, naming clarity, and error handling.
|
|
34
|
+
criteria:
|
|
35
|
+
- id: function_design
|
|
36
|
+
name: Function Design
|
|
37
|
+
points: 10
|
|
38
|
+
description: Functions are focused, small, and have clear inputs/outputs.
|
|
39
|
+
- id: naming_clarity
|
|
40
|
+
name: Naming Clarity
|
|
41
|
+
points: 10
|
|
42
|
+
description: Variables, functions, and files use descriptive, consistent names.
|
|
43
|
+
- id: error_handling
|
|
44
|
+
name: Error Handling
|
|
45
|
+
points: 10
|
|
46
|
+
description: Errors are caught, logged, or propagated appropriately.
|
|
47
|
+
|
|
48
|
+
- id: standards_compliance
|
|
49
|
+
name: Standards Compliance
|
|
50
|
+
weight: 25
|
|
51
|
+
description: Style consistency, unused code, and formatting.
|
|
52
|
+
criteria:
|
|
53
|
+
- id: style_consistency
|
|
54
|
+
name: Style Consistency
|
|
55
|
+
points: 10
|
|
56
|
+
description: Code follows a consistent style throughout the project.
|
|
57
|
+
- id: no_unused_code
|
|
58
|
+
name: No Unused Code
|
|
59
|
+
points: 8
|
|
60
|
+
description: No unused imports, variables, or dead code paths.
|
|
61
|
+
- id: formatting
|
|
62
|
+
name: Formatting
|
|
63
|
+
points: 7
|
|
64
|
+
description: Consistent indentation, spacing, and line length.
|
|
65
|
+
|
|
66
|
+
- id: testing
|
|
67
|
+
name: Testing
|
|
68
|
+
weight: 25
|
|
69
|
+
description: Test existence, passing status, and edge case coverage.
|
|
70
|
+
criteria:
|
|
71
|
+
- id: tests_exist
|
|
72
|
+
name: Tests Exist
|
|
73
|
+
points: 10
|
|
74
|
+
description: Modified or new code has corresponding test files.
|
|
75
|
+
- id: tests_pass
|
|
76
|
+
name: Tests Pass
|
|
77
|
+
points: 8
|
|
78
|
+
description: Existing tests are not broken by the changes.
|
|
79
|
+
- id: edge_cases_covered
|
|
80
|
+
name: Edge Cases Covered
|
|
81
|
+
points: 7
|
|
82
|
+
description: Tests cover boundary conditions and error scenarios.
|
|
83
|
+
|
|
84
|
+
- id: best_practices
|
|
85
|
+
name: Best Practices
|
|
86
|
+
weight: 20
|
|
87
|
+
description: Security hygiene, DRY, and separation of concerns.
|
|
88
|
+
criteria:
|
|
89
|
+
- id: no_hardcoded_secrets
|
|
90
|
+
name: No Hardcoded Secrets
|
|
91
|
+
points: 8
|
|
92
|
+
description: No API keys, passwords, or tokens in source code.
|
|
93
|
+
- id: no_duplication
|
|
94
|
+
name: No Duplication
|
|
95
|
+
points: 6
|
|
96
|
+
description: No copy-pasted logic that should be extracted.
|
|
97
|
+
- id: separation_of_concerns
|
|
98
|
+
name: Separation of Concerns
|
|
99
|
+
points: 6
|
|
100
|
+
description: Business logic, I/O, and presentation are separated.
|
|
101
|
+
|
|
102
|
+
decisions:
|
|
103
|
+
vocabulary:
|
|
104
|
+
positive: PASS
|
|
105
|
+
negative: FAIL
|
|
106
|
+
preset: quality_gate
|
|
107
|
+
|
|
108
|
+
process:
|
|
109
|
+
phases:
|
|
110
|
+
- id: discovery
|
|
111
|
+
name: Discovery
|
|
112
|
+
description: Identify source files in the target directory using Glob and Read.
|
|
113
|
+
- id: analysis
|
|
114
|
+
name: Analysis
|
|
115
|
+
description: >-
|
|
116
|
+
For each file, evaluate function design, naming, error handling,
|
|
117
|
+
style consistency, and check for corresponding test files.
|
|
118
|
+
- id: scoring
|
|
119
|
+
name: Scoring
|
|
120
|
+
description: >-
|
|
121
|
+
Score each category based on evidence found. Determine PASS (>=70)
|
|
122
|
+
or FAIL (<70) and list specific issues as recommendations.
|
|
123
|
+
|
|
124
|
+
output:
|
|
125
|
+
format: markdown
|
|
126
|
+
sections:
|
|
127
|
+
- id: header
|
|
128
|
+
template: "# Code Validator (Starter) - {{decision}}"
|
|
129
|
+
- id: score_summary
|
|
130
|
+
template: "**Score: {{score}}/{{maxScore}}**"
|
|
131
|
+
- id: categories
|
|
132
|
+
template: "## Categories\n{{#each categories}}\n- {{name}}: {{score}}/{{maxScore}}\n{{/each}}"
|
|
133
|
+
- id: issues
|
|
134
|
+
template: "## Issues\n{{#each recommendations}}\n- [{{priority}}] {{title}}\n{{/each}}"
|