feat: map flue interop gaps
This commit is contained in:
parent
68a0a48669
commit
c7cd28c404
|
|
@ -203,6 +203,7 @@ fable-agent plinius godmode "improve explanation quality"
|
|||
- `fable5 route <task>`
|
||||
- `-d, --domain <domain>`
|
||||
- `fable5 models`
|
||||
- `fable5 flue`
|
||||
- `fable5 verify <task>`
|
||||
- `--repo <path>`
|
||||
- `fable5 goal <text>`
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { FLUE_INTEROP_ROWS, formatFlueInteropReport, summarizeFlueInterop } from "./flue-interop.js";
|
||||
|
||||
describe("flue interop map", () => {
|
||||
it("keeps Flue as an inspiration map, not vendored code", () => {
|
||||
const report = formatFlueInteropReport();
|
||||
|
||||
expect(FLUE_INTEROP_ROWS.length).toBeGreaterThan(5);
|
||||
expect(report).toContain("no vendored Flue code");
|
||||
expect(report).toContain("next implementable patch: channels");
|
||||
});
|
||||
|
||||
it("prioritizes gaps before partials", () => {
|
||||
expect(summarizeFlueInterop().next.flueConcept).toBe("channels");
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
export type FlueInteropStatus = "covered" | "partial" | "gap";
|
||||
|
||||
export interface FlueInteropRow {
|
||||
flueConcept: string;
|
||||
fableSurface: string;
|
||||
status: FlueInteropStatus;
|
||||
nextPatch: string;
|
||||
}
|
||||
|
||||
export const FLUE_INTEROP_ROWS: FlueInteropRow[] = [
|
||||
{
|
||||
flueConcept: "agents",
|
||||
fableSurface: "fable5 meta/teams/chains",
|
||||
status: "covered",
|
||||
nextPatch: "Keep using existing MetaAgent, AgentTeams, and AgentChain surfaces.",
|
||||
},
|
||||
{
|
||||
flueConcept: "workflows",
|
||||
fableSurface: "fable5 workflow + DynamicWorkflows",
|
||||
status: "covered",
|
||||
nextPatch: "No new engine; add examples only when a real workflow needs them.",
|
||||
},
|
||||
{
|
||||
flueConcept: "sandboxes",
|
||||
fableSurface: "WorktreeManager + factory agent-sandbox capability",
|
||||
status: "partial",
|
||||
nextPatch: "Add a sandbox command adapter after one deploy path needs isolation beyond git worktrees.",
|
||||
},
|
||||
{
|
||||
flueConcept: "durable execution",
|
||||
fableSurface: "session checkpointing + StateStore + ZTE receipts",
|
||||
status: "partial",
|
||||
nextPatch: "Record workflow step receipts so interrupted multi-step runs resume from the last passed step.",
|
||||
},
|
||||
{
|
||||
flueConcept: "subagents",
|
||||
fableSurface: "fable5 teams + fan-out workflow",
|
||||
status: "covered",
|
||||
nextPatch: "Use existing team roles; do not add another subagent abstraction.",
|
||||
},
|
||||
{
|
||||
flueConcept: "tools and skills",
|
||||
fableSurface: "SkillRegistry + SKILLS sync + factory capability registry",
|
||||
status: "covered",
|
||||
nextPatch: "Bridge manifests only; do not vendor Flue tool code.",
|
||||
},
|
||||
{
|
||||
flueConcept: "MCP",
|
||||
fableSurface: "factory capability registry",
|
||||
status: "partial",
|
||||
nextPatch: "Add optional MCP endpoint fields to the registry when a live MCP server is adopted.",
|
||||
},
|
||||
{
|
||||
flueConcept: "observability",
|
||||
fableSurface: "agent-observability + Prometheus/Grafana factory services",
|
||||
status: "covered",
|
||||
nextPatch: "Expose existing metrics in receipts before adding tracing code.",
|
||||
},
|
||||
{
|
||||
flueConcept: "channels",
|
||||
fableSurface: "none explicit",
|
||||
status: "gap",
|
||||
nextPatch: "Add a tiny channel manifest: stdin/stdout/files/http/webhook capabilities per executor.",
|
||||
},
|
||||
];
|
||||
|
||||
export function summarizeFlueInterop(rows: FlueInteropRow[] = FLUE_INTEROP_ROWS): { covered: number; partial: number; gap: number; next: FlueInteropRow } {
|
||||
const counts = rows.reduce(
|
||||
(acc, row) => ({ ...acc, [row.status]: acc[row.status] + 1 }),
|
||||
{ covered: 0, partial: 0, gap: 0 },
|
||||
);
|
||||
return { ...counts, next: rows.find((row) => row.status === "gap") ?? rows.find((row) => row.status === "partial") ?? rows[0] };
|
||||
}
|
||||
|
||||
export function formatFlueInteropReport(rows: FlueInteropRow[] = FLUE_INTEROP_ROWS): string {
|
||||
const summary = summarizeFlueInterop(rows);
|
||||
const lines = rows.map((row) =>
|
||||
` ${row.status.toUpperCase().padEnd(7)} ${row.flueConcept.padEnd(18)} → ${row.fableSurface}\n next: ${row.nextPatch}`,
|
||||
);
|
||||
|
||||
return [
|
||||
"",
|
||||
" Flue inspiration map (no vendored Flue code)",
|
||||
" ─────────────────────────────",
|
||||
` covered=${summary.covered} partial=${summary.partial} gap=${summary.gap}`,
|
||||
"",
|
||||
...lines,
|
||||
"",
|
||||
` next implementable patch: ${summary.next.flueConcept} — ${summary.next.nextPatch}`,
|
||||
"",
|
||||
].join("\n");
|
||||
}
|
||||
|
|
@ -47,5 +47,8 @@ export type { ZteReceipt, ZteSpec, ZteSpecOptions } from "./zte-protocol.js";
|
|||
export { formatCapabilityReport, loadFactoryCapabilities, parseFactoryCapabilities, probeFactoryCapabilities } from "./factory-capabilities.js";
|
||||
export type { CapabilityProbeResult, CapabilityReport, FactoryCapabilityService } from "./factory-capabilities.js";
|
||||
|
||||
export { FLUE_INTEROP_ROWS, formatFlueInteropReport, summarizeFlueInterop } from "./flue-interop.js";
|
||||
export type { FlueInteropRow, FlueInteropStatus } from "./flue-interop.js";
|
||||
|
||||
export { createForgejoIntakeReceipt, intakeForgejoItem, parseForgejoRef, routeForgejoLabels } from "./forgejo-intake.js";
|
||||
export type { ForgejoIntakeKind, ForgejoIntakeOptions, ForgejoIntakeReceipt, ForgejoIntakeSource, ForgejoItem, ForgejoRoute } from "./forgejo-intake.js";
|
||||
|
|
|
|||
|
|
@ -1579,6 +1579,14 @@ fable
|
|||
console.log(` `);
|
||||
});
|
||||
|
||||
fable
|
||||
.command("flue")
|
||||
.description("Show Flue-inspired interop gaps without vendoring Flue")
|
||||
.action(async () => {
|
||||
const { formatFlueInteropReport } = await import("./fable5/flue-interop.js");
|
||||
console.log(formatFlueInteropReport());
|
||||
});
|
||||
|
||||
fable
|
||||
.command("verify <task>")
|
||||
.description("Run independent verifier against a task")
|
||||
|
|
|
|||
Loading…
Reference in New Issue