diff --git a/packages/cli-workflow/src/commands/thread.ts b/packages/cli-workflow/src/commands/thread.ts index 8a75d7c..eefb8ab 100644 --- a/packages/cli-workflow/src/commands/thread.ts +++ b/packages/cli-workflow/src/commands/thread.ts @@ -804,13 +804,11 @@ function spawnAgent( role: string, edgePrompt: string, ): CasRef { - const argv = [...agent.args, threadId, role]; - const env = { ...process.env, UWF_EDGE_PROMPT: edgePrompt }; + const argv = [...agent.args, "--thread", threadId, "--role", role, "--prompt", edgePrompt]; let stdout: string; try { stdout = execFileSync(agent.command, argv, { encoding: "utf8", - env, stdio: ["ignore", "pipe", "pipe"], maxBuffer: 50 * 1024 * 1024, // 50 MB — stream-json output can be large }); diff --git a/packages/workflow-agent-kit/src/context.ts b/packages/workflow-agent-kit/src/context.ts index 4c1647b..7c48b94 100644 --- a/packages/workflow-agent-kit/src/context.ts +++ b/packages/workflow-agent-kit/src/context.ts @@ -21,14 +21,6 @@ function fail(message: string): never { throw new Error(message); } -function readEdgePrompt(): string { - const value = process.env.UWF_EDGE_PROMPT; - if (value === undefined || value === "") { - fail("UWF_EDGE_PROMPT environment variable is required"); - } - return value; -} - function walkChain(store: Store, schemas: AgentStore["schemas"], headHash: CasRef): ChainState { const headNode = store.get(headHash); if (headNode === null) { @@ -123,7 +115,11 @@ async function loadWorkflow(store: Store, schemas: AgentStore["schemas"], workfl * Build agent execution context from thread head in threads.yaml. * Walks the CAS chain from head to StartNode and expands step outputs. */ -export async function buildContext(threadId: ThreadId, role: string): Promise { +export async function buildContext( + threadId: ThreadId, + role: string, + edgePrompt: string, +): Promise { const storageRoot = resolveStorageRoot(); const agentStore = await createAgentStore(storageRoot); const { store, schemas } = agentStore; @@ -142,7 +138,6 @@ export async function buildContext(threadId: ThreadId, role: string): Promise s.role === role); return { @@ -172,6 +167,7 @@ export type BuildContextMeta = { export async function buildContextWithMeta( threadId: ThreadId, role: string, + edgePrompt: string, ): Promise { const storageRoot = resolveStorageRoot(); const agentStore = await createAgentStore(storageRoot); @@ -191,7 +187,6 @@ export async function buildContextWithMeta( } const steps = await buildHistory(store, chain.stepsNewestFirst); - const edgePrompt = readEdgePrompt(); const isFirstVisit = !steps.some((s) => s.role === role); return { diff --git a/packages/workflow-agent-kit/src/run.ts b/packages/workflow-agent-kit/src/run.ts index 2a3d8fb..391e3f8 100644 --- a/packages/workflow-agent-kit/src/run.ts +++ b/packages/workflow-agent-kit/src/run.ts @@ -22,16 +22,24 @@ function agentLabel(name: string): string { return `uwf-${name}`; } -function parseArgv(argv: string[]): { threadId: ThreadId; role: string } { - const threadId = argv[2]; - const role = argv[3]; - if (threadId === undefined || threadId === "") { - fail("usage: "); +const USAGE = "usage: --thread --role --prompt "; + +function getNamedArg(argv: string[], name: string): string { + const idx = argv.indexOf(name); + if (idx === -1 || idx + 1 >= argv.length) { + return ""; } - if (role === undefined || role === "") { - fail("usage: "); - } - return { threadId: threadId as ThreadId, role }; + return argv[idx + 1]; +} + +function parseArgv(argv: string[]): { threadId: ThreadId; role: string; prompt: string } { + const threadId = getNamedArg(argv, "--thread"); + const role = getNamedArg(argv, "--role"); + const prompt = getNamedArg(argv, "--prompt"); + if (threadId === "") fail(USAGE); + if (role === "") fail(USAGE); + if (prompt === "") fail(USAGE); + return { threadId: threadId as ThreadId, role, prompt }; } function runWithMessage(label: string, fn: () => Promise): Promise { @@ -103,11 +111,11 @@ async function persistStep(options: { export function createAgent(options: AgentOptions): () => Promise { return async function main(): Promise { - const { threadId, role } = parseArgv(process.argv); + const { threadId, role, prompt } = parseArgv(process.argv); const storageRoot = resolveStorageRoot(); loadDotenv({ path: getEnvPath(storageRoot) }); - const ctx = await runWithMessage("context", () => buildContextWithMeta(threadId, role)); + const ctx = await runWithMessage("context", () => buildContextWithMeta(threadId, role, prompt)); const roleDef = ctx.workflow.roles[role]; if (roleDef === undefined) { diff --git a/packages/workflow-agent-kit/src/types.ts b/packages/workflow-agent-kit/src/types.ts index 9a25918..42f8c1e 100644 --- a/packages/workflow-agent-kit/src/types.ts +++ b/packages/workflow-agent-kit/src/types.ts @@ -13,7 +13,7 @@ export type AgentContext = ModeratorContext & { */ outputFormatInstruction: string; /** - * Edge prompt from the graph transition that led to this role (UWF_EDGE_PROMPT). + * Edge prompt from the graph transition that led to this role (--prompt CLI arg). * Always the real moderator instruction for this step. */ edgePrompt: string;