feat: FormData support, custom field names, direct API targeting for Gandalf + persistent API key config#53
Merged
andrebyrd-odingard merged 5 commits intomainfrom Apr 16, 2026
Conversation
…Gandalf + persistent API key config - Add body_format, prompt_field, extra_fields to TargetConfig - build_body_for_format() supports formdata/custom mode with .data= dispatch - _fire_via_agent_endpoint() switches between .json= and .data= based on format - CLI: --body-format, --prompt-field, --extra-field on scan/live/alec-export - Persistent config: ~/.argus/argusrc with argus config set/get/list/delete - resolve_agent_api_key() + resolve_llm_api_key() read CLI > env > config file - 352 tests pass, lint clean Architecture: James, Security Features: Mark
Contributor
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…c config write - FormData now uses files= for true multipart/form-data (not x-www-form-urlencoded) - list_all() returns raw key names (agent_api_key) not section-prefixed (keys.agent_api_key) - Config file written atomically via os.open() with 0o600 — no world-readable window QA/QC Testing: Jamie
The default return in build_body_for_format() silently dropped extra_fields when prompt_field was 'message' (the default). Now all code paths include extra_fields when provided. QA/QC Testing: Jamie
Devin Review: live and alec-export silently ignored --extra-field values without '=' separator. Now prints a warning matching scan command behavior. QA/QC Testing: Jamie
2 tasks
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.
Summary
Adds three capabilities needed for ARGUS to scan non-standard AI targets like Gandalf:
FormData body format —
_fire_via_agent_endpoint()can now sendmultipart/form-datarequests (data=) instead of JSON (json=) whenbody_format="formdata"is set on the target config.build_body_for_format()gains support forformdataandcustomformats with configurable prompt field names and extra static fields.CLI options for body negotiation —
--body-format,--prompt-field, and--extra-fieldflags added toscan,live, andalec-export. Example Gandalf usage:Persistent config (
src/argus/config.py) — newargus config set/get/delete/list/pathcommands backed by~/.argus/argusrc(TOML, 0600 perms). API keys resolve with priority: CLI flag → env var → config file. This replaces the need toexport ANTHROPIC_API_KEY=...every session.Additional changes in
prompt_injection.py:answerkey first (Gandalf returns{"answer": "..."})Review & Testing Checklist for Human
build_body_for_format("formdata")actually produces correct FormData — the function returns adictwhich is then passed asdata=to httpx. Confirm httpx sends this asmultipart/form-dataand notapplication/x-www-form-urlencoded(httpx usesdata=for form-encoded;files=is needed for true multipart). This is the most critical correctness question — Gandalf may require one or the other.argus config set anthropic_api_key sk-ant-...end-to-end — verify the file is created at~/.argus/argusrcwith 0600 permissions, and that a subsequentargus scanpicks up the key without--agent-api-keyor env var.gandalf-api.lakera.ai(not a 405 or format error).data.get("answer", ...)in prompt_injection.py doesn't break existing targets — this changes the JSON field extraction priority for ALL targets, not just Gandalf. Targets that have ananswerfield with different semantics could be affected.scan/live/alec-exportwith inconsistent error handling (onlyscanwarns on malformed values). Acceptable for now but should be extracted to a helper.Notes
prompt_injectionagent is wired to usebody_format/prompt_field/extra_fields. Other agents still use their default HTTP dispatch. This is intentional — prompt injection is the primary agent that fires at chat endpoints.config.pymodule (228 lines) has no dedicated unit tests. The 352 existing tests pass but don't exercise config file read/write/permissions.argus_config._config_path()(private function) is referenced in CLI display code — minor code smell.Link to Devin session: https://app.devin.ai/sessions/8b0c5ca873934d77aa254157cc41924c
Requested by: @andrebyrd-odingard