toolConfig / toolUse /
toolResult shapes. Define tools with a JSON Schema, the model responds with a
toolUse block (stopReason == "tool_use"), you execute it and send
back a toolResult block. Streaming tool calls arrive as
contentBlockStart (tool identity) followed by contentBlockDelta
events carrying incremental JSON argument fragments — exactly as Bedrock streams them.
response = client.converse(
modelId="gpt-5.4-mini",
messages=[{"role": "user", "content": [{"text": "What's the weather in NYC?"}]}],
toolConfig={
"tools": [{
"toolSpec": {
"name": "get_weather",
"description": "Get current weather for a city",
"inputSchema": {
"json": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
}
},
}
}],
"toolChoice": {"auto": {}},
},
)
# Assistant responds with a tool call
tool_use = response["output"]["message"]["content"][0]["toolUse"]
print(tool_use["name"]) # "get_weather"
print(tool_use["input"]) # {"city": "NYC"}
# Send the tool result back
response2 = client.converse(
modelId="gpt-5.4-mini",
messages=[
{"role": "user", "content": [{"text": "What's the weather in NYC?"}]},
{"role": "assistant", "content": response["output"]["message"]["content"]},
{"role": "user", "content": [
{"toolResult": {
"toolUseId": tool_use["toolUseId"],
"content": [{"text": "Sunny, 72°F"}],
}}
]},
],
)
const response = await client.send(
new ConverseCommand({
modelId: "gpt-5.4-mini",
messages: [{ role: "user", content: [{ text: "What's the weather in NYC?" }] }],
toolConfig: {
tools: [{
toolSpec: {
name: "get_weather",
description: "Get current weather for a city",
inputSchema: {
json: {
type: "object",
properties: { city: { type: "string" } },
required: ["city"],
},
},
},
}],
toolChoice: { auto: {} },
},
})
);
// response.stopReason === "tool_use"
const block = response.output?.message?.content?.[0];
if (block && "toolUse" in block) {
console.log(block.toolUse.name); // "get_weather"
console.log(block.toolUse.input); // { city: "NYC" }
}
resp, err := client.Converse(ctx, &audacityruntime.ConverseInput{
ModelId: audacity.String("gpt-5.4-mini"),
Messages: []types.Message{{
Role: types.ConversationRoleUser,
Content: []types.ContentBlock{&types.ContentBlockMemberText{Value: "Weather in London?"}},
}},
ToolConfig: &types.ToolConfiguration{
Tools: []types.Tool{{
ToolSpec: &types.ToolSpecification{
Name: "get_weather",
Description: audacity.String("Returns current weather"),
InputSchema: &types.ToolInputSchema{
Json: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"city": map[string]interface{}{"type": "string"},
},
"required": []string{"city"},
},
},
},
}},
ToolChoice: &types.ToolChoiceMemberAuto{},
},
})
// resp.StopReason == "tool_use"
// resp.Output.(*types.ConverseOutputMemberMessage).Value.Content[0].(*types.ContentBlockMemberToolUse)
Map<String, Object> schema = new LinkedHashMap<>();
schema.put("type", "object");
Map<String, Object> props = new LinkedHashMap<>();
Map<String, Object> cityProp = new LinkedHashMap<>();
cityProp.put("type", "string");
props.put("city", cityProp);
schema.put("properties", props);
schema.put("required", List.of("city"));
ConverseResponse resp = client.converse(request -> request
.modelId("gpt-5.4-mini")
.messages(Message.builder()
.role(ConversationRole.USER)
.content(ContentBlock.fromText("What's the weather in NYC?"))
.build())
.toolConfig(tc -> tc
.tools(Tool.builder()
.toolSpec(ts -> ts
.name("get_weather")
.description("Get current weather for a city")
.inputSchema(ToolInputSchema.builder().json(schema).build()))
.build())
.toolChoice(ToolChoice.auto())));
ContentBlock block = resp.output().message().content().get(0);
if (block.toolUse() != null) {
System.out.println("Tool: " + block.toolUse().name());
System.out.println("Args: " + block.toolUse().input());
}
// Rust follows the identical canonical shape: a ToolConfiguration with
// toolSpec { name, description, inputSchema.json } entries and a toolChoice
// of Auto / Any / Tool{name}. The assistant reply carries
// ContentBlock::ToolUse { tool_use_id, name, input } blocks and
// stop_reason == "tool_use"; return results with ContentBlock::ToolResult.
//
// See the crate docs for the builder signatures — they mirror
// aws-sdk-bedrockruntime member-for-member.