@covibes/zeroshot 5.2.1 → 5.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/CHANGELOG.md +174 -189
- package/README.md +226 -195
- package/cli/commands/providers.js +149 -0
- package/cli/index.js +3145 -2366
- package/cli/lib/first-run.js +40 -3
- package/cli/message-formatters-normal.js +28 -6
- package/cluster-templates/base-templates/debug-workflow.json +24 -78
- package/cluster-templates/base-templates/full-workflow.json +99 -316
- package/cluster-templates/base-templates/single-worker.json +23 -15
- package/cluster-templates/base-templates/worker-validator.json +105 -36
- package/cluster-templates/conductor-bootstrap.json +9 -7
- package/lib/docker-config.js +14 -1
- package/lib/git-remote-utils.js +165 -0
- package/lib/id-detector.js +10 -7
- package/lib/provider-defaults.js +62 -0
- package/lib/provider-detection.js +59 -0
- package/lib/provider-names.js +57 -0
- package/lib/settings/claude-auth.js +78 -0
- package/lib/settings.js +298 -15
- package/lib/stream-json-parser.js +4 -238
- package/package.json +27 -6
- package/scripts/setup-merge-queue.sh +170 -0
- package/scripts/validate-templates.js +100 -0
- package/src/agent/agent-config.js +140 -63
- package/src/agent/agent-context-builder.js +336 -165
- package/src/agent/agent-hook-executor.js +337 -67
- package/src/agent/agent-lifecycle.js +386 -287
- package/src/agent/agent-stuck-detector.js +7 -7
- package/src/agent/agent-task-executor.js +944 -683
- package/src/agent/output-extraction.js +217 -0
- package/src/agent/output-reformatter.js +175 -0
- package/src/agent/schema-utils.js +146 -0
- package/src/agent-wrapper.js +112 -31
- package/src/agents/git-pusher-template.js +285 -0
- package/src/claude-task-runner.js +145 -44
- package/src/config-router.js +13 -13
- package/src/config-validator.js +1049 -563
- package/src/input-helpers.js +65 -0
- package/src/isolation-manager.js +499 -320
- package/src/issue-providers/README.md +305 -0
- package/src/issue-providers/azure-devops-provider.js +273 -0
- package/src/issue-providers/base-provider.js +232 -0
- package/src/issue-providers/github-provider.js +179 -0
- package/src/issue-providers/gitlab-provider.js +241 -0
- package/src/issue-providers/index.js +196 -0
- package/src/issue-providers/jira-provider.js +239 -0
- package/src/ledger.js +50 -11
- package/src/lib/safe-exec.js +88 -0
- package/src/orchestrator.js +1348 -757
- package/src/preflight.js +306 -149
- package/src/process-metrics.js +98 -56
- package/src/providers/anthropic/cli-builder.js +73 -0
- package/src/providers/anthropic/index.js +204 -0
- package/src/providers/anthropic/models.js +23 -0
- package/src/providers/anthropic/output-parser.js +177 -0
- package/src/providers/base-provider.js +251 -0
- package/src/providers/capabilities.js +60 -0
- package/src/providers/google/cli-builder.js +55 -0
- package/src/providers/google/index.js +116 -0
- package/src/providers/google/models.js +24 -0
- package/src/providers/google/output-parser.js +101 -0
- package/src/providers/index.js +91 -0
- package/src/providers/openai/cli-builder.js +133 -0
- package/src/providers/openai/index.js +136 -0
- package/src/providers/openai/models.js +21 -0
- package/src/providers/openai/output-parser.js +143 -0
- package/src/providers/opencode/cli-builder.js +42 -0
- package/src/providers/opencode/index.js +103 -0
- package/src/providers/opencode/models.js +55 -0
- package/src/providers/opencode/output-parser.js +122 -0
- package/src/schemas/sub-cluster.js +68 -39
- package/src/status-footer.js +94 -48
- package/src/sub-cluster-wrapper.js +92 -36
- package/src/task-runner.js +8 -6
- package/src/template-resolver.js +12 -9
- package/src/tui/data-poller.js +123 -99
- package/src/tui/formatters.js +4 -3
- package/src/tui/keybindings.js +259 -318
- package/src/tui/layout.js +20 -3
- package/src/tui/renderer.js +11 -21
- package/task-lib/attachable-watcher.js +150 -111
- package/task-lib/claude-recovery.js +156 -0
- package/task-lib/commands/episodes.js +105 -0
- package/task-lib/commands/list.js +3 -3
- package/task-lib/commands/logs.js +231 -189
- package/task-lib/commands/resume.js +3 -2
- package/task-lib/commands/run.js +12 -3
- package/task-lib/commands/schedules.js +111 -61
- package/task-lib/config.js +0 -2
- package/task-lib/runner.js +128 -50
- package/task-lib/scheduler.js +3 -3
- package/task-lib/store.js +464 -152
- package/task-lib/tui/formatters.js +94 -45
- package/task-lib/tui/renderer.js +13 -3
- package/task-lib/tui.js +73 -32
- package/task-lib/watcher.js +157 -100
- package/src/agents/git-pusher-agent.json +0 -20
- package/src/github.js +0 -103
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ClaudeTaskRunner - Production implementation of TaskRunner
|
|
3
3
|
*
|
|
4
|
-
* Executes
|
|
4
|
+
* Executes provider tasks by spawning the `zeroshot task run` CLI command,
|
|
5
5
|
* following logs, and assembling results.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
const { spawn
|
|
8
|
+
const { spawn } = require('child_process');
|
|
9
|
+
const { exec, execSync } = require('./lib/safe-exec'); // Enforces timeouts
|
|
9
10
|
const fs = require('fs');
|
|
10
11
|
const TaskRunner = require('./task-runner');
|
|
11
|
-
const {
|
|
12
|
+
const { loadSettings } = require('../lib/settings');
|
|
13
|
+
const { normalizeProviderName } = require('../lib/provider-names');
|
|
14
|
+
const { getProvider } = require('./providers');
|
|
12
15
|
|
|
13
16
|
class ClaudeTaskRunner extends TaskRunner {
|
|
14
17
|
/**
|
|
@@ -36,7 +39,7 @@ class ClaudeTaskRunner extends TaskRunner {
|
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
/**
|
|
39
|
-
* Execute a
|
|
42
|
+
* Execute a task via zeroshot CLI
|
|
40
43
|
*
|
|
41
44
|
* @param {string} context - Full prompt/context
|
|
42
45
|
* @param {{agentId?: string, model?: string, outputFormat?: string, jsonSchema?: any, strictSchema?: boolean, cwd?: string, isolation?: any}} options - Execution options
|
|
@@ -45,7 +48,11 @@ class ClaudeTaskRunner extends TaskRunner {
|
|
|
45
48
|
async run(context, options = {}) {
|
|
46
49
|
const {
|
|
47
50
|
agentId = 'unknown',
|
|
48
|
-
|
|
51
|
+
provider,
|
|
52
|
+
model = null,
|
|
53
|
+
modelLevel = null,
|
|
54
|
+
modelSpec: explicitModelSpec = null,
|
|
55
|
+
reasoningEffort = null,
|
|
49
56
|
outputFormat = 'stream-json',
|
|
50
57
|
jsonSchema = null,
|
|
51
58
|
strictSchema = false, // false = live streaming (default), true = CLI schema enforcement (no streaming)
|
|
@@ -53,23 +60,110 @@ class ClaudeTaskRunner extends TaskRunner {
|
|
|
53
60
|
isolation = null,
|
|
54
61
|
} = options;
|
|
55
62
|
|
|
63
|
+
const settings = loadSettings();
|
|
64
|
+
const providerName = normalizeProviderName(provider || settings.defaultProvider || 'claude');
|
|
65
|
+
const { providerModule, providerSettings, levelOverrides } = this._getProviderContext(
|
|
66
|
+
providerName,
|
|
67
|
+
settings
|
|
68
|
+
);
|
|
69
|
+
const resolvedModelSpec = this._resolveModelSpec({
|
|
70
|
+
explicitModelSpec,
|
|
71
|
+
model,
|
|
72
|
+
reasoningEffort,
|
|
73
|
+
modelLevel,
|
|
74
|
+
providerModule,
|
|
75
|
+
providerSettings,
|
|
76
|
+
levelOverrides,
|
|
77
|
+
});
|
|
78
|
+
|
|
56
79
|
// Isolation mode delegates to separate method
|
|
57
80
|
if (isolation?.enabled) {
|
|
58
|
-
return this._runIsolated(context,
|
|
81
|
+
return this._runIsolated(context, {
|
|
82
|
+
...options,
|
|
83
|
+
provider: providerName,
|
|
84
|
+
modelSpec: resolvedModelSpec,
|
|
85
|
+
});
|
|
59
86
|
}
|
|
60
87
|
|
|
61
88
|
const ctPath = 'zeroshot';
|
|
62
89
|
|
|
63
|
-
|
|
90
|
+
const runOutputFormat = this._resolveOutputFormat({
|
|
91
|
+
outputFormat,
|
|
92
|
+
jsonSchema,
|
|
93
|
+
strictSchema,
|
|
94
|
+
});
|
|
95
|
+
const args = this._buildRunArgs({
|
|
96
|
+
context,
|
|
97
|
+
providerName,
|
|
98
|
+
runOutputFormat,
|
|
99
|
+
resolvedModelSpec,
|
|
100
|
+
jsonSchema,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Spawn and get task ID
|
|
104
|
+
const spawnEnv = this._buildSpawnEnv(providerName, resolvedModelSpec);
|
|
105
|
+
|
|
106
|
+
const taskId = await this._spawnAndGetTaskId(ctPath, args, cwd, spawnEnv, agentId);
|
|
107
|
+
|
|
108
|
+
this._log(`📋 [${agentId}]: Following zeroshot logs for ${taskId}`);
|
|
109
|
+
|
|
110
|
+
// Wait for task registration
|
|
111
|
+
await this._waitForTaskReady(ctPath, taskId);
|
|
112
|
+
|
|
113
|
+
// Follow logs until completion
|
|
114
|
+
return this._followLogs(ctPath, taskId, agentId);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
_getProviderContext(providerName, settings) {
|
|
118
|
+
const providerModule = getProvider(providerName);
|
|
119
|
+
const providerSettings = settings.providerSettings?.[providerName] || {};
|
|
120
|
+
const levelOverrides = providerSettings.levelOverrides || {};
|
|
121
|
+
return { providerModule, providerSettings, levelOverrides };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
_resolveModelSpec({
|
|
125
|
+
explicitModelSpec,
|
|
126
|
+
model,
|
|
127
|
+
reasoningEffort,
|
|
128
|
+
modelLevel,
|
|
129
|
+
providerModule,
|
|
130
|
+
providerSettings,
|
|
131
|
+
levelOverrides,
|
|
132
|
+
}) {
|
|
133
|
+
if (explicitModelSpec) {
|
|
134
|
+
return explicitModelSpec;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (model) {
|
|
138
|
+
return { model, reasoningEffort };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const level = modelLevel || providerSettings.defaultLevel || providerModule.getDefaultLevel();
|
|
142
|
+
let resolvedModelSpec = providerModule.resolveModelSpec(level, levelOverrides);
|
|
143
|
+
if (reasoningEffort) {
|
|
144
|
+
resolvedModelSpec = { ...resolvedModelSpec, reasoningEffort };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return resolvedModelSpec;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
_resolveOutputFormat({ outputFormat, jsonSchema, strictSchema }) {
|
|
64
151
|
// json output does not stream; if a jsonSchema is configured we run stream-json
|
|
65
152
|
// for live logs and validate/parse JSON after completion.
|
|
66
153
|
// Set strictSchema=true to disable live streaming and use CLI's native schema enforcement.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
154
|
+
return jsonSchema && outputFormat === 'json' && !strictSchema ? 'stream-json' : outputFormat;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
_buildRunArgs({ context, providerName, runOutputFormat, resolvedModelSpec, jsonSchema }) {
|
|
158
|
+
const args = ['task', 'run', '--output-format', runOutputFormat, '--provider', providerName];
|
|
159
|
+
|
|
160
|
+
if (resolvedModelSpec?.model) {
|
|
161
|
+
args.push('--model', resolvedModelSpec.model);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (resolvedModelSpec?.reasoningEffort) {
|
|
165
|
+
args.push('--reasoning-effort', resolvedModelSpec.reasoningEffort);
|
|
166
|
+
}
|
|
73
167
|
|
|
74
168
|
// Pass schema to CLI only when using json output (strictSchema=true or no conflict)
|
|
75
169
|
if (jsonSchema && runOutputFormat === 'json') {
|
|
@@ -78,35 +172,34 @@ class ClaudeTaskRunner extends TaskRunner {
|
|
|
78
172
|
|
|
79
173
|
args.push(context);
|
|
80
174
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
this._log(`📋 [${agentId}]: Following zeroshot logs for ${taskId}`);
|
|
175
|
+
return args;
|
|
176
|
+
}
|
|
85
177
|
|
|
86
|
-
|
|
87
|
-
|
|
178
|
+
_buildSpawnEnv(providerName, resolvedModelSpec) {
|
|
179
|
+
const spawnEnv = {
|
|
180
|
+
...process.env,
|
|
181
|
+
};
|
|
182
|
+
if (providerName === 'claude' && resolvedModelSpec?.model) {
|
|
183
|
+
spawnEnv.ANTHROPIC_MODEL = resolvedModelSpec.model;
|
|
184
|
+
}
|
|
88
185
|
|
|
89
|
-
|
|
90
|
-
return this._followLogs(ctPath, taskId, agentId);
|
|
186
|
+
return spawnEnv;
|
|
91
187
|
}
|
|
92
188
|
|
|
93
189
|
/**
|
|
94
190
|
* @param {string} ctPath
|
|
95
191
|
* @param {string[]} args
|
|
96
192
|
* @param {string} cwd
|
|
97
|
-
* @param {
|
|
193
|
+
* @param {Object} spawnEnv
|
|
98
194
|
* @param {string} _agentId
|
|
99
195
|
* @returns {Promise<string>}
|
|
100
196
|
*/
|
|
101
|
-
_spawnAndGetTaskId(ctPath, args, cwd,
|
|
197
|
+
_spawnAndGetTaskId(ctPath, args, cwd, spawnEnv, _agentId) {
|
|
102
198
|
return new Promise((resolve, reject) => {
|
|
103
199
|
const proc = spawn(ctPath, args, {
|
|
104
200
|
cwd,
|
|
105
201
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
106
|
-
env:
|
|
107
|
-
...process.env,
|
|
108
|
-
ANTHROPIC_MODEL: model,
|
|
109
|
-
},
|
|
202
|
+
env: spawnEnv,
|
|
110
203
|
});
|
|
111
204
|
|
|
112
205
|
let stdout = '';
|
|
@@ -367,7 +460,8 @@ class ClaudeTaskRunner extends TaskRunner {
|
|
|
367
460
|
_runIsolated(context, options) {
|
|
368
461
|
const {
|
|
369
462
|
agentId = 'unknown',
|
|
370
|
-
|
|
463
|
+
provider = 'claude',
|
|
464
|
+
modelSpec = null,
|
|
371
465
|
outputFormat = 'stream-json',
|
|
372
466
|
jsonSchema = null,
|
|
373
467
|
strictSchema = false,
|
|
@@ -377,47 +471,54 @@ class ClaudeTaskRunner extends TaskRunner {
|
|
|
377
471
|
|
|
378
472
|
this._log(`📦 [${agentId}]: Running task in isolated container...`);
|
|
379
473
|
|
|
380
|
-
// Determine output format: stream-json for live logs unless strictSchema=true
|
|
381
474
|
const desiredOutputFormat = outputFormat;
|
|
382
475
|
const runOutputFormat =
|
|
383
476
|
jsonSchema && desiredOutputFormat === 'json' && !strictSchema
|
|
384
477
|
? 'stream-json'
|
|
385
478
|
: desiredOutputFormat;
|
|
386
479
|
|
|
387
|
-
// Get configured Claude command (supports custom commands like 'ccr code')
|
|
388
|
-
const { command: claudeCmd, args: claudeExtraArgs } = getClaudeCommand();
|
|
389
|
-
|
|
390
480
|
const command = [
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
'
|
|
394
|
-
'--dangerously-skip-permissions',
|
|
481
|
+
'zeroshot',
|
|
482
|
+
'task',
|
|
483
|
+
'run',
|
|
395
484
|
'--output-format',
|
|
396
485
|
runOutputFormat,
|
|
486
|
+
'--provider',
|
|
487
|
+
provider,
|
|
397
488
|
];
|
|
398
489
|
|
|
399
|
-
if (
|
|
400
|
-
command.push('--
|
|
401
|
-
|
|
490
|
+
if (modelSpec?.model) {
|
|
491
|
+
command.push('--model', modelSpec.model);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (modelSpec?.reasoningEffort) {
|
|
495
|
+
command.push('--reasoning-effort', modelSpec.reasoningEffort);
|
|
402
496
|
}
|
|
403
497
|
|
|
404
|
-
// Pass schema to CLI only when using json output (strictSchema=true or no conflict)
|
|
405
498
|
if (jsonSchema && runOutputFormat === 'json') {
|
|
406
499
|
command.push('--json-schema', JSON.stringify(jsonSchema));
|
|
407
500
|
}
|
|
408
501
|
|
|
409
|
-
|
|
410
|
-
|
|
502
|
+
let finalContext = context;
|
|
503
|
+
if (jsonSchema && desiredOutputFormat === 'json' && runOutputFormat === 'stream-json') {
|
|
504
|
+
finalContext += `\n\n## Output Format (REQUIRED)\n\nReturn a JSON object that matches this schema exactly.\n\nSchema:\n\`\`\`json\n${JSON.stringify(
|
|
505
|
+
jsonSchema,
|
|
506
|
+
null,
|
|
507
|
+
2
|
|
508
|
+
)}\n\`\`\`\n`;
|
|
411
509
|
}
|
|
412
510
|
|
|
413
|
-
command.push(
|
|
511
|
+
command.push(finalContext);
|
|
414
512
|
|
|
415
513
|
return new Promise((resolve, reject) => {
|
|
416
514
|
let output = '';
|
|
417
515
|
let resolved = false;
|
|
418
516
|
|
|
419
517
|
const proc = manager.spawnInContainer(clusterId, command, {
|
|
420
|
-
env:
|
|
518
|
+
env:
|
|
519
|
+
provider === 'claude' && modelSpec?.model
|
|
520
|
+
? { ANTHROPIC_MODEL: modelSpec.model, ZEROSHOT_BLOCK_ASK_USER: '1' }
|
|
521
|
+
: {},
|
|
421
522
|
});
|
|
422
523
|
|
|
423
524
|
proc.stdout.on('data', (/** @type {Buffer} */ data) => {
|
package/src/config-router.js
CHANGED
|
@@ -27,10 +27,10 @@ function getConfig(complexity, taskType) {
|
|
|
27
27
|
return 'full-workflow';
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
const
|
|
31
|
-
if (complexity === 'CRITICAL' && role === 'planner') return '
|
|
32
|
-
if (complexity === 'TRIVIAL') return '
|
|
33
|
-
return '
|
|
30
|
+
const getLevel = (role) => {
|
|
31
|
+
if (complexity === 'CRITICAL' && role === 'planner') return 'level3';
|
|
32
|
+
if (complexity === 'TRIVIAL') return 'level1';
|
|
33
|
+
return 'level2';
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
const getValidatorCount = () => {
|
|
@@ -59,18 +59,18 @@ function getConfig(complexity, taskType) {
|
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
if (base === 'single-worker') {
|
|
62
|
-
params.
|
|
62
|
+
params.worker_level = getLevel('worker');
|
|
63
63
|
} else if (base === 'worker-validator') {
|
|
64
|
-
params.
|
|
65
|
-
params.
|
|
64
|
+
params.worker_level = getLevel('worker');
|
|
65
|
+
params.validator_level = getLevel('validator');
|
|
66
66
|
} else if (base === 'debug-workflow') {
|
|
67
|
-
params.
|
|
68
|
-
params.
|
|
69
|
-
params.
|
|
67
|
+
params.investigator_level = getLevel('planner');
|
|
68
|
+
params.fixer_level = getLevel('worker');
|
|
69
|
+
params.tester_level = getLevel('validator');
|
|
70
70
|
} else if (base === 'full-workflow') {
|
|
71
|
-
params.
|
|
72
|
-
params.
|
|
73
|
-
params.
|
|
71
|
+
params.planner_level = getLevel('planner');
|
|
72
|
+
params.worker_level = getLevel('worker');
|
|
73
|
+
params.validator_level = getLevel('validator');
|
|
74
74
|
params.validator_count = getValidatorCount();
|
|
75
75
|
}
|
|
76
76
|
|