fix(docs): (DO NOT MERGE) strands integration - #29
Conversation
|
The author of this PR, namrataghadi-galileo, is not an activated member of this organization on Codecov. |
| async def evaluate_controls( | ||
| step_name: str, | ||
| *, | ||
| input: Any = None, |
There was a problem hiding this comment.
this should be Any | None? not sure if Any covers None
There was a problem hiding this comment.
Also, in what situations would this be null?
Same question for the output.
I suppose it would only be the case if there's no args to a tool call and a void output?
| context: dict[str, Any] | None = None, | ||
| step_type: Literal["tool", "llm"] = "llm", | ||
| stage: Literal["pre", "post"] = "pre", | ||
| agent_uuid: str | UUID, |
There was a problem hiding this comment.
wonder if we should get rid of it since im getting rid of it here: #44
There was a problem hiding this comment.
We will have to uptake it once your PR is merged.
| output_text = "" | ||
|
|
||
| # BeforeInvocationEvent - has messages attribute with user input | ||
| if hasattr(event, "messages") and event.messages: |
There was a problem hiding this comment.
Explicit event type checks would be preferable IMHO - for type safety purposes and readability
Same for below for tools
| # selected_tool is an AgentTool object with name attribute | ||
| if hasattr(event.selected_tool, "name"): | ||
| tool_name = event.selected_tool.name | ||
| elif hasattr(event.selected_tool, "__name__"): |
There was a problem hiding this comment.
Did you see a case where you got something that wasn't AgentTool? Same question for below and "get"
There was a problem hiding this comment.
type check refactor takes care of this redundancy
| if isinstance(event.tool_use, dict): | ||
| tool_name = event.tool_use.get("toolName", "unknown-tool") | ||
| elif hasattr(event.tool_use, "get"): | ||
| tool_name = event.tool_use.get("toolName", "unknown-tool") |
There was a problem hiding this comment.
Similar question to the need for "get" here
There was a problem hiding this comment.
agreed. The original code had overly defensive hasattr() checks that don't correspond to any real case in Strands. Refactored code correctly removes these unnecessary checks and uses the actual types
| print(f"🔍 Extracted tool name: {tool_name}") | ||
|
|
||
| # Extract input (pre-stage) or output (post-stage) | ||
| if event_phase == "pre": |
There was a problem hiding this comment.
If you did an isinstance check for BeforeToolCall and AfterToolCall, I think you could even omit the event_phase here?
There was a problem hiding this comment.
Switching to an isinstance check let us remove a lot of code — great catch. This is handled there now.
| content = content.content | ||
|
|
||
| # List of content blocks | ||
| if isinstance(content, list): |
There was a problem hiding this comment.
Do you ever want anything other than plain text?
Our AgentResult also stringifies structured output and citation blocks
There was a problem hiding this comment.
Hooks intercept at a lower level (model/tool calls) BEFORE AgentResult is constructed. What we receive from the events is:
Message.content: list[ContentBlock]
ToolResult.content: list[ToolResultContent]
invocation_state values: Any (strings, dicts, etc.)
So we need more than plain text—thanks for flagging it. We now extract text, citations, tool info, and JSON from ContentBlock/ToolResultContent TypedDicts for control inspection, since those fields can contain content that needs policy enforcement.
Strands Integration Example
Demonstrates automatic safety controls for AWS Strands agents using a reusable hook pattern - no code decorators needed.
What's Included
Core Integration
Interactive Demo (interactive_demo/)
Steering Demo (steering_demo/)
Hook-Based Architecture