The previous commit incorrectly deleted all workflows. Only restart-gateway should be removed (replaced by direct shell trigger). Other workflows (solve-issue, extract-knowledge, develop-sense, develop-workflow) are CLI-triggered and independent of sense coupling.
85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
import { END } from "@uncaged/nerve-core";
|
|
import type { Moderator, ThreadContext } from "@uncaged/nerve-core";
|
|
|
|
import type { AnswererMeta } from "./roles/answerer.js";
|
|
import type { ExplorerMeta } from "./roles/explorer.js";
|
|
import type { QuestionerMeta } from "./roles/questioner.js";
|
|
|
|
export type WorkflowMeta = {
|
|
questioner: QuestionerMeta;
|
|
answerer: AnswererMeta;
|
|
explorer: ExplorerMeta;
|
|
};
|
|
|
|
type Steps = ThreadContext<WorkflowMeta>["steps"];
|
|
|
|
function lastQuestionerRemaining(steps: Steps): QuestionerMeta | undefined {
|
|
for (let i = steps.length - 1; i >= 0; i--) {
|
|
const s = steps[i];
|
|
if (s.role === "questioner") return s.meta;
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
/** End when the last two explorer invocations both added no new cards (issue #266 stagnation rule). */
|
|
function lastTwoExplorerRunsBothEmpty(steps: Steps): boolean {
|
|
const explorerSteps = steps.filter((s) => s.role === "explorer");
|
|
if (explorerSteps.length < 2) return false;
|
|
const e1 = explorerSteps[explorerSteps.length - 1].meta as ExplorerMeta;
|
|
const e2 = explorerSteps[explorerSteps.length - 2].meta as ExplorerMeta;
|
|
return e1.new_cards.length === 0 && e2.new_cards.length === 0;
|
|
}
|
|
|
|
function queueAfterSkippedExplorer(steps: Steps): string[] {
|
|
const q = lastQuestionerRemaining(steps);
|
|
return q?.remaining_queue ?? [];
|
|
}
|
|
|
|
function queueAfterExplorerStep(steps: Steps): string[] {
|
|
const last = steps[steps.length - 1];
|
|
if (!last || last.role !== "explorer") return [];
|
|
const q = lastQuestionerRemaining(steps);
|
|
if (!q) return [];
|
|
const e = last.meta as ExplorerMeta;
|
|
return [...q.remaining_queue, ...e.new_cards];
|
|
}
|
|
|
|
export const moderator: Moderator<WorkflowMeta> = (context) => {
|
|
const { steps } = context;
|
|
|
|
if (steps.length === 0) {
|
|
return "questioner";
|
|
}
|
|
|
|
const last = steps[steps.length - 1];
|
|
|
|
if (last.role === "questioner") {
|
|
return "answerer";
|
|
}
|
|
|
|
if (last.role === "answerer") {
|
|
const am = last.meta as AnswererMeta;
|
|
if (am.has_unanswered) {
|
|
return "explorer";
|
|
}
|
|
const q = queueAfterSkippedExplorer(steps);
|
|
if (q.length === 0) {
|
|
return END;
|
|
}
|
|
return "questioner";
|
|
}
|
|
|
|
if (last.role === "explorer") {
|
|
if (lastTwoExplorerRunsBothEmpty(steps)) {
|
|
return END;
|
|
}
|
|
const q = queueAfterExplorerStep(steps);
|
|
if (q.length === 0) {
|
|
return END;
|
|
}
|
|
return "questioner";
|
|
}
|
|
|
|
return END;
|
|
};
|