mirror of
https://github.com/usestrix/strix.git
synced 2026-08-22 11:02:08 +02:00
``@strix_tool`` was passing through every kwarg to ``@function_tool``
with the same defaults — zero Strix-specific value-add. The docstring
also still claimed terminal/browser/python tools opted into
``timeout_behavior="raise_exception"``, but those tools were all
deleted in the recent migrations.
- Replace 30 ``@strix_tool(...)`` callsites with ``@function_tool(...)``.
- Inline ``dump_tool_result(x)`` as ``json.dumps(x, ensure_ascii=False,
default=str)`` at all 64 callsites — no helper.
- Delete ``strix/tools/_decorator.py``.
Drive-by: gut dead package re-exports.
- ``strix/{agents,orchestration,tools}/__init__.py`` re-exported
symbols nobody imports via the package — every consumer uses deep
paths (``from strix.agents.factory import build_strix_agent``).
- The 8 ``strix/tools/<sub>/__init__.py`` re-exports only fed the
splat ``from .agents_graph import *`` etc. in the parent package
init, which is also gone now.
- Reduced to docstrings (or empty) so ``import strix.tools`` doesn't
drag every tool's transitive deps in eagerly.
Drive-by: drop dead helpers in ``runtime.session_manager``
(``cached_scan_ids``, ``_reset_cache_for_tests``) — zero callers since
``tests/`` was nuked in ``a6d578c``.
Verified all tool timeouts preserved (think=10, list_requests=120,
finish_scan=60, web_search=330) and ruff/mypy at baseline.
124 lines
4.9 KiB
Python
124 lines
4.9 KiB
Python
"""``web_search`` — Perplexity-backed security-focused web search."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import json
|
|
import os
|
|
from typing import Any
|
|
|
|
import requests
|
|
from agents import RunContextWrapper, function_tool
|
|
|
|
|
|
_SYSTEM_PROMPT = """You are assisting a cybersecurity agent specialized in vulnerability scanning
|
|
and security assessment running on Kali Linux. When responding to search queries:
|
|
|
|
1. Prioritize cybersecurity-relevant information including:
|
|
- Vulnerability details (CVEs, CVSS scores, impact)
|
|
- Security tools, techniques, and methodologies
|
|
- Exploit information and proof-of-concepts
|
|
- Security best practices and mitigations
|
|
- Penetration testing approaches
|
|
- Web application security findings
|
|
|
|
2. Provide technical depth appropriate for security professionals
|
|
3. Include specific versions, configurations, and technical details when available
|
|
4. Focus on actionable intelligence for security assessment
|
|
5. Cite reliable security sources (NIST, OWASP, CVE databases, security vendors)
|
|
6. When providing commands or installation instructions, prioritize Kali Linux compatibility
|
|
and use apt package manager or tools pre-installed in Kali
|
|
7. Be detailed and specific - avoid general answers. Always include concrete code examples,
|
|
command-line instructions, configuration snippets, or practical implementation steps
|
|
when applicable
|
|
|
|
Structure your response to be comprehensive yet concise, emphasizing the most critical
|
|
security implications and details."""
|
|
|
|
|
|
def _do_search(query: str) -> dict[str, Any]:
|
|
api_key = os.getenv("PERPLEXITY_API_KEY")
|
|
if not api_key:
|
|
return {
|
|
"success": False,
|
|
"message": "PERPLEXITY_API_KEY environment variable not set",
|
|
"results": [],
|
|
}
|
|
|
|
url = "https://api.perplexity.ai/chat/completions"
|
|
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
|
|
payload = {
|
|
"model": "sonar-reasoning-pro",
|
|
"messages": [
|
|
{"role": "system", "content": _SYSTEM_PROMPT},
|
|
{"role": "user", "content": query},
|
|
],
|
|
}
|
|
|
|
try:
|
|
response = requests.post(url, headers=headers, json=payload, timeout=300)
|
|
response.raise_for_status()
|
|
content = response.json()["choices"][0]["message"]["content"]
|
|
except requests.exceptions.Timeout:
|
|
return {"success": False, "message": "Request timed out", "results": []}
|
|
except requests.exceptions.RequestException as e:
|
|
return {"success": False, "message": f"API request failed: {e!s}", "results": []}
|
|
except KeyError as e:
|
|
return {
|
|
"success": False,
|
|
"message": f"Unexpected API response format: missing {e!s}",
|
|
"results": [],
|
|
}
|
|
except Exception as e: # noqa: BLE001
|
|
return {"success": False, "message": f"Web search failed: {e!s}", "results": []}
|
|
else:
|
|
return {
|
|
"success": True,
|
|
"query": query,
|
|
"content": content,
|
|
"message": "Web search completed successfully",
|
|
}
|
|
|
|
|
|
# Perplexity request timeout is 300s; give the SDK a slightly larger
|
|
# budget so the round-trip + JSON decode doesn't push us over.
|
|
@function_tool(timeout=330)
|
|
async def web_search(ctx: RunContextWrapper, query: str) -> str:
|
|
"""Real-time web search via Perplexity — your primary research tool.
|
|
|
|
Use it liberally for anything that's not in your training data:
|
|
|
|
- Current CVEs, advisories, and 0-days for a specific
|
|
service/version (``OpenSSH 9.6 RCE``, ``Jenkins 2.401.3 auth
|
|
bypass``).
|
|
- Latest WAF / EDR bypass techniques (``Cloudflare WAF SQLi
|
|
bypass 2025``, ``CrowdStrike Falcon evasion``).
|
|
- Tool documentation, flag references, payload galleries.
|
|
- Target reconnaissance / OSINT (company tech stack, leaked
|
|
credentials, exposed assets).
|
|
- Cloud-provider misconfiguration patterns
|
|
(Azure/AWS/GCP-specific attack paths).
|
|
- Bug-bounty writeups and security research papers.
|
|
- Compliance frameworks and CWE/CVSS guidance.
|
|
- Picking the right Python lib / Kali tool for a job (``best 2025
|
|
lib for JWT alg-confusion``).
|
|
- When stuck — looking up the exact error message, ``Access
|
|
denied`` quirks, kernel-specific local-privesc exploits.
|
|
|
|
Be specific: include version numbers, error messages, target
|
|
technology, and the exact problem you're stuck on. The more context
|
|
in the query, the more actionable the answer. Vague queries get
|
|
generic answers.
|
|
|
|
A security-focused system prompt biases responses toward CVEs,
|
|
exploits, Kali-compatible tooling, and concrete code/command
|
|
examples.
|
|
|
|
Args:
|
|
query: The search query — a full sentence with version numbers,
|
|
target tech, and the specific question. Treat it like a
|
|
ticket title for a senior security engineer.
|
|
"""
|
|
result = await asyncio.to_thread(_do_search, query)
|
|
return json.dumps(result, ensure_ascii=False, default=str)
|