🛂 fix: Enforce Actions Capability Gate Across All Event-Driven Tool Loading Paths (#12252)

* fix: gate action tools by actions capability in all code paths

Extract resolveAgentCapabilities helper to eliminate 3x-duplicated
capability resolution. Apply early action-tool filtering in both
loadToolDefinitionsWrapper and loadAgentTools non-definitions path.
Gate loadActionToolsForExecution in loadToolsForExecution behind an
actionsEnabled parameter with a cache-based fallback. Replace the
late capability guard in loadAgentTools with a hasActionTools check
to avoid unnecessary loadActionSets DB calls and duplicate warnings.

* fix: thread actionsEnabled through InitializedAgent type

Add actionsEnabled to the loadTools callback return type,
InitializedAgent, and the initializeAgent destructuring/return
so callers can forward the resolved value to loadToolsForExecution
without redundant getEndpointsConfig cache lookups.

* fix: pass actionsEnabled from callers to loadToolsForExecution

Thread actionsEnabled through the agentToolContexts map in
initialize.js (primary and handoff agents) and through
primaryConfig in the openai.js and responses.js controllers,
avoiding per-tool-call capability re-resolution on the hot path.

* test: add regression tests for action capability gating

Test the real exported functions (resolveAgentCapabilities,
loadAgentTools, loadToolsForExecution) with mocked dependencies
instead of shadow re-implementations. Covers definition filtering,
execution gating, actionsEnabled param forwarding, and fallback
capability resolution.

* test: use Constants.EPHEMERAL_AGENT_ID in ephemeral fallback test

Replaces a string guess with the canonical constant to avoid
fragility if the ephemeral detection heuristic changes.

* fix: populate agentToolContexts for addedConvo parallel agents

After processAddedConvo returns, backfill agentToolContexts for
any agents in agentConfigs not already present, so ON_TOOL_EXECUTE
for added-convo agents receives actionsEnabled instead of falling
back to a per-call cache lookup.
This commit is contained in:
Danny Avila 2026-03-15 23:01:36 -04:00 committed by GitHub
parent a26eeea592
commit 6f87b49df8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 372 additions and 38 deletions

View file

@ -52,6 +52,8 @@ export type InitializedAgent = Agent & {
toolDefinitions?: LCTool[];
/** Precomputed flag indicating if any tools have defer_loading enabled (for efficient runtime checks) */
hasDeferredTools?: boolean;
/** Whether the actions capability is enabled (resolved during tool loading) */
actionsEnabled?: boolean;
};
/**
@ -90,6 +92,7 @@ export interface InitializeAgentParams {
/** Serializable tool definitions for event-driven mode */
toolDefinitions?: LCTool[];
hasDeferredTools?: boolean;
actionsEnabled?: boolean;
} | null>;
/** Endpoint option (contains model_parameters and endpoint info) */
endpointOption?: Partial<TEndpointOption>;
@ -283,6 +286,7 @@ export async function initializeAgent(
userMCPAuthMap,
toolDefinitions,
hasDeferredTools,
actionsEnabled,
tools: structuredTools,
} = (await loadTools?.({
req,
@ -300,6 +304,7 @@ export async function initializeAgent(
toolRegistry: undefined,
toolDefinitions: [],
hasDeferredTools: false,
actionsEnabled: undefined,
};
const { getOptions, overrideProvider } = getProviderConfig({
@ -409,6 +414,7 @@ export async function initializeAgent(
userMCPAuthMap,
toolDefinitions,
hasDeferredTools,
actionsEnabled,
attachments: finalAttachments,
toolContextMap: toolContextMap ?? {},
useLegacyContent: !!options.useLegacyContent,