Skip to main content

interactive embedded shell for agents

Project description

aihook

Pause a running Python script and let an AI agent inspect and manipulate its live state — without restarting.

PyPI version Code style: black Python 3.11+


The problem

Some scripts are expensive to restart. A Selenium browser session takes 60 seconds to reach the interesting state. An ML pipeline loads a 4 GB model before the first inference. A scraper re-authenticates and paginates through 200 pages before getting to the data you care about.

When debugging these scripts, the standard loop — edit, restart, wait, observe — is brutal. Each hypothesis costs a full restart.

What aihook does

Drop one call into your script:

from aihook import agent_hook
agent_hook()   # script pauses here; HTTP REPL starts

The script pauses at that line. An HTTP server starts on a free port. The calling frame's variables are all live and accessible. An AI agent (or you) can then probe, manipulate, and test fixes against the real running state:

aihook 'browser.find_by_css(".comment__replies")'
aihook -f snippet.py        # run a multi-line snippet, edit, repeat
aihook --exit               # resume the script

Each probe takes 2–5 seconds instead of 60.


Real-world example

This is what a session looks like in practice. The script is a Selenium browser automation that was failing silently on every "show replies" button click:

# Start the slow script in the background
python fetch_comments.py --url "https://example.com/article" > aihook-host.log 2>&1 &

# Wait for it to reach agent_hook() — CLI validates pid + port, times out after 180s
# aihook: session found after 94.3s

# Probe the live DOM
aihook 'browser.find_by_css("[data-comment-id]")'
# -> []   ← the attribute does not exist

aihook 'browser.find_by_css("[id^=cid-]")'
# -> [<Element id="cid-4821">  ...  ]   ← found it

# Try the JS click that works despite the overlay
aihook -f snippet.py   # snippet tests execute_script("arguments[0].click()", btn)
# -> reply count went from 8 to 28

aihook --exit

Five probes. Zero restarts. A working script at the end.


Install

pip install aihook

Set up the AI agent skill

For Claude Code:

aihook --bootstrap --agent claude

For aider-desk:

aihook --bootstrap --agent aider

This installs SKILL.md (the agent's instruction file for using aihook) and creates a learnings/ directory where agent-accumulated tips are stored across sessions.


CLI reference

Command Description
aihook '<code>' Execute code; single expressions auto-print their repr()
aihook -f FILE Send contents of FILE (-f - reads from stdin)
aihook --exit Shut down the session and let the script resume
aihook --status Show whether a session is active (exits 0 if healthy)
aihook --clean Remove a stale lock file
aihook --wait N Wait up to N seconds for a healthy session (default: 180s)
aihook -p PORT Target a specific port (skips lock-file discovery)
aihook --lockfile PATH Use a custom lock-file path
aihook --bootstrap Install SKILL.md and create learnings directory

Exit code is non-zero if the remote code raised an exception or wrote to stderr.

Auto-print: if the submitted code is a single expression, its repr() is printed automatically. For multi-line snippets, use explicit print() — auto-print only applies to single expressions.


How it works

agent_hook() does three things:

  1. Captures the calling frame's globals and locals into a shared namespace.
  2. Starts a minimal HTTP server on a free port in 5001–5101 (configurable).
  3. Writes ./aihook-lock.yml containing pid, port, cwd, and start_time.

The CLI reads the lock file to find the port, POSTs code to /execute, and prints the result. The server shuts down on exit(), the lock file is removed, and the host script resumes.

The banner printed on startup includes the source file and line number where agent_hook() was called — useful when a script has multiple hook points.


One caveat: local variable write-back

Rebinding a local variable of the calling function from inside the REPL does not write back to that function's fast-locals. This is the same limitation as pdb:

# Inside my_function():
x = 1
agent_hook()
print(x)   # still prints 1 even if you did `x = 2` via aihook

Mutating mutable objects works fine:

my_list.append(99)           # visible in the host afterwards
my_dict["key"] = "new"       # same
obj.attribute = "changed"    # same

When testing a fix, mutate containers or attributes rather than rebinding local names.

(Of course, this is documented for agents in SKILL.md.)


Optional environment variables

Variable Effect
AIHOOK_PORT=NNNN Force a specific port
AIHOOK_PORT_RANGE=LO-HI Override the default 5001-5101 range

Development

git clone <repo-url>
cd aihook
pip install -e .
pytest

The learnings directory (created by --bootstrap) accumulates session tips in ~/.local/share/aihook/learnings/ (Linux) or the platform equivalent. Add topic_<name>.md files there to share domain-specific knowledge across agent sessions.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aihook-0.1.8.tar.gz (31.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aihook-0.1.8-py3-none-any.whl (20.6 kB view details)

Uploaded Python 3

File details

Details for the file aihook-0.1.8.tar.gz.

File metadata

  • Download URL: aihook-0.1.8.tar.gz
  • Upload date:
  • Size: 31.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.4

File hashes

Hashes for aihook-0.1.8.tar.gz
Algorithm Hash digest
SHA256 525f4aa75f0f0fc4e7ea8900e325bae602280e4747b7745bf4293ffe4ff3ccf0
MD5 164cb392c67109bd04465e6de5560b5c
BLAKE2b-256 d5d5772f7ba6e68fb4c4252048f5cc687c7978e29c87877f49dcc2d40a8faa05

See more details on using hashes here.

File details

Details for the file aihook-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: aihook-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 20.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.4

File hashes

Hashes for aihook-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 cf9ad7a7ceb600acf735406303b7450f904d1aeb6ebe4a40156fd8256ab0f3c6
MD5 292165ad77c3169cb4a39b40726d8e32
BLAKE2b-256 4f1c154aab981ffb96ce7c7bd31874bad65479698137c8eade47b4d157b3954d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page