LM Tools
Dapper exposes a small set of public language model tools for launching, inspecting, and controlling Python debug sessions from agents and other tool-driven workflows.
This page documents the important runtime behavior that is easy to miss from the JSON schemas alone.
Public Tool Surface
The current public tools are:
dapper_clidapper_python_diagnosticsdapper_python_environmentdapper_python_autofixdapper_python_formatdapper_python_project_modeldapper_python_renamedapper_python_symboldapper_python_typecheckdapper_launchdapper_statedapper_executiondapper_evaluatedapper_breakpointsdapper_variabledapper_session_info
Common Rules
- Most tools accept an optional
sessionId. - When
sessionIdis omitted, Dapper resolves the active Dapper debug session. - Many Python-oriented tools also accept an optional
searchRootPathto anchor the workspace folder used for tool execution when multiple workspace roots or nested projects are present. - Tools do not fall back to arbitrary non-Dapper sessions.
- Thread routing for
dapper_stateanddapper_executionremains controlled by the tool inputthreadId; the CLI does not add a separate thread-selector grammar.
dapper_python_environment
dapper_python_environment reports the selected Python environment and the
current Ty/Ruff tooling view for the workspace.
Important behavior:
- It is read-only and does not require an active debug session.
- It reports Python interpreter selection, search roots, Ty availability, Ruff availability, and Ty/Ruff config-file discovery.
searchRootPathcan be used to anchor venv discovery and config discovery to a nested project root.
dapper_python_diagnostics
dapper_python_diagnostics reports structured Python diagnostics for the
current workspace or for a selected file set.
Important behavior:
- It is read-only and does not require an active debug session.
- Ruff and Ty diagnostics are normalized into a shared schema with file/position, code, message, source, and backend-specific metadata.
- Backend coverage is reported explicitly, so agents can see when one backend produced diagnostics and the other was unavailable or failed.
filesnarrows the backend invocation to selected paths.limitbounds the number of normalized diagnostics returned while preserving the total count and truncation state.
dapper_python_autofix
dapper_python_autofix runs Ruff autofix for the current workspace or for a
selected file set.
Important behavior:
- It is a mutating tool: by default it applies fixable Ruff edits.
- Set
apply: falseto preview the Ruff diff without changing files. - The result reports whether files changed and returns diff output in preview mode.
dapper_python_format
dapper_python_format runs Ruff formatting for the current workspace or for a
selected file set.
Important behavior:
- It is a mutating tool: by default it applies formatting edits.
- Set
apply: falseto preview the Ruff formatting diff without changing files. - The result reports whether files changed and returns diff output in preview mode.
dapper_python_imports
dapper_python_imports runs Ruff-backed import hygiene actions for the current
workspace or for a selected file set.
Important behavior:
- It is a mutating tool: by default it applies changes.
modesupportscleanup,organize, andall(default).cleanupremoves unused imports with Ruff'sF401fix path.organizeruns Ruff's import-sorting path.- Set
apply: falseto preview the diff without changing files.
dapper_python_project_model
dapper_python_project_model reports a structured Python workspace model for
the current workspace or a selected search root.
Important behavior:
- It is read-only and does not require an active debug session.
- It reports search roots, source roots, test roots, config files, and package boundaries using bounded filesystem heuristics.
- It also returns the selected Python interpreter summary from the shared environment snapshot so agents can relate the project model to the active environment.
searchRootPathcan be used to anchor project-model discovery to a nested project root.
dapper_python_typecheck
dapper_python_typecheck runs Ty-backed type checking for the current
workspace or for a selected file set.
Important behavior:
- It is read-only and does not require an active debug session.
- It returns only Ty diagnostics, normalized into the same shared schema used
by
dapper_python_diagnostics. - When Ty provides richer semantic context, diagnostics may also include
typeInfoanddiagnosticContextfields with declared or inferred types, notes, related locations, and backend rule metadata. filesnarrows the Ty invocation to selected paths.limitandoffsetsupport paginating normalized diagnostics while preserving the total count and truncation state.- The result also includes
completionStatusandoutputBudgetso agents can distinguish a fully returned result from a paged, truncated, or failed one. - When Ty is unavailable, the backend status is reported explicitly instead of silently returning an empty success result.
Example request:
{
"files": ["app.py"],
"limit": 1,
"offset": 1,
"pathFilter": "source"
}
Example paged response:
{
"status": "complete",
"completionStatus": "partial",
"limit": 1,
"offset": 1,
"totalDiagnostics": 3,
"outputBudget": {
"requestedLimit": 1,
"appliedLimit": 1,
"requestedOffset": 1,
"appliedOffset": 1,
"returnedItems": 1,
"totalItems": 3,
"truncated": true,
"nextOffset": 2
},
"diagnostics": [
{
"source": "ty",
"code": "invalid-return-type",
"message": "Return type does not match returned value: expected `str`, found `Literal[42]`",
"typeInfo": {
"declaredType": "str",
"inferredType": "Literal[42]",
"symbolKind": "function",
"source": "ty"
},
"diagnosticContext": {
"summary": "Invalid Return Type",
"explanation": "Return type does not match returned value: expected `str`, found `Literal[42]`",
"rule": "invalid-return-type",
"code": "invalid-return-type"
}
}
]
}
dapper_python_symbol
dapper_python_symbol resolves definition, references, implementations, or
hover information for a symbol occurrence in a Python file.
Important behavior:
- It is read-only and does not require an active debug session.
- It is location-based: provide
file,line, and optionallycolumnfor an existing symbol occurrence. - It uses VS Code language feature providers, so the actual provider may be Ty, Pylance, or another active semantic backend.
- The result reports Ty availability as the preferred semantic backend for the workspace, but VS Code does not expose which extension satisfied the request.
actionsupportsdefinition,references,implementations, andhover.limitandoffsetcan page definition, reference, implementation, or hover results, andoutputBudgetreports the returned window and next offset.- Hover results preserve the raw
contentsarray and may additionally include derivedtypeInfo,signatures, anddocumentationfields when the hover payload contains enough structure to extract them safely.
Example request:
{
"action": "hover",
"file": "examples/sample_programs/advanced_app.py",
"line": 8,
"column": 1,
"limit": 1,
"offset": 0
}
Example paged hover response:
{
"action": "hover",
"status": "complete",
"completionStatus": "partial",
"count": 1,
"outputBudget": {
"requestedLimit": 1,
"appliedLimit": 1,
"requestedOffset": 0,
"appliedOffset": 0,
"returnedItems": 1,
"totalItems": 2,
"truncated": true,
"nextOffset": 1
},
"results": [
{
"kind": "hover",
"contents": [
"python\n(method) def add_data(\n self: Self@DataProcessor,\n category: str,\n items: list[Any]\n) -> None",
"Add data to the processor."
],
"typeInfo": {
"declaredType": "def add_data( self: Self@DataProcessor, category: str, items: list[Any] ) -> None",
"inferredType": "None",
"symbolKind": "method",
"source": "ty"
},
"signatures": [
{
"label": "def add_data( self: Self@DataProcessor, category: str, items: list[Any] ) -> None",
"parameters": [
{ "name": "self", "kind": "positional-or-keyword", "type": "Self@DataProcessor", "optional": false },
{ "name": "category", "kind": "positional-or-keyword", "type": "str", "optional": false },
{ "name": "items", "kind": "positional-or-keyword", "type": "list[Any]", "optional": false }
],
"returnType": "None"
}
],
"documentation": {
"format": "plaintext",
"summary": "Add data to the processor.",
"docstring": "Add data to the processor."
}
}
]
}
dapper_python_rename
dapper_python_rename runs semantic rename for a symbol occurrence in a Python
file.
Important behavior:
- It is a mutating tool: by default it applies the resulting workspace edit.
- Set
apply: falseto preview the rename result without changing files. - It returns a normalized summary of file edits so agents can inspect the rename impact even when applying it.
- The input is location-based: provide
file,line(1-based), and optionallycolumn(1-based) for the symbol occurrence.columnmay be omitted to use the provider's default location resolution. - It supports an optional
searchRootPathto anchor workspace folder discovery when the workspace has multiple roots or nested projects. - It uses VS Code language feature providers, so the actual rename provider may be Ty, Pylance, or another active semantic backend.
- The result reports Ty availability as the preferred semantic backend for the workspace, but VS Code does not expose which extension satisfied the request.
dapper_cli
dapper_cli is a pdb-style command interface over the public LM tools. It
keeps common debugging actions short while preserving the underlying structured
tool semantics.
Command Model
- Commands can be chained with
;and run left to right. - Chained execution stops on the first parse or runtime error.
- Completed commands still return partial results even when a later command fails.
- Frame navigation updates a wrapper-managed
frameIndex, and laterprint,locals,globals, andinspectcalls use that selected frame.
Supported commands:
help/hrunlaunchsessionsinfoinspectstatediffpauserestartcontinue/cnext/nstep/sfinishquit/qbreak/bbreakscleardisableenableprint/pwhere/btlocalsglobalslist/lupdownframe
Launch Commands
run is the short form for launching the active Python file and waiting for the
first stop.
launch exposes the richer dapper_launch surface.
Supported forms:
launch
launch file app.py
launch module package.cli
launch config My Launch Config
Supported launch flags:
--cwd PATH--env KEY=VALUE--path PATH--python PATH--venv PATH--stop-on-entry--no-stop-on-entry--just-my-code--no-just-my-code--subprocess--wait-- ARG...
Launch rules:
launchwith no target usestarget.currentFile = true.- Exactly one target form is allowed: implicit current file,
file,module, orconfig. runstays restricted to cases where no Dapper session is already active.launchmay start an additional Dapper session even when another Dapper session is already active.--ends launch-option parsing and passes all remaining tokens through to the debuggee asargs.
Examples:
launch module package.cli --cwd examples --wait -- --help --verbose
launch file app.py --python .venv/bin/python --no-stop-on-entry
Inspection and State Commands
sessionslists tracked Dapper sessions.info [SESSION_ID]returns metadata for the selected or specified session.inspectmaps todapper_variableand is intended for structured values.statemaps todapper_statewithmode: snapshot.diff [CHECKPOINT]maps todapper_statewithmode: diff.printremains the focused scalar expression path throughdapper_evaluate.
Breakpoint Commands
break TARGETadds a breakpoint.break TARGET if EXPRcreates a conditional breakpoint.break TARGET log MESSAGEcreates a logpoint.breakslists breakpoints.breaks FILEfilters to one file.breaks FILE:LINEfilters to one line through the underlyingdapper_breakpointsline filter.
Breakpoint target resolution order:
- Explicit file path
- Unique Python filename stem in the workspace
- Function name in the selected session's current call stack
dapper_launch
Use dapper_launch to start a new Dapper Python debug session for a file,
module, current editor, or named launch configuration.
Important behavior:
- Omit
targetto use the active Python file. - Provide exactly one target:
currentFile,file,module, orconfigName. dapper_launchprefers an explicitpythonPathorvenvPath, then falls back to the configured or discovered workspace environment.- Dapper may inject itself through
PYTHONPATHinstead of installing into the selected workspace interpreter. - Set
waitForStop: truewhen the next tool call needs a paused frame. - The result now includes
readinessandreadyToContinueso callers can tell whether breakpoint registration has settled before trying to resume. - The result also includes
trackedSessionsBeforeLaunch,trackedSessions, andwarnings. Treat a non-emptywarningslist as a signal to inspect existing sessions and terminate stale ones before continuing the investigation. - When another tracked session already targets the same
programormodule,warningsincludes a stronger same-target warning because duplicate repros on the same fixture are the easiest way to leave accidental sessions behind. - When
waitForStop: truesucceeds,readiness.lifecycleStatetypically ends up atstoppedandreadyToContinueshould betrueunless breakpoint registration failed.
dapper_state
dapper_state reads Python debugger state in either snapshot or diff mode.
Important behavior:
snapshotmode returns stop reason, location, call stack, locals, globals, and thread state.snapshotreads throughStateJournal.getSnapshot().- Right after a stop event, the journal may still hold a placeholder snapshot
with empty
callStack,locals, andglobalsuntil the follow-up custom request completes. - If that follow-up request fails, Dapper keeps the last successful snapshot and
may include
_adapterError.
dapper_execution
dapper_execution controls debug execution.
Important behavior:
- Use
report: truewithnext,stepIn,stepOut, orcontinuewhen you want one call to both advance execution and return the next stop plus diff. stopped: falsemeans the session did not report a new stop before the wait ended, or the target thread/session terminated instead.- Without
report: true, the tool returns acknowledgement-style statuses such asrunning,pausing,restarting, andterminating. - Use
action: terminateas the standard cleanup path after an investigative launch when you do not intend to keep the session alive.
dapper_evaluate and dapper_variable
These tools execute expressions in the debuggee process.
Use dapper_evaluate for focused scalar expressions and dapper_variable for
structured values.
Important behavior:
- Both tools run in the chosen
frameIndexand can have side effects. dapper_evaluateaccepts eitherexpressionorexpressions, but executes them as a batch in the selected frame.dapper_variableexpands dicts, lists, tuples, and public object attributes to the requested depth.
dapper_breakpoints
dapper_breakpoints manages the VS Code breakpoint set and synchronizes it with
the live adapter when a Dapper session is available.
Important behavior:
action: listreports the current VS Code source breakpoints.action: listacceptsfileas a file filter andlinesas an optional line filter.- With an active Dapper session,
listmerges adapter verification state into the returned records when that state is definitive. verificationState: pendingmeans the adapter has not yet resolved whether a breakpoint binds to executable code. It is not the same as a rejection.action: addupdates VS Code and also sendssetBreakpointsimmediately so the adapter sees the new breakpoint set without waiting for later editor events.
dapper_session_info
dapper_session_info is the single public session-inspection tool. It returns
session metadata together with debugger readiness and breakpoint lifecycle
details.
Important behavior:
- It can list tracked sessions even when more than one exists.
- Only the active session is guaranteed to have a live
DebugSession. - A targeted lookup with
sessionIdreturns the richer single-session payload; an untargeted call returns{ sessions: [...] }for enumeration. - The payload includes
lifecycleState,breakpointRegistrationComplete,lastTransition,lastError,readyToContinue, and grouped breakpoint counts plus details. - Breakpoint details are split into
breakpoints.details.accepted,breakpoints.details.pending, andbreakpoints.details.rejected. readyToContinue: falseusually means one of three things: breakpoint verification is still pending, one or more breakpoints were rejected, or the adapter recorded a readiness error.- Non-active tracked sessions can still be reported from the journal, but they may have older snapshot state than the active VS Code session.
Readiness Troubleshooting
Use dapper_session_info first when the debugger appears stalled or reports an
unexpected status.
Common interpretations:
lifecycleState: waiting-for-breakpointsmeans Dapper is still waiting for adapter verification results.breakpoints.rejected > 0means at least one breakpoint did not bind to executable code; checkbreakpoints.details.rejected[*].verificationMessage.lastErrormeans the journal or adapter recorded a concrete readiness or snapshot failure and should be surfaced directly instead of treating the session as generically unknown.- A failed
continueorstepwith a timeout message usually meansconfigurationDonenever observed breakpoint verification reaching a terminal state.
Recommended Workflow While Paused
- Call
dapper_session_infoif you need to identify the session. - Confirm
readyToContinueand inspect any pending or rejected breakpoints. - Call
dapper_statewithmode: snapshotto understand the current stop. - Use
dapper_variablefor structured objects anddapper_evaluatefor focused scalar expressions. - Use
dapper_executionwithreport: trueto advance execution while preserving checkpoint context. - Use
dapper_breakpointswithaction: listandaction: add/remove/clearwhen checking whether a breakpoint is present but not yet verified. - When the investigation is complete, call
dapper_executionwithaction: terminateunless you intentionally want to keep the session around for follow-up work.