Commit Graph
158 Commits
Author SHA1 Message Date
Alex Schapiro d3c42e5498 Wire vulnerability amendment callbacks 2026-08-19 21:53:49 +00:00
Alex Schapiro 9c1a0c9002 Refine vulnerability report amendments 2026-08-19 21:34:05 +00:00
Alex Schapiro 18556da0cd Add vulnerability report amendments 2026-08-19 21:28:10 +00:00
oyasumi 6f88b7d7d5 Require viewer session for run data 2026-08-19 15:25:57 -04:00
oyasumi 8d3693df8c Expose viewer host option 2026-08-19 15:25:57 -04:00
alex s 8ede419dcc handle resume tokens gracefully (#1097)
* Fix telemetry deltas for resumed runs

* Fix resumed telemetry duration
2026-08-17 16:55:27 -04:00
Ahmed Allam a46a60cf6a feat(reporting): require contextual CVSS and usage evidence on dependency reports 2026-08-17 14:35:21 +03:00
Ahmed Allam e442db9c93 Contextual CVSS as a full 8-metric breakdown, computed like a normal finding 2026-08-17 13:03:41 +03:00
Ahmed Allam 9c0d30a0d0 reporting: require the source-to-sink trace in reachability evidence, not just CVSS reasoning 2026-08-17 13:03:41 +03:00
Ahmed Allam 99e2d5d826 reporting: drop per-metric contextual CVSS reasoning, keep the summary 2026-08-17 13:03:41 +03:00
Ahmed Allam 310f310e28 feat(reporting): contextual CVSS environmental metrics on dependency reports 2026-08-17 13:03:41 +03:00
yoni-at-strix 8551339130 feat: place caller-provided files into the sandbox workspace (extra_files, --workspace-file) (#1085)
* add extra-files plumbing so orchestrators can drop single files into the sandbox workspace

* reject extra-file paths that collide with a local source tree

* add --workspace-file so CLI users can place files in the sandbox workspace

* reject repeated and control-character workspace paths

* revalidate persisted workspace files when resuming a run

* drop the workspace-file size limit
2026-08-14 16:43:08 -04:00
Alex Schapiro 8ca0c4a9b8 Fix LiteLLM cost model resolution 2026-08-12 17:26:00 +03:00
devin-ai-integration[bot] 174c16fa26 fix(llm): send OpenRouter app attribution on the request itself (#1045) 2026-08-10 11:24:02 -07:00
Ahmed Allam 649a2e2140 fix(llm): omit parallel_tool_calls on tool-less requests 2026-08-09 15:44:16 +03:00
Ahmed Allam 06b158d1fa fix(runner): settle child agents before closing sessions at wind-down (#1025) 2026-08-08 18:17:58 -07:00
Ahmed Allam c29eb73c7f fix(tools): coerce an empty-string list/dict argument to an empty container (#1024) 2026-08-08 16:58:30 -07:00
Ahmed Allam 72833b8e43 fix(runner): resume after a user interrupt instead of failing (#1023) 2026-08-08 16:44:12 -07:00
Ahmed Allam 1117ba6d4a fix(sessions): open a sqlite connection per operation, not per thread (#1022) 2026-08-08 16:20:01 -07:00
Ahmed Allam 53e4658d88 fix(todo): stop a todo plan failing on priority or duplicates (#1021) 2026-08-08 15:18:48 -07:00
Ahmed AllamandClaude Opus 4.8 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
Ahmed AllamandClaude Opus 4.8 0b9e029a5d test(tui): correct the nudge the internal-turn test asserts (#1016)
* correct the nudge the internal-turn test asserts

The test expected "ended the autonomous Strix run", which strix.core.execution
does not inject; it says "ended the autonomous run". The classifier was right and
the test was not, so the suite failed on main while the behaviour it guards was
fine.

The sentence is written inline in another module and copied by hand into the
classifier and again into the test, which is how it drifted. A second test now
reads it back out of that module's source, joining the adjacent string literals
its line wrapping leaves behind, and fails if either nudge is no longer injected
verbatim. Reworded one and it reports which nudge went missing and what a resumed
scan would do about it.

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

* read the nudges out of what the module can inject, not out of its text

Searching the source accepted the sentence anywhere in the file, so a stale copy
left behind in a comment would have kept the guard passing after the message it
guards had changed - the drift it exists to catch.

Parsing the module instead limits it to strings the code can actually inject.
Comments never reach the tree, docstrings are dropped as description rather than
behaviour, and adjacent literals are joined during parsing, which the line
wrapping needed and the regex was only approximating.

Checked by rewording the message and leaving the old wording in a comment: the
guard fails, where searching the text passed.

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-08 22:34:45 +03:00
Ahmed AllamandClaude Opus 4.8 b260a4ee38 fix(tui): make the mount prompt clickable, and skip the mount instead of abandoning the scan (#1015)
* make the working-directory prompt answer the mouse

Its Confirm and Cancel were drawn as buttons and did nothing when clicked: the
modal mouse handler had a case for every dialog except this one, so a click fell
through and the scan sat waiting on an answer the user believed they had given.
Only the keyboard could answer it.

The prompt is docked in a corner rather than centered, so it also needs its own
bounds; the centered ones every other dialog uses would have put the buttons in
the wrong place. Those bounds now come from the same placement cornerOverlay
draws with.

Two returns that hand back the model alongside a call that mutates it are now
sequenced explicitly. They work, but only because the compiler happens to
evaluate the call first, and one of them is what puts the prompt back in the
composer when the mount is declined.

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

* skip the mount instead of abandoning the scan

Declining the working-directory prompt threw the whole launch away and dropped
back to the start screen, which is a lot to lose for answering one question
about one directory. The two answers are now about the directory alone: mount it,
or run without it. The prompt is the whole of the input either way.

The buttons say which is which - Mount and Skip rather than Confirm and Cancel -
and the prompt says what skipping costs.

A run with neither target nor directory is a real run, so two things follow it.
It can be resumed: its instruction is what drives it, and that is in the run
record. And it tells the agent plainly that it has neither, because an agent
given no scope goes looking for the one it assumes it was meant to have.

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-08 22:34:02 +03:00
alex s 9dae76667b expand firebase storage rules coverage (#1002) 2026-08-06 23:22:06 -07:00
Ahmed Allam b69af37cb2 feat(report): keep dependency findings from distinct manifests separate in dedupe 2026-08-06 02:20:46 +03:00
Ahmed Allam 72cb15a20a feat(reporting): require repo-relative manifest_path on dependency CVE findings 2026-08-06 02:20:46 +03:00
Alex Schapiro 97336d53e4 feat(reporting): structured reachability evidence ladder for dependency CVE findings 2026-08-06 00:25:08 +03:00
devin-ai-integration[bot]andAhmed Allam 0abe82d622 fix(agents): collapse repeated waits queued inside one model turn (#979)
* fix(agents): collapse repeated waits queued inside one model turn

* fix(agents): state that one wait is enough in every prompt variant

---------

Co-authored-by: Ahmed Allam <ahmed39652003@gmail.com>
2026-08-06 00:07:30 +03:00
devin-ai-integration[bot]andAhmed Allam 6735a6f89e fix(llm): abandon a model stream that stops producing events (#978)
Co-authored-by: Ahmed Allam <ahmed39652003@gmail.com>
2026-08-06 00:07:14 +03:00
devin-ai-integration[bot]andAhmed Allam 8bd6c8e87a fix(llm): cap the tool calls one assistant response may queue (#977)
* fix(llm): cap the tool calls one assistant response may queue

* fix(llm): cap the subscription backend's responses too

---------

Co-authored-by: Ahmed Allam <ahmed39652003@gmail.com>
2026-08-06 00:06:59 +03:00
devin-ai-integration[bot]andAhmed Allam 68ea6fca65 fix(llm): keep tool-call ids unique so a recycled id can't erase history (#976)
Co-authored-by: Ahmed Allam <ahmed39652003@gmail.com>
2026-08-06 00:06:46 +03:00
devin-ai-integration[bot]andAhmed Allam 657aa5cbe6 feat(reporting): record transitive dependency chain on SCA findings (#971)
Co-authored-by: Ahmed Allam <ahmed39652003@gmail.com>
2026-08-04 12:34:52 -07:00
Anurag Mewar 6719a70611 feat: support API specs and Postman collections as targets (#866) 2026-08-03 21:07:44 -07:00
Ahmed Allam 3bcf3778f0 fix(core): settle a non-interactive agent's status before its exception unwinds
An exception escaping a non-interactive cycle re-raised before the status
handling, so a dying child stayed 'running' and its parent waited out the
timeout on a completion report the child could no longer send. Set the
terminal status and wake the parent on the way out too.
2026-08-04 06:14:54 +03:00
Ahmed Allam 4a455b1e62 fix(core): recover from hallucinated tool names instead of ending the scan
A tool call for a name Strix does not register raised ModelBehaviorError
from the SDK turn resolver, which nothing retries: the root agent's raise
tore down the whole scan and a sub-agent died before its status was set.
Opt into the SDK's tool_not_found_behavior="return_error_to_model" so the
unknown call comes back as a tool result and the agent self-corrects.

The setting landed in openai-agents 0.19.0, which requires openai>=2.45,
so both pins move.
2026-08-04 06:14:54 +03:00
Tech GuyandAhmed Allam 23f1d76d4c Create credential files with owner-only permissions (#945)
Co-authored-by: Ahmed Allam <ahmed39652003@gmail.com>
2026-08-03 19:36:59 -07:00
oyasumi 5bb9fe896b feat(tui): replace Textual with a Go/Bubble Tea interface (#941) 2026-08-03 19:23:07 -07:00
bearsyankees a51ca18666 fix: calibrate vulnerability severity to demonstrated impact 2026-08-03 23:40:32 +03:00
devin-ai-integration[bot]andAhmed Allam dbc427d816 feat(runtime): mount local targets instead of copying them in (#958)
Co-authored-by: Ahmed Allam <ahmed39652003@gmail.com>
2026-08-02 07:45:10 -07:00
Ahmed Allam b6cf156e95 fix(tools): tell a waiting parent when stop_agent stops its child 2026-08-02 15:43:43 +03:00
Ahmed Allam 002712284a fix(core): wake the parent when a child ends without a completion report 2026-08-02 15:43:43 +03:00
devin-ai-integration[bot]andAhmed Allam c240068c2c fix(tools): accept both the string and structured form of every tool argument (#957)
Co-authored-by: Ahmed Allam <ahmed39652003@gmail.com>
2026-08-01 18:53:24 -07:00
devin-ai-integration[bot]andAhmed Allam 2e7040240d feat(config): accept STRIX_REASONING_EFFORT=max for providers that support it (#956)
Co-authored-by: Ahmed Allam <allam@usestrix.com>
2026-08-01 17:10:01 -07:00
Ahmed Allam 1c1fa49961 refactor(tools): split wait_for_message into respond_to_user + wait_for_agents
One tool was doing three jobs (wait on the user, wait on other agents, and
- wrongly - wait for a long-running command), so the driver had to guess which
one an agent meant and used parent_id as the proxy: the root waits for a human,
everyone else waits for agents. That proxy is wrong, since the user can message
any agent from the TUI's agent tree.

Tool identity now carries the intent, and the coordinator records it as a
wait_kind that survives snapshot/restore:

  respond_to_user  -> wait_kind="user",   never auto-resumed (root or not)
  wait_for_agents  -> wait_kind="agents", auto-resumed on a 300s timer
  recovery exhaust -> wait_kind="stalled"

respond_to_user fuses the message and the yield into one call, so there is no
way to answer and then forget to stop - the two-step that gpt-4o-mini skipped
2/2 in live testing. Plain text still renders as before.

Auto-resume is also bounded now: an agent that re-parks after every timeout
burned a model turn every 300s for the rest of the scan (and, since parked
children notify their parent, spammed the parent's inbox on the same cycle).
After _MAX_IDLE_AUTO_RESUMES it stays parked until a real message arrives.
2026-08-02 02:15:51 +03:00
Ahmed Allam 742f382836 docs(core): correct the rationale for notifying a stalled child's parent
The user can message any agent from the TUI, not only the root, so the
justification is that the parent is an agent with no other way to learn
the child parked - not that the child has no human resumer.
2026-08-02 02:15:51 +03:00
Ahmed Allam 8f1bb64d16 fix(core): tell the parent when an interactive subagent parks
Parking is self-service only for the root, which the user is watching.
A parked child owes its parent a report it can no longer send, so the
parent would wait out its full timeout for nothing.
2026-08-02 02:15:51 +03:00
Ahmed Allam 6eec34df24 fix(core): persist the tool-call recovery counter across resumes
An exhausted agent parked in 'waiting' got a fresh nudge budget on every
600s auto-resume, so a wedged agent could nudge-park-nudge indefinitely.
Track the count on the coordinator, snapshot it, and reset it only on
real input or an explicit lifecycle tool.
2026-08-02 02:15:51 +03:00
Ahmed Allam f6f9469e00 fix(core): stop interactive runs stalling on a missing tool call
Interactive turns ended by plain text left the agent parked in 'waiting'
forever. Require an explicit lifecycle tool in both modes and nudge a
text-only turn back into a tool call, bounded by a recovery limit.
2026-08-02 02:15:51 +03:00
devin-ai-integration[bot] 5602bc23ca 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
alex s a9deb84260 fix(llm): surface structured provider refusals (#944)
* fix(llm): surface structured provider refusals

* fix(llm): settle refused autonomous agents
2026-07-31 10:57:42 -04:00