shrike-guard 4.1.0 → 4.3.0
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.
- package/CHANGELOG.md +92 -2
- package/README.md +66 -0
- package/dist/ai/index.d.mts +59 -0
- package/dist/ai/index.d.ts +59 -0
- package/dist/ai/index.js +500 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/index.mjs +496 -0
- package/dist/ai/index.mjs.map +1 -0
- package/dist/anthropic/index.d.mts +1 -1
- package/dist/anthropic/index.d.ts +1 -1
- package/dist/anthropic/index.js +4 -1
- package/dist/anthropic/index.js.map +1 -1
- package/dist/anthropic/index.mjs +4 -1
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/api/index.d.mts +1 -1
- package/dist/api/index.d.ts +1 -1
- package/dist/api/index.js +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/index.mjs +1 -1
- package/dist/api/index.mjs.map +1 -1
- package/dist/claude-agent/index.d.mts +98 -0
- package/dist/claude-agent/index.d.ts +98 -0
- package/dist/claude-agent/index.js +531 -0
- package/dist/claude-agent/index.js.map +1 -0
- package/dist/claude-agent/index.mjs +524 -0
- package/dist/claude-agent/index.mjs.map +1 -0
- package/dist/gemini/index.d.mts +1 -1
- package/dist/gemini/index.d.ts +1 -1
- package/dist/gemini/index.js +4 -1
- package/dist/gemini/index.js.map +1 -1
- package/dist/gemini/index.mjs +4 -1
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/{scanner-z9r8BJvO.d.mts → govern-olQtsipX.d.mts} +282 -2
- package/dist/{scanner-z9r8BJvO.d.ts → govern-olQtsipX.d.ts} +282 -2
- package/dist/index.d.mts +42 -16
- package/dist/index.d.ts +42 -16
- package/dist/index.js +107 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +107 -12
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.d.mts +74 -0
- package/dist/langchain/index.d.ts +74 -0
- package/dist/langchain/index.js +515 -0
- package/dist/langchain/index.js.map +1 -0
- package/dist/langchain/index.mjs +510 -0
- package/dist/langchain/index.mjs.map +1 -0
- package/dist/openai/index.d.mts +1 -1
- package/dist/openai/index.d.ts +1 -1
- package/dist/openai/index.js +4 -1
- package/dist/openai/index.js.map +1 -1
- package/dist/openai/index.mjs +4 -1
- package/dist/openai/index.mjs.map +1 -1
- package/dist/openai-agents/index.d.mts +65 -0
- package/dist/openai-agents/index.d.ts +65 -0
- package/dist/openai-agents/index.js +516 -0
- package/dist/openai-agents/index.js.map +1 -0
- package/dist/openai-agents/index.mjs +509 -0
- package/dist/openai-agents/index.mjs.map +1 -0
- package/package.json +63 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,95 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [4.3.0] - 2026-10-01
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **The adapters report what became of a governed action.** A scan proves
|
|
7
|
+
an action was authorized, never that it ran. The LangGraph and Vercel AI
|
|
8
|
+
wrappers now report `executed` when the tool returns and `failed` when it
|
|
9
|
+
throws, and the Claude Agent SDK adapter registers `PostToolUse` and
|
|
10
|
+
`PostToolUseFailure` and pairs the outcome with the call by `tool_use_id`.
|
|
11
|
+
The report names the scan by the `scan_id` the verdict carries and
|
|
12
|
+
carries a status only, never the tool's result or error text. A refusal
|
|
13
|
+
never runs the handler and reports nothing. An unreported action reads as
|
|
14
|
+
unconfirmed on the Shrike Agents screen, which is what it is.
|
|
15
|
+
- `ScanClient.reportOutcome(scanId, outcome, { exitStatus, source })` and
|
|
16
|
+
`ScanClient.reportHostOutcome({ host, outcome, tool, callId, contentHash,
|
|
17
|
+
reason, scanId })` for integrations that hold the outcome themselves.
|
|
18
|
+
Both are best effort and never throw. `Governance.reportOutcome(out,
|
|
19
|
+
outcome)` reports once per recorded decision. `ScanResult.scan_id` and
|
|
20
|
+
`Decision.scanId` are new fields.
|
|
21
|
+
- `SessionLockedNotice` is exported as the third member of the
|
|
22
|
+
`ClientSessionRotation` union, so a locked session has a type of its own
|
|
23
|
+
instead of a rotation record with its rotation fields left unset.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
- **A locked session is no longer offered a new session id.** A lock means the
|
|
27
|
+
session is finished, so the record returned on a `session_locked` verdict now
|
|
28
|
+
carries no id to adopt. The two rotating records narrow `reason` to
|
|
29
|
+
`'risk_threshold_exceeded'`, the only value either can still carry, so a lock
|
|
30
|
+
and a rotation are distinguishable by type rather than by reading a string.
|
|
31
|
+
Recovery from a lock is self-release under a live declared scope, or an
|
|
32
|
+
operator.
|
|
33
|
+
|
|
34
|
+
## [4.2.0] - 2026-09-17
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
- **An unmapped tool can still be judged by its name.** A tool with no
|
|
38
|
+
mapping has no readable surface, so the content plane has nothing to say
|
|
39
|
+
about it. The authorization plane still does: the operator's declared scope
|
|
40
|
+
judges a tool by NAME, which is the one thing every tool call has.
|
|
41
|
+
`onUnmapped: 'authorize'` sends the tool's name (and nothing else) to the
|
|
42
|
+
backend, so a tool outside the allowlist is refused even though nothing
|
|
43
|
+
read what it was carrying, and an expired or exhausted scope holds it. The
|
|
44
|
+
permit is narrower than a mapped tool's and the record says so: the
|
|
45
|
+
decision's surface is `authorization`, never a scanned surface. A client
|
|
46
|
+
too old to ask fails according to `failMode` rather than assuming.
|
|
47
|
+
`ShrikeGuard.authorizeTool` is the call underneath.
|
|
48
|
+
- **Observe-plane scans say so.** `ShrikeGuard.scan` takes an options argument
|
|
49
|
+
carrying `plane`, and `observePrompt` sends `plane: 'observe'`. A verdict on a prompt nobody is
|
|
50
|
+
gated on is advice: it is recorded and returned, and the model still reads
|
|
51
|
+
the note, but it is no longer filed as an action that was stopped.
|
|
52
|
+
|
|
53
|
+
- **Framework starters over one core.** `govern.ts` is the framework-free
|
|
54
|
+
core of a governed agent: a tool mapping table (`mapTool`, `exempt`),
|
|
55
|
+
`evaluate` (every scan a tool call needs, stopping at the first refusal,
|
|
56
|
+
into one `Outcome`: allow, warn, hold or deny, with the message written
|
|
57
|
+
for the model), `observePrompt` (never blocks), `requestScope` (the
|
|
58
|
+
backend decides; a widening is refused unless an operator grants it), and
|
|
59
|
+
the record (`decisions`, `onDecision`). Each starter is a subpath and a
|
|
60
|
+
thin translation of one framework's hooks:
|
|
61
|
+
- `shrike-guard/claude-agent` (Claude Agent SDK): `PreToolUse` and
|
|
62
|
+
`UserPromptSubmit` hooks, an in-process MCP tool. Ships mappings for the
|
|
63
|
+
SDK's built-in tools. ESM, as the SDK is.
|
|
64
|
+
- `shrike-guard/openai-agents` (OpenAI Agents SDK): a tool input guardrail
|
|
65
|
+
attached to every function tool (a refused call is answered with
|
|
66
|
+
`rejectContent`, so the model reads the reason as the tool's output), a
|
|
67
|
+
non-tripping input guardrail for the observe plane, and `request_scope`
|
|
68
|
+
as a function tool.
|
|
69
|
+
- `shrike-guard/ai` (Vercel AI SDK): `governTools` wraps each tool's
|
|
70
|
+
`execute` so a refused call returns the reason as the tool's result, a
|
|
71
|
+
language-model middleware whose `transformParams` scans a new user
|
|
72
|
+
message and prepends a note, and `request_scope` as an AI SDK tool.
|
|
73
|
+
- `shrike-guard/langchain` (LangChain `createAgent` and LangGraph): an
|
|
74
|
+
agent middleware whose `wrapToolCall` answers a refused call with a
|
|
75
|
+
`ToolMessage`, or `governTools` for a hand-built `ToolNode`, and
|
|
76
|
+
`request_scope` as a LangChain tool.
|
|
77
|
+
- **Tool mappings.** A tool is a surface (`command`, `file`, `file_path`,
|
|
78
|
+
`sql`, `web_search`, `rag_context`, `a2a_message`, `agent_card`, or
|
|
79
|
+
`none`) and the argument that carries its payload. A tool with no mapping
|
|
80
|
+
is refused with a message that says how to map it (`onUnmapped: 'deny'`),
|
|
81
|
+
or allowed and recorded (`'allow'`), or has its arguments scanned as text
|
|
82
|
+
(`'scan'`), or judged by name alone (`'authorize'`, see below). The Claude
|
|
83
|
+
Agent SDK starter defaults to `'authorize'`, and its hook now sees every
|
|
84
|
+
tool the agent can call rather than only the mapped ones, because a tool
|
|
85
|
+
with no reader is exactly the one whose authorization nobody has checked.
|
|
86
|
+
Pass an explicit tool list to `hooksFor` to narrow the matcher.
|
|
87
|
+
- **A conformance suite.** `tests/unit/frameworks.test.ts` drives every
|
|
88
|
+
starter through the same table (allow, warn, block, hold, backend down,
|
|
89
|
+
unmapped, a refused widening); each starter must answer it the same way.
|
|
90
|
+
The frameworks are optional peer dependencies; the base install is
|
|
91
|
+
unchanged.
|
|
92
|
+
|
|
3
93
|
## [4.1.0] - 2026-09-09
|
|
4
94
|
|
|
5
95
|
### Added
|
|
@@ -126,11 +216,11 @@ Cross-language SDK parity. The Python SDK ships `CircuitBreaker` + `retry_with_b
|
|
|
126
216
|
|
|
127
217
|
### Added
|
|
128
218
|
- **Client-side PII redaction.** `redactPII()`, `rehydratePII()`, `getRedactionSummary()`, `updatePIIPatterns()`, and `getPIIPatternCount()` exported from the root entry point. Detects and tokenizes 20+ PII types (SSN, credit card, email, phone, address, medical record, wallet, etc.) BEFORE the prompt leaves customer environment — Shrike backend never sees the raw PII.
|
|
129
|
-
- **`syncPIIPatterns({ endpoint, apiKey })`** — one-shot startup call fetches the canonical
|
|
219
|
+
- **`syncPIIPatterns({ endpoint, apiKey })`** — one-shot startup call fetches the canonical pattern set from the Shrike backend so client-side detection stays uniform with the server-side scan. Fails safe: on any error (network / timeout / malformed) the bootstrap patterns stay in place; sync never blocks scans.
|
|
130
220
|
- **Backend-owned prefix contract.** The recognizer ships its client-side redaction tag (e.g. `[IP_1]`) as part of the pattern payload; the client uses it verbatim. When the backend omits the field (pre-2026-07-02 releases), the SDK derives the prefix from the threat_type. No pattern is ever silently dropped for an unmapped prefix. Adding a new backend pattern requires zero SDK changes.
|
|
131
221
|
|
|
132
222
|
### Why
|
|
133
|
-
Client-side redaction removes PII before it crosses the network to Shrike's backend — defense-in-depth for HIPAA / PCI / GLBA / CMMC workloads on top of the BAA/DPA that already covers transmission. The `syncPIIPatterns` step keeps client patterns in step with backend patterns without shipping SDK updates every time
|
|
223
|
+
Client-side redaction removes PII before it crosses the network to Shrike's backend — defense-in-depth for HIPAA / PCI / GLBA / CMMC workloads on top of the BAA/DPA that already covers transmission. The `syncPIIPatterns` step keeps client patterns in step with backend patterns without shipping SDK updates every time the backend adds a recognizer.
|
|
134
224
|
|
|
135
225
|
### Fixed
|
|
136
226
|
- gemini-client test mock import matches the runtime `@google/genai` package (upstream renamed from `@google/generative-ai`).
|
package/README.md
CHANGED
|
@@ -347,6 +347,72 @@ for (const tool of tools) {
|
|
|
347
347
|
|
|
348
348
|
Screening happens once per tool at registration, not on every call.
|
|
349
349
|
|
|
350
|
+
## Governing an agent: framework starters
|
|
351
|
+
|
|
352
|
+
Shrike governs an agent from inside its tool loop: every tool call is judged
|
|
353
|
+
before it executes, the person's prompt is scanned on the way in and never
|
|
354
|
+
blocked, and the agent gets one tool, `request_scope`, to ask for more than
|
|
355
|
+
it holds. One framework-free core carries that behaviour; each starter is a
|
|
356
|
+
thin translation of one framework's hooks. Every starter is a subpath of this
|
|
357
|
+
package, and each framework is an optional peer dependency (`zod` too).
|
|
358
|
+
|
|
359
|
+
| Framework | Import | What it wires |
|
|
360
|
+
|---|---|---|
|
|
361
|
+
| Claude Agent SDK | `shrike-guard/claude-agent` | `PreToolUse` and `UserPromptSubmit` hooks, an in-process MCP tool |
|
|
362
|
+
| OpenAI Agents SDK | `shrike-guard/openai-agents` | a tool input guardrail on every function tool, a non-tripping input guardrail, a function tool |
|
|
363
|
+
| Vercel AI SDK | `shrike-guard/ai` | wrapped `execute` on every tool, a language-model middleware for the observe plane, an AI SDK tool |
|
|
364
|
+
| LangChain `createAgent` / LangGraph | `shrike-guard/langchain` | an agent middleware (`wrapToolCall`, `beforeAgent`) or wrapped tools for a `ToolNode` |
|
|
365
|
+
|
|
366
|
+
Every starter has the same shape. Build it, map your tools to Shrike's
|
|
367
|
+
surfaces, hand it to the framework:
|
|
368
|
+
|
|
369
|
+
```ts
|
|
370
|
+
import { Agent } from '@openai/agents';
|
|
371
|
+
import { ScanClient } from 'shrike-guard';
|
|
372
|
+
import { govern } from 'shrike-guard/openai-agents'; // or claude-agent, ai, langchain
|
|
373
|
+
|
|
374
|
+
const guard = new ScanClient({ apiKey: 'shrike-...' });
|
|
375
|
+
const gov = govern(guard, { agentId: 'invoice-agent' });
|
|
376
|
+
await gov.declare(['file_path', 'file_content', 'sql'], 'Reconcile Q3 vendor invoices');
|
|
377
|
+
|
|
378
|
+
gov.mapTool('run_query', { surface: 'sql', arg: 'query' });
|
|
379
|
+
gov.mapTool('save_report', { surface: 'file', pathArg: 'path', contentArg: 'text' });
|
|
380
|
+
gov.exempt('get_time');
|
|
381
|
+
|
|
382
|
+
const agent = gov.governAgent(new Agent({ name: 'invoices', tools: [runQuery, saveReport, getTime] }));
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
A tool mapping says which surface a tool is and which argument carries the
|
|
386
|
+
payload: `command` (with an optional `cwdArg`), `file` (a path and the
|
|
387
|
+
content written to it), `file_path`, `sql`, `web_search`, `rag_context`,
|
|
388
|
+
`a2a_message`, `agent_card`, or `none` for a tool allowed without a scan.
|
|
389
|
+
The Claude Agent SDK starter ships mappings for the SDK's built-in tools;
|
|
390
|
+
the others govern the tools you write, so they need your mappings.
|
|
391
|
+
|
|
392
|
+
A tool with no mapping is refused, with a message that says how to map it,
|
|
393
|
+
until you map it or choose what an unmapped tool gets. `onUnmapped: 'authorize'` asks the
|
|
394
|
+
backend whether the agent may call it at all: the arguments stay put, and the
|
|
395
|
+
tool's NAME goes up, where the operator's declared scope answers. A tool
|
|
396
|
+
outside the allowlist is refused by name even though nothing read what it was
|
|
397
|
+
carrying, and an expired or exhausted scope holds it. That permit is narrower
|
|
398
|
+
than a mapped tool's and the record says so, with the decision's surface
|
|
399
|
+
recorded as `authorization`. `'allow'` records the call and moves on without
|
|
400
|
+
asking; `'scan'` sends the arguments to be read as text.
|
|
401
|
+
|
|
402
|
+
What the model sees is the same everywhere: an allowed call runs; a warned
|
|
403
|
+
call runs with the advisory; a blocked call does not run and the model gets
|
|
404
|
+
the reason; a held call (an action outside the declared scope) does not run
|
|
405
|
+
and the model gets the reason, the recovery, and the instruction to ask with
|
|
406
|
+
`request_scope` and then stop. An action Shrike could not check is refused
|
|
407
|
+
(`failMode: 'closed'`). Every decision lands on `gov.decisions` and on your
|
|
408
|
+
`onDecision` callback, with the axis that objected.
|
|
409
|
+
|
|
410
|
+
Where a framework can route a hold to a person, `onHold: 'ask'` does that
|
|
411
|
+
(the Claude Agent SDK's `canUseTool`). Where it cannot, a hold is answered
|
|
412
|
+
like a refusal and the model is told an operator can grant it on the Shrike
|
|
413
|
+
Agents screen. The `claude-agent` subpath is ESM, because the Claude Agent
|
|
414
|
+
SDK is.
|
|
415
|
+
|
|
350
416
|
## Who is answerable: `content_origin`
|
|
351
417
|
|
|
352
418
|
Every verdict carries `content_origin`, which says where the scanned content
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ToolSet, Tool, LanguageModelMiddleware } from 'ai';
|
|
2
|
+
import { G as Governance$1, a as Guard, S as ScanClient, b as GovernanceOptions } from '../govern-olQtsipX.mjs';
|
|
3
|
+
export { D as Decision, O as Outcome, T as ToolMapping } from '../govern-olQtsipX.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Govern an agent built with the Vercel AI SDK (`ai`).
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { generateText, wrapLanguageModel } from 'ai';
|
|
10
|
+
* import { ScanClient } from 'shrike-guard';
|
|
11
|
+
* import { govern } from 'shrike-guard/ai';
|
|
12
|
+
*
|
|
13
|
+
* const guard = new ScanClient({ apiKey: KEY });
|
|
14
|
+
* const gov = govern(guard, { agentId: 'invoice-agent' }).mapTool('runQuery', { surface: 'sql', arg: 'query' });
|
|
15
|
+
* const result = await generateText({
|
|
16
|
+
* model: wrapLanguageModel({ model, middleware: gov.middleware }),
|
|
17
|
+
* tools: gov.governTools({ runQuery, saveReport, request_scope: gov.tool }),
|
|
18
|
+
* prompt,
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* A thin adapter over `shrike-guard`'s framework-free core (`govern.ts`).
|
|
23
|
+
*
|
|
24
|
+
* The act plane wraps each tool's `execute`: Shrike judges the call through
|
|
25
|
+
* the tool's mapping before the inner `execute` runs. A refused or held call
|
|
26
|
+
* never runs; the wrapper returns Shrike's reason and the recovery as the
|
|
27
|
+
* tool's result, so the model reads why and what to do next. Tools with no
|
|
28
|
+
* mapping are refused by default (`onUnmapped: 'deny'`).
|
|
29
|
+
*
|
|
30
|
+
* The observe plane is a language-model middleware whose `transformParams`
|
|
31
|
+
* scans the latest user message on the way in, once per message, and never
|
|
32
|
+
* blocks. A finding is prepended to the prompt as a system message.
|
|
33
|
+
*
|
|
34
|
+
* `request_scope` is available as `gov.tool`; add it to the tool set. A held
|
|
35
|
+
* action is answered like a refusal whatever `onHold` says; use the SDK's
|
|
36
|
+
* `needsApproval` if the run itself should pause.
|
|
37
|
+
*
|
|
38
|
+
* Requires `ai` and `zod`.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/** The latest user message's text in a language-model prompt. */
|
|
42
|
+
declare function lastUserText(prompt: unknown): string;
|
|
43
|
+
declare class Governance extends Governance$1 {
|
|
44
|
+
private toolCache?;
|
|
45
|
+
private middlewareCache?;
|
|
46
|
+
private lastObserved?;
|
|
47
|
+
/** Wrap each tool's `execute` so Shrike judges its calls. Returns a new tool set. */
|
|
48
|
+
governTools<T extends ToolSet>(tools: T): T;
|
|
49
|
+
/** `request_scope` as an AI SDK tool; add it to your tool set under that name. */
|
|
50
|
+
get tool(): Tool;
|
|
51
|
+
/** Scan a new user message in a prompt, once. Returns the note to prepend, or empty. */
|
|
52
|
+
observePromptMessages(prompt: unknown): Promise<string>;
|
|
53
|
+
/** The observe-plane middleware for `wrapLanguageModel({ model, middleware })`. */
|
|
54
|
+
get middleware(): LanguageModelMiddleware;
|
|
55
|
+
}
|
|
56
|
+
/** Build the governance for one agent. */
|
|
57
|
+
declare function govern(guard: Guard | ScanClient, options: GovernanceOptions): Governance;
|
|
58
|
+
|
|
59
|
+
export { Governance, GovernanceOptions, govern, lastUserText };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ToolSet, Tool, LanguageModelMiddleware } from 'ai';
|
|
2
|
+
import { G as Governance$1, a as Guard, S as ScanClient, b as GovernanceOptions } from '../govern-olQtsipX.js';
|
|
3
|
+
export { D as Decision, O as Outcome, T as ToolMapping } from '../govern-olQtsipX.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Govern an agent built with the Vercel AI SDK (`ai`).
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { generateText, wrapLanguageModel } from 'ai';
|
|
10
|
+
* import { ScanClient } from 'shrike-guard';
|
|
11
|
+
* import { govern } from 'shrike-guard/ai';
|
|
12
|
+
*
|
|
13
|
+
* const guard = new ScanClient({ apiKey: KEY });
|
|
14
|
+
* const gov = govern(guard, { agentId: 'invoice-agent' }).mapTool('runQuery', { surface: 'sql', arg: 'query' });
|
|
15
|
+
* const result = await generateText({
|
|
16
|
+
* model: wrapLanguageModel({ model, middleware: gov.middleware }),
|
|
17
|
+
* tools: gov.governTools({ runQuery, saveReport, request_scope: gov.tool }),
|
|
18
|
+
* prompt,
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* A thin adapter over `shrike-guard`'s framework-free core (`govern.ts`).
|
|
23
|
+
*
|
|
24
|
+
* The act plane wraps each tool's `execute`: Shrike judges the call through
|
|
25
|
+
* the tool's mapping before the inner `execute` runs. A refused or held call
|
|
26
|
+
* never runs; the wrapper returns Shrike's reason and the recovery as the
|
|
27
|
+
* tool's result, so the model reads why and what to do next. Tools with no
|
|
28
|
+
* mapping are refused by default (`onUnmapped: 'deny'`).
|
|
29
|
+
*
|
|
30
|
+
* The observe plane is a language-model middleware whose `transformParams`
|
|
31
|
+
* scans the latest user message on the way in, once per message, and never
|
|
32
|
+
* blocks. A finding is prepended to the prompt as a system message.
|
|
33
|
+
*
|
|
34
|
+
* `request_scope` is available as `gov.tool`; add it to the tool set. A held
|
|
35
|
+
* action is answered like a refusal whatever `onHold` says; use the SDK's
|
|
36
|
+
* `needsApproval` if the run itself should pause.
|
|
37
|
+
*
|
|
38
|
+
* Requires `ai` and `zod`.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/** The latest user message's text in a language-model prompt. */
|
|
42
|
+
declare function lastUserText(prompt: unknown): string;
|
|
43
|
+
declare class Governance extends Governance$1 {
|
|
44
|
+
private toolCache?;
|
|
45
|
+
private middlewareCache?;
|
|
46
|
+
private lastObserved?;
|
|
47
|
+
/** Wrap each tool's `execute` so Shrike judges its calls. Returns a new tool set. */
|
|
48
|
+
governTools<T extends ToolSet>(tools: T): T;
|
|
49
|
+
/** `request_scope` as an AI SDK tool; add it to your tool set under that name. */
|
|
50
|
+
get tool(): Tool;
|
|
51
|
+
/** Scan a new user message in a prompt, once. Returns the note to prepend, or empty. */
|
|
52
|
+
observePromptMessages(prompt: unknown): Promise<string>;
|
|
53
|
+
/** The observe-plane middleware for `wrapLanguageModel({ model, middleware })`. */
|
|
54
|
+
get middleware(): LanguageModelMiddleware;
|
|
55
|
+
}
|
|
56
|
+
/** Build the governance for one agent. */
|
|
57
|
+
declare function govern(guard: Guard | ScanClient, options: GovernanceOptions): Governance;
|
|
58
|
+
|
|
59
|
+
export { Governance, GovernanceOptions, govern, lastUserText };
|