Steer generation rules toward direction pools and readable fills.

Direction-first pools, recipes, and grade manifestation replace enum-tag stuffing; spawned products can be deleted and in-flight runs aborted.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-08 01:02:32 +08:00
co-authored by Cursor
parent 3c751988de
commit e2446b0d97
23 changed files with 2023 additions and 292 deletions
+58 -1
View File
@@ -1410,6 +1410,31 @@ export class SessionManager {
return this.toView(id);
}
/** 中止当前生成,不重跑;回到生成前的等待面或分层图。 */
async abortRun(id: string): Promise<SessionView> {
const s = this.require(id);
const session = s.runtime.getSession();
if (session.phase !== "running" || session.waitingReason) {
return this.toView(id);
}
const cutoff = s.runMessageCutoff ?? s.messages.length;
s.messages = s.messages.slice(0, cutoff);
try {
const owned = await this.runExclusive(id, s, async () => {
s.runtime.abortCurrentRun();
});
if (!owned) return this.toView(id);
} catch (err) {
const detail = err instanceof Error ? err.message : String(err);
console.error("[会话] 停止生成失败", detail);
await this.recoverFailedRun(s, detail);
}
s.messages.push(this.msg("system", "已停止生成。"));
this.syncCreationDialogue(s);
this.persist(s);
return this.toView(id);
}
/** 删除消息及其后的对话 */
async deleteMessage(id: string, messageId: string): Promise<SessionView> {
const s = this.require(id);
@@ -1686,6 +1711,27 @@ export class SessionManager {
return this.toView(id);
}
async deleteStep(id: string, stepId: string): Promise<SessionView> {
const s = this.require(id);
try {
const owned = await this.runExclusive(id, s, async () => {
await this.confirmPendingFlowPlan(s);
const waiting = s.runtime.getSession().waitingReason?.kind;
if (waiting !== "pick_creation_step") {
throw new Error("当前不是删除产物的时机");
}
await s.runtime.deleteCreationStep(stepId);
});
if (!owned) return this.toView(id);
} catch (err) {
const detail = err instanceof Error ? err.message : String(err);
console.error("[会话] 删除产物失败", detail);
s.messages.push(this.msg("system", formatRuntimeError(detail)));
}
this.persist(s);
return this.toView(id);
}
/** 已点进技能步、尚未验收:可退回分层图(误点可增殖节点时用) */
private canOfferLeaveCreationStep(
s: ManagedSession,
@@ -1699,10 +1745,21 @@ export class SessionManager {
return false;
}
const kind = reason?.kind;
if (session.phase === "running" && !kind) {
return Boolean(
s.runtime.getBlackboard().getContentByTag(CREATION_FLOW_TAG)?.trim(),
);
}
if (kind === "review_artifact") {
return Boolean(
s.runtime.getBlackboard().getContentByTag(CREATION_FLOW_TAG)?.trim(),
);
}
if (
kind !== "worker_questions" &&
kind !== "input" &&
kind !== "revision"
kind !== "revision" &&
kind !== "approve_step"
) {
return false;
}
+9
View File
@@ -515,6 +515,12 @@ const server = createServer(async (req, res) => {
typeof body.moduleName === "string" ? body.moduleName : "",
);
break;
case "delete_step":
view = await sessionManager.deleteStep(
sessionId,
typeof body.stepId === "string" ? body.stepId : "",
);
break;
case "run_outline":
view = await sessionManager.runOutline(sessionId);
break;
@@ -524,6 +530,9 @@ const server = createServer(async (req, res) => {
case "retry_run":
view = await sessionManager.abortAndRetry(sessionId);
break;
case "abort_run":
view = await sessionManager.abortRun(sessionId);
break;
default:
json(res, 400, { error: "未知 action" });
return;