Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/graphs/Graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ import { SUBAGENT_REPLAY_CONTROLLER } from '@/tools/subagent/SubagentReplay';
import { applyGraphRuntimeConfig } from '@/graphs/applyGraphRuntimeConfig';
import { isFadingTier, isInformativeFadingTier } from '@/messages/fading';
import { createContextPressureMeter } from '@/llm/contextPressureMeter';
import { validateToolResultProtection } from '@/protection/toolResult';
import { safeDispatchCustomEvent, emitAgentLog } from '@/utils/events';
import { createCloudflareCodingToolBundle } from '@/tools/cloudflare';
import { calculateMaxToolCallInputChars } from '@/utils/truncation';
Expand Down Expand Up @@ -1386,6 +1387,8 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
* these on every streamed chunk event.
*/
streamLimits: ResolvedStreamLimits;
/** Default-off mandatory tool-result release. */
toolResultProtection?: t.StandardGraphInput['toolResultProtection'];
/** Default-off mandatory provider prose release. */
providerTextProtection?: t.StandardGraphInput['providerTextProtection'];
/**
Expand Down Expand Up @@ -1568,6 +1571,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
preemption,
streamLimits,
providerTextProtection,
toolResultProtection,
toolExecution,
clientDelegatedToolNames,
}: t.StandardGraphInput,
Expand Down Expand Up @@ -1600,6 +1604,8 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
if (providerTextProtection != null)
validateProviderTextProtection(providerTextProtection);
this.providerTextProtection = providerTextProtection;
if (toolResultProtection != null) validateToolResultProtection(toolResultProtection);
this.toolResultProtection = toolResultProtection;
Comment on lines +1607 to +1608

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject protected tools delegated to the client

When a tool name appears in both toolResultProtection.toolNames and clientDelegatedToolNames, this accepts the protection policy even though the delegated-call route ends the graph without passing the call through ToolNode. The client-supplied ToolMessage on the subsequent turn is then treated as conversation history and projected into the next provider request without inspect, so a result explicitly selected for mandatory protection can reach the model and generation tracing raw; reject this overlap or protect delegated-result ingestion.

AGENTS.md reference: AGENTS.md:L147-L147

Useful? React with 👍 / 👎.

this.toolExecution = toolExecution;
if (
clientDelegatedToolNames != null &&
Expand Down Expand Up @@ -2975,6 +2981,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
maxContextTokens: agentContext?.maxContextTokens,
maxToolResultChars: agentContext?.maxToolResultChars,
toolOutputRegistry: this.getOrCreateToolOutputRegistry(),
toolResultProtection: this.toolResultProtection,
fileCheckpointer: this.getOrCreateFileCheckpointer(),
getBreakerSignal: (): AbortSignal => this.breakerAbort.signal,
getRunScope: (): RunBreakerScope => this.runScope,
Expand Down Expand Up @@ -3058,6 +3065,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
maxContextTokens: agentContext?.maxContextTokens,
maxToolResultChars: agentContext?.maxToolResultChars,
toolOutputRegistry: this.getOrCreateToolOutputRegistry(),
toolResultProtection: this.toolResultProtection,
fileCheckpointer: this.getOrCreateFileCheckpointer(),
getBreakerSignal: (): AbortSignal => this.breakerAbort.signal,
getRunScope: (): RunBreakerScope => this.runScope,
Expand Down Expand Up @@ -5381,6 +5389,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
onResolutionFailure: this.onSubagentResolutionFailure,
streamLimits: this.streamLimits,
providerTextProtection: this.providerTextProtection,
toolResultProtection: this.toolResultProtection,
humanInTheLoop: this.humanInTheLoop,
checkpointer: this.compileOptions?.checkpointer,
maxDepth: effectiveSubagentDepth,
Expand Down
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,6 @@ export type {
ProviderTextProtectionResult,
ProviderTextProtectionErrorCode,
} from './protection/providerText';

export { TOOL_RESULT_PROTECTION_VERSION, ToolResultProtectionError } from './protection/toolResult';
export type { ToolResultProtection, ToolResultProtectionResult } from './protection/toolResult';
Loading
Loading