@seanyao/roll 4.713.2 → 4.714.2
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 +10 -0
- package/dist/roll.mjs +109 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## v4.714.2 — 2026-07-14
|
|
6
|
+
|
|
7
|
+
### 稳定性
|
|
8
|
+
- agent 用哪个 model 现在完全由配置决定(`.roll/agents.yaml` 的 `rigs:`/`routing:`),源码不再写死运行时默认。以前缺配置会**静默**落到源码里写死的值(reasonix 一直跑 flash),配置丢了都发现不了;现在缺配置会**明确报错并引导**(需要显式 model 的 agent),配好的 model 一路带到 spawn。改某个 agent 的 model = 编辑一行配置,不用动源码、不用重新发版 (FIX-1249) `[loop]`
|
|
9
|
+
|
|
10
|
+
## v4.714.1 — 2026-07-14
|
|
11
|
+
|
|
12
|
+
### 稳定性
|
|
13
|
+
- roll 给用户项目自动合并 PR 时,现在同时认 GitHub 的两种检查状态——Actions 运行**和** commit status / 外部 check-run(取二者并集)。以前只看 Actions,导致用别的 CI 上报状态的项目里"其实全绿"的 PR 被误判成"状态未知"而一直卡着不自动合并、账也对不上;现在全绿(不论来自哪种)照常自动合,状态未知/进行中的按"等待"处理而非误判失败 (FIX-1248) `[loop]`
|
|
14
|
+
|
|
5
15
|
## v4.713.2 — 2026-07-13
|
|
6
16
|
|
|
7
17
|
### 自动化流水线
|
package/dist/roll.mjs
CHANGED
|
@@ -4369,6 +4369,15 @@ function normalizeAgentConfig(text2) {
|
|
|
4369
4369
|
errors
|
|
4370
4370
|
};
|
|
4371
4371
|
}
|
|
4372
|
+
function readRouteSlot(text2, slot) {
|
|
4373
|
+
const { config } = normalizeAgentConfig(text2);
|
|
4374
|
+
const resolved = config.routing[slot];
|
|
4375
|
+
if (resolved !== void 0) {
|
|
4376
|
+
const { agent, model } = resolved.rig;
|
|
4377
|
+
return model !== void 0 && model !== "" ? { agent, model } : { agent };
|
|
4378
|
+
}
|
|
4379
|
+
return readSlotFromText(text2, slot);
|
|
4380
|
+
}
|
|
4372
4381
|
var DEFAULT_STANDARD;
|
|
4373
4382
|
var init_config_v4 = __esm({
|
|
4374
4383
|
"packages/core/dist/agent/config-v4.js"() {
|
|
@@ -4382,6 +4391,24 @@ var init_config_v4 = __esm({
|
|
|
4382
4391
|
}
|
|
4383
4392
|
});
|
|
4384
4393
|
|
|
4394
|
+
// packages/core/dist/agent/model-config.js
|
|
4395
|
+
function configuredModelForAgent(agent, config) {
|
|
4396
|
+
const canonical = canonicalAgentName(agent);
|
|
4397
|
+
for (const rig of Object.values(config.rigs)) {
|
|
4398
|
+
if (canonicalAgentName(rig.agent) === canonical && rig.model !== void 0 && rig.model !== "") {
|
|
4399
|
+
return rig.model;
|
|
4400
|
+
}
|
|
4401
|
+
}
|
|
4402
|
+
return void 0;
|
|
4403
|
+
}
|
|
4404
|
+
var init_model_config = __esm({
|
|
4405
|
+
"packages/core/dist/agent/model-config.js"() {
|
|
4406
|
+
"use strict";
|
|
4407
|
+
init_registry();
|
|
4408
|
+
init_specs();
|
|
4409
|
+
}
|
|
4410
|
+
});
|
|
4411
|
+
|
|
4385
4412
|
// packages/core/dist/agent/scope-config.js
|
|
4386
4413
|
function isMap2(v) {
|
|
4387
4414
|
return typeof v === "object" && v !== null;
|
|
@@ -18228,6 +18255,7 @@ var init_dist2 = __esm({
|
|
|
18228
18255
|
init_registry();
|
|
18229
18256
|
init_specs();
|
|
18230
18257
|
init_config_v4();
|
|
18258
|
+
init_model_config();
|
|
18231
18259
|
init_scope_config();
|
|
18232
18260
|
init_scope_resolver();
|
|
18233
18261
|
init_scope_migration();
|
|
@@ -19388,6 +19416,7 @@ __export(github_exports, {
|
|
|
19388
19416
|
prViewHeadRef: () => prViewHeadRef,
|
|
19389
19417
|
prViewMergeInfo: () => prViewMergeInfo,
|
|
19390
19418
|
prViewState: () => prViewState,
|
|
19419
|
+
prViewStatusCheckRollup: () => prViewStatusCheckRollup,
|
|
19391
19420
|
prViewUrl: () => prViewUrl,
|
|
19392
19421
|
rawGh: () => rawGh,
|
|
19393
19422
|
repoViewSlug: () => repoViewSlug,
|
|
@@ -19592,6 +19621,17 @@ async function prViewMergeInfo(slug3, ref) {
|
|
|
19592
19621
|
return void 0;
|
|
19593
19622
|
}
|
|
19594
19623
|
}
|
|
19624
|
+
async function prViewStatusCheckRollup(slug3, ref) {
|
|
19625
|
+
const r = await gh(["-R", slug3, "pr", "view", ref, "--json", "statusCheckRollup"]);
|
|
19626
|
+
if (r.code !== 0 || r.stdout.trim() === "")
|
|
19627
|
+
return [];
|
|
19628
|
+
try {
|
|
19629
|
+
const j = JSON.parse(r.stdout);
|
|
19630
|
+
return Array.isArray(j.statusCheckRollup) ? j.statusCheckRollup : [];
|
|
19631
|
+
} catch {
|
|
19632
|
+
return [];
|
|
19633
|
+
}
|
|
19634
|
+
}
|
|
19595
19635
|
async function prCreate(input) {
|
|
19596
19636
|
const base = input.base ?? "main";
|
|
19597
19637
|
const r = await invokeInfraTool({
|
|
@@ -20035,11 +20075,47 @@ function reduceRunConclusions(conclusions) {
|
|
|
20035
20075
|
}
|
|
20036
20076
|
return "pending";
|
|
20037
20077
|
}
|
|
20038
|
-
|
|
20078
|
+
function reduceRollupEntry(e) {
|
|
20079
|
+
if (e.__typename === "StatusContext") {
|
|
20080
|
+
const state = e.state ?? "";
|
|
20081
|
+
if (state === "FAILURE" || state === "ERROR")
|
|
20082
|
+
return "red";
|
|
20083
|
+
if (state === "SUCCESS")
|
|
20084
|
+
return "green";
|
|
20085
|
+
return "pending";
|
|
20086
|
+
}
|
|
20087
|
+
if (e.status !== "COMPLETED")
|
|
20088
|
+
return "pending";
|
|
20089
|
+
const conclusion = e.conclusion;
|
|
20090
|
+
if (conclusion == null)
|
|
20091
|
+
return "pending";
|
|
20092
|
+
return GREEN_CONCLUSIONS.has(conclusion) ? "green" : "red";
|
|
20093
|
+
}
|
|
20094
|
+
function reduceStatusCheckRollup(entries) {
|
|
20095
|
+
if (entries.length === 0)
|
|
20096
|
+
return "unknown";
|
|
20097
|
+
const states = entries.map(reduceRollupEntry);
|
|
20098
|
+
if (states.some((s) => s === "red"))
|
|
20099
|
+
return "red";
|
|
20100
|
+
if (states.some((s) => s === "pending"))
|
|
20101
|
+
return "pending";
|
|
20102
|
+
return "green";
|
|
20103
|
+
}
|
|
20104
|
+
function mergeCiStates(a, b) {
|
|
20105
|
+
if (a === "red" || b === "red")
|
|
20106
|
+
return "red";
|
|
20107
|
+
if (a === "pending" || b === "pending")
|
|
20108
|
+
return "pending";
|
|
20109
|
+
if (a === "unknown" && b === "unknown")
|
|
20110
|
+
return "unknown";
|
|
20111
|
+
return "green";
|
|
20112
|
+
}
|
|
20113
|
+
var GREEN_CONCLUSIONS, GitHubPrStatusProvider, githubPrStatusProvider;
|
|
20039
20114
|
var init_pr_provider = __esm({
|
|
20040
20115
|
"packages/infra/dist/pr-provider.js"() {
|
|
20041
20116
|
"use strict";
|
|
20042
20117
|
init_github();
|
|
20118
|
+
GREEN_CONCLUSIONS = /* @__PURE__ */ new Set(["SUCCESS", "SKIPPED", "NEUTRAL"]);
|
|
20043
20119
|
GitHubPrStatusProvider = class {
|
|
20044
20120
|
name = "github";
|
|
20045
20121
|
/**
|
|
@@ -20070,9 +20146,11 @@ var init_pr_provider = __esm({
|
|
|
20070
20146
|
}
|
|
20071
20147
|
if (state === "OPEN") {
|
|
20072
20148
|
const branch = info6.headRefName;
|
|
20073
|
-
const runs =
|
|
20074
|
-
|
|
20075
|
-
|
|
20149
|
+
const [runs, rollup] = await Promise.all([
|
|
20150
|
+
branch !== void 0 ? runList(s, "conclusion", { branch }) : Promise.resolve([]),
|
|
20151
|
+
prViewStatusCheckRollup(s, String(prNumber))
|
|
20152
|
+
]);
|
|
20153
|
+
const ci = mergeCiStates(reduceRunConclusions(runs.map((r) => r.conclusion)), reduceStatusCheckRollup(rollup));
|
|
20076
20154
|
return { kind: "open", ci, draft: info6.isDraft, mergeable: info6.mergeable, checkedAt };
|
|
20077
20155
|
}
|
|
20078
20156
|
return { kind: "unreachable", reason: "provider_error", checkedAt };
|
|
@@ -23723,6 +23801,7 @@ __export(dist_exports, {
|
|
|
23723
23801
|
lsRemote: () => lsRemote,
|
|
23724
23802
|
mcpTools: () => mcpTools,
|
|
23725
23803
|
mergeBase: () => mergeBase,
|
|
23804
|
+
mergeCiStates: () => mergeCiStates,
|
|
23726
23805
|
networkTools: () => networkTools,
|
|
23727
23806
|
newSession: () => newSession,
|
|
23728
23807
|
openEvidenceFrame: () => openEvidenceFrame,
|
|
@@ -23751,6 +23830,7 @@ __export(dist_exports, {
|
|
|
23751
23830
|
prViewHeadRef: () => prViewHeadRef,
|
|
23752
23831
|
prViewMergeInfo: () => prViewMergeInfo,
|
|
23753
23832
|
prViewState: () => prViewState,
|
|
23833
|
+
prViewStatusCheckRollup: () => prViewStatusCheckRollup,
|
|
23754
23834
|
prViewUrl: () => prViewUrl,
|
|
23755
23835
|
projectConfigPath: () => projectConfigPath,
|
|
23756
23836
|
projectIdentity: () => projectIdentity,
|
|
@@ -23764,6 +23844,8 @@ __export(dist_exports, {
|
|
|
23764
23844
|
readPngDimensions: () => readPngDimensions,
|
|
23765
23845
|
redactInfraToolValue: () => redactInfraToolValue,
|
|
23766
23846
|
redactSecrets: () => redactSecrets,
|
|
23847
|
+
reduceRunConclusions: () => reduceRunConclusions,
|
|
23848
|
+
reduceStatusCheckRollup: () => reduceStatusCheckRollup,
|
|
23767
23849
|
reinstall: () => reinstall,
|
|
23768
23850
|
releaseLock: () => releaseLock,
|
|
23769
23851
|
remoteUrl: () => remoteUrl,
|
|
@@ -237572,14 +237654,14 @@ var AGENT_PROFILES = {
|
|
|
237572
237654
|
secretEnv: ["DEEPSEEK_API_KEY"],
|
|
237573
237655
|
buildSpawnCommand: (opts) => {
|
|
237574
237656
|
const routedModel = opts.model?.trim();
|
|
237575
|
-
const
|
|
237657
|
+
const modelArgs = routedModel !== void 0 && routedModel !== "" ? ["--model", routedModel] : [];
|
|
237576
237658
|
const maxSteps = opts.maxSteps ?? 1e3;
|
|
237577
237659
|
const roots = writableRootsForSpawn(opts);
|
|
237578
237660
|
if (roots.length > 0)
|
|
237579
237661
|
opts.cleanup = chainCleanup(opts.cleanup, writeReasonixSandboxConfig(opts.cwd, roots));
|
|
237580
237662
|
return {
|
|
237581
237663
|
bin: opts.bin ?? "reasonix",
|
|
237582
|
-
args: ["run", "--max-steps", String(maxSteps),
|
|
237664
|
+
args: ["run", "--max-steps", String(maxSteps), ...modelArgs, "--dir", opts.cwd, agentPrompt(opts)]
|
|
237583
237665
|
};
|
|
237584
237666
|
},
|
|
237585
237667
|
childEnv: reasonixEnv
|
|
@@ -269105,7 +269187,7 @@ function applyPrCloudState(facts, st) {
|
|
|
269105
269187
|
return;
|
|
269106
269188
|
case "open":
|
|
269107
269189
|
facts.prState = "OPEN";
|
|
269108
|
-
facts.ciGreen = st.ci === "green";
|
|
269190
|
+
facts.ciGreen = st.ci === "green" ? true : st.ci === "red" ? false : void 0;
|
|
269109
269191
|
facts.prDraft = st.draft;
|
|
269110
269192
|
facts.prMergeable = st.mergeable;
|
|
269111
269193
|
return;
|
|
@@ -275955,15 +276037,27 @@ function clearSelfHeal(runtimeDir11, storyId) {
|
|
|
275955
276037
|
|
|
275956
276038
|
// packages/cli/dist/runner/node-ports.js
|
|
275957
276039
|
var execFileAsync16 = promisify16(execFile16);
|
|
276040
|
+
function configuredModelBackstop(repoCwd, agent) {
|
|
276041
|
+
if (agent === "")
|
|
276042
|
+
return "";
|
|
276043
|
+
try {
|
|
276044
|
+
const { config } = normalizeAgentConfig(readFileSync120(join137(repoCwd, ".roll", "agents.yaml"), "utf8"));
|
|
276045
|
+
return configuredModelForAgent(agent, config) ?? "";
|
|
276046
|
+
} catch {
|
|
276047
|
+
return "";
|
|
276048
|
+
}
|
|
276049
|
+
}
|
|
275958
276050
|
function scopedStoryExecuteRoute(repoCwd) {
|
|
275959
276051
|
const scoped = resolveScopedStoryExecute(repoCwd);
|
|
275960
276052
|
if (scoped === null)
|
|
275961
276053
|
return null;
|
|
275962
276054
|
const { resolution } = scoped;
|
|
275963
276055
|
if (resolution.ok) {
|
|
276056
|
+
const agent = resolution.resolved.agent;
|
|
276057
|
+
const model = resolution.resolved.model ?? "";
|
|
275964
276058
|
return {
|
|
275965
|
-
agent
|
|
275966
|
-
model:
|
|
276059
|
+
agent,
|
|
276060
|
+
model: model !== "" ? model : configuredModelBackstop(repoCwd, agent)
|
|
275967
276061
|
};
|
|
275968
276062
|
}
|
|
275969
276063
|
const hasScopedBindingFailure = resolution.failure.source !== void 0 || resolution.failure.candidates.length > 0;
|
|
@@ -276216,7 +276310,11 @@ function nodePorts(opts) {
|
|
|
276216
276310
|
const rt = (process.env["ROLL_PROJECT_RUNTIME_DIR"] ?? "").trim() || join137(opts.repoCwd, ".roll", "loop");
|
|
276217
276311
|
const tried = storyId !== "" ? readSelfHeal(rt, storyId).triedAgents : [];
|
|
276218
276312
|
const dec = tried.length > 0 ? resolveRouteExcluding(tier, routeDeps, tried) ?? resolveRoute(tier, routeDeps) : resolveRoute(tier, routeDeps);
|
|
276219
|
-
|
|
276313
|
+
const routedModel = dec.model ?? "";
|
|
276314
|
+
return {
|
|
276315
|
+
agent: dec.agent,
|
|
276316
|
+
model: routedModel !== "" ? routedModel : configuredModelBackstop(opts.repoCwd, dec.agent)
|
|
276317
|
+
};
|
|
276220
276318
|
}
|
|
276221
276319
|
} : { resolve: () => ({ agent: "claude", model: "" }) },
|
|
276222
276320
|
evidence: {
|
|
@@ -277255,7 +277353,7 @@ function buildLoopRouteDeps(projectPath3) {
|
|
|
277255
277353
|
function readSlot(slot) {
|
|
277256
277354
|
const agentsYaml = join139(projectPath3, ".roll", "agents.yaml");
|
|
277257
277355
|
try {
|
|
277258
|
-
return
|
|
277356
|
+
return readRouteSlot(readFileSync124(agentsYaml, "utf8"), slot);
|
|
277259
277357
|
} catch {
|
|
277260
277358
|
return void 0;
|
|
277261
277359
|
}
|