Phi is intended to be used together with a coding agent. Install the phi CLI,
install the bundled phi-agent-runtime skill into Codex, Claude Code, or
OpenCode, configure a model API key, and then ask the coding agent to build a
Phi harness for the task you want to automate.
Download the release for your platform from
GitHub Releases, put the
phi executable on PATH, and verify it:
phi --version
phi --helpThe harness machine only needs the installed phi executable and Python for
complex controllers. It does not need a Rust toolchain or a Phi source
checkout.
The release archive already contains the skill at
phi/skills/phi-agent-runtime/. After extracting the archive, copy that
directory into the skill location supported by your coding agent. You can also
clone this repository when using a development checkout:
git clone --depth 1 https://github.com/s0duku/phi-agent.gitThe skill is the directory
skills/phi-agent-runtime/. Typical global
locations are:
| Coding agent | Skill directory |
|---|---|
| Codex | ~/.codex/skills/phi-agent-runtime/ |
| Claude Code | ~/.claude/skills/phi-agent-runtime/ |
| OpenCode | ~/.config/opencode/skills/phi-agent-runtime/ |
For example, on Unix-like systems:
cp -R phi-agent/skills/phi-agent-runtime ~/.codex/skills/
# or ~/.claude/skills/ and ~/.config/opencode/skills/Project-local installation is also supported by clients that discover
.agents/skills/, .claude/skills/, or .opencode/skills/; copy the same
phi-agent-runtime directory there when you want the skill scoped to one
project. Restart the coding agent after installing and verify that it lists
phi-agent-runtime.
Provide the API key through the environment or the Phi Home configuration. Do not put keys in a Session file, harness source, or git repository:
export PHI_PROVIDER=openai_chat
export PHI_MODEL=gpt-5
export PHI_KEY='your_api_key'Use the provider and model appropriate for your account. phi doctor reports
the resolved configuration without running an agent task:
phi doctorDescribe the automation outcome, available external systems, approval rules,
and how success should be detected. Explicitly ask the coding agent to use the
phi-agent-runtime skill and to produce a Python harness around the Phi CLI:
Use $phi-agent-runtime to build a Python harness with Phi for this task:
Monitor our issue queue, summarize new incidents, ask for approval before
creating a ticket, and persist progress so the workflow can resume tomorrow.
Use `run` for normal progress, inspect the Session after each run, route
external tools from Python, recover missing tools with rollback plus
session tool-result, and add a deterministic dry-run test.
The coding agent should create the controller, define its tool allowlist and
failure policy, use phi session state for state decisions, and test the
workflow with a bounded run budget. For a single simple task, the same skill
can produce a shell harness; Python is recommended once the workflow has
external tools, retries, approvals, or durable checkpoints.
Phi is a CLI-oriented Agent Runtime written in Rust. The CLI is its primary operational interface, rather than a thin wrapper around a hidden interactive UI or service. Sessions, agent evaluation, recovery, and persistent terminal jobs are exposed as commands with explicit, serializable inputs and outputs.
This makes the runtime usable as a standalone agent and as a composable command in scripts, pipelines, CI jobs, and other programs:
config + command + PhiHome -> runtime setup
Session -> one agent step -> Session
terminal job request -> typed job status and output
The Rust library in phi/ defines these semantics. The CLI delegates to
the same library operations, so command-line composition does not introduce a
second execution model.
A Session is Phi's durable, serializable state and the boundary between the
CLI and the agent runtime. Session commands are explicit ownership-consuming
transformations: they read one Session, apply one operation, and write the new
Session either to the same file or to stdout.
session newcreates initialized state.session appendadds user or assistant messages to the current outer delta.session nextandsession replacereproduce the corresponding step-frame transitions without running the agent.session tool-resultresolves the current executor request with an externally supplied result.session state,history,rollback, anddeleteinspect or manage state.
This interface lets a shell script, a human, or another program inspect and modify a Session between agent steps without bypassing Session semantics.
Phi treats agent execution as step-by-step evaluation of serialized ReAct expressions.
stepadvances a Session by exactly one atomic agent step.runrepeatedly applies that same step operation until the next run boundary.yolorepeatedly applies it through Phi's default continuation and recovery policy.
Failures and context compaction remain explicit step state. Each completed CLI operation persists the resulting Session, so evaluation can be inspected, rolled back, resumed, or driven by a different scheduler.
Tool calls from one assistant response form one executor batch. Successful
calls within that batch replace the current RequestExecutor step while
accumulating pending_results, so they do not create one frame per tool. When
the batch completes, Phi creates a new RequestProvider frame whose delta
commits the assistant message and every tool result. A runtime failure always
creates an empty-delta Failed frame over the step that failed; rollback
therefore restores the exact executor progress immediately before the failure.
Persistent shell and REPL processes use the same HeadlessTerminal job API at
every boundary. The phi headlessterm exec, access, and close commands call
the Rust HeadlessTerminal::exec_job, access_job, and close_job operations
directly. Their JSON outputs preserve the library return shapes:
(Option<JobHandle>, JobInfo), JobAccessResult, and JobInfo, respectively.
The built-in bash_job, job_interact, and job_close tools also use this API.
Their tool-result envelope preserves the same handle, output, truncation, wait,
and job-status semantics, including the distinction between exited jobs,
settled output, screen samples, and elapsed waits. CLI users and agents therefore
observe the same terminal lifecycle instead of separate terminal abstractions.
The full architecture, runtime semantics, CLI workflows, private protocols, and development invariants are maintained in the Phi Book.
This repository distributes a Codex-compatible skill for teaching other agents
to use Phi and build complex Python or shell harnesses. It covers external-tool
routing, workflows, Session persistence, HeadlessTerminal jobs, and the runtime
semantics needed to preserve correctness. See
skills/phi-agent-runtime/ for the skill and its
progressively loaded references.
An agent can load that directory from GitHub and invoke it as $phi-agent-runtime.
The distributed skill assumes only an installed phi executable on the user's
machine; the book is optional maintainer documentation, while the skill is the
standalone CLI integration and harness guide.
- Composable state: Session JSON can cross process boundaries through stdin/stdout or remain in a file for repeated commands.
- Auditable execution: one atomic
stepis the common evaluation unit behind the higher-level schedulers. - Persistent terminals: jobs can survive individual tool calls and support GDB, shells, and other interactive processes.
- Selectable command execution: Phi can use the host shell, enter an already-running container, or pass commands through a custom runner program.
- Structural rollback: the S-expression-style step structure makes rollback an explicit Session transformation.
For example, an existing container can be used as the command environment:
docker run -dit --name phi-test-run docker.io/library/alpine /bin/sh
phi yolo work.session --user "list files" --container phi-test-runA custom runner receives its fixed arguments followed by the complete command
as one final argument. Agent commands apply the same runner to the built-in
bash_job tool:
phi yolo work.session --runner bash --runner-arg=-c --user "list files"--runner and --container are mutually exclusive. Repeat --runner-arg for
programs that need more than one fixed argument.
Example OpenAI-compatible setup:
export PHI_PROVIDER=openai_chat
export PHI_MODEL=gpt-5
export PHI_KEY=your_api_keyOr use ~/.phi/config.yml with the typed YAML schema:
model:
name: gpt-5
provider:
kind: openai_chat
api_key: your_api_key
runtime:
# Omit this field to use Phi's built-in prompt.
# Set it to "" to commit an explicitly empty system message.
system: ""Use --config FILE to replace the config location supplied by Phi Home for a
command. PHI_* environment variables are applied last and therefore override
either YAML source.
Phi always requires an explicit session target. State-transforming commands use
- to select stdin/stdout as the session transport; session delete is a
file-management operation and accepts only a file path.
phi session new - |
phi run - --user "Hello" |
phi step -In pipeline mode:
-explicitly selects stdin/stdout- stdin is parsed as session JSON
- stdout emits the updated session JSON
phi session new -creates the initial Session- empty stdin is rejected instead of creating an implicit Session
Passing a file path selects file-backed session mode:
phi session new work.session
phi run work.session --user "Hello"
phi run work.session --user "follow up"In file-backed mode:
- the file must already exist; create it explicitly with
phi session new SESSION - an empty file is rejected instead of being treated as a new Session
- appended input and every committed Agent step are atomically written back to the same file
- readers see either the previous complete Session or the new complete Session
- user and assistant input must be passed through explicit message arguments
Main commands:
phi step SESSIONphi run SESSIONphi yolo SESSIONphi session state SESSIONphi session next SESSION --providerphi session replace SESSION --providerphi session tool-result SESSION (--json JSON|--text TEXT|--json-file FILE|--text-file FILE)phi session rollback SESSIONphi session append SESSION (--user TEXT|--assistant TEXT)phi headlessterm exec|access|closephi doctorphi session new SESSIONphi session history SESSION [--view]phi session delete SESSIONphi home new|pack|unpack
Examples:
phi session new work.session
phi step work.session --user "Inspect the repository"
phi run work.session --quiet --user "Summarize the bug"
phi yolo work.session --user "Keep going until done"
phi session state work.session
phi session next work.session --provider
phi session replace work.session --provider
# When state reports `request_executor`, resolve its next call externally:
phi session tool-result work.session --text "external tool output"
phi session tool-result work.session --json-file large-result.json
phi session rollback work.session
phi doctor
phi session history work.session
# Human-readable echo-style transcript:
phi session history work.session --viewFor explicit stdio composition, use - as the session target:
phi session append - --user "piped" < work.session |
phi session rollback - |
phi session state -HeadlessTerminal commands expose the library job API as JSON:
phi headlessterm exec --wait-ms 1000 -- sh -lc 'printf ready'
phi headlessterm exec --runner bash --runner-arg=-c -- 'printf runner-ready'
phi headlessterm access JOB_HANDLE --wait-ms 1000
phi headlessterm access JOB_HANDLE --data 'continue' --write-only
phi headlessterm close JOB_HANDLEPhi mounts a concrete PhiHome before building the runtime.
Home resolution:
--home PATHwins if provided- a directory path is mounted as a local home
- a sqlite home file such as
.phihomeis mounted directly - without
--home, Phi checkscwd/.phifirst, then falls back to the user home location
Phi can manage both directory homes and packed sqlite homes:
phi home new .phi
phi home pack .phi -o my.phihome
phi home unpack my.phihome -o unpacked.phi
phi --home my.phihome doctorPhi includes built-in governance modules for:
- step budgets
- tool execution limits
- model retry boundaries
- loop guard
- automatic context compaction
Auto-compact triggers when rendered provider-visible history approaches the configured context limit. Compact is still a normal step transition, so failures remain visible in session state and can be resumed by later scheduler steps.
Builtin tool execution is part of the same runtime step model. An assistant
message contains its tool calls directly. The current RequestExecutor keeps
the assistant and completed pending_results; neither is committed to history
until the complete tool batch produces the next RequestProvider frame.
runstops at the next boundary.yolocontinues through Phi's default failed-session recovery path.session stateexplains the current serialized eval state as structured JSON without building a runtime.doctorreports initialized runtime status, system prompt, home, and exposed tools.
Workspace aliases are defined in .cargo/config.toml.
Build examples:
cargo build-linux-x64-static
cargo test-linux-x64-static
cargo build-windows-x64-static
cargo test-windows-x64-static
cargo build-macos-arm64-release
cargo test-macos-arm64-releaseInstall helpers currently install the workspace binary locally:
cargo install-linux-x64-static
cargo install-windows-x64-static
cargo install-macos-arm64-releaseOr through xtask directly:
cargo run -p xtask -- install --target x86_64-unknown-linux-musl --offlineThe CI workflow builds Linux, Windows, and macOS artifacts.
Current packaged release archives are named after the repository, while their contents remain product-focused under phi/, including:
- the
phibinary - the workspace
README.md assets/phi-logo.svgskills/phi-agent-runtime/- bundled
.phi/content when present in the repository
Archives are published as:
phi-agent-linux-x64.tar.gzphi-agent-windows-x64.zipphi-agent-macos-arm64.tar.gz
Recommended release flow:
- regular
pushandpull_requestruns only build and test - pushing a version tag like
v0.1.0builds artifacts and publishes them to this repository's GitHub Release - if you need to republish an existing tag manually, run
workflow_dispatchand fill inrelease_tag

