ipyant

A terminal IPython extension that adds Claude Agent SDK powered prompting

View the Project on GitHub AnswerDotAI/ipyant

DEV

Setup

Editable install:

pip install -e ipyant

Run tests:

cd ipyant
./tools/test.sh

Capture fresh Claude SDK shape samples:

cd ipyant
./tools/capture_samples.sh

The wrappers intentionally keep setup small:

File Map

Current Architecture

Prompt Flow

  1. Input starting with . is rewritten into %ipyant.
  2. IPyAIExtension.run_prompt() reconstructs recent code/output/note context from IPython history.
  3. Variable refs like $nameand shell refs like `!`cmd are injected above the prompt.
  4. ClaudeBackend.stream_turn() opens a fresh ClaudeSDKClient, optionally resumes a prior Claude session ID, and streams partial events.
  5. astream_to_stdout() renders the response through Rich in TTY mode and stores the final transcript text locally.

State Model

There are two layers of state:

ipyant uses:

If prompt history was restored from an explicit notebook load and provider_session_id is still missing, ipyant synthesizes a Claude transcript JSONL file once and resumes from that instead of replaying the full prompt history turn-by-turn.

Notebook save/load is explicit only:

There is no implicit startup.ipynb behavior.

Tools

The custom tool story is intentionally small:

python does not call back into InteractiveShell.run_cell*. It delegates to pyrun from safepyrun, looked up in shell.user_ns, matching the old ipycodex direct-call boundary and avoiding nested IPython cell execution.

The ipyant CLI loads safepyrun before ipyant, so normal terminal sessions get pyrun automatically.

Skills

Skills are Claude-native:

Samples

The samples/ directory exists so stream-shape spelunking does not need to be repeated.

Artifacts currently committed:

Those captures are useful when working on:

Tests

The test suite is intentionally small and integration-heavy.

Current coverage focuses on:

There is also one real Claude-side integration point in the tests: synthetic session files are verified through claude_agent_sdk.get_session_messages() rather than only through local mocks.

Notes