feat(ENG-12325): add defender config option to StackOneToolSet#328
feat(ENG-12325): add defender config option to StackOneToolSet#328
Conversation
Adds a `defender` option to the `StackOneToolSet` constructor that allows controlling prompt injection detection behavior at the toolset level. - Add `DefenderConfig` interface with `enabled`, `blockHighRisk`, `useTier1Classification`, and `useTier2Classification` fields — matching canonical `DefenderSettings` names from `@stackone/core` - Add `defender_enabled` to `rpcActionRequestSchema` so it is no longer silently dropped by Zod validation - Forward `defender_enabled` through `RpcClient.rpcAction()` request body - Thread `defenderConfig.enabled` → `defender_enabled` in every RPC call made by `createRpcBackedTool` - Export `DefenderConfig` from the package index Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
commit: |
There was a problem hiding this comment.
1 issue found across 5 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/toolsets.ts">
<violation number="1" location="src/toolsets.ts:979">
P2: `dryRun` request serialization is now inconsistent with real RPC calls because `defender_enabled` is forwarded only in the live path.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
There was a problem hiding this comment.
Pull request overview
Adds a toolset-level defender configuration to StackOneToolSet so consumers can control prompt-injection detection behavior (currently via per-request defender_enabled), and fixes a silent validation issue where defender_enabled was previously dropped before reaching the RPC call.
Changes:
- Introduces
DefenderConfigand exports it from the public entrypoint. - Extends the RPC request Zod schema to accept
defender_enabledand forwards it in the RPC client request payload. - Adds
defendertoStackOneToolSetconfig and threadsdefender.enabled → defender_enabledinto RPC calls.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/types.ts |
Adds DefenderConfig interface describing toolset-level defender settings. |
src/toolsets.ts |
Accepts/stores defender config on the toolset and injects defender_enabled into RPC calls. |
src/schema.ts |
Updates rpcActionRequestSchema to validate defender_enabled so it isn’t stripped. |
src/rpc-client.ts |
Includes validated defender_enabled in the JSON payload sent to /actions/rpc. |
src/index.ts |
Re-exports DefenderConfig for SDK consumers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
- Include defender_enabled in dryRun payload to match live RPC path - Clarify JSDoc that only enabled is currently applied per-request - Add tests for defender_enabled forwarding in rpc-client and toolsets Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nd SDK defaults
- Replace `DefenderConfig` interface with a discriminated union:
- `{ useProjectSettings: true }` → defer to project dashboard settings
- `{ enabled?, blockHighRisk?, useTier1Classification?, useTier2Classification? }` → SDK-level config
- Add `DEFAULT_DEFENDER_CONFIG`: enabled=true, blockHighRisk=false, tier1+tier2 on
- Omitting `defender` now applies SDK defaults (enabled, not blocking) rather than
deferring to project settings — this makes SDK behavior explicit and predictable
- `defender: null` explicitly disables defender for all tool calls
- Constructor throws `ToolSetConfigError` if `useProjectSettings: true` is combined
with other fields
- Extend `rpcActionRequestSchema` and `RpcClient` to forward `block_high_risk`,
`use_tier1_classification`, `use_tier2_classification` per-request (backend support
for these is tracked separately)
- Export `DEFAULT_DEFENDER_CONFIG` from package index
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
3 issues found across 5 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/toolsets.ts">
<violation number="1" location="src/toolsets.ts:995">
P2: `dryRun` no longer matches the real RPC payload for defender settings.</violation>
</file>
<file name="src/rpc-client.ts">
<violation number="1" location="src/rpc-client.ts:56">
P1: Don't forward the unsupported defender tuning fields yet. Only `defender_enabled` is wired through the RPC API today, so sending the other three keys can break RPC calls until the backend DTO is updated.</violation>
</file>
<file name="src/types.ts">
<violation number="1" location="src/types.ts:271">
P1: Defaulting omitted `defender` to an explicit config overrides existing project settings for every RPC call.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| * Defender is enabled but outputs are never blocked — scans run and results are annotated only. | ||
| */ | ||
| export const DEFAULT_DEFENDER_CONFIG = { | ||
| enabled: true, |
There was a problem hiding this comment.
P1: Defaulting omitted defender to an explicit config overrides existing project settings for every RPC call.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/types.ts, line 271:
<comment>Defaulting omitted `defender` to an explicit config overrides existing project settings for every RPC call.</comment>
<file context>
@@ -239,28 +239,37 @@ export interface ClaudeAgentSdkOptions {
+ * Defender is enabled but outputs are never blocked — scans run and results are annotated only.
+ */
+export const DEFAULT_DEFENDER_CONFIG = {
+ enabled: true,
+ blockHighRisk: false,
+ useTier1Classification: true,
</file context>
…ults - Move defenderFields computation before dryRun block so both paths share the same logic - Fix TypeScript error: defenderConfig.enabled was accessed on the useProjectSettings union variant - Update tests to reflect new behavior: omitting defender now applies SDK defaults instead of undefined Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The ternary expression used mixed tabs+spaces alignment which oxfmt rejects. Replaced with an if-else block that uses consistent tab indentation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SDK defaults will override project-level defender settings when no explicit defender config is passed. A console.warn nudges users to either pass an explicit config or opt into useProjectSettings: true. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace flat defender_enabled/block_high_risk/use_tier*_classification fields with a nested defender_config object. Keep defender_enabled for backward compat. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
knip flagged defenderConfigRequestSchema as an unused export since it is only used internally within schema.ts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@hiskudin you now have merge conflicts |
Summary
Adds a
defenderoption toStackOneToolSetfor explicit control over prompt injection detection behavior on every tool call.defender_enabledwas dropped by Zod validation before reaching the RPC callblock_high_risk,use_tier1_classification,use_tier2_classificationper-request (backend changes tracked separately)DefenderSettingsfrom@stackone/coreBehavior
defenderomitteddefender: nulldefender: { useProjectSettings: true }defender: { enabled, blockHighRisk, ... }Default behavior (omit
defender)Disable entirely
Defer to project dashboard settings
Explicit SDK-level config
Parameters
enabledbooleantruefalsedisables all scanning.blockHighRiskbooleanfalsefalse, risky content is annotated but still returned.useTier1ClassificationbooleantrueuseTier2Classificationbooleantrueonnxruntime-nodeat runtime.Changes
src/types.ts—DefenderConfigis now a discriminated union; addsDEFAULT_DEFENDER_CONFIGconstantsrc/schema.ts— addsblock_high_risk,use_tier1_classification,use_tier2_classificationtorpcActionRequestSchemasrc/rpc-client.ts— forwards all new defender fields in request bodysrc/toolsets.ts— resolves defender config at construction, validatesuseProjectSettingsexclusivity, applies three-way logic increateRpcBackedToolsrc/index.ts— exportsDEFAULT_DEFENDER_CONFIGNotes
blockHighRisk,useTier1Classification, anduseTier2Classificationare forwarded in the RPC payload but require a backend change toActionsRpcRequestDtoto take effect. That work is tracked separately.🤖 Generated with Claude Code