Conversation
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
|
@copilot review the PR |
Greptile SummaryThis PR is a major SDK reorganization into
Confidence Score: 5/5Safe to merge; no blocking defects found in the reorganized SDK or new guard facades. The core changes are all implemented correctly. Previous issues (closing_delimiter false positives, async event-loop re-entrancy, blocking Firecrawl call, version bump, ServerContentProvider resource leak) are all addressed. Remaining findings are style and robustness nits in the optional .env fallback path and the guards package namespace. sdk/src/unplug/providers/content/env.py has the inline-comment stripping and hardcoded parent-depth issues worth a second look before the scrape feature lands. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
User["Caller (sync or async)"] --> TG["ToolGuard.filter(text)"]
User --> SG["ScrapeGuard.scrape(url)"]
TG --> TOO["ToolOutputOrchestrator.run(text)"]
SG --> SO["ScrapeOrchestrator.run(url) / run_coroutine_sync()"]
SG --> SOA["ScrapeOrchestrator.run_async(url)"]
SO --> RAC["run_coroutine_sync (asyncio.run or ThreadPoolExecutor)"]
RAC --> SOA
SOA --> FA["_fetch_async(url)"]
FA --> FP["FirecrawlProvider or ServerContentProvider"]
FP --> SC["ScrapedContent"]
SC --> TOO
TOO --> GS["Guard.scan(text)"]
GS --> ServerMode{server_mode?}
ServerMode -- yes --> UC["UnplugClient.scan()"]
ServerMode -- no --> IP["InputPipeline (regex safeguards)"]
GS --> SR["ScanResult"]
SR --> SRO["scan_result_to_outcome()"]
SRO --> CO["ContentOutcome (safe / blocked)"]
CO --> TG
CO --> SOA
Reviews (4): Last reviewed commit: "wire Guard server mode to HTTP client" | Re-trigger Greptile |
| def _register_builtins() -> None: | ||
| from unplug.safeguards.injection import InjectionScanner | ||
| from unplug.scanners.destructive import DestructiveScanner | ||
| from unplug.scanners.financial import FinancialScanner | ||
| from unplug.scanners.harmful import HarmfulScanner | ||
| from unplug.scanners.leakage import LeakageScanner | ||
| from unplug.scanners.secrets import SecretsScanner |
There was a problem hiding this comment.
The new canonical
SafeguardRegistry imports five scanners directly from unplug.scanners.*, which triggers unplug/scanners/__init__.py and emits a DeprecationWarning on every first SafeguardRegistry instantiation. Users of the new API will see a spurious deprecation warning pointing to code inside safeguards/registry.py, making it look like the SDK itself is using a deprecated module.
| def _register_builtins() -> None: | |
| from unplug.safeguards.injection import InjectionScanner | |
| from unplug.scanners.destructive import DestructiveScanner | |
| from unplug.scanners.financial import FinancialScanner | |
| from unplug.scanners.harmful import HarmfulScanner | |
| from unplug.scanners.leakage import LeakageScanner | |
| from unplug.scanners.secrets import SecretsScanner | |
| def _register_builtins() -> None: | |
| from unplug.safeguards.injection import InjectionScanner | |
| # TODO: move remaining scanners to unplug.safeguards.* and update imports below | |
| from unplug.scanners.destructive import DestructiveScanner # noqa: PLC0415 | |
| from unplug.scanners.financial import FinancialScanner # noqa: PLC0415 | |
| from unplug.scanners.harmful import HarmfulScanner # noqa: PLC0415 | |
| from unplug.scanners.leakage import LeakageScanner # noqa: PLC0415 | |
| from unplug.scanners.secrets import SecretsScanner # noqa: PLC0415 |
Reviewed on commit |
Summary
api/,config/,safeguards/,orchestrators/,guards/,providers/tool.filter(text))[messages]safeguards/injection/patterns.pyunplug[scrape]extra; server content provider stubunplug.scannersimports (shim remains)Test plan
cd sdk && uv run pytest -q(327 passed)uv run ruff check .mainat 0.3.0 checkpoint onlyFollow-up (separate branches)
feature/scrape— Firecrawl wrapper + ScrapeGuardfeature/safeguards-eval— per-category hardening vs neuralchemy evalMade with Cursor