Skip to main content

oy-cli

PyPI

Small local AI coding CLI for your shell. It can inspect files, search content, fetch public docs, and run commands in the current workspace.

oy-cli is intentionally OpenResponses-first: provider integrations are expected to support the Open Responses / OpenAI Responses API shape, and oy is optimized around that interface rather than chat-completions compatibility layers.

Quick start

uv tool install oy-cli
oy "add docstrings to public functions"
oy chat
oy chat --agent plan
oy chat --continue-session
oy run --resume 20260325
oy audit "focus on authentication"
oy audit-logic "focus on authentication logic"

Common tasks

oy "inspect the main module and suggest improvements"
OY_ROOT=./my-project oy "fix the failing tests"
echo "update the changelog" | OY_NON_INTERACTIVE=1 oy
oy chat
oy chat --agent plan
oy chat --agent accept-edits
oy chat --continue-session
oy run --resume 20260325 "finish the refactor"
oy audit [focus]
oy audit-logic [focus]
oy renovate-local
oy ralph "prompt"
oy model [filter]
oy --help

In chat, /ask <question> is research-only: no bash, no file changes, but public webfetch is still allowed. It is no-write rather than no-network.

Audit workflow

oy audit now runs a resumable 3-phase repo audit automatically:

  • phase1 plan — Python uses sloc plus tiktoken counts to build a SLOC-ranked 64k-token chunk plan and normalizes any existing ISSUES.md into inbox format before review starts
  • phase2 review — Python reads each chunk, gives the model only that chunk plus the phase2 audit system prompt and ASVS/grugbrain context, and keeps findings append-only via search and inbox_append scoped to ISSUES.md
  • phase3 summary — switch to the phase3 audit system prompt, consume the inbox, and rewrite ISSUES.md so the 10-15 most important issues keep detail and the rest become concise

oy audit-logic is a stricter variant for reviewing actual software behaviour:

  • phase1 skips docs and lockfiles from the review backlog
  • phase2 builds chunk context from code and behaviour-shaping config, stripping comments and docstrings where possible before sending context to the model
  • limited search inside audit review also defaults to excluding docs and lockfiles so the audit budget stays on executable logic, trust boundaries, authz/authn checks, state changes, parsing, persistence, and network behaviour
  • phase3 keeps the final ISSUES.md summary focused on behavioural bugs and runtime-impacting configuration after deduping the inbox

Normal oy audit is still useful when docs, comments, or dependency metadata may matter. oy audit-logic is for concentrating hard on control flow and real runtime behaviour.

Each audit mode keeps its own resumable state file in the session dir so long-running audits can resume cleanly without colliding. After each chunk, Python verifies that ISSUES.md changed; if not, it retries with a smaller chunk instead of pretending review progress happened. The per-chunk path is append-only inbox mode, so phase2 avoids repeatedly merging the full report on every chunk.

.tmp/ is still used for things like oy renovate-local reports, but audit progress itself now lives in the session cache.

Agent profiles

oy now supports simple built-in agent profiles inspired by familiar coding-agent modes:

  • default — normal tool approvals
  • plan — read-only exploration and planning
  • accept-edits — auto-approves file edits, but not shell commands
  • auto-approve — auto-approves all available tools

Examples:

oy chat --agent plan
oy run --agent accept-edits "rename the helper and update callers"
oy chat --agent auto-approve

Session continuation

Saved chat sessions can now be resumed from the CLI:

  • oy chat --continue-session — continue the most recent saved session
  • oy run --continue-session "next task" — continue the most recent session, then run one prompt
  • oy run --resume <name-or-number> "next task" — resume a specific saved session
  • in chat, /save [name] and /load [name] still work

Saved sessions now keep both the transcript and the active agent profile.

Design goals

  • keep the codebase small and auditable
  • expose a narrow built-in tool set
  • keep provider support behind thin shims
  • target providers that implement the Open Responses / OpenAI Responses API surface
  • start fresh by default for one-shot runs
  • make approvals and checkpoints explicit when they matter

Prompt text and tool descriptions live in oy_cli/session_text.toml. Core modules are oy_cli/runtime.py, oy_cli/agent.py, oy_cli/cli.py, oy_cli/tools.py, and oy_cli/providers.py. Contributor workflow lives in CONTRIBUTING.md.

Configuration

Environment variables

Variable Purpose
OY_MODEL Override the model for this session (model or shim:model)
OY_SHIM Force a shim when the model name is bare
OY_NON_INTERACTIVE Set to 1 to disable approval and prompt pauses
OY_UNATTENDED_LIMIT Agent deadline window, such as 1h, 30m, or 3600s
OY_RALPH_LIMIT Ralph deadline window, such as 3h, 90m, or 3600s
OY_ROOT Run against a different workspace
OY_SYSTEM_FILE Append extra system instructions
OY_CONFIG Override config path (default: ~/.config/oy/config.json)
OY_DEBUG Enable debug logging
OY_YOLO Start with all tool approvals enabled
OY_MAX_CONTEXT_TOKENS Override transcript and tool context budget
OY_MAX_BASH_CMD_BYTES Override max accepted bash command size

Config file

{"shim": "openai", "model": "glm-5"}

Only model and shim are persisted in config. Session continuation uses per-session files under ~/.config/oy/sessions/. Selection order is OY_MODEL, then saved config, then the first-run picker. OY_SHIM only changes backend choice when the model name is bare or no model has been saved yet.

From local testing, glm-5 and kimi-k2.5 are good defaults.

Installation

uv tool install oy-cli  # preferred
pip install oy-cli      # alternative

Requirements

  • Python 3.13+
  • bash
  • Provider credentials for a backend that supports the Open Responses / OpenAI Responses API shape (for example via OpenAI credentials, Codex auth, Copilot auth, OpenCode auth, or AWS credentials for Bedrock Mantle)

Development

Use uv for local development. Contributor workflow lives in CONTRIBUTING.md.

uv sync
uv run ruff check .
uv run pytest -q
uv run pytest tests/test_providers.py -q
uv run oy --help
uv build

Authentication

OpenAI or other Open Responses-compatible endpoint:

export OPENAI_API_KEY=...
export OPENAI_BASE_URL=https://your-endpoint.example/v1  # optional

Copilot and Codex credentials are discovered automatically when available.

Bedrock Mantle:

export OY_SHIM=bedrock-mantle
export AWS_PROFILE=my-profile
export AWS_REGION=ap-southeast-2

oy loads models from GET /models and targets the Open Responses / OpenAI Responses API at POST /responses. Provider support in oy is intentionally centered on that API shape. Providers that do not support /responses fail with a clear error instead of falling back to legacy chat-completions behavior.

Local model workflow

Run any OpenAI-compatible server on localhost. By default oy probes:

  • local-8080 at http://127.0.0.1:8080/v1 (typical llama-server port)
  • local-11434 at http://127.0.0.1:11434/v1 (typical Ollama port)

Examples:

OY_MODEL=local-8080:qwen3.5 oy chat
# or save it once:
oy model local-11434:qwen3.5
oy chat

You can also target any localhost port with the local-<port> shim form.

Troubleshooting

  • Missing credentials — start a local OpenAI-compatible server on 127.0.0.1:8080 or 127.0.0.1:11434, set OPENAI_API_KEY, sign in with codex, authenticate gh for Copilot, run opencode auth, or configure AWS credentials / SSO for Bedrock Mantle.
  • stdin is not a TTY — piping input disables ask; set OY_NON_INTERACTIVE=1 to make that explicit.
  • AWS SSO session is stale — run aws sso login --use-device-code --no-browser.

Security

oy can run shell commands and modify files with your permissions. bash also inherits your environment, so git, cloud, and SSH credentials visible to your shell are visible to the command.

Recommended:

  • run in a repo or workspace you trust
  • mount only the directories you need in containers
  • avoid exposing long-lived secrets in the environment
  • use /ask when you want no-write research mode
  • review generated changes before shipping

Protections include workspace-bound file tools, public-only webfetch, and default credential flows for supported providers. For provider authors, the intended compatibility target is Open Responses compliance rather than ad hoc OpenAI-compatible subsets. oy still acts with your user permissions, so treat generated shell commands and file edits as local code execution.

License

Apache License 2.0

Metadata

Release files for oy-cli 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for oy-cli 0.6.0
File Size Uploaded
oy_cli-0.6.0.tar.gz 131.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for oy-cli 0.6.0
File Interpreter ABI Platform
oy_cli-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 234.3 kB

Release files / oy_cli-0.6.0.tar.gz

Download URL oy_cli-0.6.0.tar.gz
Size 131.4 kB
Tags Source
SHA-256 checksum
How to use checksums
61682f90e835f0b326918ce88a127362541ac7b25c3dcd490edc6e95d7f0e2bb
BLAKE2b-256 checksum
How to use checksums
a89d43677c254f0b3ba72e3dddf800499a062dc624cb920a5fc6835dcf54d0d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 22, 2026.

Transparency log

Release files / oy_cli-0.6.0-py3-none-any.whl

Download URL oy_cli-0.6.0-py3-none-any.whl
Size 102.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1bcdffd9f1fe11ef55809c4a7e4f0d2edc768fe0addd8635b2c7165815f398f0
BLAKE2b-256 checksum
How to use checksums
5c6f433123cbf58ef19d676297418ee1292e3c3c508de5f7e8ee55db7ea376eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.6.0 This release

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.0

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page