Repository navigation
fix(integrations): map Pi JSON dispatch to --mode json - #5043
Merged
Merged
Conversation
PiIntegration inherited MarkdownIntegration.build_exec_args(), which appends --output-format json when output_json is true. Pi has no --output-format option: its parser keeps unknown long flags for extensions, and when no extension registers the flag, pi reports "Unknown option: --output-format" and exits 1 before the prompt is sent. This is reachable through dispatch_command(stream=False) when output_json is left unset (it then resolves to True), and through direct build_exec_args() calls. Override build_exec_args() to request --mode json, the flag Pi uses for JSONL events and the one the OMP integration already passes. The base requires_cli guard and argument order (EXTRA_ARGS before --model) are unchanged. docs/integrations/pi.md named the old flag and now names --mode json. Assisted-by: Claude Code (model: Claude Opus 5.5, autonomous) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The isolated fix matches Pi’s parser, preserves the dispatch contract, and includes focused regression coverage.
No open issues 🎉
What changed in this PR
Fixes Pi’s structured-output dispatch by using --mode json instead of the unsupported --output-format json.
Changes:
- Adds a Pi-specific argument builder while preserving existing dispatch behavior.
- Adds four regression tests and updates the integration documentation.
Tests were not rerun during this review.
| File | Description |
|---|---|
| tests/integrations/test_integration_pi.py | Covers text, JSON, model, and extra arguments. |
| src/specify_cli/integrations/pi/__init__.py | Overrides dispatch arguments to request Pi’s JSON mode. |
| docs/integrations/pi.md | Documents the correct structured-output flag. |
Review effort: Max
Collaborator
|
Thank you! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
PiIntegrationdoes not overridebuild_exec_args(), so it inheritsMarkdownIntegration.build_exec_args()(base.py#L1139-L1158), which appends--output-format jsonwhenoutput_jsonis true.Pi has no
--output-formatoption. It selects JSONL events with--mode json, and--modeaccepts onlytext,jsonandrpc(packages/coding-agent/src/cli/args.ts#L96-L110, documented indocs/cli.md#L43-L48). Any other long option is kept as a possible extension flag (args.ts#L249-L262). Once extensions are loaded, a flag that no extension registers becomes anUnknown optionerror (core/agent-session-services.ts#L99-L125), andpiexits 1 (main.ts#L916-L925) before it sends the prompt.71023aeis thev1.3.0tag, published as@earendil-works/pi-coding-agent@1.3.0, the current npmlatest. This reproduces without a provider account. WithHOMEandPI_CODING_AGENT_DIRpointing at empty directories (not logged in) andPI_OFFLINE=1 PI_SKIP_VERSION_CHECK=1 PI_TELEMETRY=0:The
--mode jsonrun gets past option parsing and writes its first JSONL record to stdout. It then exits 1 only because that empty agent directory has no credentials.The same failure through Spec Kit on
main(505781d), withpi1.3.0 onPATH:Reachability. The built-in workflow steps do not hit this. The
commandstep either streams, whereoutput_jsonis left asNoneand resolves tonot stream, i.e.False(base.py#L462-L463), or captures with an explicitoutput_json=False(step/command/__init__.py#L313-L319). Thepromptstep passesoutput_json=False(step/prompt/__init__.py#L248-L253). It is reached through the publicdispatch_command(..., stream=False)whenoutput_jsonis left unset (it then resolves toTrue), through directbuild_exec_args()calls (defaultoutput_json=True), and by extensions or other callers of those APIs.Fix. Override
build_exec_args()inPiIntegrationso structured output requests--mode json, the flag the OMP integration already passes (omp/__init__.py#L29-L53). The rest matches the base implementation: therequires_cliguard,-p <prompt>,SPECKIT_INTEGRATION_PI_EXTRA_ARGSbefore--model, and--model, which Pi accepts (args.ts#L117-L118). Unlike OMP, the prompt can stay right after-p: Pi's-ptakes the next argument as the message when it does not start with-or@(args.ts#L177-L183), and Spec Kit's dispatch prompts start with/. The change stays inside the Pi integration package, its test file, and its agent pagedocs/integrations/pi.md, which named--output-format json.Part of #2416, which lists Pi's inherited
pi -p "prompt" --model X --output-format jsonargv as unverified. Same shape as the Kimi Code fix in #5031.Testing
Tested locally with
uv run specify --helpRan existing tests with
uv sync && uv run pytest: run as.venv/bin/python -m pytest, results belowTested with a sample project (if applicable): see the first bullet below
Sample project:
specify init proj --integration pi --script sh --non-interactive, thendispatch_command('speckit.plan', 'x', stream=False)againstpi1.3.0. No provider account was used:PI_CODING_AGENT_DIRpoints at amodels.jsonfor a local OpenAI-compatible stub model, and itssettings.jsonsetsdefaultProjectTrust: "always"so Pi loads the project's.pi/prompts. Onmainit exits 1 with the error above. On this branch it exits 0 and stdout holds 15 JSONL events, fromsessiontoagent_settled; the user message in them is the renderedspeckit.plantemplate withxas its arguments. Without that trust setting (Pi's default isask), a non-interactive run skips the project's prompt templates and the model receives the literal/speckit.plan x; that is independent of this argv fix and not changed here.tests/integrations/test_integration_pi.pygets four argv tests: text mode,--mode json,--model, andSPECKIT_INTEGRATION_PI_EXTRA_ARGS. Run againstmain, the--mode jsonand extra-args cases fail with'--output-format' != '--mode'. All four pass on this branch..venv/bin/python -m pytest tests/integrations tests/workflows tests/test_agent_config_consistency.py -q: 3620 passed, 8 skipped.uvx ruff@0.15.0 check src tests: all checks passed.Full suite,
.venv/bin/python -m pytest tests -q(macOS, Python 3.14.3): 12517 passed, 376 skipped, 15 failed. All 15 are in 6 files this PR does not touch, and running those files on unmodifiedmainon the same machine fails the same 15 test IDs. 11 are composed-template cases intest_*_python_parity.py, whose bash variant runspython3fromPATH, and that interpreter has no PyYAML on this machine; they pass with the venv'spython3first onPATH. The other 4 are intest_workflow_step_submission.py, where the fakecurlgets a#!<sys.executable>shebang and the interpreter path on this machine contains a space.AI Disclosure
AI disclosure: Claude Code opened this PR on behalf of @RaycarlLei. Claude Code (model: Claude Opus 5.5, reasoning effort xhigh, autonomous agent mode with tool approvals bypassed) reproduced the bug against
pi1.3.0, read the Pi source for the accepted--modevalues and its unknown-option handling, wrote the override, the four tests and thedocs/integrations/pi.mdupdate, ran the checks above, wrote this description, and pushed the branch. A read-only Claude Code subagent on the same model cross-checked the description's claims and the diff, and its corrections were applied before posting. @RaycarlLei reviewed the diff and a draft of this description and approved posting, but did not re-run the tests or edit the text. The commit carriesAssisted-by: Claude Code (model: Claude Opus 5.5, autonomous).🤖 Generated with Claude Code