dogwood.integrations.strands#

Strands Agents integration for Dogwood policy enforcement.

class dogwood.integrations.strands.DogwoodIntervention(policy_source: str | None = None, policy_schema_source: str | None = None, *, event_schema_source: str | None = None, authorizer: ~dogwood.native.NativeAuthorizer | None = None, action: str = 'Drupe::Action::CallTool', principal: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_principal>, resource: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_resource>, input_mapper: ~collections.abc.Callable[[~typing.Any], dict[str, ~typing.Any]] = <function default_tool_input>, deny_message: str = 'Dogwood policy denied this tool call.', confirm_when: bool | str | ~collections.abc.Callable[[~typing.Any], bool | str | None] = False, confirm_prompt: str = 'Approve this Dogwood-controlled tool call?')[source]#

Typed Strands intervention handler backed by Dogwood authorization.

before_tool_call returns Strands typed decisions when Strands is installed. Without Strands installed, it returns small local stand-ins so the mapping behavior remains testable.

name = 'dogwood-policy'#
__init__(policy_source: str | None = None, policy_schema_source: str | None = None, *, event_schema_source: str | None = None, authorizer: ~dogwood.native.NativeAuthorizer | None = None, action: str = 'Drupe::Action::CallTool', principal: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_principal>, resource: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_resource>, input_mapper: ~collections.abc.Callable[[~typing.Any], dict[str, ~typing.Any]] = <function default_tool_input>, deny_message: str = 'Dogwood policy denied this tool call.', confirm_when: bool | str | ~collections.abc.Callable[[~typing.Any], bool | str | None] = False, confirm_prompt: str = 'Approve this Dogwood-controlled tool call?') None[source]#
before_tool_call(event: Any, **kwargs: Any) Any[source]#

Authorize a Strands tool call and return a typed control decision.

class dogwood.integrations.strands.DogwoodPlugin(policy_source: str | None = None, policy_schema_source: str | None = None, *, event_schema_source: str | None = None, authorizer: ~dogwood.native.NativeAuthorizer | None = None, action: str = 'Drupe::Action::CallTool', principal: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_principal>, resource: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_resource>, input_mapper: ~collections.abc.Callable[[~typing.Any], dict[str, ~typing.Any]] = <function default_tool_input>, deny_message: str = 'Dogwood policy denied this tool call.')[source]#

Strands plugin that auto-registers Dogwood’s before-tool-call hook.

name = 'dogwood-policy'#
__init__(policy_source: str | None = None, policy_schema_source: str | None = None, *, event_schema_source: str | None = None, authorizer: ~dogwood.native.NativeAuthorizer | None = None, action: str = 'Drupe::Action::CallTool', principal: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_principal>, resource: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_resource>, input_mapper: ~collections.abc.Callable[[~typing.Any], dict[str, ~typing.Any]] = <function default_tool_input>, deny_message: str = 'Dogwood policy denied this tool call.') None[source]#
init_agent(agent: Any) None[source]#
on_before_tool_call(event: Any) None[source]#
class dogwood.integrations.strands.StrandsPolicyHook(authorizer: ~dogwood.native.NativeAuthorizer, action: str = 'Drupe::Action::CallTool', principal: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_principal>, resource: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_resource>, input_mapper: ~collections.abc.Callable[[~typing.Any], dict[str, ~typing.Any]] = <function default_tool_input>, deny_message: str = 'Dogwood policy denied this tool call.')[source]#

Authorize Strands tool calls with a Dogwood native authorizer.

Register instances of this class as Strands hooks for BeforeToolCallEvent. If Dogwood denies the request, the hook sets event.cancel_tool with a denial message, which prevents Strands from invoking the tool.

authorizer: NativeAuthorizer#
action: str = 'Drupe::Action::CallTool'#
principal() str#

Resolve the Cedar principal from Strands invocation state.

resource() str#

Resolve the Cedar resource from Strands invocation state.

input_mapper() dict[str, Any]#

Build Dogwood request input from a Strands BeforeToolCallEvent.

deny_message: str = 'Dogwood policy denied this tool call.'#
__init__(authorizer: ~dogwood.native.NativeAuthorizer, action: str = 'Drupe::Action::CallTool', principal: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_principal>, resource: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_resource>, input_mapper: ~collections.abc.Callable[[~typing.Any], dict[str, ~typing.Any]] = <function default_tool_input>, deny_message: str = 'Dogwood policy denied this tool call.') None#
dogwood.integrations.strands.attach_before_tool_call_hook(agent: Any, hook: StrandsPolicyHook) None[source]#

Attach a Dogwood policy hook to a Strands agent.

This imports Strands only when called, keeping dogwood-py free of a hard Strands dependency.

dogwood.integrations.strands.before_tool_call_hook(policy_source: str, policy_schema_source: str, *, event_schema_source: str | None = None, action: str = 'Drupe::Action::CallTool', principal: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_principal>, resource: str | ~collections.abc.Callable[[~typing.Any], str] = <function default_resource>, input_mapper: ~collections.abc.Callable[[~typing.Any], dict[str, ~typing.Any]] = <function default_tool_input>, deny_message: str = 'Dogwood policy denied this tool call.') StrandsPolicyHook[source]#

Create a Strands BeforeToolCallEvent hook backed by Dogwood.

The native Dogwood authorizer is persistent, so policy parsing and lowering happen once when this hook is constructed.

dogwood.integrations.strands.confirm(prompt: str) Any[source]#
dogwood.integrations.strands.default_principal(event: Any) str[source]#

Resolve the Cedar principal from Strands invocation state.

dogwood.integrations.strands.default_resource(event: Any) str[source]#

Resolve the Cedar resource from Strands invocation state.

dogwood.integrations.strands.default_tool_input(event: Any) dict[str, Any][source]#

Build Dogwood request input from a Strands BeforeToolCallEvent.

dogwood.integrations.strands.deny(message: str) Any[source]#
dogwood.integrations.strands.guide(feedback: str) Any[source]#
dogwood.integrations.strands.proceed() Any[source]#
dogwood.integrations.strands.transform(apply: Callable[[Any], Any]) Any[source]#