strix/tests
Ahmed Allam 58df71d3db
fix(agents): let an agent wait on what it already said (#1020)
* let an agent wait on what it already said

An agent that answers in plain text is nudged to call a tool, and the only tool
that hands control back takes a required message. So it says the same thing
twice: once as text the user has already read, once as the argument it had to
supply to stop. Seen on a run whose whole instruction was "hi" - a greeting, then
the same greeting again through respond_to_user.

message is optional now. The nudge arms the tool with the text that was
delivered and says not to repeat it, so an agent that has said its piece can park
on it with an empty call. Anything it does want to add it passes normally.

Parking still cannot leave the user on silence: an empty call is refused unless
something was actually said, and the arming is single use - execution clears it
as soon as a turn ends any other way.

The interactive prompt now also says to answer and stop in one respond_to_user
call, which is what avoids the nudge in the first place.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* drop the worked example from the interactive prompt

"the user greeted you, asked something you can answer outright, or you need a
decision" was the run I had been reading, written into a rule that holds
whatever the reason. The rule is that replying and stopping is one call; listing
occasions only invites the model to check whether this is one of them.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* drop the arming flag; an empty message just waits

Passing the delivered text from execution into the tool, and refusing an empty
call without it, was machinery guarding against an agent parking having said
nothing. That leaves the user looking at "waiting for your reply" with a cursor
in front of them - they type. It does not need a mechanism.

What is left is the default on message, and the nudge saying the text already
landed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* only offer waiting on words that were written

The nudge told every agent its text had already been delivered, but it fires
whenever a turn leaves the agent running, and a turn can end with no tool call
and no text at all - _final_output_preview has carried <none> and <empty>
branches all along. An agent that said nothing was being invited to wait on an
answer the user never received, leaving them at a bare prompt.

It now reads the turn: waiting on what was said is offered only when something
was, and otherwise the agent is told plainly that the user has read nothing and
to send its message.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* leave the continuation nudge alone

Rewording it meant asserting from the outside whether the agent had spoken, and
the nudge fires whenever a turn leaves the agent running - text or no text. The
agent knows which it did without being told, so the guidance belongs in its
prompt, where the condition is its own to read.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* say it in the nudge, where the agent is reading

An agent stranded by the nudge reasons off the nudge. Told only to call
respond_to_user, it supplies a message, and since it has just answered in plain
text that message is the same answer again. The system prompt saying otherwise
sits thousands of tokens earlier and loses.

The clause goes on the line the agent acts on: call respond_to_user, with no
message if it has already said it. That reads true whatever the turn did,
including one that produced no text, because the agent is the one who knows
which — nothing here has to work it out from the outside.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-09 00:57:16 +03:00
..
__init__.py Add configurable token / cost usage limits (#576) 2026-06-22 11:17:08 -04:00
test_agent_factory_shell.py feat(context): spill oversized tool output into the sandbox workspace (#882) 2026-07-26 14:42:22 -07:00
test_agent_factory_tool_arguments.py fix(tools): accept both the string and structured form of every tool argument (#957) 2026-08-01 18:53:24 -07:00
test_agent_tool_registration.py refactor(tools): split wait_for_message into respond_to_user + wait_for_agents 2026-08-02 02:15:51 +03:00
test_api_spec.py feat: support API specs and Postman collections as targets (#866) 2026-08-03 21:07:44 -07:00
test_api_spec_targets.py feat: support API specs and Postman collections as targets (#866) 2026-08-03 21:07:44 -07:00
test_auth_cli.py Sign in with a ChatGPT subscription for inference (#854) 2026-07-24 15:41:19 -07:00
test_cli_target_list.py feat(tui): replace Textual with a Go/Bubble Tea interface (#941) 2026-08-03 19:23:07 -07:00
test_codex_auth.py feat(tui): replace Textual with a Go/Bubble Tea interface (#941) 2026-08-03 19:23:07 -07:00
test_codex_streaming.py Sign in with a ChatGPT subscription for inference (#854) 2026-07-24 15:41:19 -07:00
test_compaction.py fix(llm): pass LLM_EXTRA_HEADERS through ModelSettings so they reach the agent loop (#937) 2026-07-29 19:38:06 -07:00
test_config_loader.py feat(runtime): mount local targets instead of copying them in (#958) 2026-08-02 07:45:10 -07:00
test_context_budget.py fix(llm): avoid auth during ChatGPT lookup 2026-07-31 03:45:41 +03:00
test_cost_tracking.py feat(tui): replace Textual with a Go/Bubble Tea interface (#941) 2026-08-03 19:23:07 -07:00
test_dedupe_model.py fix(llm): pass LLM_EXTRA_HEADERS through ModelSettings so they reach the agent loop (#937) 2026-07-29 19:38:06 -07:00
test_disable_streaming.py fix(llm): cap the tool calls one assistant response may queue (#977) 2026-08-06 00:06:59 +03:00
test_docker_client_delete.py fix(runtime): swallow torn-down docker socket in sandbox delete() (#721) 2026-07-10 00:13:35 -04:00
test_e2e_budget_lifecycle.py refactor(tools): split wait_for_message into respond_to_user + wait_for_agents 2026-08-02 02:15:51 +03:00
test_execution.py fix(agents): let an agent wait on what it already said (#1020) 2026-08-09 00:57:16 +03:00
test_execution_transient_retry.py fix: pre-v1-style lifecycle resilience — mailbox delivery, uniform revival, unexitable runner, waiting timeout, broader retries, crash-safe identity (#923) 2026-08-01 11:17:08 -07:00
test_fenced_code.py refactor: move strix/viewer under strix/interface 2026-07-26 13:11:14 -07:00
test_go_tui_runtime.py feat(tui): replace Textual with a Go/Bubble Tea interface (#941) 2026-08-03 19:23:07 -07:00
test_hooks.py feat(runtime): graduated wrap-up warnings, budget reserve, and interactive budget pause/continue (#893) 2026-07-26 20:37:14 -07:00
test_inputs.py feat(tui): replace Textual with a Go/Bubble Tea interface (#941) 2026-08-03 19:23:07 -07:00
test_install_script.py Add Linux ARM64 standalone release support (#886) 2026-07-26 16:27:02 -07:00
test_list_reports.py feat(reporting): add read-only list_reports + get_report tools (#889) 2026-07-26 14:05:53 -07:00
test_llm_extra_headers.py fix(llm): apply LLM_EXTRA_HEADERS on native OpenAI route even without a custom base 2026-07-30 04:13:25 +03:00
test_local_sources.py feat(tui): replace Textual with a Go/Bubble Tea interface (#941) 2026-08-03 19:23:07 -07:00
test_model_retry.py Sign in with a ChatGPT subscription for inference (#854) 2026-07-24 15:41:19 -07:00
test_models.py Sign in with a ChatGPT subscription for inference (#854) 2026-07-24 15:41:19 -07:00
test_notes.py feat(reporting): add read-only list_reports + get_report tools (#889) 2026-07-26 14:05:53 -07:00
test_optional_deps.py fix(providers): declare bedrock + vertex extras and add provider import-error hints (#588) 2026-07-07 10:24:49 -04:00
test_output_store.py feat(context): spill oversized tool output into the sandbox workspace (#882) 2026-07-26 14:42:22 -07:00
test_packaging.py feat(tui): replace Textual with a Go/Bubble Tea interface (#941) 2026-08-03 19:23:07 -07:00
test_provider_hints.py fix(providers): match google submodule imports and walk full exception chain 2026-07-10 07:21:47 -07:00
test_proxy_client.py strip transfer encoding (#820) 2026-07-20 21:56:34 -04:00
test_report_pdf.py refactor: move strix/viewer under strix/interface 2026-07-26 13:11:14 -07:00
test_report_writer.py fix(reports): safe-fence markdown PoC export and share fence helpers 2026-07-25 13:09:57 -07:00
test_reporting_fields.py feat(report): keep dependency findings from distinct manifests separate in dedupe 2026-08-06 02:20:46 +03:00
test_reporting_tool.py fix: calibrate vulnerability severity to demonstrated impact 2026-08-03 23:40:32 +03:00
test_respond_to_user.py fix(agents): let an agent wait on what it already said (#1020) 2026-08-09 00:57:16 +03:00
test_runner_rate_limit.py fix(core): recover from hallucinated tool names instead of ending the scan 2026-08-04 06:14:54 +03:00
test_runner_root_prompt.py fix(core): recover from hallucinated tool names instead of ending the scan 2026-08-04 06:14:54 +03:00
test_sarif.py feat(report): SARIF 2.1.0 emitter for CI / code-scanning integration (#626) 2026-07-03 10:43:31 -04:00
test_sarif_stride.py feat(report): tag SARIF rules with STRIDE legs derived from CWE (#708) 2026-07-06 21:19:53 -04:00
test_secret_files.py Create credential files with owner-only permissions (#945) 2026-08-03 19:36:59 -07:00
test_session_entries.py feat(runtime): mount local targets instead of copying them in (#958) 2026-08-02 07:45:10 -07:00
test_skill_dir_extension.py expand firebase storage rules coverage (#1002) 2026-08-06 23:22:06 -07:00
test_state_repo_context.py fix(report): omit SARIF provenance for multiple repos (#726) 2026-07-10 09:41:18 -04:00
test_stream_idle_timeout.py fix(llm): abandon a model stream that stops producing events (#978) 2026-08-06 00:07:14 +03:00
test_tool_call_ids.py fix(llm): cap the tool calls one assistant response may queue (#977) 2026-08-06 00:06:59 +03:00
test_tool_call_limits.py fix(llm): cap the tool calls one assistant response may queue (#977) 2026-08-06 00:06:59 +03:00
test_tui_backend_controller.py fix(tui): make the mount prompt clickable, and skip the mount instead of abandoning the scan (#1015) 2026-08-08 22:34:02 +03:00
test_tui_backend_server.py feat(tui): replace Textual with a Go/Bubble Tea interface (#941) 2026-08-03 19:23:07 -07:00
test_tui_protocol_conformance.py feat(tui): replace Textual with a Go/Bubble Tea interface (#941) 2026-08-03 19:23:07 -07:00
test_tui_resume_history.py test(tui): correct the nudge the internal-turn test asserts (#1016) 2026-08-08 22:34:45 +03:00
test_unknown_tool_recovery.py fix(core): recover from hallucinated tool names instead of ending the scan 2026-08-04 06:14:54 +03:00
test_unraisable_filter.py feat(tui): replace Textual with a Go/Bubble Tea interface (#941) 2026-08-03 19:23:07 -07:00
test_update_check.py Add Linux ARM64 standalone release support (#886) 2026-07-26 16:27:02 -07:00
test_usage_subscription.py Sign in with a ChatGPT subscription for inference (#854) 2026-07-24 15:41:19 -07:00
test_viewer.py Scope viewer session cookie to the bound port (#922) 2026-07-27 20:37:54 -04:00
test_viewer_auth.py refactor: move strix/viewer under strix/interface 2026-07-26 13:11:14 -07:00
test_viewer_runs_gating.py refactor: move strix/viewer under strix/interface 2026-07-26 13:11:14 -07:00
test_wait_dedupe.py fix(agents): collapse repeated waits queued inside one model turn (#979) 2026-08-06 00:07:30 +03:00