@oisincoveney/pipeline 1.27.3 → 1.27.5
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/config.js +21 -21
- package/dist/model-resolver.js +22 -4
- package/dist/runner.js +19 -1
- package/docs/config-architecture.md +1 -1
- package/package.json +1 -1
package/dist/config.js
CHANGED
|
@@ -70,7 +70,7 @@ const PACKAGE_DEFAULT_RUNNERS_YAML = `version: 1
|
|
|
70
70
|
runners:
|
|
71
71
|
opencode:
|
|
72
72
|
type: opencode
|
|
73
|
-
model:
|
|
73
|
+
model: opencode/deepseek-v4-flash-free
|
|
74
74
|
capabilities:
|
|
75
75
|
native_subagents: true
|
|
76
76
|
rules: true
|
|
@@ -344,54 +344,54 @@ scheduler:
|
|
|
344
344
|
backlog-intake:
|
|
345
345
|
category: intake
|
|
346
346
|
profile: moka-researcher
|
|
347
|
-
models: [
|
|
347
|
+
models: [opencode/deepseek-v4-flash-free, openai/gpt-5.5-fast]
|
|
348
348
|
red-tests:
|
|
349
349
|
category: red
|
|
350
350
|
profile: moka-test-writer
|
|
351
|
-
models: [
|
|
351
|
+
models: [opencode/deepseek-v4-flash-free, openai/gpt-5.5, kimi-for-coding/kimi-k2-thinking]
|
|
352
352
|
green-implementation:
|
|
353
353
|
category: green
|
|
354
354
|
profile: moka-code-writer
|
|
355
|
-
models: [opencode
|
|
355
|
+
models: [opencode/deepseek-v4-flash-free, kimi-for-coding/k2p6, opencode-go/qwen3.7-max, opencode-go/deepseek-v4-pro]
|
|
356
356
|
verification:
|
|
357
357
|
category: verification
|
|
358
358
|
profile: moka-verifier
|
|
359
|
-
models: [
|
|
359
|
+
models: [opencode/deepseek-v4-flash-free, openai/gpt-5.5]
|
|
360
360
|
execute:
|
|
361
361
|
required_categories: [intake, research, red, green, mechanical, acceptance, verification, learn]
|
|
362
362
|
nodes:
|
|
363
363
|
backlog-intake:
|
|
364
364
|
category: intake
|
|
365
365
|
profile: moka-researcher
|
|
366
|
-
models: [
|
|
366
|
+
models: [opencode/deepseek-v4-flash-free, openai/gpt-5.5-fast]
|
|
367
367
|
research:
|
|
368
368
|
category: research
|
|
369
369
|
profile: moka-researcher
|
|
370
|
-
models: [openai/gpt-5.5-fast,
|
|
370
|
+
models: [opencode/deepseek-v4-flash-free, openai/gpt-5.5-fast, kimi-for-coding/k2p6]
|
|
371
371
|
red-tests:
|
|
372
372
|
category: red
|
|
373
373
|
profile: moka-test-writer
|
|
374
|
-
models: [
|
|
374
|
+
models: [opencode/deepseek-v4-flash-free, openai/gpt-5.5, kimi-for-coding/kimi-k2-thinking]
|
|
375
375
|
green-backend:
|
|
376
376
|
category: green
|
|
377
377
|
profile: moka-code-writer
|
|
378
|
-
models: [opencode
|
|
378
|
+
models: [opencode/deepseek-v4-flash-free, kimi-for-coding/k2p6, opencode-go/qwen3.7-max, opencode-go/deepseek-v4-pro]
|
|
379
379
|
green-frontend:
|
|
380
380
|
category: green
|
|
381
381
|
profile: moka-code-writer
|
|
382
|
-
models: [opencode
|
|
382
|
+
models: [opencode/deepseek-v4-flash-free, kimi-for-coding/k2p6, opencode-go/qwen3.7-max, opencode-go/deepseek-v4-pro]
|
|
383
383
|
acceptance-review:
|
|
384
384
|
category: acceptance
|
|
385
385
|
profile: moka-acceptance-reviewer
|
|
386
|
-
models: [
|
|
386
|
+
models: [opencode/deepseek-v4-flash-free, openai/gpt-5.5]
|
|
387
387
|
verification:
|
|
388
388
|
category: verification
|
|
389
389
|
profile: moka-verifier
|
|
390
|
-
models: [
|
|
390
|
+
models: [opencode/deepseek-v4-flash-free, openai/gpt-5.5]
|
|
391
391
|
learn:
|
|
392
392
|
category: learn
|
|
393
393
|
profile: moka-learner
|
|
394
|
-
models: [
|
|
394
|
+
models: [opencode/deepseek-v4-flash-free, openai/gpt-5.5-fast]
|
|
395
395
|
schedules:
|
|
396
396
|
quick-schedule:
|
|
397
397
|
baseline: quick
|
|
@@ -1065,18 +1065,12 @@ function parseYamlAs(source, sourcePath, schema) {
|
|
|
1065
1065
|
path: sourcePath
|
|
1066
1066
|
})));
|
|
1067
1067
|
const parsed = schema.safeParse(document.toJS());
|
|
1068
|
-
if (!parsed.success) throw validationError(parsed.error
|
|
1069
|
-
path: issue.path.join("."),
|
|
1070
|
-
message: issue.message
|
|
1071
|
-
})));
|
|
1068
|
+
if (!parsed.success) throw validationError(configIssuesFromZodError(parsed.error));
|
|
1072
1069
|
return parsed.data;
|
|
1073
1070
|
}
|
|
1074
1071
|
function validatePipelineConfig(rawConfig, projectRoot, options = {}) {
|
|
1075
1072
|
const parsed = configSchema.safeParse(rawConfig);
|
|
1076
|
-
if (!parsed.success) throw validationError(parsed.error
|
|
1077
|
-
path: issue.path.join("."),
|
|
1078
|
-
message: issue.message
|
|
1079
|
-
})));
|
|
1073
|
+
if (!parsed.success) throw validationError(configIssuesFromZodError(parsed.error));
|
|
1080
1074
|
const config = parsed.data;
|
|
1081
1075
|
const issues = [];
|
|
1082
1076
|
validateRegistryIds("runners", config.runners, issues);
|
|
@@ -1287,5 +1281,11 @@ function isLintableMissingFileReferencePath(path) {
|
|
|
1287
1281
|
function validationError(issues) {
|
|
1288
1282
|
return new PipelineConfigError("PIPELINE_CONFIG_VALIDATION_ERROR", ["Invalid pipeline config:", ...issues.map((issue) => issue.path ? `- ${issue.path}: ${issue.message}` : `- ${issue.message}`)].join("\n"), issues);
|
|
1289
1283
|
}
|
|
1284
|
+
function configIssuesFromZodError(error) {
|
|
1285
|
+
return error.issues.map((issue) => ({
|
|
1286
|
+
path: issue.path.join("."),
|
|
1287
|
+
message: issue.message
|
|
1288
|
+
}));
|
|
1289
|
+
}
|
|
1290
1290
|
//#endregion
|
|
1291
1291
|
export { DEFAULT_OPENCODE_ECOSYSTEM_MANIFEST, OPENCODE_ECOSYSTEM_MANIFEST_PATH, PIPELINE_CONFIG_PATH, PROFILES_CONFIG_PATH, PipelineConfigError, RUNNERS_CONFIG_PATH, loadPackagePipelineConfig, loadPipelineConfig, parseOpenCodeEcosystemManifest, parsePipelineConfigParts, parsePipelineConfigYaml, validatePipelineConfig, workflowSchema };
|
package/dist/model-resolver.js
CHANGED
|
@@ -1,20 +1,38 @@
|
|
|
1
1
|
//#region src/model-resolver.ts
|
|
2
2
|
const DISABLED_MODELS_ENV = "PIPELINE_DISABLED_MODELS";
|
|
3
|
+
const MODEL_OVERRIDE_ENV = "PIPELINE_OPENCODE_MODEL";
|
|
3
4
|
function selectNodeModel(node) {
|
|
4
5
|
const models = node.models ?? [];
|
|
6
|
+
return forcedModelSelection(models) ?? fallbackModelSelection(models);
|
|
7
|
+
}
|
|
8
|
+
function forcedModelSelection(models) {
|
|
9
|
+
const override = process.env[MODEL_OVERRIDE_ENV]?.trim();
|
|
10
|
+
if (!override) return;
|
|
11
|
+
return {
|
|
12
|
+
model: override,
|
|
13
|
+
reason: `forced by ${MODEL_OVERRIDE_ENV}`,
|
|
14
|
+
skipped: models
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function fallbackModelSelection(models) {
|
|
5
18
|
if (models.length === 0) return {
|
|
6
19
|
reason: "node declares no model fallback array",
|
|
7
20
|
skipped: []
|
|
8
21
|
};
|
|
9
|
-
|
|
10
|
-
|
|
22
|
+
return enabledModelSelection(models, disabledModels());
|
|
23
|
+
}
|
|
24
|
+
function enabledModelSelection(models, disabled) {
|
|
11
25
|
const model = models.find((candidate) => !disabled.has(candidate));
|
|
12
26
|
return {
|
|
13
27
|
model,
|
|
14
|
-
reason: model
|
|
15
|
-
skipped
|
|
28
|
+
reason: selectionReason(model),
|
|
29
|
+
skipped: models.filter((candidate) => disabled.has(candidate))
|
|
16
30
|
};
|
|
17
31
|
}
|
|
32
|
+
function selectionReason(model) {
|
|
33
|
+
if (model) return "selected first enabled model from node fallback array";
|
|
34
|
+
return `all configured node models are disabled by ${DISABLED_MODELS_ENV}`;
|
|
35
|
+
}
|
|
18
36
|
function disabledModels() {
|
|
19
37
|
return new Set((process.env[DISABLED_MODELS_ENV] ?? "").split(",").map((value) => value.trim()).filter(Boolean));
|
|
20
38
|
}
|
package/dist/runner.js
CHANGED
|
@@ -17,6 +17,7 @@ const OPENCODE_EXCLUDES = [
|
|
|
17
17
|
"coverage/"
|
|
18
18
|
];
|
|
19
19
|
const LINE_RE = /\r?\n/;
|
|
20
|
+
const DEFAULT_OPENCODE_MODEL = "opencode/deepseek-v4-flash-free";
|
|
20
21
|
function ensureOpencodeGitExcludes(worktreePath) {
|
|
21
22
|
const excludePath = join(worktreePath, ".git", "info", "exclude");
|
|
22
23
|
if (!existsSync(excludePath)) return;
|
|
@@ -27,9 +28,26 @@ function ensureOpencodeGitExcludes(worktreePath) {
|
|
|
27
28
|
appendFileSync(excludePath, `${existing.endsWith("\n") ? "" : "\n"}# oisin-pipeline opencode excludes\n${missing.join("\n")}\n`);
|
|
28
29
|
}
|
|
29
30
|
function optionalModelArgs(runner, actor, selectedModel) {
|
|
30
|
-
const model =
|
|
31
|
+
const model = resolveOpencodeModel(runner, actor, selectedModel);
|
|
31
32
|
return model ? ["--model", model] : [];
|
|
32
33
|
}
|
|
34
|
+
function resolveOpencodeModel(runner, actor, selectedModel) {
|
|
35
|
+
return firstDefinedModel([
|
|
36
|
+
process.env.PIPELINE_OPENCODE_MODEL,
|
|
37
|
+
selectedModel,
|
|
38
|
+
actorModel(actor),
|
|
39
|
+
runnerModel(runner)
|
|
40
|
+
]) ?? DEFAULT_OPENCODE_MODEL;
|
|
41
|
+
}
|
|
42
|
+
function firstDefinedModel(values) {
|
|
43
|
+
return values.find((value) => value !== void 0);
|
|
44
|
+
}
|
|
45
|
+
function actorModel(actor) {
|
|
46
|
+
return actor?.model;
|
|
47
|
+
}
|
|
48
|
+
function runnerModel(runner) {
|
|
49
|
+
return runner?.model;
|
|
50
|
+
}
|
|
33
51
|
/**
|
|
34
52
|
* Per-harness argv shape, excluding the leading harness binary name.
|
|
35
53
|
*/
|
package/package.json
CHANGED
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"prepack": "bun run build:cli"
|
|
121
121
|
},
|
|
122
122
|
"type": "module",
|
|
123
|
-
"version": "1.27.
|
|
123
|
+
"version": "1.27.5",
|
|
124
124
|
"description": "Config-driven multi-agent pipeline runner for repository work",
|
|
125
125
|
"main": "./dist/index.js",
|
|
126
126
|
"types": "./dist/index.d.ts",
|