Skip to content

fix(integrations): dispatch Amp via execute mode - #4581

Open
hmohammadi wants to merge 1 commit into
github:mainfrom
hmohammadi:fix/4580-amp-execute-dispatch
Open

hmohammadi wants to merge 1 commit into
github:mainfrom
hmohammadi:fix/4580-amp-execute-dispatch

Conversation

@hmohammadi

Copy link
Copy Markdown

Description

Fixes #4580. Part of the audit in #2416.

AmpIntegration never overrode build_exec_args(), so it inherited the generic implementation from MarkdownIntegration (base.py:1062), which emits -p <prompt> --model <model> --output-format json. None of those three flags exist in the Amp CLI, so every workflow command:/prompt: step targeting Amp aborted at argument parsing before the agent ran:

$ amp -p "hello" --model gpt-5 --output-format json
Error: error: unknown option '-p'
$ echo $?
1

Amp's non-interactive entry point is -x/--execute, and its structured-output flag is --stream-json (valid only alongside --execute), so this dispatches through those instead:

$ uv run python -c "from specify_cli.integrations.amp import AmpIntegration; print(AmpIntegration().build_exec_args('hello', model='gpt-5', output_json=True))"
['amp', '--execute', 'hello', '--stream-json']

Verified against amp --help (v0.0.1789372854-ge954c8):

Flag previously sent In the Amp CLI? Amp's actual flag
-p <prompt> No -x, --execute [message]
--model <model> No none (see below)
--output-format json No --stream-json

On model: it is deliberately dropped rather than remapped. Amp exposes no model-selection flag. -m/--mode takes an agent mode (low/medium/high/ultra, or a plugin mode) which "controls the model, system prompt, and tool selection" — it is not a model identifier, so forwarding the caller's model onto it would silently select the wrong thing. This is the one judgement call in the diff; happy to change it if maintainers prefer a different mapping.

On flag order: SPECKIT_INTEGRATION_AMP_EXTRA_ARGS is applied before --execute, because --execute [message] takes the prompt as an optional inline value — appending between the two would consume the prompt as the operator's flag value.

Same fix shape as the existing one-off overrides for opencode (#2409) and goose (#3781); follows the OpencodeIntegration.build_exec_args() pattern.

Testing

  • Tested locally with uv run specify --help
  • Ran existing tests with uv sync && uv run pytest
  • Tested with a sample project (if applicable)

Added 4 regression tests to tests/integrations/test_integration_amp.py (previously a stub with no build_exec_args coverage). All 4 fail on main with '-p' != '--execute' and pass with this change; the file's 22 tests pass in full.

tests/test_agent_config_consistency.py: 28 passed.

tests/integrations/test_extra_args.py, test_base.py, test_integration_base_markdown.py — the shared machinery this override calls into (_apply_extra_args_env_var, _resolve_executable, the MarkdownIntegration base): 119 passed, 1 skipped.

Full-suite context, stated plainly: on this machine (Windows 11, Python 3.14.7) main already reports 182 failed / 7694 passed / 189 skipped before this change. Every failure is environmental — 105 bash/parity and 63 symlink tests, on a box with no symlink privilege — and none are in tests/integrations/test_integration_amp.py. Of the 18 baseline failures under tests/integrations, all 18 are symlink tests. A full tests/integrations run against this branch was still in progress at the time of writing; I will post the before/after comparison as a comment when it completes.

End-to-end against the real Amp CLI (npx @sourcegraph/amp, v0.0.1789372854-ge954c8) on Windows 11: the previously generated argv exits 1 at parsing with unknown option '-p', while the argv this PR generates is accepted and proceeds to Amp's device-login prompt (this machine has no AMP_API_KEY, so execution stops there rather than at flag parsing).

AI Disclosure

  • I did use AI assistance (describe below)

Investigation, patch and tests were written with Claude Code; I reviewed them and ran every command quoted above on my own machine. The Amp flag surface was verified against amp --help from the installed binary, not from model recall.

Fixes github#4580.

`AmpIntegration` never overrode `build_exec_args()`, so it inherited
`MarkdownIntegration`'s generic `-p <prompt> --model <model>
--output-format json`. None of those flags exist in the Amp CLI, so every
workflow `command:`/`prompt:` step targeting Amp aborted at argument
parsing with `error: unknown option '-p'` before the agent ever ran.

Amp's non-interactive entry point is `-x/--execute`, and its structured
output flag is `--stream-json` (valid only alongside `--execute`), so
this dispatches through those.

`model` is deliberately dropped rather than remapped: Amp exposes no
model-selection flag. `-m/--mode` takes an agent mode (low/medium/high/
ultra or a plugin mode), not a model identifier, so forwarding the
caller's model onto it would silently select the wrong thing.

Extra args from `SPECKIT_INTEGRATION_AMP_EXTRA_ARGS` are applied before
`--execute` because the flag takes the prompt as an optional inline
value; appending between the two would consume the prompt as the
operator's flag value.

Same fix shape as the one-off overrides for opencode (github#2409) and goose
(github#3781). Part of the audit in github#2416.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X8QcZkxX87sSjsfUzBRm9h
@hmohammadi
hmohammadi requested a review from mnriem as a code owner September 14, 2026 12:09
@mnriem mnriem added the triage-nice-to-have Verdict: evidence-backed fix or greenlit feature — land after review label Sep 14, 2026
@hmohammadi

Copy link
Copy Markdown
Author

Following up on the test note in the description — the full tests/integrations run against this branch has finished, so here is the before/after comparison.

main (d848fb4) this branch
failed 18 18
passed 2873 2873
skipped 22 22

The failing set is identical — same 18 node IDs, verified by diffing the sorted FAILED lines from both runs. No test changes state in either direction.

All 18 are symlink tests, failing because this machine (Windows 11, no symlink privilege) cannot create the symlinks they set up — e.g. test_shared_template_refresh_preflights_before_writing calls os.symlink() and expects Refusing to overwrite symlinked. They are unrelated to this change, which touches only AmpIntegration.build_exec_args().

Targeted results on this branch:

  • tests/integrations/test_integration_amp.py — 22 passed (the 4 new regression tests plus the 18 inherited MarkdownIntegrationTests cases)
  • tests/integrations/test_extra_args.py, test_base.py, test_integration_base_markdown.py — 119 passed, 1 skipped (the shared machinery this override calls into)
  • tests/test_agent_config_consistency.py — 28 passed

For reference, the whole suite on main on this machine before any change: 182 failed / 7694 passed / 189 skipped, of which 105 are bash/parity and 63 symlink. Environment-specific, and CI is the authority here rather than my box.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

triage-nice-to-have Verdict: evidence-backed fix or greenlit feature — land after review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Amp dispatch sends -p/--model/--output-format — none of these exist in the Amp CLI

2 participants