diff --git a/docs/changelog.mdx b/docs/changelog.mdx index e221daa..b80ef64 100644 --- a/docs/changelog.mdx +++ b/docs/changelog.mdx @@ -1,12 +1,10 @@ --- title: "Changelog" -description: "Product updates and release notes for Intercept, including dependency limits, security patches, and changes to Tool Approval Guard defaults." sidebarTitle: "Changelog" rss: true +description: "Product updates and release notes for Intercept, including dependency limits, security patches, and changes to middleware collection." --- -Product updates and release notes for Intercept. - Supports `laravel/ai` v1.0. The SDK now runs agent middleware once per generation step, not once per prompt. diff --git a/docs/configuration.mdx b/docs/configuration.mdx index f7d540b..b2a4f80 100644 --- a/docs/configuration.mdx +++ b/docs/configuration.mdx @@ -1,6 +1,6 @@ --- title: "Configuration" -description: "Publish config/intercept.php, learn configuration priority, and set global or per-agent options for Injection Guard, PII Redactor, and Tool Approval Guard." +description: "Publish config/intercept.php, learn configuration priority, and set global or per-agent options for middleware collection." sidebarTitle: "Configuration" --- diff --git a/docs/contributor-resources/support.mdx b/docs/contributor-resources/support.mdx index 6ca2549..baef490 100644 --- a/docs/contributor-resources/support.mdx +++ b/docs/contributor-resources/support.mdx @@ -1,19 +1,19 @@ --- title: "Support utilities" -description: "Learn how the intercept-support package provides the shared config file, the InterceptConfig helper, and the service provider used by Intercept middleware." sidebarTitle: "Support utilities" --- `promptphp/intercept-support` provides shared support utilities and configuration for the Intercept middleware ecosystem. -Most users do not need to install or use this package directly. Composer installs it automatically when an Intercept middleware package requires it. +Users do not need to install or use this package directly. Composer installs it automatically when an Intercept middleware package requires it. The support package provides shared infrastructure used across Intercept packages, including: - the shared `config/intercept.php` configuration file - the `intercept-config` publish tag -- the `InterceptConfig` helper for resolving middleware configuration + - the `InterceptServiceProvider` for Laravel package registration +- the Intercept base exception class ## Installation diff --git a/docs/middleware/injection-guard.mdx b/docs/middleware/injection-guard.mdx index 9ae6fce..5028da6 100644 --- a/docs/middleware/injection-guard.mdx +++ b/docs/middleware/injection-guard.mdx @@ -1,6 +1,5 @@ --- title: "Injection Guard" -description: "Install and configure PromptInjectionGuard to detect prompt injection in Laravel AI SDK agents, then block, log, warn, sanitize, or run a custom callback." sidebarTitle: "Injection Guard" --- diff --git a/docs/middleware/pii-redactor.mdx b/docs/middleware/pii-redactor.mdx index 74f7f9b..afa082e 100644 --- a/docs/middleware/pii-redactor.mdx +++ b/docs/middleware/pii-redactor.mdx @@ -1,6 +1,5 @@ --- title: "PII Redactor" -description: "Use PIIRedactor to detect emails, phone numbers, credit cards, and secret-like data in Laravel AI agent prompts, then redact, mask, log, or block them." sidebarTitle: "PII Redactor" --- @@ -21,7 +20,7 @@ composer require promptphp/intercept-pii-redactor ``` - If you prefer to install the main Intercept package to get the full middleware collection, run: + If you prefer to install the main intercept package to get the full middleware collection, run: ```bash @@ -76,7 +75,7 @@ By default, the middleware will: The recommended default action is `redact`. -Some entities can still be blocked even when the action is `redact`. By default, the middleware blocks credit cards, API keys, and bearer tokens. +Some entities can still be blocked even when the action is `redact`. By default, credit cards, API keys, and bearer tokens are blocked. ## Supported entities @@ -97,7 +96,7 @@ Names, addresses, passports, national insurance numbers, and medical identifiers No configuration is required. The middleware works out of the box using safe internal defaults. -You can override the defaults via the constructor or via the shared `config/intercept.php` file. Publish it with: +The defaults may be overridden via the constructor or via the shared `config/intercept.php` file, published with: ```bash php artisan vendor:publish --tag=intercept-config @@ -107,7 +106,7 @@ Explore the [configuration guide](/configuration) for more details on how to con ### Configuration priority -Intercept resolves configuration in this order: +Configuration is resolved in this order: ```mermaid placement="top-right" flowchart LR @@ -263,10 +262,10 @@ public function middleware(): array } ``` -If the middleware detects PII, it throws a `PIIRedactorException`. +If PII is detected, the middleware throws a `PIIRedactorException`. - You can also catch `InterceptException`, the parent exception class that all Intercept middleware throw. + You may also catch the parent exception class `InterceptException` throwable by all Intercept middleware. ```php @@ -283,7 +282,7 @@ try { ### Blocked entities -The middleware treats some entities as high-risk and blocks them by default, even when the action is `redact`. +Some entities are treated as high-risk and are blocked by default, even when the action is `redact`. Default blocked entities: @@ -295,7 +294,7 @@ Default blocked entities: ] ``` -This means the middleware blocks a prompt containing a supported API key or bearer token by default. +This means a prompt containing a supported API key or bearer token will be blocked by default. You can override blocked entities: @@ -429,64 +428,51 @@ Use a callback when you want full control over the response. The callback receives: ```php -PendingStep $step +AgentPrompt $prompt Closure $next RedactionResult $result ``` -Return what `$next` returns. Example: +Example: ```php -use Laravel\Ai\PendingStep; - public function middleware(): array { return [ new PIIRedactor( - callback: function (PendingStep $step, Closure $next, $result) { - if ($step->isFirstStep()) { - logger()->warning('Sensitive data detected in AI prompt.', [ - 'model' => $step->model, - 'entities' => array_map( - fn ($detection) => $detection->type, - $result->detections, - ), - ]); - } - - return $next($step->withInstructions( - $step->instructions.PHP_EOL.'Treat the user input as sensitive data.' - )); + callback: function ($prompt, $next, $result) { + logger()->warning('Sensitive data detected in AI prompt.', [ + 'agent' => $prompt->agent::class, + 'entities' => array_map( + fn ($detection) => $detection->type, + $result->detections, + ), + 'prompt_hash' => hash('sha256', $prompt->prompt), + ]); + + return $next( + $prompt->prepend( + 'Privacy notice: Treat the following user input as sensitive data.' + ) + ); }, ), ]; } ``` -When you provide a callback, it takes priority over the configured action. - -The callback runs on every step whose newest user message carries PII. Check `$step->isFirstStep()` to act once per run. On a resumed run, the callback receives the `AgentPrompt`, a `null` in place of `$next`, and the result. The return value is ignored there, so throw to stop the run. - -## Generation steps - -The Laravel AI SDK runs agent middleware once for each generation step. A run that calls tools has several steps. The prompt is the newest user message in `$step->messages`. - -A change to the step history applies to that step only. The middleware therefore redacts or masks every user message in the history on every step. This includes earlier turns that the SDK replays from a conversation store. It logs and blocks once, on the step that starts the turn. - - - The SDK stores the original prompt in the conversation store, and it builds the conversation title from that prompt. Middleware cannot change either. Redaction keeps PII away from the AI provider, not away from your conversation tables. - +When a callback is provided, it takes priority over the configured action. ## Tool approval resumes -When an agent pauses for tool approval, you resume the run by passing `Decisions` back to the agent instead of a new prompt. +When an agent pauses for tool approval, the run is resumed by passing `Decisions` back to the agent instead of a new prompt. A resumed prompt carries no prompt text. The only new content is what a human supplied while resolving the pending tool calls: - edited tool arguments, from `Decision::edit()` - rejection results, from `Decision::reject()` -Both reach the AI provider, and the SDK applies them before the first step of the resumed run. Intercept therefore scans them from a listener on the SDK prompt event, before any approved or edited tool call executes. It uses the same detectors, Luhn validation, and email allowlists it applies to a prompt. +Both reach the AI provider, so this middleware scans them using the same detectors, Luhn validation, and email allowlists it applies to a prompt. ```php use Laravel\Ai\Approvals\Decision; @@ -561,7 +547,7 @@ public function middleware(): array ``` - Detection offsets on this path are relative to the decision value the detection was found in, not to the prompt. Offsets exist to drive redaction, which cannot apply to a resumed run. Custom callbacks should use the detection `type` and `value` rather than `start` and `length`. + Detection offsets on this path are relative to the decision value the detection was found in, not to the prompt. Offsets exist to drive redaction, which cannot be applied to a resumed run, so custom callbacks should use the detection `type` and `value` rather than `start` and `length`. ## Production rollout