FN-6761: add built-in marketing workflow
Add a content-focused workflow while preserving standard Fusion lifecycle and merge behavior. - Register builtin:marketing in the built-in workflow catalog and default-enabled workflow order. - Define marketing-specific columns, content brief/draft/editorial prompts, lifecycle traits, and merge primitives. - Cover the marketing workflow in built-in workflow tests and document it in workflow-step docs. - Add a minor changeset for the published Fusion package. Files changed: .changeset/fn-6761-marketing-workflow.md | 5 + docs/workflow-steps.md | 3 + .../core/src/__tests__/builtin-workflows.test.ts | 64 +++++++++++- packages/core/src/builtin-marketing-workflow-ir.ts | 116 +++++++++++++++++++++ packages/core/src/builtin-workflows.ts | 24 +++++ packages/core/src/index.ts | 1 + 6 files changed, 209 insertions(+), 4 deletions(-) Fusion-Task-Id: FN-6761 Fusion-Task-Lineage: 3242eceb-570f-47f8-8750-dc3acc971bbd
This commit is contained in:
5
.changeset/fn-6761-marketing-workflow.md
Normal file
5
.changeset/fn-6761-marketing-workflow.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Add a built-in Marketing workflow with content-specific columns and prompts for brief, drafting, editorial review, and publishing.
|
||||||
@@ -30,6 +30,7 @@ Decision-only or investigation tasks can also declare `noCommitsExpected` / `**N
|
|||||||
| Coding | `builtin:coding` | Default coding lifecycle and fallback for tasks without an explicit selection. |
|
| Coding | `builtin:coding` | Default coding lifecycle and fallback for tasks without an explicit selection. |
|
||||||
| Quick fix | `builtin:quick-fix` | Short path for trivial or no-commit/decision work; omits the standard review stage. |
|
| Quick fix | `builtin:quick-fix` | Short path for trivial or no-commit/decision work; omits the standard review stage. |
|
||||||
| Review-heavy | `builtin:review-heavy` | Standard execute/review/merge path with an additional gated security review. |
|
| Review-heavy | `builtin:review-heavy` | Standard execute/review/merge path with an additional gated security review. |
|
||||||
|
| Marketing | `builtin:marketing` | Content pipeline with custom Ideation, Backlog, Drafting, Editorial review, Published, and Archived columns plus marketing brief/draft/editorial prompts; it reuses the standard lifecycle traits and merge-primitive region. |
|
||||||
| Compound engineering | `builtin:compound-engineering` | Plugin-gated workflow that invokes Compound Engineering skills for planning, work, review, PR/feedback, and learnings capture. |
|
| Compound engineering | `builtin:compound-engineering` | Plugin-gated workflow that invokes Compound Engineering skills for planning, work, review, PR/feedback, and learnings capture. |
|
||||||
| Stepwise coding | `builtin:stepwise-coding` | Graph-executor workflow that models per-step parse/execute/review/rework explicitly. |
|
| Stepwise coding | `builtin:stepwise-coding` | Graph-executor workflow that models per-step parse/execute/review/rework explicitly. |
|
||||||
| Design | `builtin:design` | UI-heavy work path that implements, runs a gated design/UX review, then performs the standard review and merge. |
|
| Design | `builtin:design` | UI-heavy work path that implements, runs a gated design/UX review, then performs the standard review and merge. |
|
||||||
@@ -75,6 +76,8 @@ The default built-in catalog entry `builtin:coding` is backed by the canonical `
|
|||||||
|
|
||||||
`builtin:stepwise-coding` is a separate graph variant backed by `BUILTIN_STEPWISE_CODING_WORKFLOW_IR`; it keeps the same lifecycle columns/traits while modeling per-step parse/execute/review/rework as authored graph structure.
|
`builtin:stepwise-coding` is a separate graph variant backed by `BUILTIN_STEPWISE_CODING_WORKFLOW_IR`; it keeps the same lifecycle columns/traits while modeling per-step parse/execute/review/rework as authored graph structure.
|
||||||
|
|
||||||
|
`builtin:marketing` is a non-coding content workflow with marketing-specific columns (`ideation`, `backlog`, `drafting`, `editorial-review`, `published`, `archived`) and prompt seams for content brief, draft, and editorial review. It uses the same lifecycle traits (`intake`, `hold`, `wip`, `merge-blocker`, `human-review`, `complete`, `archived`) and the same merge-gate/branch-group/merge-attempt primitive region as coding workflows, so scheduler, capacity, review blocking, and merge orchestration behavior remain standard.
|
||||||
|
|
||||||
During triage/planning sessions, agents can call `fn_workflow_list` to discover available built-in and custom workflows and read their descriptions before routing work. They can call `fn_workflow_select` to select a workflow for the task being specified, or pass `workflow_id` when creating child tasks with `fn_task_create`; decision-only or investigation tasks can also set `noCommitsExpected` / `**No commits expected:** true` when no code changes are expected. The built-in triage thresholds, decision-only verb list, and default routing IDs are workflow-native typed settings resolved from the selected workflow.
|
During triage/planning sessions, agents can call `fn_workflow_list` to discover available built-in and custom workflows and read their descriptions before routing work. They can call `fn_workflow_select` to select a workflow for the task being specified, or pass `workflow_id` when creating child tasks with `fn_task_create`; decision-only or investigation tasks can also set `noCommitsExpected` / `**No commits expected:** true` when no code changes are expected. The built-in triage thresholds, decision-only verb list, and default routing IDs are workflow-native typed settings resolved from the selected workflow.
|
||||||
|
|
||||||
#### Runtime invariant criterion
|
#### Runtime invariant criterion
|
||||||
|
|||||||
@@ -20,7 +20,12 @@ const EXECUTE_NODE_MAX_RETRIES = 2;
|
|||||||
describe("built-in workflows", () => {
|
describe("built-in workflows", () => {
|
||||||
// Non-compiler built-ins model graph-only node kinds or reusable fragments the
|
// Non-compiler built-ins model graph-only node kinds or reusable fragments the
|
||||||
// linear compiler cannot lower to a step list. They still must parse as valid IR.
|
// linear compiler cannot lower to a step list. They still must parse as valid IR.
|
||||||
const NON_COMPILABLE_BUILTIN_IDS = new Set(["builtin:coding", "builtin:stepwise-coding", "builtin:pr-workflow"]);
|
const NON_COMPILABLE_BUILTIN_IDS = new Set([
|
||||||
|
"builtin:coding",
|
||||||
|
"builtin:marketing",
|
||||||
|
"builtin:stepwise-coding",
|
||||||
|
"builtin:pr-workflow",
|
||||||
|
]);
|
||||||
|
|
||||||
it("every built-in has a valid IR; linear built-ins compile without error", () => {
|
it("every built-in has a valid IR; linear built-ins compile without error", () => {
|
||||||
expect(BUILTIN_WORKFLOWS.length).toBeGreaterThanOrEqual(4);
|
expect(BUILTIN_WORKFLOWS.length).toBeGreaterThanOrEqual(4);
|
||||||
@@ -150,6 +155,55 @@ describe("built-in workflows", () => {
|
|||||||
expect(ir.settings).toEqual(BUILTIN_WORKFLOW_SETTINGS);
|
expect(ir.settings).toEqual(BUILTIN_WORKFLOW_SETTINGS);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("includes the marketing built-in with custom columns, prompts, and lifecycle traits", () => {
|
||||||
|
const marketing = getBuiltinWorkflow("builtin:marketing");
|
||||||
|
expect(marketing).toBeDefined();
|
||||||
|
expect(marketing!.kind).toBe("workflow");
|
||||||
|
expect(BUILTIN_WORKFLOWS.some((workflow) => workflow.id === "builtin:marketing")).toBe(true);
|
||||||
|
expect(defaultEnabledBuiltinWorkflowIds()).toContain("builtin:marketing");
|
||||||
|
expect(() => parseWorkflowIr(marketing!.ir)).not.toThrow();
|
||||||
|
|
||||||
|
const ir = parseWorkflowIr(marketing!.ir);
|
||||||
|
expect(ir.version).toBe("v2");
|
||||||
|
if (ir.version !== "v2") throw new Error("expected v2");
|
||||||
|
|
||||||
|
expect(ir.columns.map((column) => column.id)).toEqual([
|
||||||
|
"ideation",
|
||||||
|
"backlog",
|
||||||
|
"drafting",
|
||||||
|
"editorial-review",
|
||||||
|
"published",
|
||||||
|
"archived",
|
||||||
|
]);
|
||||||
|
|
||||||
|
const editorialReview = ir.columns.find((column) => column.id === "editorial-review");
|
||||||
|
expect(editorialReview).toBeDefined();
|
||||||
|
expect(editorialReview!.traits.map((trait) => trait.trait)).toEqual([
|
||||||
|
"merge-blocker",
|
||||||
|
"human-review",
|
||||||
|
"stall-detection",
|
||||||
|
"merge",
|
||||||
|
]);
|
||||||
|
const editorialFlags = resolveColumnFlags(editorialReview!);
|
||||||
|
expect(editorialFlags.mergeBlocker).toBe(true);
|
||||||
|
expect(editorialFlags.humanReview).toBe(true);
|
||||||
|
|
||||||
|
const drafting = ir.columns.find((column) => column.id === "drafting");
|
||||||
|
expect(drafting).toBeDefined();
|
||||||
|
expect(resolveColumnFlags(drafting!).countsTowardWip).toBe(true);
|
||||||
|
|
||||||
|
const execute = ir.nodes.find((node) => node.config?.seam === "execute");
|
||||||
|
const review = ir.nodes.find((node) => node.config?.seam === "review");
|
||||||
|
expect(execute?.id).toBe("draft");
|
||||||
|
expect(execute?.config?.name).toBe("Draft content");
|
||||||
|
expect(String(execute?.config?.prompt ?? "")).toContain("marketing copywriter");
|
||||||
|
expect(String(execute?.config?.prompt ?? "").length).toBeGreaterThan(100);
|
||||||
|
expect(review?.id).toBe("editorial");
|
||||||
|
expect(review?.config?.name).toBe("Editorial review");
|
||||||
|
expect(String(review?.config?.prompt ?? "")).toContain("editorial reviewer");
|
||||||
|
expect(String(review?.config?.prompt ?? "").length).toBeGreaterThan(100);
|
||||||
|
});
|
||||||
|
|
||||||
it("includes the design built-in with an ordered design review gate", () => {
|
it("includes the design built-in with an ordered design review gate", () => {
|
||||||
const design = getBuiltinWorkflow("builtin:design");
|
const design = getBuiltinWorkflow("builtin:design");
|
||||||
expect(design).toBeDefined();
|
expect(design).toBeDefined();
|
||||||
@@ -181,14 +235,16 @@ describe("built-in workflows", () => {
|
|||||||
).map((workflow) => workflow.id),
|
).map((workflow) => workflow.id),
|
||||||
);
|
);
|
||||||
expect(defaultEnabledBuiltinWorkflowIds()).toContain("builtin:design");
|
expect(defaultEnabledBuiltinWorkflowIds()).toContain("builtin:design");
|
||||||
|
expect(defaultEnabledBuiltinWorkflowIds()).toContain("builtin:marketing");
|
||||||
expect(defaultEnabledBuiltinWorkflowIds()).not.toContain("builtin:compound-engineering");
|
expect(defaultEnabledBuiltinWorkflowIds()).not.toContain("builtin:compound-engineering");
|
||||||
expect(defaultEnabledBuiltinWorkflowIds()).not.toContain("builtin:pr-workflow");
|
expect(defaultEnabledBuiltinWorkflowIds()).not.toContain("builtin:pr-workflow");
|
||||||
expect(getBuiltinWorkflow("builtin:pr-workflow")!.kind).toBe("fragment");
|
expect(getBuiltinWorkflow("builtin:pr-workflow")!.kind).toBe("fragment");
|
||||||
expect(defaultEnabledBuiltinWorkflowIds().length).toBeGreaterThanOrEqual(4);
|
expect(defaultEnabledBuiltinWorkflowIds().length).toBeGreaterThanOrEqual(5);
|
||||||
expect(defaultEnabledBuiltinWorkflowIds().slice(0, 4)).toEqual([
|
expect(defaultEnabledBuiltinWorkflowIds().slice(0, 5)).toEqual([
|
||||||
"builtin:coding",
|
"builtin:coding",
|
||||||
"builtin:quick-fix",
|
"builtin:quick-fix",
|
||||||
"builtin:review-heavy",
|
"builtin:review-heavy",
|
||||||
|
"builtin:marketing",
|
||||||
"builtin:stepwise-coding",
|
"builtin:stepwise-coding",
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
@@ -405,7 +461,7 @@ describe("built-in workflows", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("branching built-ins can be selected without throwing", async () => {
|
it("branching built-ins can be selected without throwing", async () => {
|
||||||
for (const workflowId of ["builtin:coding", "builtin:stepwise-coding"]) {
|
for (const workflowId of ["builtin:coding", "builtin:marketing", "builtin:stepwise-coding"]) {
|
||||||
const task = await store.createTask({ description: `select ${workflowId}`, enabledWorkflowSteps: [] });
|
const task = await store.createTask({ description: `select ${workflowId}`, enabledWorkflowSteps: [] });
|
||||||
|
|
||||||
await expect(store.selectTaskWorkflow(task.id, workflowId)).resolves.toEqual([]);
|
await expect(store.selectTaskWorkflow(task.id, workflowId)).resolves.toEqual([]);
|
||||||
|
|||||||
116
packages/core/src/builtin-marketing-workflow-ir.ts
Normal file
116
packages/core/src/builtin-marketing-workflow-ir.ts
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
import type { WorkflowIr } from "./workflow-ir-types.js";
|
||||||
|
import { parseWorkflowIr } from "./workflow-ir.js";
|
||||||
|
import { BUILTIN_WORKFLOW_SETTINGS } from "./builtin-workflow-settings.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FNXC:WorkflowMarketing 2026-06-20-00:00:
|
||||||
|
* Fusion needs a non-coding built-in workflow for marketing and content work. Keep the engine pipeline unchanged by reusing the standard lifecycle trait vocabulary and the canonical merge-primitive region while exposing marketing-specific columns and prompts for brief, draft, and editorial review phases.
|
||||||
|
*/
|
||||||
|
const RAW_BUILTIN_MARKETING_WORKFLOW_IR: WorkflowIr = {
|
||||||
|
version: "v2",
|
||||||
|
name: "builtin-marketing-workflow",
|
||||||
|
columns: [
|
||||||
|
{ id: "ideation", name: "Ideation", traits: [{ trait: "intake" }] },
|
||||||
|
{
|
||||||
|
id: "backlog",
|
||||||
|
name: "Backlog",
|
||||||
|
traits: [{ trait: "hold", config: { release: "capacity" } }, { trait: "reset-on-entry" }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "drafting",
|
||||||
|
name: "Drafting",
|
||||||
|
traits: [
|
||||||
|
{ trait: "wip", config: { limitSetting: "maxConcurrent", countPending: true } },
|
||||||
|
{ trait: "abort-on-exit" },
|
||||||
|
{ trait: "timing" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "editorial-review",
|
||||||
|
name: "Editorial review",
|
||||||
|
traits: [{ trait: "merge-blocker" }, { trait: "human-review" }, { trait: "stall-detection" }, { trait: "merge" }],
|
||||||
|
},
|
||||||
|
{ id: "published", name: "Published", traits: [{ trait: "complete" }] },
|
||||||
|
{ id: "archived", name: "Archived", traits: [{ trait: "archived" }] },
|
||||||
|
],
|
||||||
|
nodes: [
|
||||||
|
{ id: "start", kind: "start", column: "ideation" },
|
||||||
|
{
|
||||||
|
id: "brief",
|
||||||
|
kind: "prompt",
|
||||||
|
column: "ideation",
|
||||||
|
config: {
|
||||||
|
seam: "planning",
|
||||||
|
name: "Content brief",
|
||||||
|
prompt:
|
||||||
|
"You are a marketing content strategist. Turn this task into a concrete content brief: audience, channel, key message, format, success metric, required source material, and approval constraints.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "draft",
|
||||||
|
kind: "prompt",
|
||||||
|
column: "drafting",
|
||||||
|
config: {
|
||||||
|
seam: "execute",
|
||||||
|
name: "Draft content",
|
||||||
|
prompt:
|
||||||
|
"You are a marketing copywriter executing the approved brief. Produce the requested deliverable, following brand voice, audience intent, channel constraints, format requirements, and the brief's success metric.",
|
||||||
|
maxRetries: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "editorial",
|
||||||
|
kind: "prompt",
|
||||||
|
column: "editorial-review",
|
||||||
|
config: {
|
||||||
|
seam: "review",
|
||||||
|
name: "Editorial review",
|
||||||
|
prompt:
|
||||||
|
"You are an independent editorial reviewer. Check the draft for brand voice, factual accuracy, audience fit, channel fit, CTA clarity, compliance with the brief, and substantive quality issues; block on issues that would harm publication readiness.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ id: "merge-gate", kind: "merge-gate", column: "editorial-review", config: { gate: "auto-merge" } },
|
||||||
|
{ id: "merge-retry", kind: "retry-backoff", column: "editorial-review", config: { policy: "merge", maxAttempts: 3 } },
|
||||||
|
{ id: "merge-manual-hold", kind: "manual-merge-hold", column: "editorial-review", config: { release: "manual" } },
|
||||||
|
{
|
||||||
|
id: "branch-group-member-integration",
|
||||||
|
kind: "branch-group-member-integration",
|
||||||
|
column: "editorial-review",
|
||||||
|
config: { reworkRegion: true, maxReworkCycles: 3 },
|
||||||
|
},
|
||||||
|
{ id: "branch-group-promotion", kind: "branch-group-promotion", column: "editorial-review" },
|
||||||
|
{
|
||||||
|
id: "merge-attempt",
|
||||||
|
kind: "merge-attempt",
|
||||||
|
column: "editorial-review",
|
||||||
|
config: { capability: "task-merge", reworkRegion: true, maxReworkCycles: 3 },
|
||||||
|
},
|
||||||
|
{ id: "recovery-router", kind: "recovery-router", column: "editorial-review", config: { surfaces: ["merge", "retry"] } },
|
||||||
|
{ id: "end", kind: "end", column: "published" },
|
||||||
|
],
|
||||||
|
edges: [
|
||||||
|
{ from: "start", to: "brief" },
|
||||||
|
{ from: "brief", to: "draft", condition: "success" },
|
||||||
|
{ from: "draft", to: "editorial", condition: "success" },
|
||||||
|
{ from: "editorial", to: "merge-gate", condition: "success" },
|
||||||
|
{ from: "merge-gate", to: "branch-group-member-integration", condition: "outcome:auto-on" },
|
||||||
|
{ from: "merge-gate", to: "merge-manual-hold", condition: "outcome:auto-off" },
|
||||||
|
{ from: "merge-retry", to: "merge-attempt", condition: "success", kind: "rework" },
|
||||||
|
{ from: "merge-manual-hold", to: "branch-group-member-integration", condition: "success", kind: "rework" },
|
||||||
|
{ from: "branch-group-member-integration", to: "branch-group-promotion", condition: "success" },
|
||||||
|
{ from: "branch-group-member-integration", to: "merge-manual-hold", condition: "outcome:manual-required" },
|
||||||
|
{ from: "branch-group-promotion", to: "merge-attempt", condition: "success" },
|
||||||
|
{ from: "branch-group-promotion", to: "merge-manual-hold", condition: "outcome:manual-required" },
|
||||||
|
{ from: "merge-attempt", to: "end", condition: "success" },
|
||||||
|
{ from: "merge-attempt", to: "merge-retry", condition: "outcome:transient-failure" },
|
||||||
|
{ from: "merge-attempt", to: "merge-manual-hold", condition: "outcome:manual-required" },
|
||||||
|
{ from: "recovery-router", to: "merge-attempt", condition: "outcome:wake-merge", kind: "rework" },
|
||||||
|
{ from: "brief", to: "end", condition: "failure" },
|
||||||
|
{ from: "draft", to: "end", condition: "failure" },
|
||||||
|
{ from: "editorial", to: "end", condition: "failure" },
|
||||||
|
{ from: "merge-attempt", to: "end", condition: "failure" },
|
||||||
|
],
|
||||||
|
settings: BUILTIN_WORKFLOW_SETTINGS,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const BUILTIN_MARKETING_WORKFLOW_IR = parseWorkflowIr(RAW_BUILTIN_MARKETING_WORKFLOW_IR);
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { BUILTIN_CODING_WORKFLOW_IR } from "./builtin-coding-workflow-ir.js";
|
import { BUILTIN_CODING_WORKFLOW_IR } from "./builtin-coding-workflow-ir.js";
|
||||||
|
import { BUILTIN_MARKETING_WORKFLOW_IR } from "./builtin-marketing-workflow-ir.js";
|
||||||
import { BUILTIN_PR_WORKFLOW_IR } from "./builtin-pr-workflow-ir.js";
|
import { BUILTIN_PR_WORKFLOW_IR } from "./builtin-pr-workflow-ir.js";
|
||||||
import { BUILTIN_STEPWISE_CODING_WORKFLOW_IR } from "./builtin-stepwise-coding-workflow-ir.js";
|
import { BUILTIN_STEPWISE_CODING_WORKFLOW_IR } from "./builtin-stepwise-coding-workflow-ir.js";
|
||||||
import { BUILTIN_WORKFLOW_SETTINGS } from "./builtin-workflow-settings.js";
|
import { BUILTIN_WORKFLOW_SETTINGS } from "./builtin-workflow-settings.js";
|
||||||
@@ -150,6 +151,29 @@ export const BUILTIN_WORKFLOWS: WorkflowDefinition[] = [
|
|||||||
{ id: "merge", kind: "prompt", config: builtinPromptConfig("merge", "Merge boundary") },
|
{ id: "merge", kind: "prompt", config: builtinPromptConfig("merge", "Merge boundary") },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
{
|
||||||
|
id: "builtin:marketing",
|
||||||
|
name: "Marketing (built-in)",
|
||||||
|
description: "Marketing content pipeline: ideate, brief, draft, editorial review, then publish via the standard lifecycle merge primitives.",
|
||||||
|
kind: "workflow",
|
||||||
|
ir: BUILTIN_MARKETING_WORKFLOW_IR,
|
||||||
|
layout: {
|
||||||
|
start: { x: 60, y: 160 },
|
||||||
|
brief: { x: 230, y: 160 },
|
||||||
|
draft: { x: 400, y: 160 },
|
||||||
|
editorial: { x: 570, y: 160 },
|
||||||
|
"merge-gate": { x: 740, y: 160 },
|
||||||
|
"branch-group-member-integration": { x: 910, y: 80 },
|
||||||
|
"branch-group-promotion": { x: 1080, y: 80 },
|
||||||
|
"merge-attempt": { x: 1250, y: 160 },
|
||||||
|
"merge-retry": { x: 1420, y: 80 },
|
||||||
|
"recovery-router": { x: 1420, y: 240 },
|
||||||
|
"merge-manual-hold": { x: 910, y: 240 },
|
||||||
|
end: { x: 1590, y: 160 },
|
||||||
|
},
|
||||||
|
createdAt: BUILTIN_TS,
|
||||||
|
updatedAt: BUILTIN_TS,
|
||||||
|
},
|
||||||
linear({
|
linear({
|
||||||
id: "builtin:compound-engineering",
|
id: "builtin:compound-engineering",
|
||||||
name: "Compound engineering (built-in)",
|
name: "Compound engineering (built-in)",
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ export type {
|
|||||||
EffectiveAgentResult,
|
EffectiveAgentResult,
|
||||||
} from "./column-agent-resolver.js";
|
} from "./column-agent-resolver.js";
|
||||||
export { BUILTIN_CODING_WORKFLOW_IR } from "./builtin-coding-workflow-ir.js";
|
export { BUILTIN_CODING_WORKFLOW_IR } from "./builtin-coding-workflow-ir.js";
|
||||||
|
export { BUILTIN_MARKETING_WORKFLOW_IR } from "./builtin-marketing-workflow-ir.js";
|
||||||
export { resolveWorkflowOptionalSteps } from "./workflow-optional-steps.js";
|
export { resolveWorkflowOptionalSteps } from "./workflow-optional-steps.js";
|
||||||
export type { ResolvedWorkflowOptionalStep } from "./workflow-optional-steps.js";
|
export type { ResolvedWorkflowOptionalStep } from "./workflow-optional-steps.js";
|
||||||
export { BUILTIN_STEPWISE_CODING_WORKFLOW_IR } from "./builtin-stepwise-coding-workflow-ir.js";
|
export { BUILTIN_STEPWISE_CODING_WORKFLOW_IR } from "./builtin-stepwise-coding-workflow-ir.js";
|
||||||
|
|||||||
Reference in New Issue
Block a user