feat: add exec command and inline pipeline execution#7
feat: add exec command and inline pipeline execution#7numman-ali wants to merge 2 commits intoberabuddies:masterfrom
Conversation
Two new ways to run pipelines without creating files:
1. `agentflow exec <agent> <prompt>` — single agent call, raw output:
agentflow exec shell "echo hello"
agentflow exec gemini "Search the web" --model gemini-3-pro-preview
agentflow exec claude "Explain this" --tools read_only --output text
2. `agentflow run -e <json|python>` — inline pipeline:
agentflow run -e '{"name":"q","nodes":[...]}'
agentflow run -e 'from agentflow import ...; print(g.to_json())'
3. `agentflow run -` — pipeline from stdin:
echo '{"name":"q","nodes":[...]}' | agentflow run -
exec defaults to raw text output on TTY (just the agent response),
JSON when piped. Supports --model, --tools, --env, --provider,
--timeout, --extra-arg, and --output flags.
run -e auto-detects JSON (starts with {) vs Python code. Python
expressions are executed as subprocesses matching the existing
.py loader pattern.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update SKILL.md: add exec quick start, inline run examples, gemini agent, reference pointer to exec.md - Add skills/agentflow/references/exec.md: full reference for exec command (all flags, output formats, env vars, examples), inline pipeline via run -e, stdin via run -, and exec-vs-pipeline guidance - Improve exec command docstring with usage examples in --help Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
iamjacobjia
left a comment
There was a problem hiding this comment.
Thanks for the PR. Requesting changes because the new inline/stdin run paths bypass preflight, and run - will execute non-JSON stdin as Python code by default.
| show_preflight=show_preflight, | ||
| ) | ||
| _run_pipeline(pipeline, runs_dir, max_concurrent_runs, output) | ||
| if expression is not None: |
There was a problem hiding this comment.
The new inline/stdin run paths bypass preflight entirely. Only the file-path branch goes through _load_pipeline_with_optional_smoke_preflight(), so run -e ... --preflight always and run - --preflight always skip the existing doctor/preflight gate and jump straight to execution.
I reproduced this with the same Kimi-bootstrapped Claude pipeline in both forms. agentflow run /tmp/pipeline.json --preflight always ... failed immediately with the expected preflight report, but agentflow run -e '<same pipeline>' --preflight always ... skipped preflight and actually launched the run. That changes the safety contract of run in a way that can hide missing local prerequisites until runtime.
| if not data.strip(): | ||
| typer.echo("No input received on stdin.", err=True) | ||
| raise typer.Exit(code=1) | ||
| return _load_inline_expression(data) |
There was a problem hiding this comment.
run - is auto-detecting stdin as JSON-or-Python and will execute any non-JSON input with python -c. That is a dangerous default for a stdin mode, especially because the new docs explicitly recommend piping remote content with curl ... | agentflow run -.
I reproduced this by piping a short Python snippet into agentflow run - that wrote a marker file and then printed valid pipeline JSON; the marker file was created before the pipeline ran. In other words, a non-JSON stdin payload is not treated as data here, it is executed as code. Please require an explicit opt-in for Python-on-stdin instead of auto-executing everything that does not start with {.
Summary
agentflow exec— run a single agent with a prompt, get raw output back. No files needed.agentflow run -e— pass inline JSON or Python expression directlyagentflow run -— read pipeline from stdinUsage
Design
execbuilds a single-nodePipelineSpecin memory, runs through the standard orchestratorexec --output autodefaults to raw text on TTY, JSON when pipedrun -eauto-detects JSON (starts with{) vs Python (executed as subprocess, matching existing.pyloader)run -reads stdin, same JSON/Python detectionagentflow run <path>works unchangedTest plan
agentflow exec shell "echo hello"→helloagentflow exec shell "echo hello" --output text→helloagentflow run -e '{"name":"q","nodes":[...]}'→ pipeline runsagentflow run -e 'from agentflow import ...'→ Python inline worksecho '...' | agentflow run -→ stdin worksagentflow run pipeline.py→ backwards compatible🤖 Generated with Claude Code