Interface: IToolPolicy
Defined in: internal/tool-policy/types.ts:55
Registry ∩ Profile ∩ permissions ∩ caps. Stateless.
Implemented by ToolPolicy; the type of IAIGatewayDeps.toolPolicy, so a host may pass its own in overrides.
Methods
assertOfferedInStep()
assertOfferedInStep(
args):void
Defined in: internal/tool-policy/types.ts:141
assertOfferedInStep -- refuses a call to a tool hidden for this step, naming what must run first when requires hid it
About
"Not yet" with the reason, instead of a bare "not available".
A tool of the run that is not among the step's tools was hidden by requires (D88) or by its visibleWhen (D89). The
403 thrown here says it is not offered in this step and, when requires names tools, which ones the model must run first,
so the model can recover in the next step instead of guessing. A tool outside the run is left to ToolRegistry.execute,
which refuses it as before (D72). A tool of the step passes.
Who needs it
createRunHooks, in the loop's executeTool, before the registry runs the call.
Parameters
args
name
string
resolved
The run's tools.
tools
IToolDef<unknown, unknown>[]
The step's tools, as the model saw them.
Returns
void
decide()
decide(
args):Promise<TToolCallPolicyResult>
Defined in: internal/tool-policy/types.ts:170
decide -- the verdict on one tool call before it runs
About
Allow it, deny it with a reason, or hand it to a human.
Applies the tool's policy (D87) and the profile's approvals to one call: a static verdict as it is; a predicate on the
parsed input and the user context; then the static approvals of resolve (the profile's approvals, the tools with
policy: NEEDS_APPROVAL) as the floor, which turn an ALLOW into NEEDS_APPROVAL. DENY wins over the floor: a human is never
asked to approve a call that would be refused. The agent loop asks before every call of a step, through the decideToolCall hook.
Who needs it
createRunHooks, for the loop's decideToolCall.
Pitfalls
A tool outside resolved.tools is ALLOW here: ToolRegistry.execute refuses it (D72). An input the schema rejects is ALLOW
too: it never reaches the predicate, ToolRegistry.execute reports it to the model (D50).
Parameters
args
input
unknown
The model's input, as requested.
name
string
resolved
userContext
Returns
Promise<TToolCallPolicyResult>
endsRun()
endsRun(
args):Promise<boolean>
Defined in: internal/tool-policy/types.ts:197
endsRun -- whether an executed tool call is the run's final answer
About
Some tools are the end of the conversation: a handover, an order placed.
True when the tool's endsRun is true, or when its predicate says so on the parsed input and the output (D86). A
tool outside resolved.tools or an input the schema rejects never ends the run: neither can have executed.
Who needs it
createRunHooks, for the loop's endsRun hook, after every successful execution.
Pitfalls
Ask only after a successful execution: a failed, refused or rejected call must not reach here, the loop keeps that rule.
Parameters
args
input
unknown
The model's input, as requested.
name
string
output
unknown
What the tool returned.
resolved
userContext
Returns
Promise<boolean>
narrowForStep()
narrowForStep(
args):IResolvedTools
Defined in: internal/tool-policy/types.ts:118
narrowForStep -- the tools of one step of a run
About
Not every tool of the run is on the table at every step.
A tool listed in requires stays hidden until every tool it requires has been executed in this run (D15, D88); a tool
with visibleWhen is shown only when its predicate says so for this step (D89); a tool must pass both. The approvals
follow the visible tools. Returns the same object when nothing was hidden.
Who needs it
createRunHooks, for the loop's prepareStep hook, before every model call of a run.
Pitfalls
executed is the run's list: tools run in earlier runs of the thread do not count, and a rejected or failed call is
not an execution (D76).
Parameters
args
executed
string[]
Tool names already executed in this run.
resolved
stepIndex
number
Returns
resolve()
resolve(
args):IResolvedTools
Defined in: internal/tool-policy/types.ts:85
resolve -- the tool set of one run
About
Everything the profile allows and the user may use, cut to what the call asked for; the built-ins always.
The tools of allTools the profile allows and the user's permissions unlock, plus the call's additionalTools
(allowed because the app passed them, the permissions still apply, D66), narrowed to activeTools when the call
names them (D48); none when the model cannot call tools (caps.tools). The gateway's built-in tools (D61) are always
in the set, in the order of the registry: no profile, permission or activeTools filters them, and the profile's
approvals do not apply to them; a built-in's own policy still pauses (dyna_aigw_ask_user_question, D62).
approvals: the tools whose policy is NEEDS_APPROVAL, plus the tools the profile lists (D87).
Throws a 400 when activeTools names a tool the profile or the permissions do not allow (error 5373897180054): a call
narrows the set, never widens it. An additional tool whose name is in allTools, or given twice, is a 400 (error
5374506419213).
Who needs it
prepareCall, once per run(); AIGateway.resume, with the paused run's tool names, so the resumed run offers what
the paused one did.
Pitfalls
The checks run before caps.tools is read: a bad activeTools is a 400 even on a model without tools. resolved.tools
is the run's whole set; what the model sees in a step is narrowForStep's cut.
Parameters
args
activeTools?
string[]
The call's own selection; omitted = every tool the profile and the permissions allow.
additionalTools?
IToolDef<unknown, unknown>[]
Tools added for this call, on top of the registry's (D66).
allTools
IToolDef<unknown, unknown>[]
builtInTools?
string[]
Names of the gateway's own tools among allTools; offered whatever the profile and the call say (D61).