Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 0 additions & 1 deletion docs/user-guide/concepts/agents/agent-loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ def event_loop_cycle(
system_prompt: Optional[str],
messages: Messages,
tool_config: Optional[ToolConfig],
callback_handler: Any,
tool_handler: Optional[ToolHandler],
tool_execution_handler: Optional[ParallelToolExecutorInterface] = None,
**kwargs: Any,
Expand Down
28 changes: 14 additions & 14 deletions docs/user-guide/concepts/model-providers/custom_model_provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,41 +290,41 @@ Now that you have mapped the Strands Agents input to your models request, use th

### 5. Structured Output Support

To support structured output in your custom model provider, you need to implement a `structured_output()` method that invokes your model, and has it return a json output. Below is an example of what this might look like for a Bedrock model, where we invoke the model with a tool spec, and check if the response contains a `toolUse` response.
To support structured output in your custom model provider, you need to implement a `structured_output()` method that invokes your model, and has it yield a json output. Below is an example of what this might look like for a Bedrock model, where we invoke the model with a tool spec, and check if the response contains a `toolUse` response.

```python

T = TypeVar('T', bound=BaseModel)

@override
def structured_output(
self, output_model: Type[T], prompt: Messages, callback_handler: Optional[Callable] = None
) -> T:
self, output_model: Type[T], prompt: Messages
) -> Generator[dict[str, Union[T, Any]], None, None]:
"""Get structured output using tool calling."""

# Convert Pydantic model to tool specification
tool_spec = convert_pydantic_to_tool_spec(output_model)

# Use existing converse method with tool specification
response = self.converse(messages=prompt, tool_specs=[tool_spec])

# Process streaming response
for event in process_stream(response, prompt):
if callback_handler and "callback" in event:
callback_handler(**event["callback"])
else:
stop_reason, messages, _, _ = event["stop"]

yield event # Passed to callback handler configured in Agent instance

stop_reason, messages, _, _ = event["stop"]

# Validate tool use response
if stop_reason != "tool_use":
raise ValueError("No valid tool use found in the model response.")

# Extract tool use output
content = messages["content"]
for block in content:
if block.get("toolUse") and block["toolUse"]["name"] == tool_spec["name"]:
return output_model(**block["toolUse"]["input"])

yield {"output": output_model(**block["toolUse"]["input"])}
return

raise ValueError("No valid tool use input found in the response.")
```

Expand Down