opencastle 0.32.6 → 0.32.7
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/dist/cli/convoy/engine.d.ts.map +1 -1
- package/dist/cli/convoy/engine.js +79 -4
- package/dist/cli/convoy/engine.js.map +1 -1
- package/dist/cli/convoy/engine.test.js +11 -9
- package/dist/cli/convoy/engine.test.js.map +1 -1
- package/dist/dashboard/scripts/etl.js +17 -2
- package/dist/dashboard/scripts/etl.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/convoy/engine.test.ts +11 -9
- package/src/cli/convoy/engine.ts +78 -4
- package/src/dashboard/dist/_astro/index.6xXNs4L2.css +1 -0
- package/src/dashboard/dist/data/convoy-list.json +27 -13
- package/src/dashboard/dist/data/convoys/demo-api-v2.json +16 -10
- package/src/dashboard/dist/data/convoys/demo-auth-revamp.json +25 -15
- package/src/dashboard/dist/data/convoys/demo-dashboard-ui.json +35 -21
- package/src/dashboard/dist/data/convoys/demo-data-pipeline.json +17 -11
- package/src/dashboard/dist/data/convoys/demo-deploy-ci.json +8 -4
- package/src/dashboard/dist/data/convoys/demo-docs-update.json +13 -9
- package/src/dashboard/dist/data/convoys/demo-perf-opt.json +22 -14
- package/src/dashboard/dist/data/overall-stats.json +36 -2
- package/src/dashboard/dist/index.html +149 -93
- package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
- package/src/dashboard/public/data/convoy-list.json +27 -13
- package/src/dashboard/public/data/convoys/demo-api-v2.json +16 -10
- package/src/dashboard/public/data/convoys/demo-auth-revamp.json +25 -15
- package/src/dashboard/public/data/convoys/demo-dashboard-ui.json +35 -21
- package/src/dashboard/public/data/convoys/demo-data-pipeline.json +17 -11
- package/src/dashboard/public/data/convoys/demo-deploy-ci.json +8 -4
- package/src/dashboard/public/data/convoys/demo-docs-update.json +13 -9
- package/src/dashboard/public/data/convoys/demo-perf-opt.json +22 -14
- package/src/dashboard/public/data/overall-stats.json +36 -2
- package/src/dashboard/scripts/etl.ts +15 -3
- package/src/dashboard/scripts/generate-demo-db.ts +42 -34
- package/src/dashboard/src/pages/index.astro +159 -112
- package/src/dashboard/src/styles/dashboard.css +58 -3
- package/src/dashboard/dist/_astro/index.wyN9vmjZ.css +0 -1
- package/src/dashboard/dist/data/convoys/demo-convoy-1.json +0 -111
- package/src/dashboard/dist/data/convoys/demo-convoy-2.json +0 -72
- package/src/dashboard/dist/data/pipelines.ndjson +0 -5285
- package/src/dashboard/public/data/convoys/demo-convoy-1.json +0 -111
- package/src/dashboard/public/data/convoys/demo-convoy-2.json +0 -72
- package/src/dashboard/public/data/pipelines.ndjson +0 -5285
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/cli/convoy/engine.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAQ,QAAQ,EAAE,YAAY,EAAiB,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAChG,OAAO,EAA+C,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAG1F,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAC3E,OAAO,EAAwC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AAElF,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAoB,WAAW,EAAE,oBAAoB,EAAwD,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/cli/convoy/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,6 +29,28 @@ import { getArtifactDir, extractArtifactRefs } from './artifacts.js';
|
|
|
29
29
|
import { shouldCompact, parseCompactionSummary, saveCompaction, canCompact, getMaxCompactions, generateCompactionPrompt, buildContinuationPrompt } from './compaction.js';
|
|
30
30
|
import { calculateCost } from './pricing.js';
|
|
31
31
|
const execFile = promisify(execFileCb);
|
|
32
|
+
/** Map agent names to their default model. Used when adapters don't report model. */
|
|
33
|
+
const AGENT_MODEL_MAP = {
|
|
34
|
+
'developer': 'claude-sonnet-4-6',
|
|
35
|
+
'ui-ux-expert': 'claude-sonnet-4-6',
|
|
36
|
+
'testing-expert': 'claude-sonnet-4-6',
|
|
37
|
+
'security-expert': 'claude-sonnet-4-6',
|
|
38
|
+
'performance-expert': 'claude-sonnet-4-6',
|
|
39
|
+
'devops-expert': 'claude-sonnet-4-6',
|
|
40
|
+
'data-expert': 'claude-sonnet-4-6',
|
|
41
|
+
'api-designer': 'claude-sonnet-4-6',
|
|
42
|
+
'copywriter': 'claude-sonnet-4-6',
|
|
43
|
+
'content-engineer': 'claude-sonnet-4-6',
|
|
44
|
+
'database-engineer': 'claude-sonnet-4-6',
|
|
45
|
+
'researcher': 'claude-sonnet-4-6',
|
|
46
|
+
'release-manager': 'claude-sonnet-4-6',
|
|
47
|
+
'architect': 'claude-opus-4-6',
|
|
48
|
+
'team-lead': 'claude-opus-4-6',
|
|
49
|
+
'reviewer': 'claude-haiku-3-5',
|
|
50
|
+
'documentation-writer': 'claude-haiku-3-5',
|
|
51
|
+
'seo-specialist': 'claude-haiku-3-5',
|
|
52
|
+
'session-guard': 'claude-haiku-3-5',
|
|
53
|
+
};
|
|
32
54
|
export class CircuitBreakerManager {
|
|
33
55
|
states = new Map();
|
|
34
56
|
threshold;
|
|
@@ -976,7 +998,7 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
976
998
|
}
|
|
977
999
|
}
|
|
978
1000
|
process.stdout.write(` ${c.cyan('▶')} ${c.bold(`[${taskRecord.id}]`)} ${taskRecord.agent}${worktreePath ? c.dim(' (worktree)') : ''}\n`);
|
|
979
|
-
events.emit('task_started', { worker_id: workerId }, { convoy_id: convoyId, task_id: taskRecord.id, worker_id: workerId });
|
|
1001
|
+
events.emit('task_started', { worker_id: workerId, mechanism: worktreePath ? 'background' : 'sub-agent' }, { convoy_id: convoyId, task_id: taskRecord.id, worker_id: workerId });
|
|
980
1002
|
const taskStartTime = Date.now();
|
|
981
1003
|
// ── Outbound prompt scan — NEVER send a prompt containing secrets ─────────
|
|
982
1004
|
const promptScan = scanForSecrets(taskRecord.prompt, `task:${taskRecord.id}`);
|
|
@@ -1167,10 +1189,20 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
1167
1189
|
process.stdout.write(` ${c.yellow('⟳')} ${c.bold(`[${taskRecord.id}]`)} timed out, retry ${freshRecord.retries + 1}/${freshRecord.max_retries}\n`);
|
|
1168
1190
|
}
|
|
1169
1191
|
else {
|
|
1192
|
+
// Estimate tokens even for timed-out tasks — you still paid for them
|
|
1193
|
+
const estimatedPrompt = Math.ceil(taskRecord.prompt.length / 4);
|
|
1194
|
+
const estimatedCompletion = Math.ceil((result.output?.length ?? 0) / 4);
|
|
1195
|
+
const timeoutModel = taskRecord.model ?? AGENT_MODEL_MAP[taskRecord.agent.toLowerCase()] ?? taskAdapter.name;
|
|
1196
|
+
const timeoutCost = calculateCost(timeoutModel, estimatedPrompt, estimatedCompletion);
|
|
1170
1197
|
store.withTransaction(() => {
|
|
1171
1198
|
store.updateTaskStatus(taskRecord.id, convoyId, 'timed-out', {
|
|
1172
1199
|
finished_at: finishedAt,
|
|
1173
1200
|
output: result.output,
|
|
1201
|
+
prompt_tokens: estimatedPrompt,
|
|
1202
|
+
completion_tokens: estimatedCompletion,
|
|
1203
|
+
total_tokens: estimatedPrompt + estimatedCompletion,
|
|
1204
|
+
model: timeoutModel,
|
|
1205
|
+
cost_usd: timeoutCost,
|
|
1174
1206
|
});
|
|
1175
1207
|
store.updateWorkerStatus(workerId, 'failed', { finished_at: finishedAt });
|
|
1176
1208
|
});
|
|
@@ -1977,8 +2009,16 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
1977
2009
|
if (result.usage.total_tokens != null)
|
|
1978
2010
|
usageExtra.total_tokens = result.usage.total_tokens;
|
|
1979
2011
|
}
|
|
1980
|
-
else
|
|
1981
|
-
|
|
2012
|
+
else {
|
|
2013
|
+
// Estimate tokens from prompt/output text length (~4 chars per token)
|
|
2014
|
+
const estimatedPrompt = Math.ceil(taskRecord.prompt.length / 4);
|
|
2015
|
+
const estimatedCompletion = Math.ceil((result.output?.length ?? 0) / 4);
|
|
2016
|
+
usageExtra.prompt_tokens = estimatedPrompt;
|
|
2017
|
+
usageExtra.completion_tokens = estimatedCompletion;
|
|
2018
|
+
usageExtra.total_tokens = estimatedPrompt + estimatedCompletion;
|
|
2019
|
+
if (verbose) {
|
|
2020
|
+
process.stdout.write(` ${c.dim('ℹ')} Estimated ${usageExtra.total_tokens} tokens (adapter ${taskAdapter.name} returned no usage data)\n`);
|
|
2021
|
+
}
|
|
1982
2022
|
}
|
|
1983
2023
|
// ── Context compaction check (Phase 44) ─────────────────────────────
|
|
1984
2024
|
const compactionConfig = spec.defaults?.compaction;
|
|
@@ -2091,6 +2131,31 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
2091
2131
|
catch (err) {
|
|
2092
2132
|
process.stderr.write(`[artifacts] Warning: extraction failed for task ${taskRecord.id}: ${err.message}\n`);
|
|
2093
2133
|
}
|
|
2134
|
+
// ── Create file artifacts from task file list ────────────────────────
|
|
2135
|
+
if (taskRecord.files && !taskRecord.outputs) {
|
|
2136
|
+
try {
|
|
2137
|
+
const fileList = JSON.parse(taskRecord.files);
|
|
2138
|
+
for (const filePath of fileList.slice(0, 20)) {
|
|
2139
|
+
try {
|
|
2140
|
+
store.insertArtifact({
|
|
2141
|
+
id: `artifact-${taskRecord.id}-file-${filePath.replace(/[^a-z0-9]/gi, '-')}-${Date.now()}`,
|
|
2142
|
+
convoy_id: convoyId,
|
|
2143
|
+
task_id: taskRecord.id,
|
|
2144
|
+
name: filePath,
|
|
2145
|
+
type: 'file',
|
|
2146
|
+
content: '',
|
|
2147
|
+
created_at: new Date().toISOString(),
|
|
2148
|
+
});
|
|
2149
|
+
}
|
|
2150
|
+
catch (err) {
|
|
2151
|
+
if (err instanceof ConvoyArtifactLimitError)
|
|
2152
|
+
break;
|
|
2153
|
+
// Other errors are non-critical
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
catch { /* files not parseable */ }
|
|
2158
|
+
}
|
|
2094
2159
|
// ── Output contract validation ────────────────────────────────────────
|
|
2095
2160
|
const contractResult = validateOutput(taskRecord.agent, result.output);
|
|
2096
2161
|
if (!contractResult.valid) {
|
|
@@ -2153,7 +2218,7 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
2153
2218
|
}
|
|
2154
2219
|
catch { /* non-critical */ }
|
|
2155
2220
|
}
|
|
2156
|
-
const taskModel = taskRecord.model ?? taskAdapter.name;
|
|
2221
|
+
const taskModel = taskRecord.model ?? AGENT_MODEL_MAP[taskRecord.agent.toLowerCase()] ?? taskAdapter.name;
|
|
2157
2222
|
const taskCost = calculateCost(taskModel, usageExtra.prompt_tokens, usageExtra.completion_tokens);
|
|
2158
2223
|
store.withTransaction(() => {
|
|
2159
2224
|
store.updateTaskStatus(taskRecord.id, convoyId, 'done', {
|
|
@@ -2236,11 +2301,21 @@ async function runConvoy(convoyId, spec, adapter, store, events, wtManager, merg
|
|
|
2236
2301
|
process.stdout.write(` ${c.yellow('⟳')} ${c.bold(`[${taskRecord.id}]`)} retry ${freshRecord.retries + 1}/${freshRecord.max_retries}\n`);
|
|
2237
2302
|
}
|
|
2238
2303
|
else {
|
|
2304
|
+
// Estimate tokens even for failed tasks — you still paid for them
|
|
2305
|
+
const estimatedPrompt = Math.ceil(taskRecord.prompt.length / 4);
|
|
2306
|
+
const estimatedCompletion = Math.ceil((result.output?.length ?? 0) / 4);
|
|
2307
|
+
const failModel = taskRecord.model ?? AGENT_MODEL_MAP[taskRecord.agent.toLowerCase()] ?? taskAdapter.name;
|
|
2308
|
+
const failCost = calculateCost(failModel, estimatedPrompt, estimatedCompletion);
|
|
2239
2309
|
store.withTransaction(() => {
|
|
2240
2310
|
store.updateTaskStatus(taskRecord.id, convoyId, 'failed', {
|
|
2241
2311
|
finished_at: finishedAt,
|
|
2242
2312
|
output: result.output,
|
|
2243
2313
|
exit_code: result.exitCode,
|
|
2314
|
+
prompt_tokens: estimatedPrompt,
|
|
2315
|
+
completion_tokens: estimatedCompletion,
|
|
2316
|
+
total_tokens: estimatedPrompt + estimatedCompletion,
|
|
2317
|
+
model: failModel,
|
|
2318
|
+
cost_usd: failCost,
|
|
2244
2319
|
});
|
|
2245
2320
|
store.updateWorkerStatus(workerId, 'failed', { finished_at: finishedAt });
|
|
2246
2321
|
});
|