Prismer Python Debugpy logo

Prismer Python Debugpy

OrganizationPopular
Prismer-AI
prismer-python-debugpy

Debug Python: pdb REPL + debugpy remote (DAP).

Overview

PublisherPrismer-AI
RepositoryPrismerCloud
Skill nameprismer-python-debugpy
Stars
1.6K
Forks
17
Bundled files
2
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 2 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by Prismer-AI on GitHub. Read the source before you install it.

Installation

Install the Prismer Python Debugpy AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/Prismer-AI/PrismerCloud/tree/main/sdk/cloud/catalog/skills/prismer-python-debugpy
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/Prismer-AI/PrismerCloud.git /tmp/PrismerCloud
mkdir -p .claude/skills
cp -r /tmp/PrismerCloud/sdk/cloud/catalog/skills/prismer-python-debugpy .claude/skills/prismer-python-debugpy
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Prismer Python Debugpy in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Prismer Python Debugpy on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Prismer Python Debugpy is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Prismer execution contract

This is the uniquely named prismer-python-debugpy skill, adapted from Hermes. Use the actual tools exposed by the executing host; examples using terminal, process, delegate_task, vision_analyze or browser_* are not tool registrations. Missing dependencies do not hide this skill. Report command startup, version, account/permissions and task-specific live verification separately. Use task-owned artifact paths and existing user authorization; do not change shared accounts, Runtime/provider configuration, global security settings or unrelated work. See NOTICE.md and LICENSE for resource provenance. Runtime availability and upstream-entry suppression are owned by the integration layer.

Python Debugger (pdb + debugpy)

Overview

Three tools, picked by situation:

ToolWhen
breakpoint() + pdbLocal, interactive, simplest. Add breakpoint() in the source, run normally, get a REPL at that line.
python -m pdbLaunch an existing script under pdb with no source edits. Useful for quick poking.
debugpyRemote / headless / "attach to already-running process." Talks DAP, scriptable from terminal, works for long-lived processes (gateway, daemon, PTY children).

Start with breakpoint(). It's the cheapest thing that works.

When to Use

  • A test fails and the traceback doesn't reveal why a value is wrong
  • You need to step through a function and watch a collection mutate
  • A long-running process (hermes gateway, tui_gateway) misbehaves and you can't restart it
  • Post-mortem: an exception fired in prod-ish code and you want to inspect locals at the crash site
  • A subprocess / child (Python _SlashWorker, PTY bridge worker) is the actual bug site

Don't use for: things print() / logging.debug solve in under a minute, or things pytest -vv --tb=long --showlocals already reveals.

pdb Quick Reference

Inside any pdb prompt ((Pdb)):

CommandAction
h / h cmdhelp
nnext line (step over)
sstep into
rreturn from current function
ccontinue
unt Ncontinue until line N
j Njump to line N (same function only)
l / lllist source around current line / full function
wwhere (stack trace)
u / dmove up / down in the stack
aprint args of the current function
p expr / pp exprprint / pretty-print expression
display exprauto-print expr on every stop
b file:lineset breakpoint
b funcbreak on function entry
b file:line, condconditional breakpoint
cl Nclear breakpoint N
tbreak file:lineone-shot breakpoint
!stmtexecute arbitrary Python (assignments included)
interactdrop into full Python REPL in current scope (Ctrl+D to exit)
qquit

The interact command is the most powerful — you can import anything, inspect complex objects, even call methods that mutate state. Locals are read-only by default; use !x = 42 from the (Pdb) prompt to mutate.

Recipe 1: Local breakpoint

Easiest. Edit the file:

python
def compute(x, y):
    result = some_helper(x)
    breakpoint()           # <-- drops into pdb here
    return result + y

Run the code normally. You land at the breakpoint() line with full access to locals.

Don't forget to remove breakpoint() before committing. Use git diff or a pre-commit grep:

bash
rg -n 'breakpoint\(\)' --type py

Recipe 2: Launch a script under pdb (no source edits)

bash
python -m pdb path/to/script.py arg1 arg2
# Lands at first line of script
(Pdb) b path/to/script.py:42
(Pdb) c

Recipe 3: Debug a pytest test

Use raw pytest in a scoped test environment for an interactive debugger:

bash
# Drop to pdb on failure (or on any raised exception):
python -m pytest <exact-test-path> -x --pdb

# Drop to pdb at the START of the test:
python -m pytest tests/path/to/test_file.py::test_name --trace

# Show locals in tracebacks without pdb:
python -m pytest tests/path/to/test_file.py --showlocals --tb=long

The repository runner may capture output and cannot always support pdb. For an interactive session use a TTY and select one test, then rerun the actual canonical runner non-interactively for regression verification:

bash
source .venv/bin/activate
python -m pytest tests/foo_test.py::test_bar --pdb

Keep the test environment isolated; do not import shared production credentials.

Recipe 4: Post-mortem on any exception

python
import pdb, sys
try:
    run_the_thing()
except Exception:
    pdb.post_mortem(sys.exc_info()[2])

Or wrap a whole script:

bash
python -m pdb -c continue script.py
# When it crashes, pdb catches it and you're in the frame of the exception

Or set a global hook in a repl/jupyter:

python
import sys
def excepthook(etype, value, tb):
    import pdb; pdb.post_mortem(tb)
sys.excepthook = excepthook

Recipe 5: Remote debug with debugpy (attach to running process)

For long-lived processes: Hermes gateway, tui_gateway, a daemon, a process that's already misbehaving and can't be restarted clean.

Setup

bash
source <hermes-agent-repo>/.venv/bin/activate
pip install debugpy

Pattern A: Source-edit — process waits for debugger at launch

Add near the top of the entry point (or inside the function you want to debug):

python
import debugpy
debugpy.listen(("127.0.0.1", 5678))
print("debugpy listening on 5678, waiting for client...", flush=True)
debugpy.wait_for_client()
debugpy.breakpoint()       # optional: pause immediately once attached

Start the process; it blocks on wait_for_client().

Pattern B: No source edit — launch with -m debugpy

bash
python -m debugpy --listen 127.0.0.1:5678 --wait-for-client your_script.py arg1

Equivalent for module entry:

bash
python -m debugpy --listen 127.0.0.1:5678 --wait-for-client -m your.module

Pattern C: Attach to an already-running process

Needs the PID and debugpy preinstalled in the target's environment:

bash
python -m debugpy --listen 127.0.0.1:5678 --pid <pid>
# debugpy injects itself into the process. Then attach a client as below.

If attach is blocked by OS policy, do not lower global ptrace protections. Start a new task-owned process under debugpy, or ask the system owner for an approved debugging environment.

Connecting a client from the terminal

The easiest terminal-side DAP client is VS Code CLI or a small script. From inside Hermes you have two practical options:

Option 1: debugpy's own CLI REPL — not an official feature, but a tiny DAP client script:

Use the bundled scripts/dap_client.py (Python stdlib); resolve its directory from the installed skill, not cwd. With that directory on sys.path:

python
import socket
from dap_client import DapClient
with socket.create_connection(("127.0.0.1", 5678), timeout=5) as sock:
    client = DapClient(sock, timeout=5)
    client.request("initialize", {"adapterID": "python"})
    attach_seq = client.send("attach", {})
    client.wait(lambda p: p.get("event") == "initialized")
    # Configure the exact authorized source and line here.
    client.request("setBreakpoints", {"source": {"path": SOURCE},
                                     "breakpoints": [{"line": LINE}]})
    client.request("configurationDone")
    client.response(attach_seq)
    # Continue/step only the authorized target; disconnect when finished.
    client.request("disconnect", {"terminateDebuggee": False})

The transport handles EOF, timeout, size limits, events and request_seq matching. It is not a full IDE, and live debugpy handshake compatibility still needs a real session. Do not leave the target paused or enable remote/public listeners.

Option 2: Attach from VS Code / Cursor / Zed — if the user has one open, they can add a launch.json:

json
{
  "name": "Attach to Hermes",
  "type": "debugpy",
  "request": "attach",
  "connect": { "host": "127.0.0.1", "port": 5678 },
  "justMyCode": false,
  "pathMappings": [
    { "localRoot": "${workspaceFolder}", "remoteRoot": "<hermes-agent-repo>" }
  ]
}

Option 3: Ditch DAP, use remote-pdb — usually what you actually want from a terminal agent:

bash
pip install remote-pdb

In your code:

python
from remote_pdb import set_trace
set_trace(host="127.0.0.1", port=4444)   # blocks until connection

Then from the terminal:

bash
nc 127.0.0.1 4444
# You get a (Pdb) prompt exactly as if debugging locally.

remote-pdb is the cleanest agent-friendly choice when debugpy's DAP protocol is overkill. Use debugpy only when you actually need IDE integration.

Debugging Hermes-specific Processes

Tests

See Recipe 3. The wrapper captures subprocess output, so run pytest directly for interactive pdb.

run_agent.py / CLI — one-shot

Easiest: add breakpoint() near the suspect line, then run hermes normally. Control returns to your terminal at the pause point.

tui_gateway subprocess (spawned by hermes --tui)

The gateway runs as a child of the Node TUI. Options:

A. Source-edit the gateway:

python
# tui_gateway/server.py near the top of serve()
import debugpy
debugpy.listen(("127.0.0.1", 5678))
debugpy.wait_for_client()

Start hermes --tui. The TUI will appear frozen (its backend is waiting). Attach a client; execution resumes when you continue.

B. Use remote-pdb at a specific handler:

python
from remote_pdb import set_trace
set_trace(host="127.0.0.1", port=4444)   # in the RPC handler you want to trap

Trigger the matching slash command from the TUI, then nc 127.0.0.1 4444 in another terminal.

_SlashWorker subprocess

Same pattern — remote-pdb with set_trace() inside the worker's exec path. The worker is persistent across slash commands, so the first trigger blocks until you connect; subsequent slash commands pass through normally unless you re-arm.

Gateway (gateway/run.py)

Long-lived. Use remote-pdb at a handler, or debugpy with --wait-for-client if you're restarting the gateway anyway.

Common Pitfalls

  1. pdb under a parallel/output-capturing runner silently does nothing. You won't see the prompt, the test just hangs (true of pytest-xdist and of scripts/run_tests.sh's captured per-file subprocesses). Run pytest directly on a single file for interactive debugging.

  2. breakpoint() in CI / non-TTY contexts hangs the process. Safe locally; never commit it. Add a pre-commit grep as a safety net.

  3. PYTHONBREAKPOINT=0 disables all breakpoint() calls. Check the env if your breakpoint isn't hitting:

    bash
    echo $PYTHONBREAKPOINT
  4. debugpy.listen blocks only if you also call wait_for_client(). Without it, execution continues and your first breakpoint may fire before the client is attached.

  5. Do not change global ptrace policy; use a task-owned debugpy child.

  6. Threads. pdb only debugs the current thread. For multithreaded code, use debugpy (thread-aware DAP) or set threading.settrace() per thread.

  7. asyncio. pdb works in coroutines but await inside pdb requires Python 3.13+ or await from interact mode on older versions. For 3.11/3.12, use asyncio.run_coroutine_threadsafe tricks or !stmt-based awaits via asyncio.ensure_future.

  8. Repository runners may isolate HOME/credentials or capture output. Inspect the actual runner before choosing an interactive invocation. Do not import real API keys into a debug session; use a scoped test credential only when authorized.

  9. Forking / multiprocessing. pdb does not follow forks. Each child needs its own breakpoint() or set_trace(). For Hermes subagents, debug one process at a time.

Verification Checklist

  • After pip install debugpy, confirm: python -c "import debugpy; print(debugpy.__version__)"
  • For remote debug, confirm the port is actually listening: ss -tlnp | grep 5678
  • First breakpoint actually hits (if it doesn't, you likely have PYTHONBREAKPOINT=0, you're under a parallel/capturing runner, or execution finished before attach)
  • where / w shows the expected call stack
  • Post-debug cleanup: no stray breakpoint() / set_trace() in committed code
    bash
    rg -n 'breakpoint\(\)|set_trace\(|debugpy\.listen' --type py

One-Shot Recipes

"Why is this dict missing a key?"

python
# add above the KeyError site
breakpoint()
# then in pdb:
(Pdb) pp d
(Pdb) pp list(d.keys())
(Pdb) w                # how did we get here

"This test passes in isolation but fails in the suite."

bash
python -m pytest tests/the_test.py   # replace with the project's actual canonical runner
# For interactive debugging, or if it only fails WITH other tests:
source .venv/bin/activate
python -m pytest tests/ -x --pdb
# Now it pdb-traps at the exact failing test after state accumulated.

"My async handler deadlocks."

python
# Add at handler entry
import remote_pdb; remote_pdb.set_trace(host="127.0.0.1", port=4444)

Trigger the handler. nc 127.0.0.1 4444, then w to see the suspended frame, !import asyncio; asyncio.all_tasks() to see what else is pending.

"Post-mortem on a crash in an Ink child process / subprocess."

bash
PYTHONFAULTHANDLER=1 python -m pdb -c continue path/to/entrypoint.py
# On crash, pdb lands at the frame of the exception with full locals

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Prismer Python Debugpy AI skill do?

Debug Python: pdb REPL + debugpy remote (DAP).

Why use Prismer Python Debugpy on TypingMind?

Because you install it once and use it with any model. Prismer Python Debugpy is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Prismer Python Debugpy in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/Prismer-AI/PrismerCloud/tree/main/sdk/cloud/catalog/skills/prismer-python-debugpy. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Prismer Python Debugpy?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Prismer Python Debugpy?

As many as you like. As long as a model supports skills, you can use Prismer Python Debugpy with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Prismer Python Debugpy AI skill free?

Yes. It is published on GitHub by Prismer-AI under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇